docs release evidence p13 t04b binding - AlexandreZanata/Abastevo GitHub Wiki
P13-T04B — Contributor binding + recovery audit
Status: LOCAL_DONE on codex/phase-13-free-accounts (phase PR #27,
draft). Issue: #25 (slice 2 of P13-T04; T04C cross-module erasure +
transport follows). No live-provider contact; no identity imports —
ports only, stubs in tests.
Slice acceptance (frozen before coding)
- T04B (this commit) — binding core: migration
000022(account_contributor_bindingswithUNIQUE(contributor_id)+account_binding_auditappend-only), dual-proofBind(live session + key proof, account server-derived), stolen-ID refusal, same-account converge,Unbind+ not-found, audit trail, delete drops bindings. Freshness holds by construction (access ≤900s). No transport/OpenAPI (T04C). - T04C (next) — key-proof production adapter, bind/unbind transport, cross-module erasure on delete, old-key/session revoke races.
What changed
db/migrations/000022_account_bindings.sql(append-only) +sqlc.yamlstanza + 9 owner queries + committed regeneration.account/domain:ContributorBinding,BindingAudit, bind/unbind actions;ErrBindingCrossAccount(binding-cross-account-refused),ErrBindingNotFound,ErrBindingInvalid,ErrKeyUnavailable+ verdicts;KeyProverport (opaque proof in, proven fingerprint out).account/application:Storegains bind/unbind/list/owner/audit;binding.goceremony (session → status pre-check → key proof → atomic bind+audit);Service.KeyProver(nil fails closed).account/adapters:MemStoreparity +PGStoretransactional lanes (owner check then insert/update, unique-race maps to cross-account);DeleteAccount(both) drops bindings.contracts/testdata/account/account-binding-cross-account.jsonfrozen stolen-ID vector.
RED → GREEN
- RED proven by dropping the
byContributorstolen-ID guard inMemStore.BindContributor: the stolen bind succeeds and persists a second owner row instead of refusing; GREEN on restore. - Status-first ordering reused from T04A (suspended/deleted binds refuse before key verification, without burning proofs).
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/...
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/...
make quick-verify
git diff --check
Outcome: unit 6/6 green (6 new binding suites); integration with
-race green (4 new PG suites incl. 16-way same-contributor race
splitting winners/refusals with one surviving owner);
quick-verify selection=full ok 16s; diff --check clean; secrets
scan clean.
Limits (not claimed)
- Production key-proof adapter, bind/unbind transport + OpenAPI, cross-module social erasure and old-key revoke races are T04C.
- Audit retention purge follows the scheduler inventory (P07-T05 pattern); no TTL delete in this slice.
- Live providers stay P13-T05/G13.
Rollback
Append-only migration stays; code rollback = revert binding use cases, store methods, queries and vectors. No transport to unwind.
Next
P13-T04C binding transport + erasure wiring (#25, same branch). Issue #25 stays open until the phase PR merges.