Non-Determinism and Calculation Validation: How the Document Substrate Keeps the Model Away From the Numbers

An AI model is probabilistic. Give it the same request twice and it can return different words, and sometimes different numbers. Financial work needs figures that are right every time. This article describes how the Document Substrate handles that, for accountants and finance people rather than developers. The numbers quoted are measured results from real client files. Technical terms are explained in the glossary, and there is a short version.


The Rule

The model never produces a number anyone relies on.

Every figure in a report, workpaper or answer is one of two things:

  • a figure stated in a source document, or
  • a figure computed by ordinary code from figures stated in source documents.

Any other figure is a defect and is reported as a finding.

Every figure on a deliverable is either stated in a source document or computed by code from stated figures; any other figure is reported as a finding and never carried

The model Code
Reads figures off a page into named fields Checks those figures against the page they came from
Decides which tool a question needs Does every calculation
Writes the sentences around figures Decides whether a client's file is complete
Suggests a document's type Compares documents against each other
Drafts the narrative in a client letter Re-checks the finished deliverable against its sources

This is the third of the eight principles: the model reads and suggests, code checks and decides, a person signs. A rule the model is only asked to follow is not a control, so the rest of this article describes how each boundary is enforced.


Drift, and Where It Is Kept

Token-prediction drift means a model's output moving away from what was expected over a long or multi-step task. The term covers three different problems, and each needs a different answer.

Three drift mechanisms and where each is confined: no conversation where numbers are made; the model performs no arithmetic; surface-form sensitivity is measured rather than prevented

1. Context accumulation. As a conversation grows, early instructions lose weight against everything added after them. A rule such as "never estimate a missing number" stops being followed.

The part of the system that produces numbers has no conversation. A workflow run is a single pass over stored fields, and the queue that runs forty clients unattended carries record identifiers, not document content. Chat does have multiple turns, and it is bounded: the last two questions, at most three document overviews, capped excerpts, and at most three memories recalled from the same client. Only the excerpts have a hard size limit, so this control is partial.

2. Error cascade. The model writes one token at a time, each based on what it has already written. If it misreads 100,000 as 105,000, the later totals and the summary follow the mistake and stay consistent with it, which makes the error hard to find by reading.

The model does no arithmetic, so there is nothing for an error to cascade through (section 1). Each document is read in its own model call, so a misread invoice cannot affect the next one. The completeness engine reads stored fields, not the model's prose. The misread itself is caught by tracing each value to the page (section 2) and by the check on answers for figures that appear in no source.

3. Surface-form sensitivity. Small differences in the input, such as an extra space or a different line break, change how the text is split into tokens and can change the output. "Total" with a leading space is a different token from "Total" without one.

This one is measured, not prevented. The same document extracted twice at temperature zero can differ. A parse-fidelity test reads seven pages in two forms, the digital original and a scanned image of the same page, and checks that the figures, headers and table shape survive. It is a partial control.

Drift is not prevented. It is kept to the places where a drifted output is visible and can be checked, and out of the arithmetic.


1. Separating Arithmetic From Reasoning

The chat assistant's instructions say:

Report figures as the documents state them. Do not calculate. Do not add, subtract, total, average, or convert. A number you compute appears in no document, and a reader cannot check it against anything.

Quoting a total the document itself states is not calculating.

A prompt is a request, not a guarantee. Three mechanisms enforce it.

A calculation tool written in code. When a question needs a figure nobody wrote down, such as a total across invoices, the model calls a tool. The tool does the arithmetic with no model involved and returns the total and every row that produced it.

  • Currencies are never added together. Each currency comes back as a separate total. The result has no field that could hold a mixed-currency figure.
  • A missing currency is stated, not dropped. Many New Zealand till slips and trade invoices print no currency code. Early on, a chat answer totalled nine of eleven repair invoices while the workpaper beside it totalled all eleven, because two receipts had no currency and dropped out. The tool now treats an unstated currency as the home currency and says so: "totalled as NZD; four of these documents print no currency". A currency it cannot read is never guessed.
  • An unreadable value cancels the total. A partial sum labelled "your total" would mislead, so the tool lists the readable rows instead.

