# AGENT-PROMPT-v5-P1-1b — O10 amendment 3: decompose into four independently reviewed increments

**Date:** 2026-08-06
**Follows:** `docs/AGENT-PROMPT-v5-P1-1b-o10-amendment.md`, `-o10-amendment-2.md`,
`docs/p1-1b-status.md` (the third-Reject stop record at the pushed tip),
`docs/p1-1b-o10-independent-review.md` (all three review rounds), `docs/PROJECT-STATE.md`
**Authority:** Miguel, after reviewing the repeated-failure pattern as amendment-2 required.
This amendment changes **strategy**, not substance: it reopens no decision. O9-P, O9-D1…D5,
and O10-D1/D2 remain closed and govern unchanged. The five completeness baselines stay
119 / 119 / 52 / 221 / **2,787**, and the two `Routine` rows still import verbatim. Rejected
`b324a3e…`, `57f0f023…`, and `7ea6c0f…` remain neutralized evidence only — never resurrected,
never cherry-picked, not even in part.

## Why strategy changes: the pattern across three rejects

Three consecutive from-scratch implementations of one corrective migration were independently
rejected. The findings did not converge toward zero — they moved between categories:

- **Provenance integrity (R4) was flagged in round 2 and flagged again, differently, in round
  3** after a claimed fix. A requirement that survives two remediation attempts inside one
  monolithic change is not being closed by construction; it is being patched at the surface.
- **Company-scoping escalated between rounds** — an audit-completeness Medium in round 2 became
  an authorization-boundary High in round 3. A cross-cutting invariant (every governed write is
  company-scoped and company-audited) is not surviving contact with a change this large.
- **Half of round 3's findings are about proof, not code** — a NULL round-trip test that never
  touches a real database, a "complete catalog" proof that omits new roles/ACLs/functions, an
  EF model that silently drifts from its own generated columns. These are the failure mode of a
  large surface reviewed and tested all at once: individually tractable properties get lost in
  aggregate.

Conclusion: the corrective work is correct in outline (O9-D1…D5, O10-D1/D2 all survive review
unchanged across all three rounds) but too large a single unit to implement and prove
correctly in one pass. **This amendment splits it into four independently reviewed increments,
each gated on the previous one's Accept verdict before it starts** — the same sequencing
pattern that worked for O8→O9→O10 as separate decisions, now applied inside O10's own
implementation.

## The four pieces

Every open finding from all three rounds is assigned to exactly one piece below. If an
implementer believes a finding belongs somewhere else, that is a stop-and-report, not a
judgment call.

### Piece A — Schema completeness and honest validator observation

**Scope:** pure additive DDL plus the validator surface that observes it. No roles, no
`SECURITY DEFINER` functions, no governed commands.

- O9-D1/D2/D3 nullability relaxations (`ENTMST.DirectDebit`, `ENTMST.TaxIdVerificationStatus`,
  `DOCEFL.ItemClass`).
- O9-D4 six-literal `ReviewPriority` CHECK (`Before Posting`, `High`, `Immediate`,
  `Informational`, `Periodic Review`, `Routine`).
- O9-D5 terminal DOCFLG `ResolutionEvidence` CHECK re-scoped to non-imported rows.
- O10-D1: DOCFLG snapshot `ItemClass` nullable; the composite FK stays declared and self-scopes
  under `MATCH SIMPLE`; a plain `EFCode` FK is added; the prospective full-snapshot CHECK binds
  every non-imported instance.
- The accepted P1-1a fixture updated from historical `EF0000046` to O8-authorized `EF0000053`.
- **R5 (round 2), carried forward:** validator/DTO surfaces preserve NULL as NULL; no invented
  `false` / `Verified` / `Annotation` defaults anywhere the new nullable columns are read.
  **Required proof, restated because round 3's attempt did not satisfy it:** a test that writes
  genuine SQL `NULL` through a real disposable-database insert, reads it back through
  `PostgresRegistryValidationSnapshotSource`, and asserts the DTO/validator value is still null
  — no in-memory construction, no reflection over constructor defaults.
- **ENTMST count scope (round 3 Medium), carried forward:** the validator source for the
  `DirectDebit`/`TaxIdVerificationStatus` findings must select every imported ENTMST row the
  baselines govern, not only rows referenced through FDCHDR/FDCDTL. Prove the 119/119 counts
  reproduce against the full imported entity set, with a test fixture containing at least one
  imported entity with no FDCHDR/FDCDTL reference.
- Every generated column this piece touches (if any) is modelled in the EF snapshot exactly as
  generated, matching the SQL catalog — not as an ordinary nullable column.

**Acceptance:** TDD; disposable suite green including the NULL round-trip and full-scope-count
tests above; `Down` removes exactly what this piece's `Up` added; build 0 warnings; push;
**independent review, Accept required before Piece B starts.**

### Piece B — Provenance integrity as a database-enforced invariant

**Scope:** `RegistryFieldProvenance` alone — its constraints, triggers, and every governed
write path that touches it (including `WaiveDOCFLG`). No other accepted object changes.

- **R4 in full, this time closed by construction, not patched:** FK from every provenance row
  to its target row; company agreement between the provenance row and its target; exact
  cardinality (a governed snapshot member has exactly one provenance row); `absent` provenance
  exists only where the value is genuinely NULL. This must hold across **every** path that can
  change a provenance row's target or the row itself: `INSERT`, `UPDATE`, `DELETE` (the trigger
  must not return early on delete without a cardinality recheck), and moving a provenance row
  to a new target (the old target must be rechecked too). DOCEFL insertion gets its own
  exact-one cardinality trigger. `WaiveDOCFLG` must not be able to populate
  `ResolutionEvidence` while leaving stale `absent` provenance with a NULL hash — the accepted
  terminal command and the provenance invariant must agree on every path, not just the happy
  path.
- Any generated column this piece adds to `RegistryFieldProvenance` (e.g. `DOCEFLCode`,
  `DOCFLGFlagInstanceID`) is modelled in the EF snapshot exactly as generated.
- **R7, verified here and re-verified in Piece D:** the accepted `ImportEvidenceRow` uniqueness
  constraints are untouched — same names, same definitions, same semantics. Nothing replaces
  them with partial indexes or any other structure.

**Required proof:** schema-level rejection tests (not application-code checks) for: a missing
provenance row, an orphan provenance row, a wrong-company provenance row, a
value/provenance-contradiction row, a delete that would break cardinality, and a move that
leaves the old target inconsistent. A test proving `WaiveDOCFLG` cannot leave stale `absent`
provenance with a NULL hash.

**Acceptance:** TDD; disposable suite green; `Down` exact; build 0 warnings; push;
**independent review, Accept required before Piece C starts.**

### Piece C — Governed commands: roles, company-scoped authorization, concurrency

**Scope:** `AssignDOCEFLItemClass` (O10-D2's atomic snapshot-completion command) and the
evidence-append command, plus whatever roles and `SECURITY DEFINER` surface they need. Assumes
Piece A's nullable columns and Piece B's provenance invariants are already in place and
accepted.

- **O10-D2:** the governed assignment command completes `NULL` snapshots atomically
  (`NULL`→value, `absent`→`authored`) and never modifies a non-null snapshot.
- **R1, fail-closed role provisioning (round 2):** the migration never adopts a pre-existing
  role. It grants ownership, DML, or `SECURITY DEFINER` reachability only to roles it creates
  itself, in this same piece's migration. If an expected role name already exists, `Up` fails
  closed with a clear error. **Proof:** a disposable test creates a hostile pre-existing role
  with an expected name and proves `Up` refuses; a normal-path test proves the roles are
  created fresh.
- **R6, accurate and complete company scope (round 2 Medium → round 3 High):** `P11aCurrentActor`
  authorizes one company; `AssignDOCEFLItemClass` touches a global rule's DOCFLG rows across
  potentially many companies. The command must prove authority for **every** company it writes,
  not just the caller's, and must audit **every** affected company — including inactive ones —
  with exact per-company completion counts. The evidence-append audit records the governed
  value/hash it appended. **Proof:** a multi-company test where the test principal is
  authorized for only a subset of affected companies, proving the command either fails closed
  for the unauthorized companies or requires elevated multi-company authority explicitly; a
  test with an inactive affected company proving it still receives its audit row.
- **R3, genuine concurrency, both orderings (round 2 → round 3 Low):** the assignment command
  and the importer serialize on the parent DOCEFL rule (row lock on `EFCode` or equivalent).
  **Proof:** two concurrency tests, each genuinely concurrent (not sequential-with-mocked-
  timing) — assignment committed before an in-flight import lands, and import in flight while
  an assignment runs — each proving no unaudited NULL snapshot survives and the audited count
  is exact.
- **R2, scoped to this piece's own objects:** `Down` performs no `DROP OWNED`, changes no
  ownership of any object it did not create (explicitly including `WaiveDOCFLG` — this piece
  must not touch it at all), and restores any accepted function it must reference to its
  accepted definition byte-exactly if it was ever altered (it should not need to be).

**Acceptance:** TDD; disposable suite green; `Down` exact for this piece's own objects; build 0
warnings; push; **independent review, Accept required before Piece D starts.**

### Piece D — Integration gate: cumulative catalog equivalence and Scope 1 readiness

**Scope:** no new migration content. This is verification that Pieces A + B + C together are
byte-exact-invertible and complete, run once all three are independently Accepted.

- **R2 in full, cumulative:** a recorded `pg_catalog` snapshot (objects, owners, ACLs,
  constraint and index names, function definitions — including every role, ACL, and function
  Pieces A–C added) taken before the combined `Up` sequence, compared to the state after the
  combined `Up` → `Down` → `Up` cycle. The post-`Down` state must equal the pre-`Up` accepted
  P1-1a catalog exactly; the second `Up` must reproduce the first exactly. This closes the
  proof that rounds 1–3 all found incomplete.
- **R7, re-verified end to end:** `ImportEvidenceRow` uniqueness constraints unchanged after
  the full combined cycle.
- **The five completeness baselines end to end:** 119 / 119 / 52 / 221 / 2,787, plus the two
  `Routine` rows importing verbatim, measured against the full combined migration set in one
  disposable-database run.
- **Unknown-`ItemClass` fail-closed coverage, both imported and native rows** (the recurring
  "required coverage" item from every round): confirm it still holds after the full sequence.
- Full disposable suite, focused registry tests, ordinary suite, build 0 warnings, 0 residual
  containers.

**Acceptance:** an integration-focused independent review (lighter than a from-scratch
adversarial pass, since A/B/C each already passed one) confirming the cumulative proof above
holds and that nothing at the seams between pieces was missed. **Accept here is what
authorizes the Scope 1 restart** — not before.

## Process rules, binding across all four pieces

- **One piece implemented and pushed at a time.** Do not start Piece B until Piece A has a
  recorded Accept verdict; the same for C after B and D after A+B+C.
- **Minimal-surface discipline, carried from amendment-2, applies to every piece
  individually:** each piece's migration is strictly additive against the accepted P1-1a
  catalog plus whatever prior pieces already added and were Accepted. It must not alter, drop,
  re-own, or replace any object it did not itself create, unless a numbered requirement above
  names that exact change. An apparent need to touch an unnamed object is a stop-and-report.
- **A piece that is Rejected is neutralized exactly as before** — a normal branch-tip stop
  commit restoring that piece's changed paths byte-for-byte to its own starting point — and
  only that piece is reattempted. Earlier Accepted pieces are not touched, re-litigated, or
  re-reviewed.
- **A piece rejected twice stops and escalates to Miguel**, tighter than the project-level
  three strikes, because a piece is deliberately narrow: two failures on a narrow, well-scoped
  surface is already a strong signal that either the requirement needs Miguel's clarification
  or the piece needs further splitting.
- **Green build and tests are never semantic proof by themselves**, for the fourth time.
- **This is only Piece A's authorization.** Implement Piece A now. Stop after its independent
  review records a verdict — Accept or Reject — and report. Pieces B, C, and D each need their
  own go-ahead once the piece before them is Accepted; this amendment pre-authorizes their
  content so no further amendment is needed, but not their start.

## What this amendment does not authorize

Any prototype write. Resurrecting or cherry-picking any part of `b324a3e…`, `57f0f023…`, or
`7ea6c0f…`. Starting Piece B, C, or D before its predecessor's Accept verdict is recorded.
Reopening O9-P, O9-D1…D5, or O10-D1/D2. Any shared/live database write before the complete
disposable rehearsal passes and a verified fresh backup exists. Production go-live (O5 remains
open and remains the project's only other item). History rewrite in either repository.

## Report after each piece

Commit hash; the requirements this piece closes with proof evidence per item; the independent
review verdict in full; build/test/container evidence; and, only after Piece D's Accept, the
statement that Scope 1 is ready to restart at preflight against pin `b917685…`.
