Keep the inputs, not just the output
The decision your system logs is the one number that can never reconstruct itself — keep the inputs it rested on, or you have saved the verdict and thrown away the trial.
Open the table where your system records its decisions and look at what a row actually contains. In most systems you will find the outcome — approved, flagged, tier three, a score, a code — and then, if you are lucky, a handful of foreign keys pointing at the account, the applicant, the transaction, the model version. What you will almost never find is the thing that actually determined the outcome: the input values the decision consumed, as they stood at the instant it consumed them. Those live somewhere else, in tables that keep moving. The row you saved is the verdict. The evidence it rested on has been left to drift.
This is the failure that only shows itself the day someone asks you to explain a decision. You pull the record, you follow the foreign keys, you retrieve the inputs — and they are not the inputs the decision saw. The customer's balance has changed. The risk score has been recomputed by a newer model. The upstream table was backfilled last month to fix a data-quality issue. The feature store recomputed its aggregates overnight, as it does every night. Each of those systems did exactly what it was built to do, and between them they have quietly rewritten the question your decision was answering. You still have the answer. You no longer have anything it is the answer to.
The verdict that cannot reconstruct itself
The seductive mistake is to believe you can re-query and reconstruct. The record says which account it decided on; the account is right there; you will simply fetch its state and rebuild the picture. But the state you fetch is today's state, and the decision was made against a state that no longer exists anywhere. Live data is not an archive. A production database is a running estimate of the present, continuously overwritten, and it keeps no promise to any decision that once read from it. The moment you decided, the inputs became history — and a system that stores only a pointer to mutable data has, by construction, promised to lose that history. The re-query does not recover the decision's basis. It fabricates a new one that happens to share an identifier, and then invites you to mistake it for the original.
So the record rots silently, which is the dangerous kind of rot. Nothing throws an error. The foreign keys still resolve, the joins still return rows, the reconstruction still produces numbers — they are simply the wrong numbers, presented with total confidence. A decision that cannot be told apart from a plausible forgery of itself is not a record of anything. It is a claim, and a claim you have no way to check is worse than no record at all, because it wears the costume of evidence while offering none of the substance.
A decision stored without its inputs is a signature at the bottom of a blank page — authoritative to look at, and impossible to hold to anything.
Capture the inputs at the instant, bind them to the decision
The directive is narrow and it belongs on the write path. At the moment your code commits a consequential decision, capture the actual input values that decision consumed — not references that will drift, but the values as they were — and bind them to the decision record so the two are one object. Where an input is small and stable, snapshot it directly: write the number, the flag, the feature vector, the policy version into the record itself. Where an input is large or external — a document, a dataset, a model, a rules file — do not copy it into every row, but do not point at a mutable name either. Pin it by content: store a hash of the exact bytes the decision read, so the reference resolves to that version and to nothing that came after it. Content-addressing is an ordinary technique, and it is the difference between "the applicant's file" and "the applicant's file as it existed at 14:07:33 on the day we decided." Only the second one can be reconstructed against.
Snapshot for the small and decision-relevant; hash-and-pin for the large and external. Either way the test is the same one that governs a decision record generally: could someone who was not present, and who does not trust you, replay this decision against exactly what it consumed and watch it land where it landed? A Decision Receipt earns its name only when the answer is yes — when replay is deterministic because the inputs are fixed, not fetched. If any input to the replay is read live, the replay is not a reconstruction; it is a fresh decision in a costume, and its agreement with the original proves nothing.
This has to happen at decision time because it can only happen at decision time. The inputs are knowable, exactly and cheaply, at the instant the code reads them; a microsecond later they begin their slow departure into staleness, and no amount of forensic effort will retrieve them. Input capture is therefore not a logging concern to bolt on after the fact. It is part of committing the decision — as load-bearing as the write that records the outcome, and written in the same breath, so that a decision and the basis it rested on are never persisted apart.
The objections, answered
An engineer will raise the real ones, and they deserve real answers. Storage cost: you are not archiving your data lake per decision. You are capturing the inputs that were decision-relevant — the specific values the branch actually read — plus content hashes for anything large. That is a bounded, usually small payload, and the storage is trivially cheap set against the cost of a decision you cannot defend. Minimization and PII: this is the objection worth taking seriously, and it resolves in the same move. Capture what is needed to justify the decision, not everything within reach. Data-minimization discipline and input capture are not in tension; they are the same instinct pointed at the same target, because the inputs that justify a decision are a far smaller and more defensible set than the sprawl of everything the system could see. If a field played no part in the outcome, it does not belong in the record. If it did, then keeping it is not surveillance — it is the minimum you owe the person the decision was about.
Mutable feature stores and upstreams: yes, they recompute, backfill, and drift — that is precisely the argument, not a counter to it. A store that rewrites itself nightly is a store you cannot cite after the fact, so you snapshot the values you drew from it at read time and let it churn. "We can just re-query": you cannot, and the whole essay is an argument that this sentence is the most expensive false economy in the system. The data has changed; that is what production data does.
Underneath all four objections sits the one discipline that makes this tractable: decide, up front, what is decision-relevant. That is engineering judgment, and it is the same judgment good instrumentation and honest minimization both demand — name the inputs a decision truly rests on, capture those at the instant it rests on them, pin the rest by content, and let everything else go. Do that and each row in your decisions table stops being a verdict floating free of its trial. It becomes a decision you can stand behind, because it carries, inside itself, the evidence that it was right.
— Dispatches · Summit Cognitive
Continue from here
Turn the argument into a practice.
Get new dispatches, assess how your organization handles consequential decisions, or explore Summit Cognitive.