skip to content

A filer challenges an audit selection from last year — what makes the decision log credible rather than a mutable table?

level: seniorimportance: should knowfreq 48%

answer

  1. insert only, corrections append
  2. tamper evident beats tamper resistant
  3. chain each row's hash to the last
  4. anchor the head outside the operator
  5. prove completeness, not only integrity

basics

~20 s

Insert-only write grants with corrections appended rather than applied, each row's hash chained to the previous so an edit is detectable, the chain head anchored beyond the operators' reach, and a sequence check proving no row is missing.

solid answer

~40 s

Credibility is a property of how the store is operated, not of the application's habits. The writing identity holds insert only — no update, no delete — and a correction is a new row referencing the original, never an edit to it. Each row's canonical bytes are hashed and chained to the previous row's hash, so any later edit or removal breaks every hash downstream and the break is visible. That only binds if the chain head is anchored outside the team that operates the log: a trusted timestamp over the head, or the head written into a system with separate administrators. Otherwise whoever can rewrite a row can recompute the chain. Finally, integrity is not completeness — add gap-detectable sequence numbers and a reconciliation of decisions made against rows landed.

go deeper

for a junior

Know that a decision row is written once and never edited, and that a mistake is fixed by appending a new row that points back at the original rather than by changing it.

for a middle

Explain hash chaining: each row commits to the previous one, so an edit or a removal breaks every hash after it and verification finds the break.

for a senior

Cover the parts candidates skip — an externally anchored chain head, write grants separated from read and from retention, and a completeness check beside the integrity one.

for a principal

Decide how much evidence the challenge actually demands, and who inside the organisation must be unable to alter the record for it to count as evidence at all.

## Append-only is a grant, not a habit "We never update the decision table" is a statement about the current code. The property you need is that nobody *can*, including the operator holding elevated credentials. That is expressed in the store: the identity the scoring service writes with holds insert permission and nothing else; retention settings are administered by a different identity; readers authenticate separately again. If one role can write rows, change rows and shorten the retention window, the log's evidential value collapses to that role's trustworthiness — which is exactly the thing under challenge when a filer disputes a selection. Corrections follow from the same rule. A row written with the wrong threshold value is repaired by **appending** a correction row that references the original's `decisionId`, carries the corrected values, the reason and the author, and supersedes it in any read view. The original stays. Editing it in place removes the only evidence of what the system actually recorded at decision time, which is the thing the log exists to prove. ## Tamper evidence, not tamper resistance The realistic goal is **detection**, not prevention. Hash each row's canonical serialisation — a byte-stable encoding, so that two encoders agree — with a standard construction such as SHA-256, and include the previous row's hash in what you hash. Every row then commits to its predecessor, and the sequence forms a chain. - An **edit** to row 4,101 changes its hash, so row 4,102's stored hash no longer matches what recomputation produces, and every row after that fails too. - A **removal** breaks the chain at the same place. - An **append** is the normal operation and simply extends the chain; it breaks nothing. The chain does not stop an administrator from rewriting a row. It makes the rewrite visible to anyone who verifies. ## The chain only binds if it is anchored Here is the failure that sounds fine in a design review and is not: the chain head is stored beside the log. An operator with write access to the rows also has write access to the head, so they can rewrite a row, recompute every downstream hash, and rewrite the head to match. The chain verifies perfectly and proves nothing. The fix is an anchor outside that control. Periodically — hourly, daily — fix the current head somewhere the log's operators cannot revise it: 1. a trusted timestamp over the head from an independent authority, under the RFC 3161 protocol; 2. the head written into a system administered by a different team, with its own append-only property; 3. both, so a single compromised party cannot produce a consistent false history. Between two anchors, history is only as good as the operator. That is an acceptable, statable window — "tamper evident to within an hour" — and it is a far better answer than claiming the chain is self-sufficient. ## Integrity and completeness are different properties A verified chain says *nothing that is here was changed*. It says nothing at all about rows that were never written. A decision silently dropped on the write path leaves no trace: the chain over the surviving rows verifies cleanly. Completeness needs its own mechanism: - **Monotonic sequence numbers per partition**, so a missing row shows as a hole rather than as an absence. - **Reconciliation**: a count of decisions made by the scoring service against rows landed in the log, per window, with the difference alarmed. For sampled rows this is a count of rows expected under the policy; for actioned decisions it must be exact. A candidate who offers a hash chain as an answer to "how do you know nothing is missing" has answered a different question, and it is worth pressing on. ## Timing, again All of this presumes the row was written at decision time. A record assembled afterwards from a request log, a feature table and a configuration snapshot can be made immutable from that moment on, and it is still a reconstruction of what those sources look like now. Immutability applied to a reconstruction preserves the reconstruction, not the decision. When a filer's challenge turns on what the system did in March, the chain has to start in March.

  • A hash chain shows nothing was edited — what shows that nothing is missing?
    A gap-detectable sequence: monotonic per-partition sequence numbers so a missing row appears as a hole, plus a reconciliation between decisions made and rows landed, alarmed on the difference. Integrity and completeness are separate properties, and a chain computed over the rows that exist says nothing about the rows that never arrived.
  • Why anchor the chain head outside the team that operates the log?
    Because anyone who can rewrite a row can also recompute every hash after it, and the head along with them. The chain binds only if some value derived from it is fixed where those operators cannot revise it — a trusted timestamp over the head under RFC 3161, or the head written into a system with separate administrators.
  • How do you correct a decision row that was written with a wrong field?
    Append a correction row referencing the original's identifier, with the corrected values, the reason and who made the change, and have read views prefer it. The original stays in place. Editing it removes the evidence of what the system actually recorded, which is precisely the thing a challenge is asking about.

A bound ledger with numbered pages is no harder to write in than a loose stack of sheets. What it adds is that a removed page leaves a stub and a gap in the numbering — you cannot prevent the removal, you can only make it impossible to hide.

saying these in an interview costs you the question

  • Claims a row is immutable because the application never overwrites it
  • Corrects a bad row by editing it in place
  • Computes the hash chain and stores the head beside the log
  • Treats a verified hash chain as proof that no row is missing
  • Assembles the decision record afterwards from other systems
  • Gives the scoring service delete rights for cleanup