DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path standing-notes/loomworks-standing-note-operational-identifiers-are-not-audit-trail-facts-v0_1.md

Loomworks — standing note: an operational identifier is not an audit-trail fact — v0.1

Version. 0.1 Date. 2026-08-08 Status. STANDING. Ratified by the Operator, 2026-08-08. Author. Claude Code (execution session). Operator: Marvin Percival. Charter. standing-notes/dunin7-standing-authorization-charter-v0_1. Origin. CR-2026-191 Step 1, which found that three migrations had already relied on this principle without it ever being ratified. Reads with. standing-notes/loomworks-standing-note-legacy-engagements-cannot-be-rebuilt-from-the-log-v0_1; inspection-briefs/loomworks-b70-log-reconstruction-findings-v0_1.


The ratification

> An operational identifier that did not exist when the object was created is not an audit-trail fact. > > The record is ABOUT content, state, and commit facts. A display number is what the record is ADDRESSED BY. Adding a handle is not editing the account.

Backfilling such an identifier into existing event payloads is permitted, and is a one-time data evolution rather than an audit-trail rewrite.

This was first stated in migration 0041 (Phase 16) and acted on three times — 0041, 0055, 0094 — without ever being ratified. It is ratified now, with the boundary that was missing.


The boundary — read this before reaching for the principle

This covers identifiers that are derived, verifiable, and determined by facts already in the log — where the backfill computes what was always true.

It does not cover content, state, commit facts, attribution, or any value that is a judgment rather than a computation.

> A future migration wanting to write something that cannot be recomputed from the log does not inherit this answer.

The boundary is written first, and stated as a limit rather than a caveat, because a ratified principle gets reached for later — usually by someone who needs the permission more than they need the reasoning. The test is not "is this an identifier." The test is can the value be recomputed from the log, and would it have been the same value had the field always existed.


Reason 1 — the counterfactual test

Had display_number existed from the start, every object would carry exactly the number the backfill assigns. This is not an argument from plausibility: recomputing 0054's own ROW_NUMBER() formula against the live projections reproduced all 54 values — 33 shape, 21 render — with zero mismatches.

So the backfill writes down something the log already determined. It does not add a new fact about the past.

A content edit has no such counterfactual. Absent the assertion, there is no fact of the matter — nothing to recompute, nothing that was always true and merely unrecorded. That asymmetry is the whole principle, and it is what makes the boundary above enforceable rather than rhetorical: can you compute it from the log? is a question with an answer.


Reason 2 — the compensating-event path fails its own standard

The alternative was to append new events carrying the numbers, touching nothing that exists. It keeps the letter of append-only perfectly.

It would write 52 revisions that never happened into a record whose purpose is truthfulness about what happened. UNIQUE (object_id, object_version) means a compensating event cannot attach a fact to an existing version — it must mint one. Every shape and render would read as revised, the engagement version would advance 52 times, and a person reading that engagement afterwards would see 52 events with no correspondent in the world.

> Keeping the letter of append-only while making the record false about the past is worse than the mutation it avoids.

And the missing author is not a gap to route around. ActorKind is contributor | agent | person | companion; all four are in live use; none is the system. No actor did anything. That is the schema telling you the event should not exist — not an omission inviting a fifth kind.


What this settles, and what it does not

Settles: 0041, 0055 and 0094 applied the principle correctly. 0054 skipped a step its siblings took deliberately, and B-70 finishes it — the remedy is the in-place backfill, keyed on NOT (payload ? 'display_number') for idempotency, following 0041 and 0094's pattern including their downgrade paths.

Does not settle: anything about values that are judgments. Do not cite this note for a backfill you cannot recompute. If a future migration needs to write an unrecomputable value into existing payloads, that is a new ratification, and this note is evidence that such things get decided rather than assumed.


DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — standing note: an operational identifier is not an audit-trail fact — v0.1 — 2026-08-08