Skip to content

@a2ml-metadata launcher header: ship a compat reader before converting mint (ruled 2026-09-22) #40

Description

@hyperpolymath

Owner-ruled 2026-09-22: compat reader first, then convert. Recorded here with acceptance
criteria so the sequencing is not lost.

Why this one is not like D73-C

PR #36 converted launcher-standard to a praxis DEED. That file is read only by this crate,
so a hard switch was safe.

The @a2ml-metadata block is different in kind. It is emitted into every launcher by
templates/launcher.sh.tera and parsed back by crates/launcher-common/src/metadata_block.rs —
so it is a wire format shared between mint and realign. A hard cutover does not break a
build; it strands every launcher already minted on disk, silently, until someone re-mints it.
That is why #36 deliberately left it alone and named it as deferred rather than missed.

The two phases, in this order

Phase 1 — realign accepts both. Teach metadata_block.rs to parse the existing
# @a2ml-metadata begin … end block and a new deed-shaped block. Ship this alone and let
it reach installed copies. mint is untouched and keeps emitting the old form.

Phase 2 — mint switches. Only once phase 1 has baked, change the template to emit the new
form. On-disk launchers then migrate naturally on their next realign, because the reader from
phase 1 still understands what they carry.

Shipping these together is the failure mode: a launcher minted before the change meets a binary
that no longer reads it.

⚠ The fixture must be captured BEFORE mint changes

The whole test rests on one artefact: a launcher minted by the current mint, committed as a
fixture. Capture it after phase 2 and you are asserting the new emitter against the new parser —
which passes regardless of whether backwards compatibility survived. That is the
generate-then-compare blindness: when generation and comparison share a predicate, a mutation in
it cancels itself out and the mutant survives both kills.

So: commit the fixture first, in its own commit, before a line of either phase lands.

Acceptance criteria

  • A launcher minted by today's mint is committed as a fixture, in a commit that changes
    nothing else, before either phase begins.
  • Phase 1 ships alone. metadata_block.rs parses that fixture and a deed-shaped block;
    a test asserts both, and a test asserts the old fixture specifically.
  • Phase 1 does not change templates/launcher.sh.tera. Verify with git diff --name-only.
  • Phase 2 changes the emitter. The phase-1 fixture test still passes unchanged — if it
    needed editing to pass, backwards compatibility was broken and the edit hid it.
  • A round-trip test: mint → parse → realign → parse, on both forms.
  • Mutant kill: revert the compat branch of the reader and confirm the old-fixture test goes
    red. A green suite proves nothing here until that mutant dies.

Not in scope

The per-app <app>.launcher.a2ml config (config.rs, discovery.rs, cmd_config.rs) is a
separate surface tracked as hyperpolymath/standards#960 and ruled to be picked up next — do not
fold it into this. docs/ruleset-audit-2026-04-10/ and docs/compliance-audit-2026-04-10.adoc
are dated audit records and stay as written.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions