# AGENT-PROMPT-v5-P1-567 — Governance train: flag governance, persisted review queues, decision-application engine

**Date:** 2026-08-06
**Follows:** `docs/AGENT-PROMPT-v5-P1-1b.md` and its C8/O8/O9 amendments,
`docs/PROJECT-STATE.md`, `docs/project-todo.md` (P1-5, P1-6, P1-7 sections — the normative
item lists this prompt executes), `docs/p1-0-vocabularies.md`, the six P1-0 drafts
**Authority:** Miguel. This prompt authorizes the **P1-5 + P1-6 + P1-7 train** — the governance
backbone every UI phase depends on. It does not authorize P1-2, P1-3, P1-4, P1-8, P1-9, any
production go-live claim (O5 remains open), or any deployment; deployment of this train is a
separate authorization. It reopens no closed decision.

## Gate — this prompt does not start until all of these are true

1. `docs/PROJECT-STATE.md` records **O9 closed** and **P1-1b Scopes 1–6 complete** with the
   disposable rehearsal green (Scopes 7–8 may or may not be done; they are not a precondition,
   but if the hash-index swap (Scope 7) has shipped, build on the swapped index, not the old one).
2. The imported reference layer exists and its counts are recorded in `docs/p1-1b-status.md`
   (expected shape: 52 imported + 2 authored DOCEFL rules, 19 DOCTYP rules, ~2,787 DOCFLG
   instances, the imported `user_observations` set, and the O9 data-quality baselines).
3. Sibyla builds clean at 0 warnings and the full ordinary suite passes at the branch tip you
   start from.

If any is false: **stop and report.** If `PROJECT-STATE.md` contradicts this prompt anywhere,
stop and report the contradiction.

## Standing context you must honor

- **The imported data is the acceptance fixture.** Synthetic fixtures are for TDD; phase
  acceptance runs against a disposable database seeded by the accepted P1-1b import path with
  the real imported set. The prototype (read-only, at the recorded pin) is the behavioral
  reference for ported logic; its scripts are spec, never code to call.
- **O9-D3 is in force:** imported DOCEFL rows carry `NULL` `ItemClass` until governed
  assignment. Everything in this train must handle `NULL` `ItemClass` gracefully — it is a
  counted data-quality finding, never a crash, never a silent default, never a reason to stop.
- **O9-P is in force:** completeness gaps on imported historical rows are data-quality
  findings. Identity-class violations (unknown vocabulary literal, permanent-code conflict,
  natural-key collision) remain fail-closed findings raised loudly.
- **Every literal comes from `docs/p1-0-vocabularies.md`** (as amended by O9-D4's six-literal
  `ReviewPriority`). Never from prose, never from memory. Hyphenation is load-bearing.
- **Schema:** the accepted P1-1a migration and the P1-1b corrective migration are immutable.
  Preflight the deployed schema against what this train needs; anything missing (a table, a
  column, an index) arrives by **additive migration with its own tests** — report exactly what
  was missing and why, and keep `Down` scoped to what you add.
- Server-side authority: every new governed command follows the accepted `RuntimePrincipal`
  pattern — caller-set GUCs grant nothing.

## Scope, in order

### Stage A — P1-5, flag governance (DOCEFL/DOCFLG, blocking, grandfathering)

Execute the P1-5 backlog items exactly as written in `docs/project-todo.md`:

1. **DOCEFL as the rule catalogue** — rules are data (52 imported + sentinel `EF0000000` +
   inactive Monthly-gap `EF0000053`), administered later in P1-8, never code. The governed
   activation guard (`RequireRunnableActiveDecisionDOCEFL` / `ActivateDOCEFLRule`) and the
   O9-D3 `ItemClass` assignment command are the only write paths besides import.
2. **DOCFLG as the instance log** — lifecycle and audit authority; an instance has its own
   identity and status and is never recomputed away. The C13 five-field natural key rule and
   the S2 snapshot rule (instance snapshots the rule's `ItemClass` at detection, never
   recomputed) are settled — implement them, do not re-litigate them.
3. **The blocking vocabulary** — `Block Document`, `Block Financial Entry`,
   `Block Classification`, `Block Reconciliation` — reconciled deliberately with v4's "gates"
   so the system has **one** enforcement mechanism.
4. **`blocking_open_instances()` as the single enforcement view**, wired in code from the
   start. The capture/entity/item flows it guards mostly do not exist yet (they are P1-4):
   implement the view, the .NET service surface over it, and its tests now; document each
   future wiring point explicitly in the status record. DOCRQE displays blocking but never
   enforces it.
5. **Prospective enforcement with grandfathering** — consume the `IsGrandfathered` values
   persisted at import (never recompute); port TC5: a blocked document cannot post, a
   grandfathered one does not block.
