Part of #2643 (ADR-0087). Covers D3 (the migration chain) and the D4 artifacts (change manifest + generated guide). For the semantic changes conversion can't hide, ship declarative migrations that replay from any past major to current in one command; publish the machine-readable change record that everything else consumes.
Depends on P1 (retired conversions graduate into the chain).
D3 — the replayable migration chain
D4 — machine-readable-first release artifacts
Acceptance criteria
- A metadata app authored at 10.x runs
migrate meta --from 10 and lands on current in one command; the diff is generated + provably schema-valid; the consumer's own validate && typecheck && test passes.
- CI replays the full chain from the oldest supported major's fixtures to current on every release; a composability break is a release blocker.
- The support floor (how far back the chain reaches) is an explicit, documented release-policy value — not an accident of deletion.
spec-changes.json validates against its own schema and is attached to the release; the generated guide matches it entry-for-entry.
- The three live windows (
titleFormat, kind:'jsx', sqlPredicateToCel) each appear as a chain step + a spec-changes.json entry.
Boundaries
- Declarative migrations express less than arbitrary code; the structured-TODO hatch keeps honesty and delegates judgment to the consumer agent.
- Prose is load-bearing in exactly one place: the
rationale field.
Refs: #2643, ADR-0087 (D3, D4), ADR-0059 §3.
Part of #2643 (ADR-0087). Covers D3 (the migration chain) and the D4 artifacts (change manifest + generated guide). For the semantic changes conversion can't hide, ship declarative migrations that replay from any past major to current in one command; publish the machine-readable change record that everything else consumes.
Depends on P1 (retired conversions graduate into the chain).
D3 — the replayable migration chain
migrations/N.json: per-surface transforms with machine-readable pre/post conditions + a single proserationalefield. Two feeders: semantic changes authored for major N, and graduated conversions (P1 entries retired from the load path).objectstack migrate meta --from Ncomposes steps N→N+1→…→current and applies them to the consumer's metadata source files in one run. Cross-major is the designed-for case, not an edge.--stepcheckpoints after each major so an agent can run its verify loop per hop and bisect a failure to the exact major (git bisectfor an upgrade).D4 — machine-readable-first release artifacts
spec-changes.jsonper release: the Release workflow diffs the currentapi-surface.jsonagainst the previously published one (reusing the ADR-0059 §3 gate artifact instead of discarding it), joins the conversion table + migration set →{ from, to, added[], converted[], migrated[], removed[] }, each entry with replacement + conversion/migration id + rationale anchor. Per-major manifests compose into a singlefrom→toview.spec-changes.jsonrationales (hand-written narrative only for architectural context) — a projection of the registry, so it can't drift.Acceptance criteria
migrate meta --from 10and lands on current in one command; the diff is generated + provably schema-valid; the consumer's ownvalidate && typecheck && testpasses.spec-changes.jsonvalidates against its own schema and is attached to the release; the generated guide matches it entry-for-entry.titleFormat,kind:'jsx',sqlPredicateToCel) each appear as a chain step + aspec-changes.jsonentry.Boundaries
rationalefield.Refs: #2643, ADR-0087 (D3, D4), ADR-0059 §3.