The model may only add caution
Model output passes through an action allow-list: the only thing it can contribute to a decision is an extra HOLD. Approval is a deterministic rule outcome with a confidence floor of 0.85.
An accounts-payable workflow where AI reads, code decides, and people own the exceptions: every invoice ends as approve, hold with one question, or reject, and every check cites its source record.
Accounts payable has to match each invoice against its purchase order, goods receipt, and vendor master, and catch duplicates, bank-change fraud, and GST errors. A model that approves payments is a liability, and one that can be talked into approving by text inside the invoice is worse.
01
Text PDFs go through pdftotext and scans through OCR. Row totals, subtotal, and grand total are cross-checked, so OCR digit errors are caught without a model, and an idempotency key means a resent invoice is processed once.
02
A database-backed queue claims each job, retries with backoff up to three times, and turns a system error into HOLD. Nothing approves by accident.
03
Intake scans for injected instructions, then each check writes evidence of expected versus actual: arithmetic, vendor and bank details, and the PO. It catches a PO edited after the invoice date, a recently changed bank account, and a cancelled GSTIN.
04
Price is checked against the PO and the rate contract, quantity against cumulative goods receipts (which catches split-PO overruns), and the GST head against supplier and buyer state. Credit notes skip the match.
05
A TypeSafe Jev decision model judges likely duplicates and suggests a PO, but an action allow-list drops anything it says except an added HOLD. The most severe finding wins, and approval needs confidence of at least 0.85.
06
Every HOLD carries a named owner, a next step, and a draft email to the vendor (except suspected bank fraud, which gets no draft). Every check is cited in the evidence trail.
07
One offline command runs every eval suite, and CI runs it on every change with recorded model answers, so no secrets are needed. A regression below the gate fails the build.
Model output passes through an action allow-list: the only thing it can contribute to a decision is an extra HOLD. Approval is a deterministic rule outcome with a confidence floor of 0.85.
System errors become HOLD, a resent invoice is idempotent, and the queue gives up after three tries into HOLD rather than dropping the job.
The LLM-as-judge was checked against a 69-item human-labelled gold set (kappa 0.659, bad-item recall 1.0). It is only allowed to gate on criteria that passed that meta-evaluation; the explanation criteria failed it, so they stay advisory.
Replay mode serves recorded model answers by default, so CI and the free Render deployment need no API key, and the whole eval suite costs nothing to rerun.
Python · FastAPI · SQLite · poppler + tesseract OCR · TypeSafe Jev · OpenTelemetry · Next.js · Docker · GitHub Actions · Render