Skip to content

ADR-0087 P2: replayable migration chain + machine-readable change manifest + generated guide #2647

Description

@os-zhuang

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

  • Per-major declarative migration artifacts migrations/N.json: per-surface transforms with machine-readable pre/post conditions + a single prose rationale field. Two feeders: semantic changes authored for major N, and graduated conversions (P1 entries retired from the load path).
  • objectstack migrate meta --from N composes 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.
  • --step checkpoints after each major so an agent can run its verify loop per hop and bisect a failure to the exact major (git bisect for an upgrade).
  • A migration that can't be expressed declaratively emits a structured TODO (surface, reason, acceptance criteria) — never silence.

D4 — machine-readable-first release artifacts

  • spec-changes.json per release: the Release workflow diffs the current api-surface.json against 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 single from→to view.
  • The major-N upgrade guide is generated from spec-changes.json rationales (hand-written narrative only for architectural context) — a projection of the registry, so it can't drift.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions