docs(prd): anti-hallucination contract for agent writes

Operator requirement (2026-07-11): mechanical measures against
hallucinated values in agent-performed edits. Four deterministic
layers in agent-architecture: (1) no free-text critical fields —
code copies values from validated extraction/bank-feed payloads,
the model never re-types them; (2) provenance anchors per critical
field {source_sha256, raw_excerpt} re-verified by a deterministic
checker against re-extracted source text (locale-normalized);
(3) cross-system corroboration against FRESH bank pulls + arithmetic
/checksum invariants; (4) read-back closes the loop. A failed check
refuses, never repairs. Woven into hub goal, C1 strategy, and QA
write-path (seeded-wrong-value fixtures must FAIL). Proven live:
the books-regularization pack shipped with a standalone
verify-provenance checker — 36 field-level checks green against
source PDFs + fresh Qonto/Wise feeds before the human gate.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
2026-07-11 17:41:56 +02:00
co-authored by Claude Fable 5
parent 8e4186dbeb
commit 58968135d0
4 changed files with 14 additions and 2 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ A **single operator wearing three hats**, plus the fleet itself:
**Goals** **Goals**
- **Enumerate every recurring admin/accounting task** with an explicit mode opératoire, guardrails, and a target autonomy level — the [task inventory](task-inventory.md) is the requirement backbone of this PRD. - **Enumerate every recurring admin/accounting task** with an explicit mode opératoire, guardrails, and a target autonomy level — the [task inventory](task-inventory.md) is the requirement backbone of this PRD.
- **Atomic excellence**: each capability is one narrow, contract-bound atom (extract, validate, record, reconcile, report) that does its one job measurably well. Formats are guaranteed by **deterministic validators, not by model goodwill** — the LLM proposes, code disposes. - **Atomic excellence**: each capability is one narrow, contract-bound atom (extract, validate, record, reconcile, report) that does its one job measurably well. Formats are guaranteed by **deterministic validators, not by model goodwill**, and every written value is **provenance-anchored** — mechanically re-verified in its source document or bank feed before any gate ([anti-hallucination contract](agent-architecture.md#anti-hallucination-contract-for-agent-writes)). The LLM proposes, code disposes.
- **The right model for each job** across four tiers — Claude (frontier reasoning), Mistral (EU cloud), local model on the M4 MacBook, SLM on the Raspberry Pi cluster — with graceful degradation when a tier is unavailable. See [model fleet](model-fleet.md). - **The right model for each job** across four tiers — Claude (frontier reasoning), Mistral (EU cloud), local model on the M4 MacBook, SLM on the Raspberry Pi cluster — with graceful degradation when a tier is unavailable. See [model fleet](model-fleet.md).
- **Human-gated writes as an invariant**: every ERP mutation is rehearsed on the sandbox and promoted through the existing ADR-0003 gate; approvals and digests flow through Telegram. See [agent architecture](agent-architecture.md). - **Human-gated writes as an invariant**: every ERP mutation is rehearsed on the sandbox and promoted through the existing ADR-0003 gate; approvals and digests flow through Telegram. See [agent architecture](agent-architecture.md).
- **Ledger-grade compliance**: production is operated to the discipline expected of certified French accounting software — validated documents are immutable, corrections are new documents (avoirs), the FEC is producible on demand, and the piste d'audit fiable falls out of the architecture. The sandbox stays exempt *because* it is disposable. See [compliance](compliance.md). - **Ledger-grade compliance**: production is operated to the discipline expected of certified French accounting software — validated documents are immutable, corrections are new documents (avoirs), the FEC is producible on demand, and the piste d'audit fiable falls out of the architecture. The sandbox stays exempt *because* it is disposable. See [compliance](compliance.md).
@@ -93,6 +93,17 @@ flowchart TB
This PRD adds around it: idempotency keys on every write atom, predicted-delta assertions (rehearse → re-read → compare *before* asking for approval), pre/post snapshots ([T13](task-inventory.md#t13--erp-snapshot--drift-detection)), a **compliance linter** in `promote-plan` (a manifest with any operation outside the [ledger grammar](compliance.md#the-ledger-grammar-production) never reaches the approval card), and approval cards as the human interface to the gate. This PRD adds around it: idempotency keys on every write atom, predicted-delta assertions (rehearse → re-read → compare *before* asking for approval), pre/post snapshots ([T13](task-inventory.md#t13--erp-snapshot--drift-detection)), a **compliance linter** in `promote-plan` (a manifest with any operation outside the [ledger grammar](compliance.md#the-ledger-grammar-production) never reaches the approval card), and approval cards as the human interface to the gate.
### Anti-hallucination contract for agent writes
No value reaches the books because a model "remembers" it. Four mechanical layers, all deterministic:
1. **No free-text critical fields.** Amounts, dates, refs, IBANs and transaction ids are *copied by code* from the validated extraction payload or the bank feed into the manifest — the orchestrating model routes and assembles; it never re-types a value it read.
2. **Provenance per critical field.** Write manifests carry a source anchor per critical field — `{source_sha256, raw_excerpt}` — and a deterministic checker re-extracts the source text (pdftotext / feed pull) and asserts the excerpt exists and parses to the same value (locale-normalized: `219,50``219.50`, `2,147``2147.00`). A value not literally present in its source cannot be promoted.
3. **Cross-system corroboration.** Every payment amount must equal its bank-feed movement to the cent, against a **fresh** pull at check time (never a cached copy); arithmetic (`HT + TVA = TTC ± 0.01`), checksums (SIREN, IBAN mod-97) and dedupe keys apply regardless of source.
4. **Read-back closes the loop.** Predicted-delta on the sandbox and post-write verification on prod prove that what was *written* equals what was *checked* — source → manifest → ERP, corroborated at every hop.
A failed check refuses; it never repairs. Proven in practice: the 2026-07 books-regularization pack shipped with a standalone `verify-provenance` checker (36 field-level checks against the source PDFs and fresh Qonto/Wise pulls, run before the human gate) — [POC-1](poc-plan.md#poc-1--supplier-invoice-end-to-end) industrializes it as a linter stage alongside the ledger grammar.
## Environments — sandbox vs production ## Environments — sandbox vs production
The environment split is not an implementation detail — it is both the **safety** device (ADR-0003) and the **compliance** device ([compliance](compliance.md)): the sandbox may host any experiment because its state is disposable; production is held to append-only ledger discipline because it *is* the books. The environment split is not an implementation detail — it is both the **safety** device (ADR-0003) and the **compliance** device ([compliance](compliance.md)): the sandbox may host any experiment because its state is disposable; production is held to append-only ledger discipline because it *is* the books.
+1 -1
View File
@@ -12,7 +12,7 @@ Each challenge states what breaks, the mitigation strategy, and the **residual**
## C1 — Extraction reliability ## C1 — Extraction reliability
**Breaks:** a hallucinated amount, date, or IBAN lands in the books; supplier PDFs vary wildly in layout and quality. **Breaks:** a hallucinated amount, date, or IBAN lands in the books; supplier PDFs vary wildly in layout and quality.
**Strategy:** deterministic validators on every payload (arithmetic, VAT-rate whitelist, SIREN/IBAN checksums, date plausibility); **dual independent extraction** with exact agreement required on critical fields; confidence thresholds with refuse-and-escalate (an "I can't read this" is a *good* output); quarantine queue instead of best-effort guesses; per-field accuracy measured on a golden set before any autonomy ([QA strategy](qa-strategy.md#golden-datasets)). **Strategy:** deterministic validators on every payload (arithmetic, VAT-rate whitelist, SIREN/IBAN checksums, date plausibility); **dual independent extraction** with exact agreement required on critical fields; **provenance anchors on every written field** — the value must be mechanically re-findable in its source document or bank feed, or it cannot be promoted ([write contract](agent-architecture.md#anti-hallucination-contract-for-agent-writes)); confidence thresholds with refuse-and-escalate (an "I can't read this" is a *good* output); quarantine queue instead of best-effort guesses; per-field accuracy measured on a golden set before any autonomy ([QA strategy](qa-strategy.md#golden-datasets)).
**Residual:** two models can agree on the same wrong value (same-family bias) — mitigated by picking *diverse* extractor families and by the human approval card showing the source PDF side-by-side. **Residual:** two models can agree on the same wrong value (same-family bias) — mitigated by picking *diverse* extractor families and by the human approval card showing the source PDF side-by-side.
## C2 — ERP write integrity ## C2 — ERP write integrity
+1
View File
@@ -35,6 +35,7 @@ Per atom, mechanical, recorded in the registry ([ladder](README.md#the-autonomy-
## Write-path QA ## Write-path QA
- **Compliance linter:** `promote-plan` rejects any manifest operation outside the production [ledger grammar](compliance.md#the-ledger-grammar-production) (mutating a validated document, supplying a manual ref where Dolibarr owns the sequence, detaching a GED original); the linter carries its own test suite of forbidden manifests. - **Compliance linter:** `promote-plan` rejects any manifest operation outside the production [ledger grammar](compliance.md#the-ledger-grammar-production) (mutating a validated document, supplying a manual ref where Dolibarr owns the sequence, detaching a GED original); the linter carries its own test suite of forbidden manifests.
- **Provenance check (anti-hallucination):** before any approval card, the deterministic checker re-verifies every critical field against its source anchor — document text re-extracted, bank feed re-pulled fresh ([write contract](agent-architecture.md#anti-hallucination-contract-for-agent-writes)); a field without a passing anchor blocks the card. Hallucination is mechanically *detectable*, not merely reviewable; the checker's own test suite includes seeded-wrong-value fixtures that must FAIL.
- **Predicted-delta assertion:** every rehearsed manifest re-reads what the sandbox created and diffs it against the draft *before* the approval card goes out; a mismatch is a bug, never a "close enough". - **Predicted-delta assertion:** every rehearsed manifest re-reads what the sandbox created and diffs it against the draft *before* the approval card goes out; a mismatch is a bug, never a "close enough".
- **Post-write verification:** after promote, the prod object is re-read and compared again; the pre/post snapshot pair ([T13](task-inventory.md#t13--erp-snapshot--drift-detection)) must show *exactly* the journaled writes and nothing else — and the diff must be **pure-append** (a mutation of a validated document is an incident, not a diff). - **Post-write verification:** after promote, the prod object is re-read and compared again; the pre/post snapshot pair ([T13](task-inventory.md#t13--erp-snapshot--drift-detection)) must show *exactly* the journaled writes and nothing else — and the diff must be **pure-append** (a mutation of a validated document is an incident, not a diff).
- **Ledger & FEC checks:** quarterly FEC export validated with the DGFiP *Test Compta Demat* tool (once the accounting-module binding is verified — [compliance](compliance.md#dolibarr-verifications-sandbox-first)); numbering gaplessness across validate + avoir cycles; BlockedLog chain verification if adopted. All rehearsed on a sandbox checkpoint before running against prod. - **Ledger & FEC checks:** quarterly FEC export validated with the DGFiP *Test Compta Demat* tool (once the accounting-module binding is verified — [compliance](compliance.md#dolibarr-verifications-sandbox-first)); numbering gaplessness across validate + avoir cycles; BlockedLog chain verification if adopted. All rehearsed on a sandbox checkpoint before running against prod.