The audit ledger is the schema migration you never write
Every schema change eventually runs two versions of the system against one database. The append-only answer is not a cleverer migration — it is a decision to never rewrite the past.

Rename a column and two versions of your application will find out for you. The recurring story is not the migration itself; it is the data written by an old version, read by a new one. The ledger’s answer is to make that situation structurally impossible.
A schema change is the rare change that looks trivial in review. A column renames, a field appears, a payload drops something nobody used. Staging is green. Production is on fire, and the root cause is not the migration: two versions of the application were running against the same database, and only one referenced the new shape. Worse, the problem is not bounded by the deploy window — rows written by code that no longer exists, messages queued by a consumer that was replaced, a client that was installed eighteen months ago and still calling the API. Data written under schema v1 is read under schema v2. That mismatch is a schema-drift, and no migration makes it safe.
The append-only answer
DEINO’s audit ledger treats schema drift as something to eliminate rather than manage. Every ledger record is a versioned NodeVersion, hash-linked to its predecessor in a chain (BR-842). Nothing is rewritten. A schema change is not a migration that touches the past; it is a new version of the schema that new records carry, alongside the version of the old records it did not disturb. The manifest attests which node version produced an output, so the reader never has to guess which schema a row was written under — the record says so, and the chain seals it. The past is a sealed archive, not a table that gets edited.

The contract travels with the record
- No rewrites: an update is a new version, never a mutation of an existing one.
- Self-describing records: each row carries the schema version that wrote it, so a reader does not infer.
- The chain is the only shared contract: replay (any anchor, third-party) rebuilds the same sequence of versions — there is nothing to re-interpret.
Schema drift is not something you migrate against. It is something you refuse to have, by deciding that the past cannot be rewritten.
The cost we pay on purpose
Append-only is deliberately not cheap. Storage grows with every version, cold data never truly leaves, and queries must walk the chain. We pay it for the one reason the ledger exists: if the past can be rewritten, nothing can be proven. This is also why DEINO’s persistence is reached through port traits and never through raw SQL — the migration is an additive change behind a repository boundary, not a schema surgery in application code (ledger traits, not sqlx, and sqlx checks compile-time queries). The integrity gate treats the chain as the only shared state, and an archive that can be edited is not an archive.
You never make schema drift safe with a cleverer migration. You decide whether the past can be rewritten, and the chain answers it.
— deployment note — the ledger