Skip to content

Contract Migration Tooling

coo1white edited this page Jun 8, 2026 · 1 revision

Contract Migration Tooling (v0.1.36)

Schema migration becomes a first-class, declared subsystem: a registry of edges with compatibility proofs, fail-closed reachability, and a round-trip / non-destruction prover — over the existing migrateRunState pipeline, extended to the workflow-app schema. Shipped in v0.1.36. Repo doc: docs/contract-migration-tooling.7.md.

Before v0.1.36 migration was ad-hoc and run-state-only (RUN_STATE_MIGRATIONS walked by migrateRunState), with no declared registry, no recorded compatibility proof, no round-trip guarantee, and nothing for the workflow-app schema (an old app was flatly rejected). v0.1.36 closes that.

Design Mantra

A declared registry, not an inline step array.
Fail closed on reachability; no partial migration.
Prove it: validates, append-only, idempotent, source-immutable.
The transform is reused, never forked.

The Borrowed Idea: Declare the Edges, Prove the Move

migration list is the single declared source of "what versions exist and how to advance them": one MigrationContract per schema (run-state, workflow-app), each with edges carrying a mechanically-checkable MigrationCompatibilityProof (addsDefaulted, dropsNothing). The run-state edges are RUN_STATE_MIGRATIONS — the transform is not duplicated.

Principles

  1. Fail closed on reachability (load-bearing) — before transforming, resolve detected → current. Below minimum, above current, or no chained path → unsupported with a named reason and NO write. An older workflow-app (no edge yet) fails closed with a precise reason instead of a flat reject.
  2. Round-trip / non-destruction provermigration prove <target> proves four properties and emits a deterministic sha256-fingerprinted MigrationProof: validatesAtCurrent, appendOnly (every source key survives), idempotent (re-running yields no change), sourceImmutable (migrateRunState clones; the source is byte-unchanged). An unsupported verdict never claims a proof.
  3. Dry-run verdictmigration check <target> reports status (current|migrated|normalized|unsupported), detected/current versions, the chain, and errors, without mutating.
  4. Append-only proof storage — proofs persist beside the target under migration/<fingerprint>.json, never overwriting state.json or the manifest.
  5. Reuse, don't fork — the chain runner wraps migrateRunState; the registry declares and proves over the existing transform.

Why It Matters

A durability promise is only as good as the proof behind it. v0.1.36 turns "we migrate state" into a checkable claim: every edge declares what it preserves, and the prover verifies the move was non-destructive and reproducible — fail-closed when a version can't be reached. Verified live: migration prove over a real legacy state.json passed all four properties, source byte-unchanged.

See Also

Clone this wiki locally