6. **Supersede logic is not append-only** — every dimension supersedes against its own current
   finding set; port the Stage 10 R6 lesson (26 stale findings) as a regression test.
7. **Idempotent flag writes**; human review state is never destroyed.

**Stage A acceptance** (against the imported set in a disposable database): a blocked item is
refused by code rather than discipline; grandfathered rows import without raising; a detector
whose finding disappears supersedes its instance within one run; the 172-open / terminal split
measured on the imported instances is recorded as a control (*Initial + Expected = Result*).

### Stage B — P1-6, persisted review queues (DOCRQE + RECREV)

Execute the P1-6 backlog items exactly as written:

1. **DOCRQE (document) and RECREV (line) as persisted tables** sharing one layout and one
   vocabulary; permanent ReviewIDs; never-delete semantics; decisions survive full reruns.
2. **The 5-value decision vocabulary** — `Accept`, `Reject`, `Accept with Changes`,
   `Need More Information`, `Defer`; `Accept with Changes` carries structured single-field
   master-data edits.
3. **Structural fields** — `Status`, `DecidedBy`, `DecisionDate`, `AppliedReference`,
   `TargetField`, plus the finding discriminator on the RECREV key.
4. **`ItemClass` as a first-class column under the S2 snapshot correction.** Only
   Decision-class items are ever Open; Status and Annotation are never Open and never counted
   as work outstanding. A reviewer's UserDecision overrides the classifier immediately.
   Imported rows whose rule `ItemClass` is still `NULL` (O9-D3) surface in a distinct
   "unclassified" bucket — counted as the existing data-quality finding, excluded from the
   Open count, never coerced.
5. **A finding that clears is CLOSED with evidence** — Retained ≠ Open; no annotate-and-leave-
   open ghosts.
6. **Severity tiering as ordering** over the persisted table, not a recomputation;
   `Critical` reserved for actively-blocking DOCFLG-linked items.
7. **The Observations mechanism** — one note keyed to a list of ReviewIDs, surfaced on both
   queues; seed it from the imported `user_observations` set.

**Stage B acceptance:** a decision recorded on either queue survives two full pipeline reruns
byte-identically; an Observations note stamped on ten items renders on all ten (service-level
render — the UI is P1-9); the ItemClass split over the imported instances is measured and
recorded, with the phantom-backlog contrast (open Decision-class vs. total) stated in the
status record.

### Stage C — P1-7, decision-application engine

Execute the P1-7 backlog items exactly as written:

1. **One engine serving both queues**, executing `Accept` and `Accept with Changes` against
   target tables: flags, structured single-field master-data updates, RECREV links.
2. **Reject-persistence as a matcher constraint** — a rejected proposal is never re-proposed
   by any matcher on any subsequent run; enforce it in the schema so a violating insert fails
   with SQLSTATE `23514` regardless of MatcherKind.
3. **Decisions map to DOCFLG status transitions** so an applied decision closes its flag
   instance through the Stage A lifecycle, with evidence.
4. **Every application writes an audit record** correlated to the ReviewID and the actor,
   through the server-side principal.

**Stage C acceptance:** a real decision on each queue executed end to end; the reject-once /
refused-everywhere proof (rerun + second matcher both receive `23514` for the same
company/source/candidate identity); control records *Initial + Expected = Result*; idempotency
byte-stable across reruns.

## Discipline

TDD first on every stage. Disposable PostgreSQL 17 for all database acceptance, through the
established runner pattern, containers removed in `finally`, 0 residual. Build 0 warnings at
every commit; ordinary suite green; each stage lands as its own reviewed, pushed commit series
with clean multi-line bodies (no literal `\n`). Records as you go: `docs/p1-567-status.md`
with per-stage control tables, `docs/PROJECT-STATE.md` phase table and changelog,
`docs/project-todo.md` items ticked as they genuinely complete — never in advance.

## What you may not do

No UI (P1-8/P1-9), no extraction runtime (P1-2/P1-3), no P1-4 pipeline flows beyond the
documented wiring points, no bank-matching logic (P1-11). No prototype writes. No edits to the
accepted P1-1a or P1-1b migrations. No live/production database write and no deployment under
this prompt — all acceptance is disposable-database; a live rollout is a separate
authorization. No invented data: imported rows keep their honest NULLs and provenance; the
governed commands are the only mutation paths. No reopening of C1–C19, S1–S4, D1–D9, A1–A7,
B1, O7, O8, or O9. If sources conflict or are silent, stop and report.

## Report at the end

Commit hashes per stage; the additive migrations added, each with its justification; per-stage
acceptance evidence with control tables; the measured ItemClass and blocking splits over the
imported set; data-quality counts touched (unchanged unless a governed command ran, and then
by exactly the audited amount); test totals (ordinary, focused, disposable) and container
hygiene; the updated backlog tick count; and the exact list of what still separates the train
from P1-8/P1-9 readiness.
