Invoice disputes need a verified ledger
An invoice-dispute workbench that connects evidence, exact human approval and verified credits, including recovery when a response is lost.
4 min read

An accounts-receivable analyst has a USD 10,000 invoice, a USD 9,000 payment and a customer disputing ten missing units. Shipping says 100 units left the warehouse. Receiving says 90 arrived. Before anyone issues a credit, the analyst needs to establish which records belong to this invoice and what the controller accepts as the settlement.
The invoice-dispute workbench makes that investigation reviewable. It keeps the claim, contradictory evidence, human decision and accounting result together. Its most important question comes after approval: can the application prove that the intended credit actually happened?
Editorial archive date: 10 September 2026. This article was updated on 24 October using October implementation and evaluation evidence; those results were not produced in September.
Follow one dispute through to resolution
The demonstration uses synthetic, tax-free USD invoices and shortage or agreed-price claims. For invoice INV-104, a carrier exception supplies further evidence. A controller records a disposition accepting 90 units at USD 100 each. Deterministic policy calculates the USD 1,000 adjustment in integer cents.
Approval binds that specific proposal to its invoice and ledger versions, evidence hashes, disposition and policy. If a payment allocation or supporting record changes, the old approval becomes unusable. The controller must review a new proposal.

The controller sees the exact adjustment and projected balance before approving. Framed detail from the packaged application, captured on 22 October with synthetic data and rules-only assessment.
After execution, the workbench reads the simulated ledger back. It compares the credit's identity, invoice, customer, currency and line amounts with the approved action. Only a matching result resolves the case. Cash received remains USD 9,000; the credit becomes USD 1,000; outstanding becomes zero. New cash received is zero. Closing a dispute through a credit does not collect money.
Recover an uncertain action without duplicating it
A timeout can happen after the ledger commits but before the application receives the answer. Treating every timeout as a failed write would risk issuing another credit.
The workflow stores an action intent and queue entry together. Execution uses an operation key that identifies the approved action. If an interrupted execution leaves the result uncertain, recovery looks up that original key and verifies the existing credit.
flowchart TD
A[Review and approve one proposal] --> B[Persist action and queue work]
B --> C[Execute using the original operation key]
C --> D{Result known?}
D -->|No| E[Keep verification pending]
E --> F[Look up the original credit]
D -->|Yes| G[Verify ledger readback]
F --> G
G --> H{Matches the approved action?}
H -->|Yes| I[Resolve the case]
H -->|No or unavailable| E
A deliberately lost response leaves verification pending. This is a real capture of the simulator's failure path, not a live accounting incident.
The recorded verification includes killing the compiled API and worker after a credit committed. After restart, reconciliation found the original credit without adding another. A separate database-and-evidence restore preserved the operation identity and passed four restored-stack browser scenarios. These are bounded local proofs; an external ERP needs its own idempotency and lookup contract. Verification report
What the agent contributes
An optional Claude investigator uses a bounded LangGraph loop to read scoped evidence, request missing information and propose a cited assessment. It cannot approve a proposal, post a credit or change policy. Deterministic code checks identity, amounts and authority.
The agent's intended value is handling evidence that needs investigation. The evaluations do not yet establish an advantage over rules:
| Recorded evaluation | Rules | Claude |
|---|---|---|
| Ordinary synthetic cases, every assertion passing | 46/46 | Haiku 42/46; Sonnet 43/46 |
| Separate raw-wording evaluation, exact extracted claims | 0/4 | Haiku pipeline 1/4 |
Each arm ran once. In the ordinary cases, model misses were more cautious stops, with no false resolutions or unapproved or duplicate credits. The raw-wording comparison changed both extraction and investigation; no case reached approval or credit execution. Its extraction adapter is an evaluation harness, not a product upload feature. Ordinary-case report, raw-wording report
Run the workbench and inspect the boundary
The public repository provides a Next.js interface, Fastify API, pg-boss worker and simulated ledger in one application container beside PostgreSQL. Its recorded final verification passed 346/346 workflow assertions and four packaged browser scenarios after fixing a first-load test defect. Those October development runs precede the fresh public snapshot.
A separate read-only ERPNext sandbox adapter imported invoice and payment snapshots successfully. It is not the workbench's live data source, and all credits remain simulated. Fixture roles are not production authentication; no customer trial or analyst time study has been conducted.
The experiment page gives the shorter walkthrough. The useful boundary to inspect is the complete chain: evidence supports a decision, a person approves an exact action, and the system verifies the accounting result before calling the dispute resolved.