Non-Determinism and Calculation Validation: How the Document Substrate Keeps the Model Away From the Numbers
A finance forum thread asked how teams bridge the gap between probabilistic AI models and the zero-error requirement of financial data. This is my answer, written for accountants and finance people rather than developers. It is grounded in the Document Substrate as deployed on a New Zealand accounting practice's real files: sole trader annual accounts, rental property accounts, wealth portfolios, with their real defects. Where a number appears, it is a measured result from that corpus. Where something failed, it is described as a failure. Technical terms are explained in the glossary at the end.
The short version
The AI model is never allowed to be the thing that produces a number anybody relies on.
Stated precisely: every figure that reaches a report, a workpaper or an answer is one of exactly two things. It is a figure stated in a source document, or it is a figure computed by ordinary code from figures stated in source documents. There is no third category. A number that resolves to neither appeared during composition, belongs to nobody, and is treated as a defect on the deliverable.
The model has jobs, and none of them is arithmetic.
| The model does | The code does |
|---|---|
| Read figures off a page into named fields | Check those figures against the page they came from |
| Decide which tool a question needs | Do every calculation the tool performs |
| Write the sentences around figures | Decide whether a client's file is complete |
| Suggest a document's type | Compare documents against each other |
| Draft the narrative in a client letter | Re-check the finished deliverable against its sources |
This is the third of the eight principles behind every Orbital system: the model reads and suggests, code checks and decides, a person signs. The rest of this article is how each of those boundaries is enforced, because a rule the model is merely asked to follow is not a control.
What token-prediction drift is, and where it applies
The thread named token-prediction drift as one of the risks. It is worth setting out, because the phrase covers three different failure modes that need three different answers. Engineers also call it context drift, perception drift or tokenisation drift. It describes a model's output gradually shifting, degrading or deviating from what was expected over a long or multi-step task.
1. Context accumulation. In a multi-step pipeline, every turn carries forward the system instructions, the previous tool results, the chat history and the intermediate files. As the input grows, the model's attention is spread across thousands of tokens, so the early instructions lose weight against everything added after them. Rules stated at the start, such as "never estimate a missing number", stop being followed, because the recent conversation outweighs them.
2. Error cascade. The model writes one token at a time, each conditioned on everything it has already written. An early error is not contained. It becomes part of the context for every prediction that follows. If the model misreads 100,000 as 105,000, it then works to make the rest of its output consistent with its own mistake. The later totals, the forecast and the summary all move further from the truth, and the output stays internally consistent while they do, which is what makes the error hard to find by reading.
3. Surface-form sensitivity. Small changes to the input text, an extra space, a different line break, a different currency symbol, change how the text is split into tokens before the model sees it. "Total" with a leading space is a different token from "Total" without one. Those shifts alter how the model processes the input, and produce unpredictable changes in figures or in the shape of structured output, from an input a person would call identical.
The three mitigations usually named are pruning and summarising the context, running arithmetic through external code, and re-validating against strict schemas at every step. Here is where the Document Substrate sits against each, mechanism by mechanism.
Against context accumulation, the answer is structural: the part of the system that produces the numbers has no conversation in it. A workflow run is a single pass over stored fields, not a dialogue. Nothing accumulates across steps because there are no turns to accumulate across, and the queue that runs forty clients unattended carries record identifiers only, never document content. Chat is genuinely multi-turn, and it is bounded rather than pruned: the last two prior questions are included, at most three document overviews, retrieved excerpts are capped, and memory recalled from past sessions is limited to three entries scoped to the client it was learned from. The gap is that the bound is not a budget. Token accounting on every turn shows only the excerpts are actually capped, so the control here is real but partial.
Against the error cascade, the answer is the whole of section 1: an error cannot cascade through arithmetic the model never performs. Two further boundaries matter. Each document is read in its own separate model call, so a misreading of one invoice cannot condition the reading of the next. And the completeness engine reads stored fields, never the model's prose about them, so a sentence the model wrote badly cannot reach a verdict. What catches the misread itself is grounding, which asks whether the figure can be found on the page it supposedly came from, and the check on answers for figures that appear in no source excerpt.
Against surface-form sensitivity, the honest position is that extraction is not reproducible, and the documentation says so. The same document extracted twice at temperature zero can differ. A quality gate refused the same code change twice on that variation before it was worked around. The nearest thing to a direct control is the parse-fidelity test, which reads seven source pages in two forms, the digital original and a rasterised image of the same page, and checks that the figures survive, the headers are present, the table shape holds and nothing drops out. That measures sensitivity to surface form where it matters most, which is reading the page rather than tokenising the prompt. It is a partial control and not more than that.
Drift is not prevented. It is confined to the parts of the work where a drifted output is visible and checkable, and kept out of the parts where it would be neither.
1. Separating arithmetic from reasoning
The rule the assistant is given
The chat assistant's instructions say it plainly:
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 figure the document itself computed is not calculating. A stated total is a stated figure like any other.
Why the instruction is the weakest layer
A prompt is a request, not a guarantee. Three mechanisms enforce it.
A calculation tool that is pure code. When a question needs a figure nobody wrote down, a total across invoices or an average over a period, the model calls a tool. The tool does the arithmetic in ordinary code with no model involved, and returns the total plus every row that produced it. Three details in that tool matter more than the arithmetic:
- Currency is a grouping key, never something added up. There is no field in the result a mixed-currency figure could occupy, so a NZ dollar plus US dollar total is not merely discouraged. It is unrepresentable. Different currencies come back as separate totals.
- A missing grouping key is the dangerous case. A New Zealand corpus is full of till slips and tradesmen's invoices that print an amount and no currency code. Early on, a repairs question answered from chat returned nine of eleven invoices while the workpaper next to it summed all eleven, because two receipts named no currency and fell out of every group. The total looked correct. It was short by two invoices. The tool now reads an unstated currency as the install's home currency, counts those rows separately, and the answer states the assumption: "totalled as NZD; four of these documents print no currency". A currency it cannot read is still never guessed.
- An unreadable value invalidates its total rather than being skipped. A workpaper table shows its own gaps, so a partial sum there is visibly partial. Prose labelled "your total" is not, so no total is returned and the readable rows are listed individually.
A completeness engine with no model in it. The check that decides whether a client's file is whole, in period and self-consistent runs entirely in code. The engine's own comment states the rule: no AI model ever decides completeness. Models run earlier, to read fields off documents. The verdict is a plain check over those fields.
A check on the answer before it is shown. Every answer is scanned for figures that appear in none of the source excerpts it was given. This flags and never blocks, for a reason worth stating: a figure can be absent from the excerpts and still be right, such as a legitimate total the user asked for or a figure quoted from earlier in the conversation, and blocking on that would withhold correct answers. The settled position is that deterministic and catastrophic failures may block. Probabilistic signals only flag.
On AI-generated code and queries
The thread asked how teams validate that generated Python, SQL or DAX has not invented a filter or dropped a join. My answer is that I do not validate it, because I do not generate it.
The checks are written as data, not code. A rule declares its kind (does this reconcile, does this chain continuously across statements, is this row unique, do this row's figures foot) and declares the exact fields it reads. That has three consequences:
- The system can tell what a rule reads. When a rule was an opaque function, renaming a field in an extraction schema left it compiling while comparing nothing to nothing. Field paths in rules are now checked against the schemas automatically, so a rename fails the build rather than silently breaking a check.
- Every failure reports its own inputs. Because the inputs are declared, a failing rule reports which document, which field, which page and which figure was on each side. There is nothing to reconstruct afterwards.
- "Equal" means one thing. The tolerance for money is stated once, half a cent, rather than re-derived in each rule, where it had come to mean three different things.
New rules are a code change and go through review like code, deliberately. There is no rule-authoring interface for arbitrary logic, because a rule has professional consequences.
The limit: this works because the checks are a bounded set an expert can enumerate. If a workload genuinely needs open-ended query generation, none of the above helps, and I do not have a good answer for validating a generated join.
2. What goes in decides what comes out
The thread's question about auditing uncleaned inputs is the one that decides everything downstream. Five layers, in order.
Classification, with a confidence gate. Every document is read and typed: bank statement, purchase invoice, property schedule, rates bill. The suggested type is applied automatically only when the classifier's confidence clears 0.9, and only where no person has already set a type and no extraction has already run. Below that threshold it is a suggestion with an "Accept and extract" button, and nothing is applied. An earlier ungated version was removed because a confident but wrong guess ran an expensive extraction against the wrong schema, and the result had to be discarded.
This is not a minor detail. The single most common cause of a wrong report is a wrong or missing document type. A transaction-history export looks like a bank statement and is not one, and that distinction once took four rounds of investigation to establish.
A declared field list per document type. Each type has an explicit list of the fields to read, with a written description of each. Shape is validated automatically: right fields, right types, nothing extra.
Shape validation is not enough. Shape checking cannot tell you that a bank statement's transactions do not add up to its closing balance, which is exactly what a dropped row from a sixty-row table looks like: a perfectly shaped result with a wrong number in it. So arithmetic checks run on every extraction, inside the document, at the moment it is read. Everything ships as a warning first. A new check's false-positive rate is unknown until it has run over a real corpus, and a check that refuses a document on its first day teaches people to ignore checks.
Grounding: every value is searched for on the page it supposedly came from. After extraction, every value is re-located in the document's own page text by code, with no model involved, and the page number and character position are recorded. It exists because of a specific asymmetry: a wrong number is visible, but an invented number that looks plausible passes into validation as though it had been read off the page.
The question grounding answers is deliberately narrow. It asks "was this string found on the page", not "is this value correct". A value that cannot be found is not deleted and not treated as an error, because a legitimately derived subtotal is just as absent from the page as an invented figure. Five statuses come out of it:
| Status | Meaning | What to do |
|---|---|---|
| Grounded | Located; 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 schema says this field is the model's own wording (a summary, a label), so it was never searched. | Read it, don't match it. |
| Reformatted | Date-shaped and not found. The page probably prints "14 March 2025" and the field holds the ISO form. | Eyeball the day and month. |
| Not checkable | Under three characters. 0, 47 and NZ match almost any page by coincidence. |
Nothing. |
The headline reads "28 of 32 fields found in the document, 51 not checked". Skipped fields are kept out of the denominator on purpose. A document whose every field was skipped is not 100 per cent grounded. It is unmeasured, and averaging the two together overstates it.
Four different things produce a "Check", and only one of them is a problem: a composite value the extractor joined together, a long passage that did not match in full, a genuinely derived subtotal, and a fabrication. A single, clean, uncomposed figure that still says Check is the one to look at first.
Corrections are stored beside the extraction, never over it. A person correcting a figure is recorded as a decision, with the superseded value still visible. Workflow runs read the corrected value. Quality measurement keeps measuring the extraction, rather than measuring how much hand-correcting has been going on.
The spreadsheet question
The thread asked how to catch a formula written over B2:B10 when it should have been B2:B12. It is the right question, and my answer is structural rather than a review process: I do not have a model write formulas into a person's spreadsheet.
The workbook is generated by code from a structured model of the deliverable. Formulas are written by code at known positions, each with its evaluated value cached alongside so the file opens correctly everywhere, and a write-then-read-back test asserts that both survive the file, because that class of defect fails silently at write time. Excel, Numbers and LibreOffice recalculate on open, so the workbook computes its own figures rather than holding fixed ones.
The check that answers a wrong range is a second pass over the finished artefact, run after it is composed and before anyone sees it. Two tiers answer different questions.
- Does the workpaper agree with itself? Do the lines foot to the stated totals, do the monthly figures roll up to the annual ones, does ex-GST plus GST equal inclusive on every line.
- Does the workpaper agree with the documents? Every stated figure is re-derived from the extracted fields and compared. Deliberately never by re-adding the artefact's own numbers, which would only prove the artefact is internally consistent. The first tier already established that, and a figure invented during composition would also satisfy it.
The rule this enforces is that every figure on the deliverable resolves either to a document it was read from, or to an arithmetic relation over figures that do. A figure that resolves to neither is named as a finding on the deliverable.
A wrong range shows up as a mismatch, not as a plausible number. The worked example is two cents: revenue lines summing to 705,255.64 against a stated total of 705,255.66. That discrepancy cannot exist until something composes a statement, so no check over the source documents could ever see it. It is created by the composition, which is why the composition gets its own check.
On a rental property schedule, the same pass found the client's own net operating income row was lower than rent less expenses by exactly 1,800.00, meaning an expense was in the total but not in the breakdown. The finding names the failing step and the figures on each side. Deciding which figure is wrong is the preparer's call, and that is exactly where the system stops.
The limit. All of this works because I generate the workbook. If an AI model is editing somebody's existing spreadsheet in place, I have no equivalent control, and I would not trust it for figures going to a client without a person re-footing the sheet. The generated-and-checked path is not better because the model is better. It is better because every figure in the workbook has a known source.
3. Personal details in a multi-step pipeline
Yes, the Document Substrate runs a redaction and rehydration gateway, and the order is the design: redact, then retrieve, then prompt, then put the real values back only in the response to an already authorised person. The FYI comparison has a diagram of the two paths, with and without that step.
How it works
Redaction happens once, when a document is first processed, in three stages:
- Pattern rules. Eleven of them on this install, each precise about a specific format rather than matching any run of digits: the IRD number's hyphenation, the New Zealand bank account 2-4-7-2/3 shape, NZBN with its check digit, ABN with its ATO checksum, credit cards with the Luhn check plus an issuer prefix, email, and phone numbers with the trunk-prefix rule.
- A model pass for what patterns cannot catch. Names, organisations and addresses have no format. This stage is the only detector for them, which makes it the part of the system where tuning has the most effect.
- A check afterwards to catch what the first two missed.
Real values are encrypted into a vault and replaced by placeholder tokens. Everything downstream operates on the placeholders: the search index, the summaries, the extracted fields, the prompts, and the stored conversation history. The model reasons about [A1B2C3D4_PERSON_7], never about a name.
Asking a question needs the inverse step. "Who is Moore?" cannot match a placeholder, so the question's own words are hashed, resolved against the vault, and turned into the matching tokens. That lookup is bounded by the words in the question, not by the corpus.
Putting the real values back happens after the model has responded, on the server, with three rules enforced in code:
- Scope. Only entities belonging to the documents actually in play are ever loaded. An empty document list throws an error rather than falling back to a broad lookup.
- Audit. One audit row per disclosure, written only when at least one real value was actually revealed. Re-reading a saved conversation is not a new disclosure and does not write one.
- Never guess. A second pass repairs tokens the model mangled, but accepts a match only when every candidate resolves to the same real value. Anything still token-shaped degrades to a neutral label like
[person]rather than being guessed at. All three parts of that repair exist because of a specific string that reached a real user.
Zero data retention is not a substitute for redaction
This is the part of the thread I would push back on hardest, because the framing is the common mistake.
A zero-retention agreement is a promise about what a vendor does with data it has already received. Redaction changes what the vendor receives at all. The difference does not show while nothing goes wrong, and decides the outcome when something does.
Set out as goals rather than products:
| Goal | Redaction | ZDR contract | Self-hosted model | Processing agreement alone |
|---|---|---|---|---|
| Personal details never reach a third party | Mostly, with named exceptions below | No, the vendor still receives them | Yes | No |
| Personal details never land in vendor logs or training data | Yes, there is nothing to log | Yes, this is exactly what ZDR buys | Yes | Contractual only |
| An injected instruction cannot exfiltrate identities | Yes, the model has no identities to leak | No | No | No |
| Survives a vendor breach | Yes, tokens are useless without the vault | No | Not applicable | No |
| Auditable per disclosure | Yes, every reveal writes a row | Nothing to audit | No | No |
| Answer quality | Costs some | Unaffected | Bounded by a weaker model | Unaffected |
| Operating burden | Rules, a prompt and tests to maintain | Sign once | Highest | Lowest |
The third row is the one that decides it for me. A prompt-injection payload inside an uploaded PDF, instructing the model to repeat identities into its output, is defeated only by the model not having the identities. A contract does nothing against it, and neither does a subpoena-proof clause, a misconfigured log, or a breach at the vendor.
Neither control is a compliance answer on its own. Redaction reduces what you have to justify. It does not decide where processing happens, who your processors are, or what your local privacy act requires you to tell people. Those remain separate questions, and I would not let a redaction gateway be used as an answer to them. The plain-language guide to personal information and the cloud AI covers the same distinction for a non-technical reader.
What redaction costs
- The parser sees the whole unredacted document. You cannot redact text you have not extracted yet. This is inherent, not an oversight, and the only real control over it is a retention agreement with that vendor.
- Layout-heavy extraction sends the raw PDF too. Seven of the extraction schemas, all the financially sensitive ones, send the original file because extraction fails on placeholder text. The returned data is redacted against the vault immediately, and the vendor's copies are deleted on both the success and the failure path.
- The settled recommendation is therefore both: redaction, plus a retention agreement on the parsing account. They cover different halves of the problem.
- Answer quality takes a small hit, mostly in the final presentation of names and figures, which putting the values back then repairs. Relationships, counts, date arithmetic, contradiction-finding and cross-document linking all survive reasoning over tokens almost entirely.
- New failure modes appear that would not otherwise exist: a token mangled by the model, a token orphaned by a deleted document, a placeholder embedded mid-string in an extracted value. Each one needed its own handling.
Self-hosting a model closes the first gap completely and is not worth it here. It trades a well-understood third-party risk for a large operational one and a weaker model, on a corpus where reading the page accurately, not reasoning, is the limiting factor.
4. Verification and audit trails
Taking the thread's three suggestions in order.
Schema validation between steps: necessary, not sufficient
Shape validation runs on every extraction. It catches the wrong field, the wrong type, the missing key. It cannot catch the wrong number in the right field, and the wrong number in the right field is the entire risk. So the arithmetic checks described in section 2 run alongside it, inside each document, on every extraction.
Threshold circuit breakers: calibrated on real data, not chosen
This is where I would most strongly disagree with picking a number like "flag anything over 5 per cent variance" up front.
The test for whether a check should block is not how important it is. It is its false-positive rate, measured over every real document of that type before the severity is set.
Two worked examples from this corpus:
- The bank statement footing rule (opening plus deposits must equal closing plus withdrawals, computed from the couple of hundred transaction lines rather than from a summary the extraction might have invented) was run across all 27 real bank statements in the corpus. Twenty-five footed to the cent. Both failures were genuine, and one of the two documents turned out not to be a bank statement at all. That measurement is what makes blocking defensible: the rule does not fire spuriously, so a failure is worth stopping for.
- Total deposits banked across the year against sales declared inclusive of GST, tolerance one dollar, is a permanent warning and will never be promoted. Personal deposits, cash sales and GST timing make an exact match the exception rather than the rule. It is a prompt to understand a difference, never a verdict that something is wrong. A finding you accept with a note is that check working exactly as designed.
Human sign-off: a finding is a stored record, not a notification
Every rule failure is stored with a review state, and the two states behave differently on purpose:
- Accept means "we know, and it is fine": a known personal deposit explains a banked-versus-declared gap. Accepted findings carry forward by fingerprint, so re-running after new documents arrive does not re-open settled exceptions.
- Resolve means "we fixed the underlying cause". Resolved findings deliberately do not carry forward. If the exception is raised again, it was not fixed.
The counts on a job read "N errors, M warnings, K open", because six accepted and six open exceptions are materially different situations.
The audit trail
- Run history stores the snapshot, not a re-run. A run signed off in April renders later exactly as it read in April. Review controls are deliberately absent on history. Review happens on the current run.
- Corrections, disclosures and generated client letters each write their own record. A client-facing letter is generated once by an explicit click, stored as a file, and that stored file is the record of what was sent. Regenerating it replaces the letter and is audited.
- Every figure on a deliverable has a traceable origin, per the rule in section 2.
What a passing run is allowed to mean
Every workflow carries, on its own definition, a statement of what it establishes and what a pass must never be read as concluding. Those statements travel with the workflow into the report and into the practice manual, so they are not prose somebody might not read. The sole trader workflow's, verbatim:
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.
That last line is where the professional liability sits, which is why it is attached to the definition rather than left to a footnote.
Measuring whether any of this still works
Ordinary unit tests do not catch a regression in answer quality. There is a separate test harness for that, split into two families that must never be mixed:
- Gates use only deterministic scorers and are expected to sit at 100 per cent. Any drop is a real defect. Extraction accuracy, redaction leakage, parse fidelity and citation resolution are gates.
- Trends are scored by a model acting as judge, which varies by a few points run to run. Read the direction. Never gate on the number.
That split is itself a non-determinism control, and it was forced by measurement: on identical code, a blended suite once scored 94, 100 and 100 across three runs. A six-point band is invisible until you measure for it, and a team gating releases on that number would be responding to variation rather than to change. The guide to how answers stay good explains the harness for a non-technical reader.
What has gone wrong
Every mechanism above exists because something failed first. The failures are more useful than the architecture.
The 230.00. The footing rule fired on a 218-transaction bank statement, off by exactly 230.00. The first explanation written down was "the extraction dropped a line". That was wrong. The document was a filtered transaction-history export that prints a running balance column and no opening balance, and the schema required an opening balance, so the model supplied the nearest number that looked like one: the balance printed against the oldest row, which is the balance after that transaction, not before it. That counted one 230 dollar deposit twice.
The fix was one word and one paragraph. The field became optional, and its description now states the specific error to avoid, not only what the field holds: null if the document does not state one, and do not derive it from the transaction list, because the balance beside the oldest row is the balance after that transaction. Re-extracting all 27 statements gave 25 footing, 2 where the rule correctly declined to check, and 0 false failures. The prohibition mattered as much as the optionality. Making the field optional without saying what not to do would have left the same pressure to guess.
The invented explanation. The rule reported a real fact and I attached a guessed cause to it. Reading one page of the document falsified the guess in a minute. Stating a cause is a claim like any other, and a system that reports facts it computed should not also report a cause it guessed.
Nine of eleven. The chat total that silently excluded two receipts printing no currency, described in section 1. Nothing looked wrong.
A test that measured nothing. A parse-fidelity suite reported a stable 50 per cent for ten days while actually reading empty files. A missing fixture now throws rather than scoring zero, and the existence of every fixture is asserted on every change.
Two code paths that drifted. A redaction placeholder reached a real user because the live route and the test harness each post-processed answers separately and had diverged, which also meant the tests were scoring a pipeline that was not the one in production. Both now call a single check.
Rules written against invented examples. This project keeps being caught out by schemas and rules built on made-up sample documents that fail on the first real one. The rental workflow therefore ships without a rent-continuity check, because no real property-manager statement has ever been in the corpus. The manual says so rather than pretending. A document type with no real example simply waits.
What I would not claim
- None of this makes the model deterministic. It removes the model from the sequence of steps that produces a number. Those are different claims, and only the second one is true.
- Extraction still varies between runs, at temperature zero, on the same document. Anyone telling you temperature zero gives you reproducible extraction has not measured it on a hundred documents.
- Nothing here decides whether a figure is correct. It establishes that a figure is stated in a document, consistent with the other documents, and traceable back to a page. Whether the underlying number is right, and what to do about it, remains a professional judgement. That boundary is the design, not a gap in it.
- The verification is only as good as the document typing. Everything depends on knowing what kind of document each file is, and the most common cause of a wrong report is still a wrong type.
The actionable pattern
If you are designing or evaluating AI for finance or accounting work, everything above reduces to four rules.
- Let the model read, classify and draft language. Reading figures off a page, suggesting a document type and writing the sentences around the numbers are the jobs it is good at, and the jobs where its output is visible and checkable.
- Put all arithmetic, completeness decisions and final numeric checks in deterministic code, running over well-typed fields that have been grounded to the page they came from.
- Handle personal details with redaction, a vault and rehydration, and cover the exposure that remains, such as the page-reading service, with a data processing agreement.
- Treat prompts as guidance only. Enforce the real constraints through schemas, code, thresholds calibrated on real documents, and workflows that state on their own definition what a pass does and does not establish.
Glossary
Terms used above, and terms used in the original thread.
Agent / agentic. A setup where an AI model is given tools and decides for itself which to call and in what order, rather than following a fixed script. Powerful and correspondingly hard to audit, because the sequence differs each time.
Audit log. A permanent record of who saw what and when. Here, one row is written each time real personal details are revealed to someone.
Circuit breaker. A threshold that stops a process when a number falls outside an expected range. Useful only once the threshold has been calibrated on real data, otherwise it fires constantly and gets ignored.
Classification. Deciding what kind of document a file is (bank statement, invoice, rates bill). Everything downstream depends on getting this right.
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, which is why it is used only as a gate for automation and never reported as accuracy.
Context / context window. Everything the model can see when answering: your question, the retrieved document excerpts, and its instructions. It has a size limit, so what goes in is a deliberate choice.
DAX. The formula language used in Microsoft Power BI and Analysis Services, mentioned in the original thread as one of the languages a model might be asked to generate.
Deterministic. Same input, same output, every time. Ordinary code is deterministic. AI models are not. In this article, "checked by code" and "deterministic" mean the same thing.
DPA (Data Processing Agreement). A contract governing how a vendor may handle personal data on your behalf. It constrains behaviour. It does not constrain what the vendor receives.
Embedding / vector search. A way of turning text into numbers so that passages about similar things can be found without matching exact words. It is how the search index finds relevant excerpts. Here, the index is built entirely from redacted text.
Eval / evaluation suite. An automated test of answer quality, run over a fixed set of questions with known good answers. Ordinary software tests check that code runs. Evals check that answers are still good.
Extraction. Reading specified figures and dates off a document into named fields, so code can work with them.
Golden set. The fixed set of questions and known-correct answers an eval suite runs against.
Grounding. Checking that a value the model reported can actually be found in the source document, and recording where. A value that cannot be found is flagged for review, not deleted, because a legitimately calculated subtotal is also absent from the page.
Guardrail. An automatic check on a model's output before a person sees it.
Hallucination. A model stating something that is not in its sources and is not true, in a form indistinguishable from a correct answer. In financial work the dangerous case is not an obviously wrong number. It is a plausible invented one.
HITL (Human in the loop). A required human decision at a defined point, rather than an optional review.
LLM (Large Language Model). The AI model itself. It predicts likely continuations of text, which is why it is described as probabilistic: run the same request twice and you can get different words, and sometimes different numbers.
LLM-as-judge. Using a second model to score the first model's output. Cheap and useful for tracking direction, but it varies run to run, so it must never be the thing a release is gated on.
MCP (Model Context Protocol). A standard way of exposing tools and data sources to an AI model, mentioned in the original thread.
Non-determinism. The property that the same input can produce different outputs. This is the core issue the thread raises, and the answer above is about working around it rather than eliminating it.
PII (Personally Identifiable Information). Personal details: names, addresses, tax numbers, bank accounts, phone numbers.
Prompt. The instructions given to the model. Necessary, and the weakest form of control, because it is a request rather than an enforced constraint.
Prompt injection. Instructions hidden inside a document or web page that the model reads and follows as though they came from you. The relevant defence here is that the model has no personal details to be tricked into revealing.
Provenance. Where a figure came from. A figure with provenance can be traced to a page or to an arithmetic relation over figures that can.
Pydantic / Zod. Libraries (Python and TypeScript respectively) for declaring the expected shape of data and rejecting anything that does not match. Both check shape. Neither checks whether the numbers are right.
RAG (Retrieval-Augmented Generation). Finding relevant document excerpts first, then asking the model to answer using only those. It reduces invention but does not eliminate it, which is why the outbound figure check exists.
Redaction. Replacing personal details with placeholder tokens before anything is sent to a model.
Rehydration. Putting the real values back into the response, on the server, after the model has answered, for a person already authorised to see them.
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 is a direct cause of invented values.
Substrate. The layer between raw documents and anything that uses them: the processed, redacted, searchable, structured form of a document set. See Why "substrate"?
Temperature. A setting nominally controlling how varied a model's output is, where zero means "least varied". Zero is not the same as reproducible, and on extraction tasks the difference is measurable.
Token. Two unrelated meanings, both appearing above. In AI, the small chunks of text a model reads and writes. In redaction, the placeholder that stands in for a real personal detail, such as [A1B2C3D4_PERSON_7].
Token-prediction drift. The gradual shift, degradation or deviation of a model's output over a long or multi-step task. Also called context drift, perception drift or tokenisation drift, depending on which of its three mechanisms is meant: early instructions losing weight as the context grows, an early error conditioning everything written after it, or small changes in the input's surface form changing how it is tokenised and therefore how it is processed.
Tokeniser. The step that splits raw text into the integer token IDs a model actually reads, before any reasoning happens. It is why "Total" with a leading space and "Total" without one are not the same input, and why text a person would call identical can produce a different answer.
Tool call / function calling. The model choosing to invoke a piece of ordinary code and use its result, rather than answering from its own reasoning. The mechanism that lets a model participate in a calculation without performing it.
Vault. The encrypted store mapping placeholder tokens back to real values. Tokens are useless to anyone who does not hold it.
Workflow. Here, a saved completeness check for one client over one reporting period: are all the required documents present, valid, in period and mutually consistent.
Workpaper. The compiled document a preparer works from, generated here from the checked figures rather than assembled by hand.
ZDR (Zero Data Retention). A vendor agreement not to store or train on what you send. It is a promise about data the vendor has already received, which is a different thing from not sending it.
The Document Substrate · How Orbital thinks · Finance and the dice-rolling AI, explained simply · FYI and the Document Substrate · Project detail
Email: info@orbital.co.nz