A completeness engine with no model in it. The check that decides whether a client's file is complete, in period and consistent runs entirely in code over extracted fields.

A check on every answer. Each answer is scanned for figures that appear in none of its source excerpts. This flags and does not block, because a figure can be missing from the excerpts and still be correct, such as a total the user asked for. Deterministic failures may block. Probabilistic signals only flag.

Rules Are Data, Not Generated Code

No model writes Python, SQL or spreadsheet formulas here. Each check is declared as data: its kind (reconciles, continues across statements, is unique, foots) and the exact fields it reads. That gives three things:

  1. A renamed field breaks the build. Field names in rules are checked against the schemas, so a rename cannot leave a rule silently comparing nothing.
  2. Every failure reports its inputs: the document, field, page and figure on each side.
  3. "Equal" means one thing. The tolerance for money is half a cent, set once.

New rules are a code change and are reviewed like code. This works because the checks are a set an expert can list. For work that needs open-ended query generation, I do not have a good way to validate a generated query.


2. What Goes In Decides What Comes Out

Five layers, in order.

1. Classification, with a confidence gate. Each document is typed: bank statement, purchase invoice, property schedule, rates bill. The suggested type is applied automatically only when confidence is above 0.9, no person has set a type, and no extraction has run. Otherwise it is a suggestion with an "Accept and extract" button. A wrong or missing type is the most common cause of a wrong report. A transaction-history export looks like a bank statement and is not one.

2. A declared field list per document type, with a description of each field. Shape is validated automatically: right fields, right types, nothing extra.

3. Arithmetic checks inside each document. Shape checking cannot tell you that a statement's transactions do not add up to its closing balance, which is what a dropped row looks like. So arithmetic checks run on every extraction. New checks start as warnings until their false-positive rate on real documents is known. A check that wrongly refuses documents on its first day teaches people to ignore checks.

4. Tracing each value to the page. After extraction, code searches the document's own text for every value and records the page and position. This catches a plausible invented number, which would otherwise pass as though it had been read. It answers "was this found on the page", not "is this correct". A value that is not found is flagged, not deleted, because a legitimate subtotal is also absent from the page.

Status Meaning What to do
Grounded Found; page and position recorded. Click through to the highlighted page. Nothing, unless it matters.
Check Searched, not found. This is the review list. Look at it.
Derived The field is the model's own wording (a summary, a label), so it was not searched. Read it, don't match it.
Reformatted A date that was not found. The page probably prints "14 March 2025" and the field holds 2025-03-14. Check the day and month.
Not checkable Under three characters. 0, 47 and NZ match almost any page. Nothing.

The summary reads "28 of 32 fields found in the document, 51 not checked". Skipped fields are left out of the count, so a document with nothing checkable shows as unmeasured, not 100 per cent.

A "Check" has four possible causes: a value the extractor joined together, a long passage that did not match in full, a derived subtotal, or an invented figure. Look first at a single, plain figure that still says Check.

5. Corrections stored beside the extraction. A correction is recorded as a decision, with the old value still visible. Workflow runs use the corrected value. Quality measurement keeps measuring the original extraction.

Workbooks

A model does not write formulas into anyone's spreadsheet. Code generates the workbook from a structured model of the deliverable, writing formulas at known positions with their values cached, and a test writes the file and reads it back to confirm both survive. Excel, Numbers and LibreOffice recalculate on open.

A second pass checks the finished workbook before anyone sees it, in two tiers.

Source documents are extracted into fields and composed by code into a workpaper; a second pass checks that the workpaper agrees with itself and, separately, that every figure re-derives from the fields; a mismatch becomes a finding

  • Does it agree with itself? Lines foot to totals, months roll up to the year, ex-GST plus GST equals inclusive on every line.
  • Does it agree with the documents? Every figure is re-derived from the extracted fields and compared. Re-adding the workbook's own numbers would only repeat the first tier, and an invented figure could pass it.

