Files
erp/.claude/skills/dolibarr-sandbox-write/replay-packs/2026-07-11-books-regularization/README.md
T
arcodangeandClaude Fable 5 fb13bdcc4f feat(write-skill): GED attach op — upload the source document onto its invoice (erp#43)
document-attach.sh uploads a source piece (the supplier's own PDF) onto an
invoice's GED via POST /documents/upload — idempotent by (object, filename,
sha256): before any POST the object's GED is listed and a same-named entry is
downloaded back and sha256-compared. Identical → deduped no-op; different
content → ABORT (refuse-never-repair, overwriteifexists always 0, never
Dolibarr's overwrite flag). Read-back after upload: re-list + download +
sha256-verify. Module-relative download paths are derived from the listing's
fullname (supplier invoices carry an id-derived get_exdir prefix like
9/2/FAF2026013/…, so reconstruction would be wrong).

Promote integration: new `attach` op in promote-plan/promote-apply (OP_SCRIPT),
object_id resolvable via @ref and #supplierinvoice lookups; a relative `file`
resolves against the manifest's directory (replay packs carry pdfs/ beside the
manifest, gitignored — README documents the books@ re-fetch message ids).
promote-plan prints each file's sha256 (or a loud MISSING) at review time.
CLI: `arcodange sandbox attach`.

Proof: offline case 12 in tests/run-tests.sh (upload body, dedupe, conflict
abort, field refusal, manifest-relative resolution via stubbed /documents);
live: manifest-C-ged-attach.json applied twice on the sandbox — run 1 four
created, run 2 four deduped, one GED file per FAF2026010-013, stored sha256s
equal to the re-fetched sources; tests/replay-idempotency.sh extended with an
attach op (4 created → 4 deduped, ged_files count unchanged) and a live
same-name/different-bytes abort verified.

Closes erp#43

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh
2026-07-19 00:11:59 +02:00

51 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Replay pack — books regularization 2026-07-11
The complete, provenance-verified write pack from the 2026-07-11 books-regularization session
(memory: `books-gap-2026-07`). Rehearsed green on the sandbox (FAF2026010013 + payments,
predicted-delta verified). **Prod replay: EXECUTED 2026-07-15** (operator "go", key derived
at runtime, never stored): prelude green (7 drafts → FAC004-007 + FAF2026010-012), manifests
A+B applied (F1045 → FAF2026013; payment ids 7,8,13-16), fresh provenance 36/36 BEFORE writing
(PDFs re-fetched from books@ per the section below — the re-fetch path works), snapshots
before `e97fc10e256d…` / after `731c8f443ebf…`, `bank match --since 2026-01-01`**0 UNKNOWN**.
Remaining: bucket C non-invoice UI entries (erp#57).
## Contents
| File | What it is |
| --- | --- |
| `manifest-A-km-payments.json` | 2 KissMetrics customer payments (Wise wires 2 147,00 € + 2 195,97 €, tx ids from the activity feed) |
| `manifest-B-suppliers.json` | DARNIS F1045 supplier invoice (214,70 HT / 257,64 TTC) + its payment + Anthropic/Mistral payment ops |
| `manifest-B2-sandbox-payments.json` | Sandbox-side payment re-run after the varchar(50) fix (erp#37) |
| `manifest-C-ged-attach.json` | erp#43 — attach the four source PDFs onto the FAF supplier invoices (GED). `#supplierinvoice:ref_supplier=` lookups + `pdfs/`-relative paths, so the same file replays sandbox↔prod once `pdfs/` is populated (see below). Rehearsed green on the sandbox 2026-07-19: run 1 = 4 created, run 2 = 4 deduped (sha256 no-op). |
| `prod-replay-prelude.sh` | Pre-replay guards: fresh checkpoint assumptions, target checks, env pinning |
| `rehearsal-runbook.md` | Step-by-step of the rehearsal: what ran, in what order, with which gates |
| `verify-provenance.py` | **The anti-hallucination PoC** — 36 field-level checks: every critical value re-verified against source-PDF text (pdftotext) + FRESH Qonto/Wise pulls; locale-normalized (`219,50``219.50`, Wise `2,147` thousands format). 36/36 green at rehearsal time. |
## Source PDFs (not committed — re-fetchable)
`verify-provenance.py` expects `./pdfs/` containing:
`F1045_ARCODANGE_2026-06-30.pdf`, `F1046_ARCODANGE_2026-06-29.pdf`,
`Invoice-9BF0758D-695749.pdf` (Anthropic), `invoice-MSTRL-API-814045-001.pdf` (Mistral).
Re-fetch via the `arcodange-email-ingest` skill (workflow 2 downloads attachments by
message id) or from the GED once erp#43's attach replays on prod. Message ids (Zoho,
verified 2026-07-19 — sha256 matched the golden-set sidecars): F1045 →
`1780782481239014300` (`/Notification`), F1046 → `1782725019202004300` (`/Notification`),
Anthropic Invoice-9BF0758D-695749 → `1776017238960014300` (`/Inbox/books`), Mistral →
`1775141901205014300` (`/Inbox/books`). `pdfs/` is gitignored — populate it, then
`promote plan` prints each file's sha256 before any apply.
## Who consumes this pack
- **erp#41** (provenance checker as a promote-plan stage) — industrializes `verify-provenance.py`.
- **erp#42** (compliance linter) — these manifests are the *legitimate* fixtures that must PASS.
- **erp#44** (idempotency keys) — replay these manifests twice on a checkpoint; run 2 must be all-deduped.
- **erp#43** (GED attach) — `manifest-C-ged-attach.json` attaches the four PDFs to
FAF2026010013. Sandbox rehearsal done (attach + re-attach no-op proven); the prod
replay of manifest C is the remaining human-gated step.
## Rule this pack proves
No agent-typed value reaches a write without **mechanical corroboration**: source-anchored
(the exact string exists in the source document) + cross-system (bank feed to the cent, fresh
pull at check time) + read-back (predicted-delta after apply). Refuse, never repair.