roadmap: P2 milestone — DESIGN.md -> design/ role-split

User-authored proposal added during the embedding-abi-m1.1 implement
run (path-disjoint from the iter; Boss roadmap maintenance, not
bundled into the iter commit). Role-split of the 2905-line DESIGN.md
into a typed contract ledger + per-model whitepapers + decision-
records rehomed to docs/journals/, on the consumer/lifetime axis.
This commit is contained in:
2026-05-18 14:32:14 +02:00
parent b0bd7efeaf
commit 123ae1be5c
+97
View File
@@ -290,6 +290,103 @@ work progresses.
## P2 — Medium-term
- [ ] **\[milestone\]** DESIGN.md → `design/` — role-split into a
typed contract ledger + per-model whitepapers, decision-records
rehomed to `docs/journals/`. `docs/DESIGN.md` is one 2905-line
file doing three different jobs for three different consumers
with three different lifetimes; the line count is the symptom of
role-conflation, not of mess. Replace it with a `design/`
directory split along the consumer/lifetime axis, with a typed
`design/INDEX.md` as the sole addressable spine and primary
entry point.
**Motivation.** The just-closed `docs-honesty-lint` milestone is
the proof this is not a cleanup problem: it ran a full docs pass
and DESIGN.md stayed 2905 lines, because honesty-lint operates
*within* a job (tense / Wunschdenken / citation) and its own
audit-trail invariant *mandates retaining* the bulky
decision-record prose (DESIGN.md:242 "records the *why* … for
the audit trail"; the architect Sweep-5 discriminator explicitly
keeps "present-tense design rationale"). You cannot clean your
way out of conflation — the conflation itself is the structural
defect.
The three conflated jobs and their distinct consumers:
- **Contract layer** — prescriptive, test-linked invariants
(e.g. Decision 6's seven hard constraints, the Roundtrip
Invariant, the borrow/own binding rules). Consumer:
`architect` (mandatory full read at *every* milestone close),
`grounding-check` (every spec), the bench drift lints. Wants:
structured, addressable, test-linked, small, hot. This is the
only job that belongs on the per-milestone hot path.
- **Model exposition** — whitepaper-shaped model narratives
(RC + Uniqueness, typeclasses, effects). Consumer: onboarding
(fresh-context LLM, `fieldtester`). Irreducible — the code
cannot speak the gestalt; one whitepaper per model.
- **Decision-record / relitigating-guard** — why X was chosen,
why Y/Z were rejected (region inference, tracing GC, …).
Consumer: a future `brainstorm`, so it does not re-propose a
settled-and-rejected idea. This already has a home —
`docs/journals/` — and sits in DESIGN.md only because the
audit-trail invariant predates per-iter addressable journals.
Underlying principle: the code is authoritative for *what it
does* — delete every description of behaviour, the code speaks;
the spec's irreducible job is *what is promised* plus a pointer
to the green test that ratifies it (code answers *what*; spec
answers *what is promised*; test answers *does the promise still
hold*).
**Decided shape.** `design/` split on the consumer/lifetime
axis — **not** by Decision-number (that is cosmetic; the
architect would still read everything). `design/contracts/` (the
hot, test-linked invariant set), `design/models/` (one
whitepaper per model). `design/INDEX.md` is the typed ledger
spine: per entry a one-liner + metadata
`{kind, ratifying-test, consumer/lifetime}` + a content link
whose target is polymorphic — a `design/contracts/…` file, a
single-owner `//!` source header (mangling, env, roundtrip,
float, tail-calls, data-model), or a `design/models/…`
whitepaper. INDEX.md is the sole addressable entry point.
Decision-records move out to `docs/journals/`; the honesty-lint
audit-trail invariant is repointed there in the same milestone.
**Rejected — do not relitigate.** Quarto / `.qmd` was evaluated
and rejected: every distinctive Quarto feature (rendered
HTML/site, figures, citations, cross-ref resolution, executable
chunks) is render-time value for a *human reader who does not
exist here* — the `design/` consumer is an LLM reading raw
files. Executable chunks would reintroduce a second "is the
invariant green?" truth that can diverge from `cargo test` (the
duplicate-source-of-truth failure mode); Quarto `@ref`
cross-refs degrade the raw-file reader (unresolved tokens vs.
resolving relative-path links); plus a non-Rust toolchain
dependency for zero in-loop value. Plain Markdown + a typed
INDEX.md is strictly better for this consumer. A plain shard by
Decision-number is likewise rejected (changes nothing for the
architect hot path).
**Sequencing / blast radius.** Deliberately scheduled *after*
the in-flight Embedding ABI arc — a substantive sequencing
reason, not effort. `DESIGN.md` is referenced by name by at
least `bench/check.py` (history-anchor / `design_schema_drift`),
`bench/architect_sweeps.sh` (Sweep 5; exit 2 = "could not find
DESIGN.md"), the reading lists of `ailang-architect` /
`ailang-grounding-check` / `ailang-fieldtester`, the CLAUDE.md
"Roles of docs/…" section, and the honesty-lint invariant's own
scope — load-bearing invariants and agent contracts, not just
paths. Every Embedding-ABI milestone close runs `audit`
(architect + bench) against DESIGN.md; restructuring it mid-arc
would break the architect's reading list and the drift scripts
*under* an in-flight milestone. Hence no overlap with active
implementation that closes audits against the current
DESIGN.md. Brainstorm hard-gate before any plan/code — it
rewrites enforced invariants and agent contracts.
- context: 2026-05-18 chat (DESIGN.md-management dialogue —
six-turn convergence: role-conflation diagnosis, three-job
split axis, "let the code speak" principle, qmd rejection,
blast-radius sequencing). No journal entry yet; pre-brainstorm.
- [ ] **\[milestone\]** Flat array/slice primitive — performance
follow-up to the Embedding ABI arc, *not* a capability gap.
AILang's only sequence is the recursive `List` ADT (one RC cell