A figure that comes from neither a source document nor arithmetic over source figures is reported as a finding.

A wrong range therefore shows up as a mismatch. In one case, revenue lines summed to 705,255.64 against a stated total of 705,255.66. That two-cent difference exists only once a statement is composed, which is why the composed statement gets its own check. On a rental property schedule, the client's net operating income was lower than rent less expenses by exactly 1,800.00: an expense was in the total but not in the breakdown. The finding names the step and the figures on each side. Deciding which figure is wrong is the preparer's job.

This works because the system generates the workbook. If a model edits an existing spreadsheet in place, there is no equivalent control, and a person should re-foot the sheet before it goes to a client.


3. Personal Details

The Document Substrate removes personal details before the model that answers sees the text, and restores them only in the response to an authorised person. The order is: redact, retrieve, prompt, restore. The FYI comparison has a diagram of both paths.

How It Works

Redaction runs once, when a document is first processed:

  1. Pattern rules for identifiers with a fixed format: IRD numbers, New Zealand bank accounts, NZBN and ABN with their check digits, credit cards with the Luhn check, email addresses and phone numbers. There are eleven rules on this install.
  2. A model pass for names, organisations and addresses, which have no fixed format.
  3. A check afterwards for anything the first two missed.

Real values are encrypted into a vault and replaced by placeholders. The search index, summaries, extracted fields, prompts and conversation history all hold placeholders. The model sees [A1B2C3D4_PERSON_7], never a name.

To answer "Who is Moore?", the words in the question are hashed and looked up in the vault to find the matching placeholders.

Real values are restored on the server after the model answers, under three rules enforced in code:

  • Scope. Only values from the documents in play are loaded. An empty document list is an error, not a broad lookup.
  • Audit. One audit row per disclosure. Re-reading a saved conversation does not write another.
  • No guessing. A placeholder the model mangled is repaired only when every candidate resolves to the same value. Otherwise it becomes a neutral label such as [person].

Zero Data Retention Does Not Replace Redaction

A zero-retention agreement governs what a vendor does with data it has received. Redaction changes what the vendor receives.

Goal Redaction ZDR contract Self-hosted model Processing agreement alone
Personal details never reach a third party Mostly, with the exceptions below No Yes No
Personal details never go into vendor logs or training data Yes Yes Yes Contractual only
An injected instruction cannot leak identities Yes No No No
Survives a vendor breach Yes, placeholders are useless without the vault No Not applicable No
Auditable per disclosure Yes No No No
Answer quality Slightly lower Unaffected Limited by a weaker model Unaffected
Operating burden Rules, a prompt and tests to maintain Sign once Highest Lowest

The deciding row is prompt injection: an instruction hidden in an uploaded PDF telling the model to repeat identities in its output. Only a model that has no identities is safe from it. A contract does not help, and it does not help with a misconfigured log or a breach at the vendor either.

Redaction is not a compliance answer on its own. Where processing happens, who your processors are and what your privacy act requires you to tell people are separate questions. The guide to personal information and cloud AI covers this for a non-technical reader.

What Redaction Costs

  • The document reader sees the whole document. Text must be extracted before it can be redacted. The only control here is a retention agreement with that vendor.
  • Some extraction sends the original PDF. Seven schemas, all of them financially sensitive, send the file because extraction fails on placeholder text. The results are redacted immediately, and the vendor's copies are deleted whether extraction succeeds or fails.
  • So use both: redaction, and a retention agreement on the document-reading account.
  • Answer quality drops slightly, mostly in how names and figures are presented, which restoring the values fixes. Counts, dates, relationships and links between documents work almost unchanged over placeholders.
  • There are new failure modes: mangled placeholders, placeholders left behind by a deleted document, and placeholders inside an extracted value. Each needed its own handling.

