In this note
An invoice says USD 120.50. A proposed record says USD 120.00. Its invoice ID looks right, its currency is allowed, and its amount is a valid integer expressed in cents. The validator returns no errors.
That can happen even when the proposal includes a genuine quote from the invoice. The quote may say “Total: 120.50” while the amount field says 12000. Both fields can pass their individual checks without agreeing with each other.
Revision note, 16 October 2026: added links to a prepared invoice-extraction lab with authored cases and runnable local offline checks. The live model comparison has not run.
Write down what each check proves
A structural validator checks the record’s shape: required fields, types, allowed values, and bounds. It can reject a missing currency, a negative amount, fractional cents, or an unexpected payment instruction. These are useful checks. They give the rest of the software a predictable object to handle.
Both 12050 and 12000 are nonnegative integers within the permitted range, so the format check accepts either. To catch the wrong amount, the source checker needs a separately checked answer: INV-101, USD, 12050 cents.
| Item | Value or result |
|---|---|
| Authoritative hypothetical source | INV-101 · USD 120.50 · recorded source revision |
| Deliberately altered proposal | INV-101 · USD 120.00 · unchanged source quote |
| Structure and quote-presence check | Pass: valid fields; quote occurs in the source |
| Independent source comparison | Reject: 12000 cents does not equal 12050 cents |
Keep the answer key outside the proposed record. A field saying correct: true tells you what the producer claims. The test code must choose the case and compare it with a reference the producer cannot change.
Someone can put the wrong amount in the answer key too. Have the source owner establish the expected fields and another responsible person check them. Resolve any disagreement before using that answer to pass or fail a test.
A real quote can support the wrong answer
Checking whether a quote appears in a source helps reject invented evidence. It cannot establish that the quote answers the business question. An invoice might contain a subtotal, an old estimate, a credit, and a final amount due. Every number can be copied faithfully; only one may belong in the requested field.
Consider another hypothetical source: an old USD 250.00 estimate is superseded by a signed USD 225.00 invoice at revision 2. Quoting USD 250.00 exactly would still give the wrong current amount. The checker needs the field’s meaning and the revision that applies to the decision.
The checker needs to know which invoice and source version the answer belongs to, as well as its currency and amount. If the document is unreadable or the amount is disputed, send the case for review. Choosing the most plausible number would hide the gap.
Use units that make the comparison unambiguous. Here USD 120.50 becomes 12050 integer cents, and an exact comparison is appropriate. A different workflow might permit rounding, a currency conversion, or a calculated total. Have the responsible owner define that rule and its inputs before applying a tolerance. Letting each model choose its own rounding would make the expected answer move between runs.
A label saying revision 2 cannot tell you whether revision 3 has arrived. A real service needs the source connector, an approved snapshot, or the source owner to establish which version applies. The companion uses a fixed test version; it does not check a live source for updates.
Test a record you know is wrong
A negative control is a deliberately bad case that should fail. Start with a known correct record, change its amount, and leave everything else alone. Assert both results: structure passes, source correctness fails. If you only assert rejection, the test might pass because you accidentally broke the format, leaving the source error untested.
The first downloaded test passes both checks. Five altered records keep a valid structure but change the amount, currency, invoice, source, or revision. The test also rejects fractional cents, an extra action field, and an invented quote. Its answer key stays separate from every proposed record.
node source-check.mjswrong amount: shape PASS; source REJECT (amount_cents mismatch)The companion compares structured records without writing files or making network calls. It has no credentials or payment tools. It does not parse PDFs or implement a full JSON Schema validator, so passing it says nothing about a model’s ability to read a messy invoice.
Check the fix against nearby cases
A rule that compares the proposal with a clearly labeled final total could catch this failure. Before adding it, try the rule on narrative wording, superseded estimates, disputed amounts, credits, missing currency, and unreadable text. The rule may reject valid work or confidently choose the wrong label.
Save the failed proposal and the source version beside it. Change one thing, then rerun that failure and the nearby cases. Have the source owner review the expected answers. Keep the fix from changing its own answer key to match its output.
Before relying on the checker for an accounts-payable queue, test it on permitted cases from that queue. Keep some cases out of development, include costly mistakes, and measure the corrections reviewers make. Count unresolved invoices separately. The small public exercise cannot estimate accuracy for that workload.
Keep the proposed record, checker version, source version, and answer key together. If a later run fails, you can then tell whether the software changed or the invoice did. Preserve the old test result when updating its reference.
A checked draft still needs its own next step
A checked draft still cannot pay an invoice or contact a supplier. Before software changes a record, it needs current permission and any required approval for that exact proposal. Changing the amount or source may mean asking for approval again.
If you later add a permitted update, read the result from the destination system. Check that the intended invoice changed. A successful API response alone cannot confirm it, and this read-only companion does not exercise that step.
Take one record your team currently accepts. Change an amount or another source-backed field without breaking the format, then run the same checks. Which check rejects it? Which source version does that check use? If nothing catches the changed value, save that failure before improving the prompt.