## Summary
This PR is Phase 3 of 5 in [AERIE-2174 — Bring Document Field Reconciliation to Forge parity](https://linear.app/builder-team/issue/AERIE-2174).
It adds Aerie's verified reconciliation write boundary: final registration, rollout, receipt, source, proposal, citation and target-state checks; atomic Site, history, provenance, audit and execution updates; replay and concurrency protection; and bounded authorised evidence projections. The product slice is tracked by [AERIE-2195 — Port the verified reconciliation write boundary](https://linear.app/builder-team/issue/AERIE-2195), with the current-main delivery tracked by [AERIE-2437 — Reconstruct the Phase 3 verified-write slice from current main](https://linear.app/builder-team/issue/AERIE-2437).
Production effect: dormant/additive. commitVerified remains an internal mutation with no production caller. Registration controls are capability-gated and default disabled. Merging this PR starts no reconciliation run, external traffic, deployment, upstream writeback or Site mutation. Phase 4 owns lifecycle activation and automation.
---
## Why
Phase 2 lets agents read immutable evidence and validate proposals, but it deliberately cannot change Aerie fields. Phase 3 establishes the system-of-record boundary that independently revalidates every proposal immediately before an atomic write. This prevents stale evidence, revoked rollout permission, replay, concurrent commits or malformed citations from producing partial or unaudited Site changes, and gives Phase 4 a safe internal commit primitive to call later.
---
## Business Value
- Allows approved reconciliation proposals to update Aerie safely without granting agents direct write access.
- Preserves a complete, queryable decision trail across field history, provenance and audit records.
- Prevents stale, duplicated, partially applied or no-longer-authorised changes.
- Provides bounded and redacted evidence projections for operators and future Site-facing presentation.
- Establishes the dormant write primitive required before lifecycle automation can be introduced.
---
## How does it work
1. Capability-gated registration controls create and manage one pinned Workflow Instance and service user. Changes fence existing executions and revoke live read grants before control state changes.
2. commitVerified({ executionId }) reloads the execution, registration, rollout policy, immutable receipt, current source facts, accepted proposal, citations and current target state inside the final mutation boundary.
3. Aerie's field policy converts only valid set, replace and clear operations into a mutation plan. Stale, revoked, malformed, conflicting or already-terminal state fails closed or returns its existing terminal outcome without a partial write.
4. A valid update atomically patches the Site, advances its revision, records generic field history and current provenance, writes a redacted audit entry and closes the execution. No-update and no-write outcomes close without false field history or provenance.
5. Authorisation-first admin queries expose bounded field evidence, citation detail, reconciliation history and run lineage while keeping raw storage rows and private source content internal.
6. The write boundary remains unused by production orchestration in this phase. Phase 4 will own start, poll, recovery, settlement, scheduling and cron registration.
---
## Scope
### Included in this phase
- Capability-gated reconciliation registration controls and execution fencing.
- Internal verified commit with final receipt, rollout, source, proposal, citation and target-state checks.
- Atomic Site revision, history, provenance, audit and execution closure.
- Replay, concurrency, rollback and stale-state protection.
- Bounded, authorised and redacted evidence/history/lineage projections.
- The deletion-reduced AERIE-2279 test surface plus eight focused review regressions: 1,412 physical lines across 24 Phase 3 tests.
- Exact final diff paths:
chat/convex/_generated/api.d.tschat/convex/reconciliation/admin.test.ts
chat/convex/reconciliation/admin.ts
chat/convex/reconciliation/commit.test.ts
chat/convex/reconciliation/commit.ts
chat/convex/reconciliation/operator.ts
chat/convex/reconciliation/readiness.ts
chat/convex/reconciliation/reads.ts
chat/convex/reconciliation/registry.test.ts
chat/convex/reconciliation/registry.ts
chat/convex/rhodes/runtime/audit.ts
### Deliberately excluded for later phases
- Coordinator start, poll, recovery and terminal settlement — Phase 4 / AERIE-2196.
- Scheduler and cron registration — Phase 4 / AERIE-2196.
- Any production caller of commitVerified — Phase 4 / AERIE-2196.
- Site-facing evidence and decision-lineage presentation — Phase 5 / AERIE-2197.
- Roswell and Austin end-to-end execution — deferred until the complete stack is reviewed and integrated.
- Deployment, activation, asset publication, credential binding, shared-data mutation and upstream REBL3, Rhodes or Due Diligence writeback.
- Specifications, implementation evidence, review reports and temporary workflow artifacts.
---
## Test plan
### Automated validation
- focused commit, registry, admin and policy tests — 34/34 passed (pnpm --dir chat exec vitest run convex/reconciliation/commit.test.ts convex/reconciliation/registry.test.ts convex/reconciliation/admin.test.ts convex/reconciliation/rolloutPolicy.test.ts convex/reconciliation/propertyAcquisitionFieldPolicy.test.ts)
- Phase 3 tests — 24/24 passed across admin.test.ts, commit.test.ts and registry.test.ts (16 retained AERIE-2279 tests plus 8 focused review regressions)
- complete current reconciliation suite — 65/65 passed (pnpm --dir chat exec vitest run convex/reconciliation)
- Chat typecheck — passed (pnpm --dir chat typecheck)
- architecture boundaries — passed (pnpm lint:boundaries)
- Convex paths — passed (pnpm lint:convex-paths)
- read bounds — passed (pnpm lint:read-bounds)
- test architecture — passed (pnpm lint:test-architecture)
- exact repair-path Biome — passed for all AERIE-2441, AERIE-2442 and AERIE-2454 paths; the existing generated declaration remains ignored by repository configuration
- git diff --check — passed
- exact-head scope — the reviewed Phase 3 commit plus three bounded repair commits over current main, exactly the 11 paths listed above
- independent write-safety review — PASS on tree 65f0f91b024ab6f3737b97d09bb72eb6cad782bf
- independent scope and test-architecture review — PASS on the same tree
- production preservation — the accepted Phase 3 implementation remains intact except for the bounded AERIE-2441, AERIE-2442 and AERIE-2454 integrity repairs recorded below
- reduced-test preservation — all 16 accepted AERIE-2279 behaviours remain, with exactly eight focused review regressions; 1,412 physical lines across the three Phase 3 test files
- dormancy audit — commitVerified has no production caller; no coordinator, settlement, scheduler, cron, external fetch or upstream-writeback surface added
### Time for Implementation
An engineer working without AI assistance would likely need 3 to 4 weeks to recover and reconcile the accepted implementation, reduce and validate the write-safety tests, review the transaction and authorisation boundaries, resolve current-main integration, and prepare the slice for review.
---
## Review repairs and contract clarifications
Mercy review [5307918096](https://github.com/AI-Builder-Team/Aerie/pull/1489#pullrequestreview-5307918096) was classified at reviewed head 373a1eb1cb844d7295dab6062dca6d6f5141c173 under [AERIE-2441](https://linear.app/builder-team/issue/AERIE-2441/fix-the-3-valid-blockers-from-mercys-first-phase-3-review).
Three blockers were repaired before merge:
- Receipt freshness now distinguishes an ordinary source or target mismatch from a structural or unexpected capture failure. Only the former may close the execution as stale; the latter rejects the mutation atomically without history or execution writes.
- The admin history projection preserves canonical JSON null while treating malformed, missing or oversized stored JSON as unavailable rather than presenting corruption as a valid null value.
- The admin lineage projection verifies that every persisted citation row belongs to the field of its owning operation or disposition, matching the final commit boundary while preserving intentional citation reuse across the two citation arrays.
Five blocking claims do not require code changes:
- auditLog.sourceExecution already uses v.optional(sourceExecutionValidator) in the current-base chat/convex/rhodes/schema.ts; this PR does not omit that schema contract.
- The projection inventory cannot lose a possible destination field at its 51-row read bound. Aerie has an exact 12-field policy, every accepted proposal covers those 12 fields exactly once, current changed-field provenance persists, and each complete execution adds all 12 history decisions.
- A starting execution fenced with registration_control_changed is an intentional Phase 4 hand-off state while an external Sindri start may be in flight. Phase 4 records the returned run ID before terminalising it; Phase 3 has no production writer of starting.
- A committed execution can contain at most 12 field-history rows under the exact-coverage policy, below the existing 200-row replay bound.
- commitVerified writes history and terminal state in one Convex mutation. The planned settlement path leaves commit-mode proposals ready_to_commit; no separate path writes terminal no_update, so partial or foreign terminal update state is not reachable.
The operator test suggestion was explicitly nonblocking, and the two defence-in-depth suggestions remain outside this blocker-only repair.
The repair does not change ownership or activation: Aerie still performs all validation and writes, agents still cannot write Site fields directly, and commitVerified remains dormant until Phase 4 supplies a production caller. It adds no schema, migration, external traffic, deployment, scheduler, cron, credential binding or upstream writeback. The repair has three focused red → green regressions. The resulting candidate passes 29/29 focused tests, all 19 Phase 3 tests, the complete 60/60 reconciliation suite, Chat and Convex typechecks, architecture boundaries, Convex-path, read-bound and test-architecture checks, exact-path Biome and git diff --check. Two independent focused reviews returned PASS on uncommitted diff SHA-256 1e09aba8da309d6f947b555ba292f4511290b5b3e510cb64578d3f65df326220.
### Second review
Mercy review [5308495458](https://github.com/AI-Builder-Team/Aerie/pull/1489#pullrequestreview-5308495458) was classified at reviewed head fa2ef2e9c761d2f1719aa3b6f93846bc65351d0b under [AERIE-2442](https://linear.app/builder-team/issue/AERIE-2442/validate-every-citation-before-reporting-current-reconciliation).
One blocker was repaired: evidenceFor still checks every citation's source state and now also checks locator and quote shape for every citation before reporting current. A malformed later citation produces the existing unavailable representation without exposing its quote.
Two blocking claims do not require code changes:
- Aerie does not grant Site Detail read access per tenant or per Site. requireSiteDetailReadUser grants organization-wide Site Detail access from the role's capability set, and existing Site Detail, Document Knowledge and Portfolio Workbench queries then resolve caller-supplied Site identifiers. Reconciliation follows that platform authority; history and lineage additionally require forge.runs.read. Users and Sites contain no per-site read grant against which the proposed check could run.
- The current Property Acquisition policy builds a flat Record<AllowedField, unknown> containing exactly 12 fields. Planning obtains a changed field's beforeValue from that same flat capture. If it is null, the fallback rereads the same top-level null; a nested duplicate field is not a valid target capture, and freshness requires exact canonical equality with the current flat capture. The admin hash path receives that same shape.
The two registry findings are explicitly deferred and nonblocking. The three suggestions remain outside this blocker-only repair. The AERIE-2442 change adds no capability, role, Site authorization, schema, registry, generated contract, Phase 4 or live-action surface. Its focused regression went red on the reviewed head and green after the two-path repair. The final candidate passes 30/30 focused tests, 20/20 Phase 3 tests, the complete 61/61 reconciliation suite, Chat and Convex typechecks, all architecture/static checks, exact-path Biome and git diff --check. Two independent checks returned PASS on diff SHA-256 7255f413e40a2eda1934a7f4f131576b0cc4b2a9fba9c030e9148337f0761540.
### Third review
Mercy review [5308962284](https://github.com/AI-Builder-Team/Aerie/pull/1489#pullrequestreview-5308962284) was classified at reviewed head c50ba930e4ceb2de6c5ec6c6126941de7b97b923 under [AERIE-2454](https://linear.app/builder-team/issue/AERIE-2454/fail-closed-on-mixed-stale-issues-and-corrupt-reconciliation-lineage).
Four blockers were repaired:
- stale terminalisation now accepts only a non-empty issue set made entirely of target/source stale codes; mixed validation failures reject atomically;
- every durable citation pointer consumed by evidence, history, lineage or replay now matches the semantic field that owns it, as well as its execution and Site;
- required history metadata is validated rather than replaced with empty strings or clamped into a successful DTO;
- duplicate provenance produces unavailable evidence, while genuinely absent provenance remains no_citation.
The registry run-ID and same-millisecond CAS findings are explicitly deferred and nonblocking. Terminal replay hardening, identity-validator centralisation, general timestamp hardening, source-document hardening and the other suggestions remain outside this blocker-only repair.
The repair changes only admin.ts, admin.test.ts, commit.ts and commit.test.ts. It changes no capabilities, roles, per-site authorization, null lookup, schemas, migrations, generated contracts, registry behaviour or Phase 4/live-action surface. Four focused regressions went red on the reviewed head and green on the final candidate. The candidate passes 34/34 focused tests, 24/24 Phase 3 tests, the complete 65/65 reconciliation suite, Chat and Convex typechecks, every architecture/static check, exact-path Biome and git diff --check. Two independent checks returned PASS on diff SHA-256 9bf0974164f02565f9cdfddc50b228174ca883089361edfaa5559df187e6b840.
### Fourth review and approval
Mercy approved exact head 2a93a15b3d5ee608a14022ec6ee842fcbc070cfa in review 5309412250. It confirmed the four AERIE-2454 blockers are fixed and reported no remaining blocking findings.
No further Phase 3 repair is planned. The source-set completeness claim has a false premise: the current capture type has no incomplete successful state, receipt hydration requires persisted sourceSetCompleteness: "complete", and current source capture either returns a complete set or throws. The empty-source-inventory and malformed-target findings require durable-row corruption and concern a dormant lineage projection with no Phase 3 production caller; they are bounded follow-up hardening rather than verified-write blockers. The registry run-ID and same-millisecond CAS findings remain explicitly deferred, and the replay/registration/source-join items remain suggestion-only hardening.
Hosted CI passed lint and boundaries, typecheck, tests, both builds, both Docker builds and secret scan on the approved head. No deployment, activation, asset publication, credential binding, E2E, shared-data mutation, discovery invocation or upstream writeback occurred.