Self-hosting a model would close the first gap, but it trades a known third-party risk for a large operating burden and a weaker model, on work where reading the page accurately is the hard part.


4. Verification and Audit

Schema Validation Is Necessary, Not Sufficient

It catches the wrong field, the wrong type and the missing key. It cannot catch the wrong number in the right field, which is the actual risk. That is what the arithmetic checks in section 2 are for.

Thresholds Are Measured, Not Chosen

Whether a check should block depends on its false-positive rate across every real document of that type, not on a number picked in advance.

  • Bank statement footing (opening plus deposits equals closing plus withdrawals, computed from the transaction lines) was run on all 27 real bank statements. 25 footed to the cent. Both failures were genuine, and one of the two documents was not a bank statement. Because the rule does not fire wrongly, it can block.
  • Deposits banked against sales declared including GST, with a one-dollar tolerance, stays a warning. Personal deposits, cash sales and GST timing mean an exact match is rare. Accepting the finding with a note is the check working as designed.

Findings Are Stored Records

Each failure is stored with a review state:

  • Accept: known and fine, for example a personal deposit explains the gap. Accepted findings carry forward, so a re-run does not reopen them.
  • Resolve: the cause was fixed. Resolved findings do not carry forward. If the finding returns, it was not fixed.

A job shows "N errors, M warnings, K open", because six accepted and six open exceptions are different situations.

The Audit Trail

  • Run history stores a snapshot, not a re-run. A run signed off in April shows later exactly as it did in April.
  • Corrections, disclosures and client letters each write a record. A client letter is generated by an explicit click and stored, and the stored file is the record of what was sent.
  • Every figure on a deliverable has a traceable source, per the rule in section 2.

What a Pass Means

Each workflow states, on its own definition, what it establishes and what a pass does not mean. That statement goes into the report and the practice manual. The sole trader workflow's statement:

Purpose. Establishes that a sole trader's annual file holds every document the accounts need, in period, with the bank statements footing and the figures agreeing across documents.

Does not compute a tax position, a GST return, or an IR3. Does not decide the business/private split on any expense, because apportionment is a professional judgement, not a check. Does not verify that the underlying figures are correct, only that the documents agree with each other and with themselves. A complete verdict is not a professional opinion and is not a substitute for review.

The last line is where the professional liability sits, which is why it is on the definition and not in a footnote.

Measuring Quality

Unit tests do not catch a drop in answer quality. A separate test harness does, split into two groups that are never mixed:

  • Gates use deterministic scoring and must stay at 100 per cent: extraction accuracy, redaction leakage, parse fidelity and citation resolution.
  • Trends are scored by a model acting as judge, which varies by a few points between runs. Read the direction and never gate a release on the number.

The split came from measurement: a combined suite scored 94, 100 and 100 on identical code. The guide to how answers stay good explains the harness for a non-technical reader.


What Has Gone Wrong

Each control above exists because something failed first.

The 230.00. The footing rule failed on a 218-transaction bank statement by exactly 230.00. The document was a filtered transaction-history export with a running balance and no opening balance. The schema required an opening balance, so the model used the balance printed beside the oldest row, which is the balance after that transaction. One 230-dollar deposit was counted twice. The first explanation written down, "the extraction dropped a line", was wrong, and one page of the document disproved it in a minute.

The fix was to make the field optional, with a description that says to leave it empty if the document does not state it and not to derive it from the transactions. Re-extracting all 27 statements gave 25 footing, 2 where the rule correctly declined to check, and no false failures. Making the field optional without saying what not to do would have left the same pressure to guess.

Nine of eleven. The chat total that left out two receipts with no currency (section 1). Nothing looked wrong.

A test that measured nothing. A parse-fidelity suite reported 50 per cent for ten days while reading empty files. A missing test file now causes an error instead of a score.

Two code paths. A redaction placeholder reached a real user because the live route and the test harness processed answers separately and had diverged, so the tests were not scoring the production pipeline. Both now call one check.

Rules written against invented examples. Schemas and rules built on made-up sample documents keep failing on the first real one. The rental workflow has no rent-continuity check because no real property-manager statement has been in the corpus, and the manual says so.


What This Does Not Claim

  • The model is not deterministic. It is removed from the steps that produce numbers.
  • Extraction still varies between runs, at temperature zero, on the same document.
  • Nothing decides whether a figure is correct. The system establishes that a figure is stated, consistent with the other documents and traceable to a page. Whether it is right is a professional judgement.
  • Everything depends on document typing. A wrong type is still the most common cause of a wrong report.

The Pattern

For anyone designing or evaluating AI for finance or accounting work:

  • Let the model read, classify and draft. Its output there is visible and can be checked.
  • Put all arithmetic, completeness decisions and numeric checks in code, over typed fields traced to the page.
  • Handle personal details with redaction, a vault and restoring on the server, and cover what remains, such as the document reader, with a data processing agreement.
  • Treat prompts as guidance. Enforce constraints with schemas, code, thresholds measured on real documents, and workflows that state what a pass means.

Glossary

Audit log. A permanent record of who saw what and when. Here, one row is written each time real personal details are shown to someone.

Classification. Deciding what kind of document a file is (bank statement, invoice, rates bill). Everything downstream depends on it.

Confidence score. A number from 0 to 1 the model attaches to its own answer. It is a rough self-assessment, not a probability of being right, so it is used only as a gate for automation and never reported as accuracy.

Context. Everything the model can see when answering: the question, the retrieved excerpts and its instructions. It has a size limit.

Deterministic. Same input, same output, every time. Ordinary code is deterministic. AI models are not.

DPA (Data Processing Agreement). A contract governing how a vendor may handle personal data on your behalf. It limits what the vendor does, not what it receives.

Eval. An automated test of answer quality, run over a fixed set of questions with known good answers.

Extraction. Reading specified figures and dates off a document into named fields, so code can work with them.

LLM (Large Language Model). The AI model itself. It predicts likely continuations of text, so the same request can produce different words, and sometimes different numbers.

Model as judge. Using a second model to score the first model's output. Useful for tracking direction, but it varies between runs, so a release is never gated on it.

Non-determinism. The same input producing different outputs.

Prompt. The instructions given to the model. The weakest form of control, because it is a request, not an enforced constraint.

Prompt injection. Instructions hidden in a document that the model reads and follows as though they came from you.

Redaction. Replacing personal details with placeholders before anything is sent to a model.

Restoring. Putting the real values back into the response, on the server, after the model has answered, for a person authorised to see them. Also called rehydration.

Schema. The declared list of fields expected from a document type, with each field's description and whether it may be empty. Making a field required when the document might not state it causes invented values.

Temperature. A setting that controls how varied a model's output is. Zero means least varied, which is not the same as reproducible.

Token. Two meanings. In AI, the small chunks of text a model reads and writes. In redaction, the placeholder that stands in for a personal detail, such as [A1B2C3D4_PERSON_7].

Token-prediction drift. A model's output moving away from what was expected over a long or multi-step task. Also called context drift or tokenisation drift.

Tokeniser. The step that splits text into tokens before the model reads it. It is why "Total" with and without a leading space are different inputs.

Tool call. The model choosing to run a piece of ordinary code and use its result, instead of answering from its own reasoning.

Tracing. Searching the source document for a value the model reported and recording where it was found.

Vault. The encrypted store that maps placeholders back to real values.

Workflow. A saved check for one client over one period: are all the required documents present, valid, in period and consistent.

Workpaper. The compiled document a preparer works from, generated here from checked figures.

ZDR (Zero Data Retention). A vendor agreement not to store or train on what you send. It covers data the vendor has already received.


The Document Substrate · Principles · Finance and the dice-rolling AI, explained simply · FYI and the Document Substrate · Worked examples across six professions