⚠ This body was rewritten 2026-09-22 after a citation error. The first version cited deed/spec/abnf/deed.abnf, which is a stale v0.1.0 DRAFT sitting in a peer branch's working tree. The sole normative grammar is 1-formats/deed/spec/abnf/deed.abnf (v1.0.0) on standards origin/main. The conclusion did not change, but two constraints below were missed the first time and both matter. See the comment for the diff.
Context
hyperpolymath/standards#960 AC2 asked whether the 21 per-app launcher descriptors (*.launcher.a2ml) should migrate to .deed or be declared out of scope for D73-C. The owner has ruled: migrate to .deed (2026-09-22, recorded at standards#960).
AC2 is closed by that decision — its wording is "decided, not left to decay". This issue is the design work the decision creates. It is deliberately not a migration PR: it sequences behind #40 (the @a2ml-metadata compat reader), under the dual-accept rule — do not migrate extensions before dual-accept, and a dry-run manifest first, never a bulk pass.
All citations below are to hyperpolymath/standards origin/main.
Question 1 — the filename. <app>.launcher.deed is not a legal deed name.
Deed filenames are a normatively closed production. 1-formats/deed/spec/abnf/deed.abnf:66-71:
deed-filename = estate-file / atlas-file / praxis-file / repo-file
estate-file = %s"estate_chora.deed" ; -> estate-deed
atlas-file = %s"ATLAS.deed" ; -> estate-atlas-deed
praxis-file = stem %s"_praxis.deed" ; -> praxis-deed
repo-file = stem %s"_chora.deed" ; -> repo-deed
stem = 1*( ALPHA / DIGIT / "-" / "." / "_" )
with the matching closed head set at deed.abnf:46 and DEED-GRAMMAR-SPEC.adoc:192, and a semantic constraint at deed.abnf:50-56: "The doc-head MUST match the filename dispatch … A mismatch is a validation error."
Filename dispatch is normative in its own right — the spec says outright that "the grammar alone is not sufficient to dispatch a filename" (DEED-GRAMMAR-SPEC.adoc:310-315). So <app>.launcher.deed, matching none of the four productions, is not a deed.
The stem→head table (DEED-GRAMMAR-SPEC.adoc:276-295) is the authority on meaning:
| pattern |
head |
meaning |
estate_chora.deed (exact) |
estate-deed |
Noun. The estate's vocabulary. |
*_chora.deed excl. the above |
repo-deed |
Noun. What a repo IS. A record. |
ATLAS.deed (exact) |
estate-atlas-deed |
Noun. The registry of all deeds. |
*_praxis.deed |
praxis-deed |
Verb. What a tool DOES. Rules. |
⭐ Arm B — <app>.launcher_praxis.deed (recommended)
A stem may contain dots. deed.abnf:71 admits . in stem, and deed.abnf:62-64 says so explicitly: "Do NOT split on . — the stem may contain dots (my.project_chora.deed → stem my.project)." (Mirrored at DEED-GRAMMAR-SPEC.adoc:297-299.)
So myapp.launcher_praxis.deed is a legal deed filename, stem myapp.launcher, dispatching to praxis-deed. That matters: the rename is a suffix swap, .launcher.a2ml → .launcher_praxis.deed, and the existing .launcher naming survives intact. No discovery pattern elsewhere in the estate has to learn a new stem shape.
It is also the semantically correct head. A per-app launcher descriptor states what the launcher does for that app — its runtime, its version-output behaviour, its desktop integration. That is a verb, and praxis-deed is the verb form. It composes with what already exists: launcher-standard_praxis.deed states the general rules; <app>.launcher_praxis.deed states that app's conforming praxis. Same head, two scopes.
Arm A — add a fifth head (launcher-deed + its stem pattern)
Honest cost: six sites across three repos, plus an owner ruling — all four existing heads are owner rulings, and praxis-deed was RULED 2026-09-08 on standards#752 as "a genuine fourth head, not a facet of repo-deed."
| repo |
site |
standards |
1-formats/deed/spec/abnf/deed.abnf:46 (doc-head) and :66 (deed-filename) |
standards |
1-formats/deed/spec/DEED-GRAMMAR-SPEC.adoc:192 (DocHead) + stem table :276-295 + dispatch side condition :301-308 |
standards |
1-formats/deed/README.adoc (stem/head table) |
deed-ecosystem |
validate-action/validate-a2ml.sh:167 — a regex alternation over the four heads |
deed-ecosystem |
conformance/manifest.a2ml, conformance/run-deed-tests.sh:15, conformance/README.adoc:28 |
launch-scaffolder |
crates/launcher-common/src/deed.rs:187 — pub const DOC_HEADS: [&str; 4], a fixed-size array, so a typed change here and a silent one everywhere else |
Justified only if a launcher descriptor is genuinely a fifth document form rather than a praxis document. The burden is on arm A to show that.
Arm C — <app>_chora.deed
Semantically wrong, recorded so it is not rediscovered. repo-deed is "What a repo IS — a record", a noun. A launcher descriptor is not a record of what a repo is. It also discards the .launcher infix that arm B keeps for free.
Question 2 — the grammar. A rewrite, not a rename.
The descriptors are TOML-shaped; a deed is not TOML, and the differences are structural:
| descriptors use |
a deed permits |
key = value |
no = as a separator — KEYWORD Sep Value inside s-expressions (= may appear only inside a symbol) |
[section] headers |
no sections — nested ( ... ) clauses; the only bracket is ( |
| tabs |
tabs are INVALID separators |
| any UUID |
uuid5 only (#u5"…"); v4 is deliberately excluded |
true / false |
#t / #f only |
| TOML escapes |
exactly four: \" \\ \n \t — \r and \uXXXX are invalid |
⚠ The two constraints the first draft of this issue missed
1. :beholding-chora is REQUIRED, and it must be a uuid5. DEED-GRAMMAR-SPEC.adoc:379-414, The praxis-deed form: a praxis deed requires :schema-version, :canonical-name and :beholding-chora. The reason is the one declaration site rule (:398-400, :420-433) — a tool may not declare its own vocabulary, so it must name the chora it reads, "A UUID, never a bare filename — a bare filename resolves against nothing."
So every converted descriptor must name a chora. The good news is that one already serves: launcher-standard_praxis.deed beholds #u5"estate/chora". Whether 21 per-app descriptors should behold the estate chora directly, or a dedicated launcher chora should be declared once and beheld by all of them, is a design decision this issue must make — it is not a detail to settle per-file during a conversion.
2. The praxis field set beyond those three is formally provisional. The spec carries a WARNING: the owner ruled the head but "did not rule on which fields beyond these three a praxis deed must carry — candidates such as :invokes, :emits and :may-refuse are not specified here, because inventing them is precisely the failure this document exists to stop."
Read strictly that blocks arm B, since a launcher descriptor's substance (runtime, version-output, integration) has no specified fields. But there is working precedent in the very file D73-C shipped: launcher-standard_praxis.deed already carries :standard-version, :standard-date and :compliance beyond the required three. So the practical question is not "may a praxis deed carry more fields" — it demonstrably does — but "which fields, named once, for all 21." That is this issue's real substance, and it should be settled as one vocabulary rather than invented 21 times.
⚠ Two versions, not one. :schema-version is the DEED grammar (1.0.0); :standard-version is the document (0.4.0 on the launcher standard today). A converted descriptor carries the first and cites the second. Conflating them makes a stale document read as a newer spec.
⚠ launch-scaffolder has no per-app config deed grammar today. #36 shipped a reader for the standard; there is no schema, reader or writer for a per-app descriptor.
Sequencing
#40 (compat reader, dual-accept) → this issue (design) → dry-run manifest → conversion
Nothing here moves a file. The citation-text fix for these same descriptors is a separate already-ruled workstream (standards#960 AC1): comment-only, independent of the file extension, and must not be folded into this migration.
Acceptance criteria
- The filename arm is ruled (A, B or C) with the reason recorded.
- The beholding question is ruled: estate chora directly, or a dedicated launcher chora declared once — with the uuid5 named, not left as a filename.
- A per-app descriptor field vocabulary is written down once, covering every
[section] and key = value in the current descriptors. A TOML key with no deed equivalent is a recorded finding, not a silent drop. Fields are named in one place and reused, never invented per file.
- A conformance fixture pair — one valid, one invalid — lands in the deed conformance corpus for the chosen form, and the corpus runner exercises them.
launch-scaffolder reads the new form, with a round-trip test proving a descriptor survives read→write→read byte-identically.
- A dry-run manifest lists every file the conversion would touch, current and proposed path, reviewed before any file moves. Both forms are accepted for a stated overlap window before the old one is refused.
- If arm A is ruled: all six sites are updated in one change, and the conformance suite fails if any is missed — the
[&str; 4] array makes a partial change a compile error in one repo and silent in the others.
Cross-references
🤖 Generated with Claude Code
https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo
Context
hyperpolymath/standards#960AC2 asked whether the 21 per-app launcher descriptors (*.launcher.a2ml) should migrate to.deedor be declared out of scope for D73-C. The owner has ruled: migrate to.deed(2026-09-22, recorded at standards#960).AC2 is closed by that decision — its wording is "decided, not left to decay". This issue is the design work the decision creates. It is deliberately not a migration PR: it sequences behind #40 (the
@a2ml-metadatacompat reader), under the dual-accept rule — do not migrate extensions before dual-accept, and a dry-run manifest first, never a bulk pass.All citations below are to
hyperpolymath/standardsorigin/main.Question 1 — the filename.
<app>.launcher.deedis not a legal deed name.Deed filenames are a normatively closed production.
1-formats/deed/spec/abnf/deed.abnf:66-71:with the matching closed head set at
deed.abnf:46andDEED-GRAMMAR-SPEC.adoc:192, and a semantic constraint atdeed.abnf:50-56: "The doc-head MUST match the filename dispatch … A mismatch is a validation error."Filename dispatch is normative in its own right — the spec says outright that "the grammar alone is not sufficient to dispatch a filename" (
DEED-GRAMMAR-SPEC.adoc:310-315). So<app>.launcher.deed, matching none of the four productions, is not a deed.The stem→head table (
DEED-GRAMMAR-SPEC.adoc:276-295) is the authority on meaning:estate_chora.deed(exact)estate-deed*_chora.deedexcl. the aboverepo-deedATLAS.deed(exact)estate-atlas-deed*_praxis.deedpraxis-deed⭐ Arm B —
<app>.launcher_praxis.deed(recommended)A stem may contain dots.
deed.abnf:71admits.instem, anddeed.abnf:62-64says so explicitly: "Do NOT split on.— the stem may contain dots (my.project_chora.deed→ stemmy.project)." (Mirrored atDEED-GRAMMAR-SPEC.adoc:297-299.)So
myapp.launcher_praxis.deedis a legal deed filename, stemmyapp.launcher, dispatching topraxis-deed. That matters: the rename is a suffix swap,.launcher.a2ml→.launcher_praxis.deed, and the existing.launchernaming survives intact. No discovery pattern elsewhere in the estate has to learn a new stem shape.It is also the semantically correct head. A per-app launcher descriptor states what the launcher does for that app — its runtime, its version-output behaviour, its desktop integration. That is a verb, and
praxis-deedis the verb form. It composes with what already exists:launcher-standard_praxis.deedstates the general rules;<app>.launcher_praxis.deedstates that app's conforming praxis. Same head, two scopes.Arm A — add a fifth head (
launcher-deed+ its stem pattern)Honest cost: six sites across three repos, plus an owner ruling — all four existing heads are owner rulings, and
praxis-deedwas RULED 2026-09-08 on standards#752 as "a genuine fourth head, not a facet ofrepo-deed."standards1-formats/deed/spec/abnf/deed.abnf:46(doc-head) and:66(deed-filename)standards1-formats/deed/spec/DEED-GRAMMAR-SPEC.adoc:192(DocHead) + stem table:276-295+ dispatch side condition:301-308standards1-formats/deed/README.adoc(stem/head table)deed-ecosystemvalidate-action/validate-a2ml.sh:167— a regex alternation over the four headsdeed-ecosystemconformance/manifest.a2ml,conformance/run-deed-tests.sh:15,conformance/README.adoc:28launch-scaffoldercrates/launcher-common/src/deed.rs:187—pub const DOC_HEADS: [&str; 4], a fixed-size array, so a typed change here and a silent one everywhere elseJustified only if a launcher descriptor is genuinely a fifth document form rather than a praxis document. The burden is on arm A to show that.
Arm C —
<app>_chora.deedSemantically wrong, recorded so it is not rediscovered.
repo-deedis "What a repo IS — a record", a noun. A launcher descriptor is not a record of what a repo is. It also discards the.launcherinfix that arm B keeps for free.Question 2 — the grammar. A rewrite, not a rename.
The descriptors are TOML-shaped; a deed is not TOML, and the differences are structural:
key = value=as a separator —KEYWORD Sep Valueinside s-expressions (=may appear only inside a symbol)[section]headers( ... )clauses; the only bracket is(#u5"…"); v4 is deliberately excludedtrue/false#t/#fonly\"\\\n\t—\rand\uXXXXare invalid⚠ The two constraints the first draft of this issue missed
1.
:beholding-chorais REQUIRED, and it must be a uuid5.DEED-GRAMMAR-SPEC.adoc:379-414, The praxis-deed form: a praxis deed requires:schema-version,:canonical-nameand:beholding-chora. The reason is the one declaration site rule (:398-400,:420-433) — a tool may not declare its own vocabulary, so it must name the chora it reads, "A UUID, never a bare filename — a bare filename resolves against nothing."So every converted descriptor must name a chora. The good news is that one already serves:
launcher-standard_praxis.deedbeholds#u5"estate/chora". Whether 21 per-app descriptors should behold the estate chora directly, or a dedicated launcher chora should be declared once and beheld by all of them, is a design decision this issue must make — it is not a detail to settle per-file during a conversion.2. The praxis field set beyond those three is formally provisional. The spec carries a WARNING: the owner ruled the head but "did not rule on which fields beyond these three a praxis deed must carry — candidates such as
:invokes,:emitsand:may-refuseare not specified here, because inventing them is precisely the failure this document exists to stop."Read strictly that blocks arm B, since a launcher descriptor's substance (runtime, version-output, integration) has no specified fields. But there is working precedent in the very file D73-C shipped:
launcher-standard_praxis.deedalready carries:standard-version,:standard-dateand:compliancebeyond the required three. So the practical question is not "may a praxis deed carry more fields" — it demonstrably does — but "which fields, named once, for all 21." That is this issue's real substance, and it should be settled as one vocabulary rather than invented 21 times.⚠ Two versions, not one.
:schema-versionis the DEED grammar (1.0.0);:standard-versionis the document (0.4.0on the launcher standard today). A converted descriptor carries the first and cites the second. Conflating them makes a stale document read as a newer spec.⚠
launch-scaffolderhas no per-app config deed grammar today. #36 shipped a reader for the standard; there is no schema, reader or writer for a per-app descriptor.Sequencing
Nothing here moves a file. The citation-text fix for these same descriptors is a separate already-ruled workstream (standards#960 AC1): comment-only, independent of the file extension, and must not be folded into this migration.
Acceptance criteria
[section]andkey = valuein the current descriptors. A TOML key with no deed equivalent is a recorded finding, not a silent drop. Fields are named in one place and reused, never invented per file.launch-scaffolderreads the new form, with a round-trip test proving a descriptor survives read→write→read byte-identically.[&str; 4]array makes a partial change a compile error in one repo and silent in the others.Cross-references
hyperpolymath/standards#960— AC2, the ruling this issue implements@a2ml-metadatacompat reader; this issue sequences behind itREQUIRED_KEYSvs the deed's:required-fields; same metadata surfacestandards1-formats/deed/spec/DEED-GRAMMAR-SPEC.adocand1-formats/deed/spec/abnf/deed.abnf— the normative grammar (v1.0.0)🤖 Generated with Claude Code
https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo