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
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
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-standardto a praxis DEED. That file is read only by this crate,so a hard switch was safe.
The
@a2ml-metadatablock is different in kind. It is emitted into every launcher bytemplates/launcher.sh.teraand parsed back bycrates/launcher-common/src/metadata_block.rs—so it is a wire format shared between
mintandrealign. A hard cutover does not break abuild; 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 —
realignaccepts both. Teachmetadata_block.rsto parse the existing# @a2ml-metadata begin … endblock and a new deed-shaped block. Ship this alone and letit reach installed copies.
mintis untouched and keeps emitting the old form.Phase 2 —
mintswitches. Only once phase 1 has baked, change the template to emit the newform. On-disk launchers then migrate naturally on their next
realign, because the reader fromphase 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
mintchangesThe whole test rests on one artefact: a launcher minted by the current
mint, committed as afixture. 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
mintis committed as a fixture, in a commit that changesnothing else, before either phase begins.
metadata_block.rsparses that fixture and a deed-shaped block;a test asserts both, and a test asserts the old fixture specifically.
templates/launcher.sh.tera. Verify withgit diff --name-only.needed editing to pass, backwards compatibility was broken and the edit hid it.
red. A green suite proves nothing here until that mutant dies.
Not in scope
The per-app
<app>.launcher.a2mlconfig (config.rs,discovery.rs,cmd_config.rs) is aseparate surface tracked as
hyperpolymath/standards#960and ruled to be picked up next — do notfold it into this.
docs/ruleset-audit-2026-04-10/anddocs/compliance-audit-2026-04-10.adocare dated audit records and stay as written.
🤖 Generated with Claude Code
https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo