docs release evidence p13 t04a status lifecycle - AlexandreZanata/Abastevo GitHub Wiki
P13-T04A — Account suspension/deletion + status enforcement
Status: LOCAL_DONE on codex/phase-13-free-accounts (phase PR #27,
draft). Issue: #25 (slice 1 of P13-T04; slice plan below — P13-T04 is
oversized for one commit, so it ships letter-suffixed per ROADMAP
rules). No live-provider contact; no contributor-key binding yet.
Slice acceptance (frozen before coding)
- T04A (this commit) — status lifecycle + enforcement:
Suspend(status + revoke all families atomically),Reactivate(suspended→active; sessions stay revoked; deleted refuses),Delete(status + revoke + drop address/provider bindings; audit row stays). Status-first ordering on consume (pre-check without code burn + post-session race guard), refresh (pre + post-rotate guard with revoke),ValidateAccess(covers all session transport), link (pre-check before nonce burn + store re-check), unlink (store check). Deleted addresses re-sign as NEW accounts. Transport:POST /v1/accounts/deletionself-delete + 403/410 mapping. Suspend has no public route (operatorServiceAPI). - T04B (next) — contributor-key binding with fresh reauth, stolen-ID cases, old-key/session revoke races, cross-module erasure (community/evidence/trust) and recovery audit.
What changed
account/domain:ErrAccountSuspended(account-suspended),ErrAccountDeleted(account-deleted) + verdicts (ports.go,stdlib_test.go);Account.Active()(account.go).account/application:StoregainsGet/Suspend/Reactivate/ DeleteAccount;status.gouse cases +accountUsable(unknown status fails closed as suspended);RequestCodeskips issuance for dead addresses with identical nil answers (no oracle);ConsumeCode/Refreshrace guards revoke-then-refuse;LinkProviderpre-checks before nonce burn.account/adapters:MemStore+PGStore(SetAccountStatus,DeleteAccountAddresses/Providersvia new sqlc queries, stanza unchanged — same000021schema); suspend/delete are single transactions (status + revoke + drops).account/adapters/http:POST /v1/accounts/deletion(session-derived self-delete only; suspended callers use the operator path),fail()403 suspended / 410 deleted.contracts/openapi/v1.yaml: additivedeletionpath +Goneresponse ref + 403/410 refs on consume/refresh/link/unlink/list;vacuum0 errors/0 warnings (DELETE-with-body and verb-in-path variants refused during work:no-request-body,no-http-verbs-in-path; POST noun path is the repo convention).contracts/testdata/account:account-suspended.json,account-deleted.jsonfrozen vectors.
RED → GREEN
- RED proven by dropping the consume pre-check: the suspended
consume burns the code and the reactivated re-consume fails with
code already consumedinstead of succeeding; GREEN on restore. - Status-first ordering proven by post-suspend refresh answering
suspended(notrevoked) in unit + PG suites.
Validation (exact commands, this host)
cd backend && GOTOOLCHAIN=go1.27.1 go build ./... && sqlc vet && sqlc generate
gofmt -l internal/modules/account; GOTOOLCHAIN=go1.27.1 go vet ./internal/modules/account/... ./cmd/api/...
GOTOOLCHAIN=go1.27.1 go test -count=1 ./internal/modules/account/...
export ANPFUEL_TEST_DATABASE_URL=postgres://anpfuel:[email protected]:5434/anpfuel?sslmode=disable
GOTOOLCHAIN=go1.27.1 go test -count=1 -race -tags=integration ./internal/modules/account/...
vacuum lint -r contracts/openapi/vacuum-rules.yaml contracts/openapi/v1.yaml --no-update-check
(cd backend && GOTOOLCHAIN=go1.27.1 go test -count=1 ./internal/platform/apicontract/...)
make quick-verify
git diff --check
Outcome: unit 6/6 green (5 new status suites + 8 HTTP incl. 4
deletion suites); integration with -race green (3 new PG status
suites incl. 16-way post-delete refresh all deleted); build
ok; sqlc clean + stable; vacuum 0/0/13 info; apicontract ok;
quick-verify selection=full ok 10s; diff --check clean; secrets
scan clean.
Limits (not claimed)
- Contributor-key binding, fresh-reauth proofs, stolen-ID races and cross-module social erasure are T04B.
- Suspended self-delete via transport refuses 403 (operator
Service.DeleteAccountcovers it); unsuspend is operator-only. - Nonce ledger has no purge; live providers stay P13-T05/G13.
Rollback
No migration change in this slice (status columns since 000020).
Code rollback = revert status use cases, enforcement guards,
transport route, OpenAPI additions and vectors; stores keep inert
methods.
Next
P13-T04B contributor binding + cross-module erasure (#25, same branch). Issue #25 stays open until the phase PR merges.