feat(deed): translate launcher-standard to .deed (D73-C, #837) - #952
Conversation
Owner ruling D73-C (standards#787, 2026-09-22): "convert launcher-standard
to .deed". First real increment of the standards#837 campaign.
Adds launcher/launcher-standard_praxis.deed (262 lines), validated OK by
1-formats/deed/tools/deed_lint.py with --self-test and --fixtures green in
the same run as positive controls.
The head is praxis-deed, not repo-deed, because this document states what a
tool DOES: it is almost entirely first-match-wins ladders. Order is NOT
semantic in DEED, so every ordered ladder carries :priority (27 fields across
8 blocks); the unordered sets deliberately carry none. launcher-standard.deed
is not a legal name under the closed dispatch set -- proven, not assumed, by
mutant M1.
Adds the mandatory mapping spec at
1-formats/deed/mappings/launcher-standard-to-praxis-deed.adoc. Per that
directory's README a mapping spec is the only document a family translation
may cite as its authority. It is the campaign's first with status RULED AND
TRANSLATED rather than PROPOSAL, and it records six mutants plus a negative
control, the drop doctrine, and the acceptance greps.
Removes launcher/launcher-standard.a2ml per the owner's standing A2ML
doctrine ("do not ... leave it in place"). It was the toml-like surface ruled
superseded on 2026-09-08. Recoverable as blob adc2830 (11,863 B); recorded
in the spec as provenance item P-7.
Updates all six live consumers. The lockstep gate needed both of its
functional sites, not just the on: paths: filter -- the in-job GROUP array
names the file too, and patching only the filter would leave the gate
asserting a file that no longer exists. Prose comments move from TOML
[section].key notation to DEED clause notation. No uses: line is touched, so
no actions.lock change is due.
docs/audits/launcher-standard-review-2026-05-26.{adoc,a2ml} are deliberately
left alone: they are a dated historical record of that review and are correct
as written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (9)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
CI triage — the two checks that are about this change both pass; the three reds are pre-existingMeasured, not inferred. Runs on ✅ The gates this PR exists to satisfy
The lockstep gate actually fires — it does not read ABSENT. That matters because a ❌ The three reds, each traced to a cause outside this diff1. That ref lives in 2. This diff adds 0 TODO/FIXME markers, 0 occurrences of 3. Nothing to do with the launcher. Confirmed pre-existing: the Also red and also pre-existing: Baseline summary
Per the standing stopping rule, none of these is a merge blocker for this PR; each is an existing issue on its own track. 🤖 Generated with Claude Code |
Round 3. #954 merged as 9c256b6 (with its 3 known failures); this PR carries the two fixes that landed after the merge, rebased onto main+9c256b67 (+#948, +#952): 1. **Standards map integrity** (`www` unmapped since #851, `SECURITY.md` unmapped since the #947 squash, `.well-known` entry stale since #851): replace with `www/` + `SECURITY.md` entries, entry_count 122 -> 123. All 5 assertions pass locally. 2. **Both Hypatia gates**: the real scanner emits `invalid_actions_lock` TWICE (verified by building Hypatia locally and scanning this tree): `workflow_audit` (acked in round 2) and WH004 standalone (`rule_module workflow_hardening`, full path — acked here, 211 -> 212, same #951 root cause). Also verified by local full-fidelity scan (194 findings, token-enabled): the only unacknowledged findings are CI-invisible (git-state dirty-tree + code-scanning-alert echoes that need a live PAT — see #957 for the PAT-refresh tripwire). #948/#952 introduce zero new findings. Local battery: debt run 0 breached, map rc=0, uses-lock clean, registry in sync, both ratchets OK, gate keeps nothing CI-visible. Co-authored-by: hyperpolymath <hyperpolymath@users.noreply.github.com>
…983) Closes two of the four acceptance criteria on #960, and corrects three claims in the mapping spec that measurement has since falsified. ## AC4 — the check (`815531de`) `scripts/check-launcher-standard-currency.sh` (100755, 9,987 B) fails a repo that claims launcher-standard compliance while naming a filename or version that no longer exists upstream. #952 (`be6c9580`, 2026-09-22) deleted `launcher/launcher-standard.a2ml` and replaced it with `launcher/launcher-standard_praxis.deed` at v0.4.0; every downstream citation became dangling, not merely stale. The two defect classes fail **independently**, which is the point — a repo that updated the version but not the filename is still broken: | filename | version | verdict | |---|---|---| | `launcher-standard.a2ml` | v0.3.0 | FAIL (both) | | `launcher-standard.a2ml` | **v0.4.0** | **FAIL** — filename alone | | `launcher-standard_praxis.deed` | v0.3.0 | FAIL — version alone | | `launcher-standard_praxis.deed` | v0.4.0 | PASS | Three design choices worth stating, because each has a tempting wrong answer: - **The expected version is not magic.** `CURRENT_VERSION="0.4.0"` is a named constant, and the test suite asserts it equals the `:standard-version` in the real deed. A built-in default is fine for a consumer; this repo owns the standard, so its own test has to close the drift loop. - **It reads `:standard-version`, never `:schema-version`.** A deed carries two versions — the DEED grammar (1.0.0) and the document (0.4.0). Reading the first yields a number that looks like a *newer* spec, so the error would read as an upgrade rather than as drift. - **The historical-record exemption is a PATH allowlist, not a content heuristic.** A heuristic sparing lines containing "formerly" or "translated from" would spare the live defect too. The allowlist was derived by measuring this repo's tree, not guessed: exactly four legitimately-historical paths, plus the standard itself and the two new script paths. **Proof:** 19 assertions across 7 sections, 19/19 passing. Run against `metadatastician/stapeln` it finds 4 real defects; against a clean tree, zero. The anti-drift mutant (lowering `CURRENT_VERSION` to 0.3.0) produces **2** failures, not 1 — it trips both the anti-drift assertion and the gate's own `--self-test`, whose stale-version fixture then reads as current. Both are coherent and expected. ## The mapping-spec corrections (`66eb76b9`) Three claims in `1-formats/deed/mappings/launcher-standard-to-praxis-deed.adoc` were true when written and are false now. Each is withdrawn **in place and dated**, rather than silently edited — a spec that quietly changes its mind teaches the next reader to distrust the parts that did not change. 1. **"There is no Rust `.deed` parser in the estate"** — false since D73-C part 2. `launcher-common/src/deed.rs` is a purpose-built recursive-descent DEED parser, 37,039 B, `pub mod deed;` at `lib.rs:23`. This claim had propagated into a memory file and into this campaign's notes; both are corrected. 2. **"10 downstream `*.launcher.a2ml` files"** — an undercount by more than 5×. Re-measured today: **23 distinct descriptors across 52 on-disk paths, 39 of those paths citing the deleted file.** Written as a dated measurement, not a standing fact, because it moves every time a repo is cloned twice. (#960's "21" is correct for the question it asked — it counted app names; two of the 23 are set-level.) 3. **"the vendored `launch-scaffolder` copy is still v0.2.0, still missing `[resolution]`, still `.a2ml`"** — false in all three parts. `diff -q` against canon reports no difference: 13,803 B at `:standard-version "0.4.0"`. ## Status, stated honestly (AGENTS.md §6) The gate is `implemented` and `tested`. It is **not `wired`**: no workflow names it. It *is* executed on every PR here, because `scripts/run-shell-test-suite.sh` discovers `scripts/tests/*.sh` by glob and invokes `bash "$f"` — which also makes the test file's 100644 mode safe, rather than an exit-126 trap waiting in CI. **No consumer repo invokes it, deliberately.** Wiring it into the 412 consumers would arm a new scan across all of them on their next pin bump. That is an owner decision, and it is recorded on #960 rather than smuggled in here. ## Not in scope `docs/UX-standards/launcher-standard.adoc` declares **no version**, yet two files cite it at v0.2.0 (`docs/audits/launcher-standard-review-2026-05-26.adoc:33`, `docs/UX-standards/LM-LA-LIFECYCLE-STANDARD.adoc:61`). A separate defect, deliberately outside this gate. Refs #960 · #952 · #837 · D73-C in #787 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…14) 19 citations in this repo named `launcher-standard.a2ml v0.3.0`. That file was **deleted upstream** on 2026-09-22 by hyperpolymath/standards#952 (`be6c9580`, owner ruling D73-C) and translated to `launcher/launcher-standard_praxis.deed`. Every one of these pointed at a path that no longer resolves. This is AC3 of hyperpolymath/standards#960. ## Why the v0.4.0 claim is earned, not assumed Rewriting `v0.3.0` → `v0.4.0` is a **compliance claim**, not a rename, so it had to be checked rather than swept. The deed states its own delta at lines 22–24: > Bumped 0.3.0 -> 0.4.0 because the resolution ladders below now name the .deed file, which is consumer-visible. That delta lands entirely in `(resolution (standard-search` — the ladder a consumer uses to **locate the standard at runtime**. This launcher never reads the standard at runtime: it inlines the `(resolution (desktop-tools-search` ladder, whose six priorities match the deed's in the same order and are untouched by 0.4.0. So nothing 0.4.0 added is unimplemented here. If that had not held, the honest move would have been to name 0.4.0 **and record the gap** — it did hold. ## Why this is safe Comments only, with one deliberate exception: the `--version` output prints a `Standards Compliance:` line, rewritten because a compliance claim has to name the standard that exists. The deed's `(version-output` clause constrains only `:first-line-format`, which is untouched and still conforms. `bash -n` passes. The launcher was **not executed** — it `source`s `keepopen.sh` unconditionally at top level. **No consumer breaks.** `launch-scaffolder`'s metadata parser keys on a literal `# @a2ml-metadata begin` delimiter (`metadata_block.rs:109`); this launcher has no such line and is not parseable by it today, before or after this change. All eleven fields the deed's `(metadata-block :required-fields` demands are present and untouched. ## Clause notation `§x` → `(x ...)`, the deed's s-expression heads. Three were not mechanical and were each verified against the deed rather than guessed: | was | now | why | |---|---|---| | `§a2ml-metadata-block` | `(metadata-block ...)` | the deed's only clause rename, authorised by its own comment: *"A2ML is a dead format name and the deed era does not carry it forward"* | | `§disinteg.remove` | `(disinteg :remove ...)` | `:remove` is a **key** on `(disinteg`, not a subclause — deed:228 | | "ladder from launcher-standard.a2ml" | `(resolution (desktop-tools-search ...))` | the deed has **two** ladders; this one resolves `.desktop-tools`, so it is the first, not `(fallback-ladder` | The old filename is deliberately **not** carried as a "formerly …" gloss. The #960 AC4 gate flags a retired filename at any version, by design — the history belongs in the commit message, not in the source. ## Proved The AC4 gate (`scripts/check-launcher-standard-currency.sh`, hyperpolymath/standards#983) run against this worktree: - **before:** 23 defect rows over 19 lines, rc=1 — four lines carry *both* a retired-filename and a stale-version defect, which is why 19 lines yield 23 rows - **after:** `No stale launcher-standard references.`, rc=0 This is also the gate's first run against a hand-written launcher rather than a generated descriptor. ## What is deliberately left alone `dev-notes/HANDOVER.adoc` keeps its two v0.3.0 citations. It carries `:revdate: 2026-08-13` on its face and is a historical record; the gate allowlists it by path for exactly that reason. Rewriting a handover to name a file that did not exist at handover time would falsify the record. Refs hyperpolymath/standards#960 · hyperpolymath/standards#952 · hyperpolymath/standards#983 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated compliance references to the current launcher standard version. * Runtime paths, timeout settings, and version output remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated the launcher’s compliance declaration to the newer v0.4.0 standard. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Updated compliance references to reflect the renamed launcher standard and its newer version. - No user-facing configuration behavior changed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Updates** * Updated the launcher configuration to reference the newer launcher standard version. * Runtime PID and log paths, timeout settings, and version-output behavior remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Updated launcher compliance references to the renamed `launcher-standard_praxis.deed v0.4.0` standard. - Revised the referenced clause wording for runtime and version-output requirements. - Confirmed that launcher configuration values, including logging, process, timeout, version-output, and icon settings, remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Chores** - Updated launcher compliance metadata to the latest standard. - No changes to project settings, runtime behavior, version output, or icons. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the stated launcher standard compliance reference to version 0.4.0. * No functional behavior or public interfaces changed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated launcher configuration references to the v0.4.0 launcher specification. * Revised compliance, PID/log-file requirement, and version-output comments. * Runtime settings remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated launcher configuration compliance references to the latest standard version. * No runtime behavior or configuration values were changed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## What This repo's launcher descriptor cited `launcher-standard.a2ml`, which [standards#952](hyperpolymath/standards#952) deleted. ## The change Comment lines only: | from | to | |------|-----| | `# Compliant with launcher-standard.a2ml v0.3.0` | `# Compliant with launcher-standard_praxis.deed v0.4.0` | | `# Per launcher-standard.a2ml [version-output] section` | `# Per launcher-standard_praxis.deed (version-output ...) clause` | | `# Per launcher-standard.a2ml [runtime] section:` | `# Per launcher-standard_praxis.deed (runtime ...) clause:` | The old citation was wrong twice over: wrong **file**, and `[section]` bracket notation the DEED grammar does not have. DEED is s-expression based — the real clause heads are `(version-output ...)` and `(runtime ...)`, verified in `hyperpolymath/standards` `launcher/launcher-standard_praxis.deed`. ## Why v0.4.0 is earned, not asserted This descriptor does **not** resolve the standard — `(resolution (standard-search ...))` does not apply to it. So naming the current version is a statement of conformance, not a claim about a resolution path. ## Scope Comment-only. No behaviour change, and **independent of the file extension** — migrating `.launcher.a2ml` → `.deed` is a separate workstream gated behind `hyperpolymath/launch-scaffolder#40` under the dual-accept rule, and is deliberately not attempted here. ## Verification `git grep -c 'launcher-standard\.a2ml'` over this repo returns **0**. Refs: hyperpolymath/standards#960 (AC1), standards#837, owner ruling D73-C. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated the launcher configuration’s declared compliance standard. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
standards#960 AC4 was implemented and tested but never wired -- no workflow in any repository invoked it. This arms it in the `quality` job, in tiers. The gate is copied out inside the existing `Check documentation` step, before that step's `rm -rf .standards-checkout`, and run from $RUNNER_TEMP afterwards. That shape is forced, and it is this file's own established idiom (see validate-hypatia-baseline): the sparse checkout puts standards' scripts at .standards-checkout/scripts/, and the gate's allowlist entries for its own source carry no '*/' prefix, so run in place it reports 16 defects on itself and would red every consumer. Self-lint fallback, likewise copied from the neighbouring gates: prefer the caller's own scripts/check-launcher-standard-currency.sh when present, so standards validating itself runs the tree under test rather than main's copy. Without it this pull request's own CI would judge the fix by the version it replaces. Tiers, with the evidence recorded in standards#991: retired-filename BLOCKS. The predicate is stable -- launcher-standard.a2ml was deleted upstream (standards#952) and stays deleted, so a clean caller cannot become defective without editing the citation. Measured over 26 consumers: 3 carry defects, all archived or on the DO-NOT-MERGE list, so arming this reds zero live callers. stale-version WARNS. The predicate is time-dependent -- the gate compares against its own CURRENT_VERSION, so every correctly-citing caller flips to defect at the next bump having done nothing. A cutoff date does not cure that; each CURRENT_VERSION bump is a measure-then-arm event. The split greps the gate's typed stdout lines rather than its exit code, because both classes return 1. rc=2 (usage error, or a surviving self-test mutant) fails before the split, so a broken invocation can never read as a clean pass, and the gate's header is echoed unconditionally so a vacuous run is visible. Proven, not asserted: the wrapper was run under `bash -eo pipefail` against seeded gates emitting clean / retired-only / stale-only / mixed / rc=2 / rc=1-with-no-defect, and each branch returned the intended exit code -- stale-only exits 0 with a ::warning::, retired-only exits 1. The fixed gate returns rc=0 with zero defects on standards' own tree at origin/main, so the self-lint path does not red this pull request. actionlint reports the same 5 pre-existing findings before and after, and no `uses:` is added, so actions.lock is untouched. Refs: #960, #983, #990, #991, #952, #505 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
) Closes the last open half of **#960 AC4**. The gate merged in **#983** was `implemented` and `tested` but **never `wired`** — no workflow in any repository invoked it. This pull request does both halves, and they have to travel together: consumers fetch the gate from `ref: main`, so wiring before the cure would arm the false positives estate-wide, and curing without wiring leaves a gate nothing runs. --- ## Part 1 — the cure: three false positives Measured across 27 repositories, the gate reported **19** defects. Three were implementation defects in the gate itself. **G1 — version conflation.** The gate accepted any version number within 24 non-digit characters of the filename. A line reading `` `launcher-standard_praxis.deed` (DEED v1.0.0). Per-app config: `` captured the **grammar** version `1.0.0` and reported it as **document** drift. The gate's own header distinguishes `:schema-version` (grammar, 1.0.0) from `:standard-version` (document, 0.4.0) — this is the guard-asks-a-different-question trap inside the guard's own implementation. Cured by reading the gap between filename and number: `deed` / `schema` / `grammar` in the gap means a grammar version, not a conformance claim. **G2 — the allowlist was keyed to `standards`' own layout.** `launcher-standard_praxis.deed` was exempt at a repository root but not when **vendored at any depth** by a consumer. Cured with a `*/launcher-standard_praxis.deed` entry. **G3 — no exemption for dated ADR carriers.** `*/descriptiles/META.a2ml` and the deprecated `*/6a2/META.a2ml` spelling are dated architecture decision records; naming a retired file is precisely what they are for. Both are on disk today (measured 2026-09-22: 164 `descriptiles` directories, 770 deprecated). This is the repo-that-migrated-correctly-looks-worst-to-a-grep pattern — `launch-scaffolder` ranked worst on AC1 *because* it recorded its own migration. **Acceptance control, measured before and after:** | repository | before | after | |---|---|---| | `launch-scaffolder` | 4 | **0** | | `the-nash-equilibrium` | 4 | 4 | | `tma-mark2` | 7 | 7 | | `canonical-ums` | 4 | 4 | | **total over 27 repos** | **19** | **15** | Only genuine defects survive. The shell suite is `19 passed, 0 failed`, rc=0. --- ## Part 2 — the wiring, and the depth trap that forces its shape The gate is copied out **inside the existing `Check documentation` step**, before that step's `rm -rf .standards-checkout`, and run from `$RUNNER_TEMP` in a new step afterwards. That shape is not a preference — it is forced, and it is this file's own established idiom. `validate-hypatia-baseline` already carries the reasoning verbatim: > Move the baseline filter OUT of the scanned tree, then delete the standards > checkout, so `hypatia scan .` only ever sees the CALLER's own files. The docs-gate step sparse-checks `standards`' `scripts/` into `.standards-checkout/scripts/`. The gate's allowlist entries for **its own source** (`scripts/check-launcher-standard-currency.sh`) carry no `*/` prefix, so they stop matching at that depth. Run in place, the gate reports **16 defects on itself** — which would red every consumer. **Self-lint fallback**, copied from the neighbouring gates: prefer the caller's own `scripts/check-launcher-standard-currency.sh` when present, so `standards` validating itself runs the tree under test rather than `main`'s copy. Without it **this pull request's own CI would judge the fix by the version it replaces**. **No second `actions/checkout`** — a new `uses:` would force an `actions.lock` regeneration. The diff adds **zero** `uses:` lines; `git diff -U0 | grep -E "^[+-] *uses:"` is empty. --- ## The tiers, and why they differ Recorded with its evidence in **#991**. | class | predicate | tier | |---|---|---| | `retired-filename` | **stable** — `launcher-standard.a2ml` was deleted upstream (#952) and stays deleted, so a clean caller cannot become defective without editing the citation itself | **fails the job** | | `stale-version` | **time-dependent** — the gate compares against its own `CURRENT_VERSION`, so every correctly-citing caller flips to defect the moment the standard bumps, having done nothing | **`::warning::`, non-blocking** | A baked-in cutoff **date** does not cure `stale-version`. The #505 docs split above can use one because its missing-`CONTRIBUTING` population is **static** — it only shrinks. This population is **regenerated at every bump**. So each `CURRENT_VERSION` bump is a measure-then-arm event, not a date, and #991 records that rule plus the open question of whether the class should ever be promoted. **Arming `retired-filename` today reds zero live callers.** Measured over 26 consumers: 23 clean, 3 defective — `tma-mark2` (archived), `canonical-ums` (archived), `the-nash-equilibrium` (live but AC1-exempt and on the DO-NOT-MERGE list). All three pin a SHA, not `@main`; the 13 `@main`-pinned consumers carry none. The split greps the gate's **typed stdout lines**, not its exit code — both classes return 1, and `DEFECT` lines go to stdout, not stderr. `rc=2` (a usage error, or a seeded self-test mutant that survived) fails **before** the split, so a broken invocation can never read as a clean pass. The gate's `canonical=… expected=…` header is echoed unconditionally, so a vacuous run is visible rather than green. --- ## Proven, not asserted - **The wrapper's mutants die.** Run under `bash -eo pipefail` against seeded gates emitting clean / retired-only / stale-only / mixed / rc=2 / rc=1-with-no-defect: **6 of 6** branches returned the intended exit code. `stale-only` exits **0 with a `::warning::`**; `retired-only` exits **1**. `::warning::` cannot fail a job, so a tier split that is merely *written* proves nothing — this one was executed. - **⭐ The armed fail tier caught the patch that armed it.** This is the finding worth keeping, and it is stronger evidence than the mutant harness — that was simulated, this was live. Commit `418662fb` wired the gate and went **red on its own CI**: the new step's arming-policy comment and its `::error::` both named `launcher-standard.a2ml` literally, and `governance-reusable.yml` is part of every caller's scanned tree, so the gate read its own prose and reported two `retired-filename` defects on it. Correct behaviour, not a gate defect: the fail tier demonstrably reds a real tree. - **Cured in `013fa07d`** by naming the *concept*, not the literal. Nothing is lost — the step already `cat`s the gate's output, which prints the offending `file:line` **and** a fuller remedy than the `::error::` was restating. - **Rejected:** allowlisting `*/governance-reusable.yml`. A consumer workflow naming the retired file **is** a genuine defect, and the allowlist would hide it. - **Why the go/no-go missed it:** it ran against `origin/main`'s tree — *without* this patch — and returned rc=0. **A pre-patch clean run is not evidence the post-patch tree is clean.** Re-run on the patched tree: **rc=0, zero `DEFECT` lines.** This is the "run the tree under test, not `main`'s copy" rule that Part 2 invokes, firing against its own author. - **No new lint debt.** `actionlint` reports the same **5** pre-existing findings before and after the patch; zero introduced. - **The tested wrapper IS the shipped wrapper.** It is extracted from this file by `yq '.jobs.quality.steps[7].run'` rather than maintained as a parallel copy, so there is no second artefact that can drift out of step. The 6-of-6 mutant run above was re-executed against that extraction **after** the `013fa07d` fix, not only before it. ## After this lands **#991** carries the arming policy, the re-arm rule, and the one open owner question (`stale-version`: warn permanently, or warn-until-a-sweep-confirms-zero then promote). #960's AC4 line can be marked `wired`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo --------- Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> Signed-off-by: Jonathan D.A. Jewell <jonathan.jewell@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>



Executes owner ruling D73-C (standards#787, 2026-09-22): "convert
launcher-standardto.deed". First real increment of the #837 campaign — one family, translated end to end, rather than a sweep across 222 files.What lands
launcher/launcher-standard_praxis.deed— 262 lines, validatedOKby1-formats/deed/tools/deed_lint.py1-formats/deed/mappings/launcher-standard-to-praxis-deed.adoclauncher/launcher-standard.a2mlWhy
praxis-deedand notrepo-deedThis document states what a tool does: it is almost entirely first-match-wins ladders. Order is not semantic in DEED, so every ordered ladder carries
:priority— 27 fields across 8 blocks — while the unordered sets (required-modes,aliases) deliberately carry none. The grammar's own rationale is the argument: "with first-match-wins, a broad rule inserted above a narrow one silently shadows it. No error is raised; the narrow rule simply stops firing."launcher-standard.deedis not a legal name under the closed dispatch set. That is proven by mutant M1, not assumed from reading the dispatch table.The mapping spec is mandatory, not decorative
1-formats/deed/mappings/README.adoc: "A mapping spec is the only document a family translation may cite as its authority." This is the campaign's first spec with status RULED AND TRANSLATED rather than PROPOSAL. It carries the full field table over all 18 source sections, the drop doctrine, seven provenance items, six mutants plus a negative control, and the acceptance greps.⚠
a2ml_to_deed.pywas deliberately not used. It fails closed on untabled fields by design and this family is not tabled; adding a table entry would create a second authority for the same output.Three things verification caught that review would not
declare -a GROUP=(…)array names the file as well as theon: paths:filter. Patching only the filter would leave the gate asserting a file that no longer exists; patching only the array would leave it never firing. Both are updated, and this PR satisfies its own gate because it touches the deed and the prose adoc.:prioritycount must exclude;;comments. A bare count returns 32; five of those are the prose explaining the rule. The real field count is 27, broken down per block in the spec.trueused as a boolean each returned one hit on a line that is clean —:trust-command "gio set {file} metadata::trusted true"— the second fooled a second time because::trustedinside the string re-supplies the:keywordshape. Only a parser knows a value position from a string interior. The check is delegated to the validator; mutant M4 proves it fires. Both failed attempts are recorded in the spec as a worked example.Deliberately out of scope
docs/audits/launcher-standard-review-2026-05-26.{adoc,a2ml}— a dated historical record of that review, correct as written.⚠ Sequencing —
launch-scaffoldersilently downgrades when this mergesThis is a fact the merger needs, not a scope boundary. Measured in
hyper-repos/launch-scaffolderatac67073:crates/launcher-common/src/standard.rsparses the standard withtoml::from_strand requires the sectionsrequired-modes,runtime,integration,a2ml-metadata-block. It has no notion ofresolution.LauncherStandard::resolve()consults one hardcoded absolute path —/var/mnt/eclipse/repos/developer-ecosystem/standards/launcher/launcher-standard.a2ml— and, when that path is absent, falls back to the baked copy with no error and only atracing::debug!line.standards/launcher-standard.a2ml, 5,272 B,[spec].version = "0.2.0", 151 lines, and it has no[resolution]section at all (verified:grep -c '^\[resolution'⇒ 0).So on any machine where that canonical path currently resolves, merging this PR deletes it and
launch-scaffoldersilently downgrades from the live standard to a stale v0.2.0 copy that cannot express the resolution ladder. Nothing fails; the fallback is by design.Two acceptable resolutions — the merger picks one:
launch-scaffolderDEED reader together with (or before) this PR, so there is no window.Unrelated pre-existing defect found while measuring this:
standard.rs's own test assertsspec_version == "0.1.0"while the baked file says0.2.0.No
actions.lockchange is dueNo
uses:line is touched — the workflow's only one remainsactions/checkout@3d3c42e5…. Per AGENTS.md §5 rule 3 the lockfile is not hand-edited.Refs #837 · owner ruling D73-C in #787
🤖 Generated with Claude Code
https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo