diff --git a/1-formats/deed/mappings/ai-manifest-decision.adoc b/1-formats/deed/mappings/ai-manifest-decision.adoc new file mode 100644 index 000000000..7c39b6033 --- /dev/null +++ b/1-formats/deed/mappings/ai-manifest-decision.adoc @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: CC-BY-SA-4.0 += Decision spec — `0-AI-MANIFEST.a2ml` → deed era (family 7) +Campaign: standards#837 · Frame: link:README.adoc[mappings/README] · +Status: **DECISION REQUIRED (owner)** — raised by the first live +conformance finding of the wave (marid, verified 2026-09-19): a +*renamed-not-translated* `0-AI-MANIFEST.deed` carrying INI content already +exists in the wild. Renames are not translations; this spec exists so the +wave converts ~900 generated files instead of ~900 ad-hoc moves. + +== 0. Naming collision (wave rule #1: do not conflate) + +**`0.2-AI-MANIFEST.a2ml` (cartridge directory-manifests) is a DIFFERENT +family.** Found during recon: `1-formats/sub-specs/cartridges/` +and `docs/wikis/0.2-AI-MANIFEST.a2ml` carry YAML-ish `key: value` +directory-manifest content (boJ cartridge system, governed by +`cartridge-v1.json` schema) — unrelated to the per-repo agent-allocation +file. The wave must match on the agent-allocation *content shape*, never +on the filename alone. Sub-family separation recorded here; cartridge +manifests get their own spec when their registry moment comes (linked to +the #732 rename batch, not this campaign). + +== 1. Source surface (family 7 proper) + +`/0-AI-MANIFEST.a2ml` at repo root — generated, ~900 estate copies +per the #646 audit note. Instance norm (marid, 2026-09-18 vintage): + +[cols="1,3"] +|=== +| Section | Content + +| `[metadata]` | `version`, `last-updated` (strings) +| `[project]` | `name`, `purpose` (strings) +| `[ai-allocation]` | `agents` = array of `{ name, role }` (the estate's agent-identity table: CLAUDE / CHATGPT / GEMINI / VIBE …) +| `[policy]` | `rules` = array of prose-rule strings +| `[work-allocation]` | `items` = array of `{ agent, task }` +|=== + +== 2. The options on the table + +**A. `(manifest …)` clauses on the repo deed (RECOMMENDED).** AI-MANIFEST +content is *repo state*: who is allocated here, under what policy. The +one-deed-per-repo doctrine already lands AGENTIC/PLAYBOOK here; the +allocation manifest is the same epistemic kind. Fields map cleanly with +zero invented grammar. + +**B. `*_praxis.deed`.** Rules-shaped? The policy rules are *prose*, not +machine rules — no `:when`/`:then`, no precedent for `:priority` +proration; forcing them into praxis invents exactly the field shapes the +grammar's provisional-note forbids. Recorded and rejected; not asked for. + +== 3. Field table (option A; translator refuses anything else — P-2a) + +[cols="2,3,4"] +|=== +| a2ml surface | deed path | transform / type + +| `[metadata] version` / `last-updated` | `(manifest :version "…" :last-updated "…")` | verbatim STRINGs +| `[project] name` | `(manifest :project "Marid")` | verbatim STRING — cross-checked against deed `:canonical-name` (P-6 analogue; mismatch fails closed: catches a manifest read into the wrong repo) +| `[project] purpose` | `(manifest :purpose "…")` | verbatim STRING +| `[ai-allocation] agents[]` | one clause per entry: `(agent :name CLAUDE :role "…")` | `name` → SYMBOL (agent identities ARE identifiers — estate greps depend on the literal symbol; closed seen-set extended by ruling, never silently), `role` → STRING verbatim +| `[policy] rules[]` | `(policy (rules ("rule text" "rule text")))` | list of STRINGs — order is semantic here, and *list order is preserved by the grammar* (a list is a value, unlike clause order); no invented rule-ids +| `[work-allocation]` items[] | `(work :agent GEMINI :task "…")` per entry | agent → SYMBOL (same identity table as `:name`s above; agent in items[] but not in agents[] fails closed — allocation without a declared identity), task → STRING +|=== + +== 4. Must-preserve + wave rules (the hazard table) + +1. **No renames. Only translations.** A `.deed` file contains a deed. The + marid `0-AI-MANIFEST.deed` class (INI content, `.deed` name, root + location, no dispatch pattern) fails on three independent counts — + the whole-tree deed-lint CI gate (already in standards' + `deed-conformance.yml;` wave repos inherit it) is what kills this class + on contact, not review-eyeballs. +2. **Agent-identity table verbatim.** `:name CLAUDE` etc. are estate-wide + greppable constants; any fourth-name propagation anomaly is flagged + (P-9 analogue). +3. **The no-duplicate-tasks invariant** rides as a policy rule text + verbatim; translators dedupe nothing, interpreters dedupe nothing — + the text itself is the contract. +4. **Generator-first for the wave.** ~900 files are *generated*: convert + the generator's emit surface BEFORE the files (the #645 lesson: fix at + source, then re-propagate). The 6a2/A2ML generator home is an + owner-information dependency (same hunt as #646's, now with a deed-era + destination). + +== 5. Acceptance (once ruled) + +* Zero `0-AI-MANIFEST.deed` files containing `=` as a field separator + exist estate-wide (the in-the-wild rename class: zero). +* Every converted repo's deed carries `(manifest …)` with agent symbol + counts matching its old a2ml arrays one-for-one. +* `grep -rn ":name CLAUDE\b" --include='*_chora.deed'` reproduces the + pre-wave allocation table byte-for-meaning. + +== 6. Ruling asks + +. Option A confirm (or an alternative home — with reasons, so the next + family spec inherits the principle). +. Whether the agent *seen-set* is closed-and-ruled (CLAUDE/CHATGPT/ +GEMINI/VIBE) or open-with-review — translator default without an answer: + open + flag-any-unknown (fails captured, not blocked). +. Generator location/home for the wave's source-fix step (owner-info).