# DESIGN.md → `design/` role-split — Design Spec

**Date:** 2026-05-19
**Status:** Draft — awaiting user spec review
**Authors:** Brummel (orchestrator) + Claude

## Goal

`docs/DESIGN.md` is one **3020-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: the
just-closed `docs-honesty-lint` milestone ran a full honesty pass and
DESIGN.md stayed 3020 lines, because honesty-lint operates *within* a
job and its own audit-trail invariant *mandates retaining* the bulky
decision-record prose (DESIGN.md Decision 6, lines 241–243: "records
the *why* … for the audit trail"). You cannot clean your way out of
conflation; the conflation is the structural defect.

Replace `docs/DESIGN.md` with a `design/` directory split on the
**consumer/lifetime axis** — `design/contracts/` (the hot,
test-linked invariant set), `design/models/` (one whitepaper per
model) — with `design/INDEX.md` as the **sole addressable spine**.
Decision-record prose moves to `docs/journals/`. The split is a
**clean cut**: `docs/DESIGN.md` is deleted; every named reference is
repointed in one build-atomic milestone.

The three conflated jobs and their distinct consumers:

- **Contract** — prescriptive, test-linked invariants (Decision 6's
  binding Form-A constraints, the Roundtrip Invariant, the
  borrow/own binding rules, the frozen value layout). Consumer:
  `architect` (mandatory full read at *every* milestone close),
  `grounding-check` (every spec), the honesty sweep. Wants:
  structured, addressable, test-linked, small, hot. The only job on
  the per-milestone hot path.
- **Model exposition** — whitepaper-shaped narratives (RC +
  Uniqueness, typeclasses, effects, the authoring-surface rationale).
  Consumer: onboarding (fresh-context LLM, `fieldtester`).
  Irreducible — the code cannot speak the gestalt.
- **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/`.

Underlying principle: the code is authoritative for *what it does*;
the spec's irreducible job is *what is promised* plus a pointer to
the green test that ratifies it.

## Architecture

```
design/
  INDEX.md                 sole addressable spine — a typed two-table ledger
  contracts/               prose-authoritative invariants (the architect hot path)
    feature-acceptance.md  authoring-surface.md  roundtrip-invariant.md
    memory-model.md        typeclasses.md        float-semantics.md
    frozen-value-layout.md honesty-rule.md       tail-calls.md
    data-model.md          embedding-abi.md      verification.md
  models/                  one whitepaper per model (onboarding path)
    rc-uniqueness.md  typeclasses.md  effects.md  authoring-surface.md  pipeline.md

docs/journals/2026-05-19-design-decision-records.md   relitigation-guard archive
docs/DESIGN.md                                        DELETED (clean cut)
```

Five structural commitments:

1. **Polymorphic INDEX link.** An INDEX row's `link` is *either* a
   `design/` file *or* an authoritative source path. Where code is
   the single source of truth (mangling, env construction,
   qualified-cross-module-ref resolution), there is **no prose
   contract file** — the row points at the source `//!` header and
   names the ratifying test, killing the prose-vs-code second truth.
   `frozen-value-layout` is the deliberate dual-link exception (a
   one-way human commitment *and* a codegen contract → both a prose
   file and a source pointer). The polymorphic disposition is fixed
   per-contract in the Components disposition table below.

2. **`###`-subsection is the unit of relocation.** No sentence-
   surgery. Each `###` subsection of DESIGN.md moves whole to
   `contracts/`, `models/`, or the decision-record journal. The
   MIXED `##` Decisions (6/9/10/11) decompose at their existing
   `###` seam, which recon confirmed resolves cleanly.

3. **Build-atomic, not just semantically atomic.**
   `crates/ailang-core/tests/design_schema_drift.rs:22` uses
   `include_str!("../../../docs/DESIGN.md")` — a compile-time path.
   The instant `docs/DESIGN.md` is deleted the workspace **does not
   compile** until that `include_str!` is retargeted. The content
   move + the 4-executable retarget + the 2-diagnostic/2-E2E
   retarget + the new pin test land in **one commit**; the tree is
   never half-moved. This is a fail-closed property, not a hazard.

4. **The honesty-rule self-repointing resolves the internal
   contradiction.** Two distinct self-referential passages, with
   *different* pin status (grounding-check verified):
   - `### What this document is — and the honesty rule it holds
     itself to` (DESIGN.md:56–82) **is** pinned: `docs_honesty_pin.rs:70`
     pins `"the honesty rule it holds itself to"` and `:72` pins
     `"whether the document asserts something exists, works, or
     changed that does not"` (both inside
     `design_md_present_tense_anchors_present`). This becomes
     `contracts/0007-honesty-rule.md`, **rewritten** so the rule states
     the new home (rationale → `docs/journals/`); those two pins are
     retargeted to the new file *and* the new wording in the same
     atomic change.
   - Decision 6's :242 sentence — *"The rest of this section records
     the why of Decision 6 for the audit trail; the constraints
     listed below describe the surface as shipped."* — is pinned by
     **no test anywhere** (grounding-check grepped `crates/*/tests/`,
     in-source `crates/*/src/`, `effect_doc_honesty_pin.rs`: zero
     matches). It is itself decision-record self-assertion describing
     the *old conflated structure*. The milestone **retires** it: its
     "why of Decision 6" content moves to the decision-record journal;
     the meta-sentence that asserts DESIGN.md retains audit-trail
     prose is not carried forward and needs **no successor pin** —
     code never protected it, and should not, because that sentence
     is exactly the audit-trail self-claim the split removes from the
     contract surface.

   The internal contradiction (a doc asserting of itself that it
   "records the why for the audit trail" while the milestone moves
   the why out) is closed *by* the milestone: the asserting sentence
   is retired, and the only honesty self-claim that survives —
   "rationale lives in `docs/journals/`" — is the rewritten
   `honesty-rule.md`, which the retargeted `:70,72` pins protect.

5. **Clean cut, no stub, no redirect.** `docs/DESIGN.md` is deleted.
   No transitional pointer file (a "see elsewhere" file is itself
   history-pointing — a doc-honesty violation in the milestone that
   exists to enforce doc honesty). Matches the no-deprecation-window
   precedent (mut/var/assign removal) and the current-state-mirror
   discipline.

## Concrete code shapes

### 1. The delivered artifacts (this is an infra milestone — these are the headline)

**`design/INDEX.md`** — the typed two-table ledger. `link` is
polymorphic; `ratifying-test` is mandatory for `kind=contract`:

```markdown
# AILang Design — Index

The sole addressable entry point. Every contract and model is
reached from here. A contract is a prescriptive, test-linked
invariant; a model is a whitepaper narrative. `ratifying-test` names
the green test that proves a contract still holds. `link` is
polymorphic: a `design/` file, or the authoritative source `//!`
header when the code is the single source of truth.

## Contracts
| id | consumer / lifetime | ratifying-test | link |
|----|---------------------|----------------|------|
| feature-acceptance   | brainstorm-gate / stable      | skills/brainstorm/SKILL.md Step 4         | contracts/0004-feature-acceptance.md |
| authoring-surface    | LLM author / stable           | crates/ailang-surface round_trip.rs       | contracts/0001-authoring-surface.md |
| roundtrip-invariant  | every release / stable        | crates/ailang-surface round_trip.rs       | contracts/0009-roundtrip-invariant.md |
| memory-model         | LLM author / stable           | crates/ailang-check/src/uniqueness.rs (in-source mod tests) | contracts/0008-memory-model.md |
| data-model           | LLM author / stable           | crates/ailang-core/tests/design_schema_drift.rs | contracts/0002-data-model.md |
| mangling             | codegen / stable              | crates/ail/tests/eq_ord_e2e.rs            | crates/ailang-codegen/src/lib.rs //! |
| env-construction     | codegen / stable              | crates/ailang-check/tests/duplicate_ctor_pin.rs | crates/ailang-codegen/src/lib.rs //! |
| qualified-xref       | codegen / stable              | crates/ail/tests/codegen_import_map_fallback_pin.rs | crates/ail/src/main.rs //! |
| frozen-value-layout  | embedding ABI / one-way-frozen| crates/ailang-codegen/tests/embed_record_layout_pin.rs | contracts/0006-frozen-value-layout.md + runtime/rc.c §layout |
| float-semantics      | LLM author / stable           | crates/ail/tests/eq_float_noinstance.rs   | contracts/0005-float-semantics.md |
| typeclasses          | LLM author / stable           | crates/ail/tests/show_no_instance_e2e.rs  | contracts/0013-typeclasses.md |
| str-abi              | runtime ABI / stable          | crates/ail/tests/e2e.rs (Str path)        | contracts/0011-str-abi.md + runtime/str.c §heap-Str |
| tail-calls           | codegen / stable              | crates/ailang-check/src/lib.rs (in-source tail_call_in_non_tail_position_is_rejected) | contracts/0012-tail-calls.md |
| honesty-rule         | architect+grounding / stable  | crates/ailang-core/tests/docs_honesty_pin.rs | contracts/0007-honesty-rule.md |
| embedding-abi        | embedding host / stable       | crates/ailang-codegen/tests/embed_record_layout_pin.rs | contracts/0003-embedding-abi.md |
| scope-boundaries     | architect+author / stable     | crates/ailang-core/tests/effect_doc_honesty_pin.rs | contracts/0010-scope-boundaries.md |
| verification         | architect / stable            | bench/architect_sweeps.sh                 | contracts/0014-verification.md |

## Models
| id | consumer / lifetime | link |
|----|---------------------|------|
| rc-uniqueness     | onboarding / evolves | models/0004-rc-uniqueness.md |
| typeclasses       | onboarding / evolves | models/0005-typeclasses.md |
| effects           | onboarding / evolves | models/0002-effects.md |
| authoring-surface | onboarding / evolves | models/0001-authoring-surface.md |
| pipeline          | onboarding / evolves | models/0003-pipeline.md |
```

The `ratifying-test` column above is now **Boss-resolved to exact
recon-verified paths** (plan-recon confirmed each file exists; the
`design_index_pin.rs` clause-2 check, widened to accept
`crates/**/src/*.rs` in-source `#[cfg(test)] mod tests`, requires
every token to resolve to a real file). The full per-`###`
relocation map and the adjudication rationale for the three
ledger additions (`qualified-xref`, `str-abi`, `scope-boundaries`)
are in the **Appendix — Boss-adjudicated relocation map** at the
end of this spec; that appendix is the authoritative,
placeholder-free map the planner consumes.

**A sample contract file** — `design/contracts/0005-float-semantics.md`
(content moved verbatim from DESIGN.md:2700–2838, header re-levelled
to file root, all decision-record/why-prose stripped to the journal):

```markdown
# Float semantics

Float is the IEEE-754 double-precision primitive. Float has **no
`Eq` and no `Ord` instance by design**: IEEE-754 ordering is partial
(NaN is unordered), so a total `Eq`/`Ord` would be a lie about the
type. … [present-tense contract prose only] …

`float_to_str` is type-installed; codegen is reserved and not yet
shipped.

Ratified by: `crates/ail/tests/eq_float_noinstance.rs`.
```

**The anti-regrowth guard** — `crates/ailang-core/tests/design_index_pin.rs`
(the concrete must-fail artifact for an infra milestone — its correct
behaviour is to go RED the instant the structure re-conflates):

```rust
//! Structural pin for the design/ ledger. Sibling of
//! docs_honesty_pin.rs. Fails RED the instant the design/ split
//! re-conflates contract + rationale + narrative, an INDEX row
//! dangles, a contract loses its ratifying test, or docs/DESIGN.md
//! is resurrected.

// helper: workspace root = CARGO_MANIFEST_DIR/../.. ; norm() =
// split_whitespace().join(" ") — line-wrap-independent, identical
// shape to docs_honesty_pin.rs.

#[test]
fn design_md_is_gone() {
    // clause 4 — clean-cut pin
    assert!(!root().join("docs/DESIGN.md").exists(),
        "docs/DESIGN.md was resurrected; the split is clean-cut");
}

#[test]
fn every_index_link_resolves() {
    // clause 1 — parse design/INDEX.md tables; for each row, the
    // `link` target (design/ file OR source path; the dual-link
    // row's first segment before " + ") exists on disk.
}

#[test]
fn every_contract_names_a_resolvable_ratifying_test() {
    // clause 2 — every kind=contract row's ratifying-test token
    // resolves to a real file under crates/**/tests, crates/**/src
    // (in-source `#[cfg(test)] mod tests` are first-class ratifiers
    // in this project — see Boss adjudication OQ1/OQ2), bench/, or
    // skills/**/SKILL.md.
}

#[test]
fn contracts_carry_no_decision_record_prose() {
    // clause 3 — the conflation tripwire. For each
    // design/contracts/*.md, norm() the body and assert it contains
    // none of: "we rejected", "an earlier draft", "Why not other",
    // "was retired in iter", "rollback plan", "previously all".
}
```

### 2. The one real code change — compiler diagnostic, before → after

This is the clause-1 / clause-3 evidence. The pre-existing fixture
the diagnostic E2E runs (unchanged), the program an LLM author
writes that **must fail** to typecheck:

```scheme
; examples/eq_float_noinstance.ail
(module eq_float_noinstance
  (fn main
    (type (fn-type (params) (ret (con Unit)) (effects IO)))
    (params)
    (body (app print (if (app eq 1.0 2.0) 1 0)))))
```

`crates/ailang-check/src/lib.rs:873` (the Float branch):

```
- orderability per IEEE-754); see DESIGN.md §\"Float semantics\".",
+ orderability per IEEE-754); see design/contracts/0005-float-semantics.md.",
```

`crates/ailang-check/src/lib.rs:888` (the Show branch):

```
- the prelude; see DESIGN.md §\"Prelude (built-in) \
- classes\". User types declare their own \
+ the prelude; see design/contracts/0013-typeclasses.md. \
+ User types declare their own \
```

`crates/ail/tests/eq_float_noinstance.rs:40` — the assertion
currently passes on `"Float semantics" || "DESIGN"`; both substrings
vanish, so it updates in lockstep:

```rust
-   no_inst.message.contains("Float semantics") || no_inst.message.contains("DESIGN"),
-   "expected NoInstance message to cross-reference DESIGN.md §Float semantics, got: {:?}",
+   no_inst.message.contains("design/contracts/0005-float-semantics.md"),
+   "expected NoInstance message to cross-reference the float-semantics contract, got: {:?}",
```

`crates/ail/tests/show_no_instance_e2e.rs:48` — analogous: the
asserted substring becomes `"design/contracts/0013-typeclasses.md"`.

### 3. The four executable retargets (before → after)

`bench/architect_sweeps.sh:22-28`:

```sh
- DESIGN="docs/DESIGN.md"
- [[ ! -f "$DESIGN" ]] && { echo "could not find $DESIGN"; exit 2; }
+ INDEX="design/INDEX.md"
+ [[ ! -f "$INDEX" ]] && { echo "could not find $INDEX"; exit 2; }
```

Each `run_sweep` greps the `design/contracts/*.md` + `design/models/*.md`
set instead of the single file; exit-code contract preserved
(0 clean / 1 anchor-found / 2 spine-not-found). Sweep 5 (honesty)
scans all `design/` prose; the verbatim regexes are unchanged.

`crates/ailang-core/tests/design_schema_drift.rs:22`:

```rust
- const DESIGN_MD: &str = include_str!("../../../docs/DESIGN.md");
+ const DATA_MODEL: &str = include_str!("../../../design/contracts/0002-data-model.md");
```

The `data_model_section()` slicer (`## Data model` … `\n## Pipeline`)
and `data_model_section_is_bounded` are **removed**: the whole file
is now the data-model contract, so the section-extraction premise
vanishes — a simplification the split enables. Every
`section.contains(anchor)` assertion runs against the whole
`DATA_MODEL` string.

`crates/ailang-core/tests/docs_honesty_pin.rs` and
`effect_doc_honesty_pin.rs`: the `read("docs/DESIGN.md")` calls split
into reads of the specific `design/` files where each pinned sentence
now lives. The present/absent pin strings are unchanged **except**
the two honesty-rule anchors at `docs_honesty_pin.rs:70,72` (`"the
honesty rule it holds itself to"` / `"whether the document asserts
something exists, works, or changed that does not"`), which are
updated to the rewritten `contracts/0007-honesty-rule.md` wording in
lockstep with that file. The Decision-6 `:242` audit-trail sentence
is pinned by no test (verified) and is retired to the decision-record
journal, not retargeted — there is nothing to repoint, by design.

### 4. Agent reading-list rewrite (representative before → after)

`skills/audit/agents/ailang-architect.md:30`:

```
- 2. `docs/DESIGN.md` — the canonical specification. Drift is measured against
+ 2. `design/INDEX.md` — the typed contract ledger and sole spine.
+    Walk the Contracts table; drift is measured against each row's
+    `link` target (a `design/contracts/` file or the source `//!`
+    it names). `design/models/` is context, not a drift surface.
```

The other ~11 reading-list bullets
(`grounding-check`, `fieldtester`, `debugger`, `bencher`, `tester`,
`implementer`, `implement-orchestrator`, `spec-reviewer`,
`quality-reviewer`, `plan-recon`, `docwriter`) are rewritten to their
role: grounding-check and architect read `contracts/`; fieldtester
reads `INDEX.md` + `models/` (no-edit limit preserved, repointed);
bencher reads `models/0004-rc-uniqueness.md` (Decision-9/Boehm narrative);
the rest point at `design/INDEX.md` as the spine.

## Components

The per-contract disposition (fixes the polymorphic link, planner
does not re-decide it):

| Contract | Disposition | Rationale |
|----------|-------------|-----------|
| feature-acceptance | prose file | gate text, prose-authoritative |
| authoring-surface | prose file | binding Form-A constraints, prose-stated |
| roundtrip-invariant | prose file | the invariant statement is prose |
| memory-model | prose file | Decision 10 `### Language-design constraints (binding)` + `### Schema additions` + `### Codegen contract`; binding, prose-stated |
| data-model | prose file | the wire schema an author must produce is a *promise* (prose-authoritative); `design_schema_drift.rs` `include_str!`s it |
| float-semantics | prose file | author-facing; the diagnostic points here |
| typeclasses | prose file | coherence/dispatch rules + prelude classes; the Show diagnostic points here |
| tail-calls | prose file | the propagation rule is prose-stated, check-ratified |
| frozen-value-layout | prose file **+** source link | one-way human commitment AND codegen contract — deliberate dual-link |
| honesty-rule | prose file | rewritten; resolves the internal contradiction |
| embedding-abi | prose file | the M3-frozen ABI contract, author + host facing |
| verification | prose file | the cross-cycle verification contract |
| mangling | **source link only** | codegen behaviour; prose would duplicate code; `eq_ord_e2e.rs` ratifies |
| env-construction | **source link only** | codegen behaviour; `duplicate_ctor_pin.rs` ratifies |

Models (always prose whitepapers): `rc-uniqueness` (Decision 10
narrative + Decision 9 Boehm rationale), `typeclasses` (resolution /
monomorphisation narrative), `effects` (Decision 3 narrative),
`authoring-surface` (notation rationale, candidate notations,
empirical addendum), `pipeline` (Pipeline + CLI).

Decision-record archive — `docs/journals/2026-05-19-design-decision-records.md`:
the `### Why not other memory models`, `### What this Decision
deliberately does not do` (×N), `### Empirical addendum`,
`### First choice and rollback plan`, and every "considered and
rejected" passage, moved whole at `###` granularity. The journals
`INDEX.md` gets the one-line pointer per project convention.

## Data flow

- **Architect, milestone close:** reads `design/INDEX.md` → walks
  the Contracts table → for each row reads the `link` target →
  measures drift against it. `architect_sweeps.sh` scans the
  `design/` prose set; exit codes unchanged.
- **grounding-check, per spec:** reads `design/INDEX.md` → the
  contract rows the spec's assumptions touch → composes.
- **LLM author, NoInstance:** the diagnostic names
  `design/contracts/0005-float-semantics.md` (or `…/typeclasses.md`) →
  opens exactly that contract → self-corrects.
- **Future brainstorm tempted to re-propose region inference:** the
  "why rejected" prose is in
  `docs/journals/2026-05-19-design-decision-records.md`, reachable
  from the journals INDEX — not in any contract file.
- **`design_index_pin.rs`, every `cargo test`:** parses INDEX.md →
  asserts all links resolve, all contracts name a resolvable
  ratifying-test, no contract carries decision-record prose,
  `docs/DESIGN.md` is absent.

## Error handling

All failure modes fail closed:

- INDEX row → missing target ⇒ `design_index_pin.rs`
  `every_index_link_resolves` RED.
- A `contracts/` file regrows "we rejected"/"Why not other"/… ⇒
  `contracts_carry_no_decision_record_prose` RED (the conflation
  tripwire — the milestone's reason to exist, enforced in code).
- `docs/DESIGN.md` resurrected ⇒ `design_md_is_gone` RED.
- A contract names a ratifying-test that does not resolve ⇒
  `every_contract_names_a_resolvable_ratifying_test` RED.
- `architect_sweeps.sh` cannot find `design/INDEX.md` ⇒ exit 2
  (preserved "infra missing" semantics, repointed).
- Content move lands without the `include_str!` retarget ⇒
  `cargo build` fails. This is the build-atomic fail-closed
  property; the planner sequences the single landing build-green.
- **Recon-undercount countermeasure (acceptance gate).** The
  milestone's acceptance includes a tree-wide
  `grep -rIn 'DESIGN\.md'` over *all file types*
  (`bench/ skills/ crates/ runtime/ ail-embed/ examples/ docs/
  CLAUDE.md`) returning **only** the append-only history docs
  (`docs/journals/`, `docs/specs/`, `docs/plans/`,
  `docs/roadmap.md`, `docs/WhatsNew.md`, `docs/journal-archive.md`)
  — zero live references in code, scripts, agent files, or
  comments. Recon proved the carrier's file-type list
  (`*.md *.rs *.py *.sh *.toml`) silently misses `.c`/`.h`/`.ail`;
  the gate is unfiltered (`grep -rIn`, no `--include`) and any
  claimed-absent path is `ls`-verified. This is the
  fourth-recurrence recon-undercount class made an explicit gate.

## Testing strategy

- **RED-first spine:** `design_index_pin.rs` (the 4 clauses above)
  is written first; RED until `design/` exists, is consistent, and
  `docs/DESIGN.md` is gone; GREEN when the split is complete and
  faithful.
- **Retarget, not rewrite:** `design_schema_drift.rs`,
  `docs_honesty_pin.rs`, `effect_doc_honesty_pin.rs` keep their
  *property* (the schema/honesty invariant stays documented); only
  the path/anchor moves. `design_schema_drift.rs` additionally
  *simplifies* (the `## Data model`/`## Pipeline` slicer is removed
  — the file boundary now bounds the section).
- **Lockstep E2Es:** `eq_float_noinstance.rs`,
  `show_no_instance_e2e.rs` updated with the diagnostic strings;
  they continue to assert the author-affordance (a correct,
  resolvable pointer).
- **Whole-suite GREEN:** `cargo test` workspace-wide must be green
  post-split (the `include_str!` retarget + all path moves
  consistent). Build-atomicity makes a half-move a compile failure,
  not a silent-wrong state.
- **Bench unaffected:** recon confirmed the bench harness
  (`bench/check.py`, `compile_check.py`, `cross_lang.py`,
  `run.sh`) has zero `DESIGN.md` references; only
  `architect_sweeps.sh` (audit-time, not bench-time) opens it.
  Generated IR is byte-identical (no codegen change — the
  diagnostic *string* is not in the IR). Any bench firing is the
  tracked P2 noise and is causally exonerable by byte-identical-IR.
- **Audit, mandatory at milestone close:** architect drift review
  against the *new* `design/` (the architect's own reading list is
  one of the rewritten artifacts — the audit validates the
  structure it now reads); bencher causal exoneration as usual.
- **No fieldtest:** zero authoring-surface change. The
  diagnostic-string change is a doc-pointer, not a language or
  authoring-surface change. (Recorded explicitly so the post-audit
  step is not skipped by omission but by reasoned exclusion.)

## Acceptance criteria

1. `docs/DESIGN.md` does not exist; `design/INDEX.md`,
   `design/contracts/*.md`, `design/models/*.md`, and
   `docs/journals/2026-05-19-design-decision-records.md` exist and
   are internally consistent.
2. Every `###` subsection of the former DESIGN.md is accounted for
   in exactly one destination (contract / model / decision-record);
   no content is silently dropped.
3. `design/INDEX.md` Contracts table: every `link` resolves, every
   row names a resolvable `ratifying-test`. Models table: every
   `link` resolves.
4. `crates/ailang-core/tests/design_index_pin.rs` is GREEN with all
   four clauses; it was demonstrably RED before the split landed.
5. `design_schema_drift.rs`, `docs_honesty_pin.rs`,
   `effect_doc_honesty_pin.rs` are GREEN against the new files;
   their protected properties are unchanged.
6. The compiler emits `design/contracts/0005-float-semantics.md` /
   `design/contracts/0013-typeclasses.md` in the two NoInstance
   diagnostics; `eq_float_noinstance.rs` and `show_no_instance_e2e.rs`
   assert the new pointer and are GREEN.
7. `cargo test` workspace-wide is GREEN; `cargo build` is clean.
8. Tree-wide `grep -rIn 'DESIGN\.md'` (no `--include`) returns
   matches **only** in the append-only history docs; zero live
   references in code, scripts, agent files, SKILL bodies,
   `CLAUDE.md`, `skills/README.md`, or comments.
9. `bench/architect_sweeps.sh` runs against `design/`, exits 0 on
   the clean tree, and its exit-2 path triggers on a missing
   `design/INDEX.md`.
10. The ~12 agent reading lists, the 5 SKILL.md bodies,
    `CLAUDE.md`, and `skills/README.md` name the new spine; no agent
    contract still instructs reading a file that does not exist.
11. The milestone landed in a build-atomic shape (no commit leaves
    the workspace non-compiling).
12. Every `##`/`###` of the former DESIGN.md maps to exactly one
    destination in the Appendix table; the three ledger additions
    (`qualified-xref`, `str-abi`, `scope-boundaries`) have INDEX
    rows and resolvable ratifiers; the `crates/ailang-codegen/src/lib.rs:103`
    "Iter 13b" dangling cite is rewritten to drop the unresolvable
    reference (keeping it would itself violate the honesty rule).

## Appendix — Boss-adjudicated relocation map (authoritative, placeholder-free)

This appendix supersedes any ambiguity in §Components. It is the
map the planner consumes. Every `##`/`###` of DESIGN.md (3020
lines; no `## Decision 7` — numbering gap, not drift) has exactly
one destination. `D` = `docs/journals/2026-05-19-design-decision-records.md`
(decision-record archive). `IX` = `design/INDEX.md` preamble.

**Bucketing principle.** *Contract* = prescriptive + obeyed/checked
by an author, the architect, or a green test (binding, schema,
enforcement, honesty-pinned, present-tense scope claim). *Model* =
explanatory narrative; reading it is optional for correctness; no
test pins it. *Decision-record* = why-X-chosen / why-Y-rejected /
"deliberately does not do" / rollback / empirical addendum /
how-the-doc-reached-its-wording.

| `##` / `###` | Lines | Destination |
|---|---|---|
| `## Goal` | 6–18 | IX preamble |
| `## Project ecosystem` (intro) | 19–55 | IX preamble |
| ` ### What this document is — honesty rule` | 56–82 | `contracts/0007-honesty-rule.md` (**rewritten**; pins `docs_honesty_pin.rs:70,72`) |
| `## Project language: English` | 83–92 | IX preamble |
| `## Feature-acceptance criterion` | 93–164 | `contracts/0004-feature-acceptance.md` |
| `## Decision 1: source = data` | 165–176 | D |
| `## Decision 2: content-addressed` | 177–189 | D |
| `## Decision 3: pure core + effects` | 190–204 | `models/0002-effects.md` (pins `effect_doc_honesty_pin.rs` present-anchors — pin reads this file) |
| `## Decision 4: HM + refinements` | 205–213 | D |
| `## Decision 5: emit LLVM IR as text` | 214–229 | D |
| `## Decision 6` intro | 230–240 | `contracts/0001-authoring-surface.md` |
| ` (Decision 6 :241–243 audit-trail sentence)` | 241–243 | D (retired, no successor pin — §Architecture-4) |
| ` ### Why this is opening up` | 245–267 | D |
| ` ### Architectural pin: data structure is SoT` | 268–297 | `contracts/0001-authoring-surface.md` |
| ` ### Constraints (hard, in priority order)` | 298–331 | `contracts/0001-authoring-surface.md` |
| ` ### Candidate notations` | 332–471 | `models/0001-authoring-surface.md` |
| ` ### First choice and rollback plan` | 472–486 | D |
| ` ### Implementation outline` | 487–519 | D |
| ` ### What this Decision deliberately does not do` | 520–536 | D |
| ` ### Form refinements during implementation` | 537–589 | D |
| ` ### Form (B) — human prose projection` | 590–674 | `models/0001-authoring-surface.md` (the Form-B placeholder present-anchor in `docs_honesty_pin.rs` re-points here) |
| ` ### Empirical addendum` | 675–730 | D |
| `## Decision 8: explicit verified tail calls` | 731–787 | `contracts/0012-tail-calls.md` |
| `## Decision 9` intro | 788–852 | `models/0004-rc-uniqueness.md` |
| ` ### Per-fn arena via stack alloca` | 853–913 | `models/0004-rc-uniqueness.md` |
| `## Decision 10` intro | 914–977 | `models/0004-rc-uniqueness.md` |
| ` ### Why not other memory models` | 978–1014 | D |
| ` ### The LLM-aware sharpening` | 1015–1122 | `models/0004-rc-uniqueness.md` |
| ` ### Language-design constraints (binding)` | 1123–1150 | `contracts/0008-memory-model.md` |
| ` ### Schema additions` | 1151–1312 | `contracts/0008-memory-model.md` |
| ` ### Advisory diagnostics` | 1313–1351 | `contracts/0008-memory-model.md` |
| ` ### Why advisory + suppress instead of inference` | 1352–1377 | D |
| ` ### Inference algorithm` | 1378–1393 | `models/0004-rc-uniqueness.md` |
| ` ### Codegen contract` | 1394–1412 | `contracts/0008-memory-model.md` |
| ` ### Mode metadata is load-bearing for codegen` | 1413–1509 | `contracts/0008-memory-model.md` |
| ` ### Adjacent extensions for mutability (out of scope)` | 1510–1519 | D |
| ` ### What this Decision deliberately does not do` | 1520–1535 | D |
| `## Decision 11` intro | 1536–1577 | `models/0005-typeclasses.md` |
| ` ### Form-A schema (JSON authoring surface)` | 1578–1639 | `contracts/0013-typeclasses.md` |
| ` ### Resolution and monomorphisation` | 1640–1752 | `models/0005-typeclasses.md` |
| ` ### Cross-module references in synthesised bodies` | 1753–1823 | `contracts/0013-typeclasses.md` (pins `codegen_import_map_fallback_pin.rs:2`, `polyfn_dot_qualified_branch_pin.rs:2`) |
| ` ### Defaults and superclasses` | 1824–1855 | `contracts/0013-typeclasses.md` |
| ` ### Diagnostic categories` | 1856–1917 | `contracts/0013-typeclasses.md` |
| ` ### Method dispatch` | 1918–1964 | `contracts/0013-typeclasses.md` |
| ` ### What the typeclass design explicitly does NOT support` | 1965–2000 | D |
| ` ### Prelude (built-in) classes` | 2001–2042 | `contracts/0013-typeclasses.md` (pins `show_no_instance_e2e.rs:47`; Show diagnostic target) |
| ` ### Heap-Str primitives` | 2043–2088 | `contracts/0011-str-abi.md` (ledger addition — see below) |
| ` ### What this decision does NOT commit to` | 2089–2112 | D |
| `## Roundtrip Invariant` (+ 3 `###`s 2152–2208) | 2113–2208 | `contracts/0009-roundtrip-invariant.md` (whole block kept together — pins `round_trip.rs:10,72`) |
| `## Mangling scheme` | 2209–2218 | **source-link only** (no prose file): behaviour → dropped (code is SoT); any "why" sentence → D |
| `## Convention: qualified cross-module references` | 2219–2236 | **source-link only** `qualified-xref` (ledger addition): behaviour → dropped; rationale → D |
| `## Env construction` | 2237–2265 | **source-link only** (no prose file): behaviour → dropped (code is SoT); any "why" sentence → D |
| `## Embedding ABI` intro | 2266–2333 | `contracts/0003-embedding-abi.md` (pins `docs_honesty_pin.rs:135`) |
| ` ### Frozen value layout (M3 — one-way commitment)` | 2334–2376 | `contracts/0006-frozen-value-layout.md` + source-link `runtime/rc.c §layout` (dual; pins `embed_record_layout_pin.rs:1`) |
| `## Data model` (+ 4 `###`s) | 2377–2615 | `contracts/0002-data-model.md` (whole; `design_schema_drift.rs` `include_str!`s it) |
| `## Pipeline` | 2616–2662 | `models/0003-pipeline.md` |
| `## CLI` | 2663–2686 | `models/0003-pipeline.md` |
| `## Verification and correctness (across cycles)` | 2687–2699 | `contracts/0014-verification.md` |
| `## Float semantics` | 2700–2838 | `contracts/0005-float-semantics.md` (the inline `**Str ABI.**` para at 2802 is **moved to `contracts/0011-str-abi.md`** — the one sentence-level exception, justified below) |
| `## What is not (yet) supported` | 2839–3020 | `contracts/0010-scope-boundaries.md` (ledger addition — present-tense, honesty-pinned by `effect_doc_honesty_pin.rs:28`) |

### Ledger additions — rationale (the brainstorm's 12-list under-counted)

Plan-recon's exhaustive live-xref sweep proved three genuine,
distinct, currently-referenced contracts the 12-row first pass
missed. Forcing them into ill-fitting existing files would
re-create the conflation this milestone exists to end; the
ledger's purpose is per-contract addressability, so a genuine
distinct contract earns a row.

- **`qualified-xref`** (13th, source-link only). `## Convention:
  qualified cross-module references` is code-SoT per §Architecture
  commitment 1 ("qualified-cross-module-ref resolution"). No prose
  file; INDEX row links the resolution `//!`; ratifier
  `codegen_import_map_fallback_pin.rs`. `crates/ail/src/main.rs:1393`
  retargets to this row.
- **`str-abi`** (14th, prose + source-link). `### Heap-Str
  primitives` (2043–2088) + the inline `**Str ABI.**` para (2802)
  are one runtime-ABI contract, SoT `runtime/str.c`. Three live
  xrefs name `§"Str ABI"`/`§"Heap-Str primitives"`
  (`runtime/str.c:172,198`, `crates/ail/tests/e2e.rs:2843`) — they
  would dangle with no destination. The 2802 para is the **single
  sanctioned sentence-level move** (it is one inline bold-paragraph,
  not a `###`; leaving it in `float-semantics.md` would mis-file a
  Str contract under Float). Recorded as the explicit, bounded
  exception to §Architecture commitment 2.
- **`scope-boundaries`** (15th, prose). `## What is not (yet)
  supported` is present-tense scope assertion, honesty-pinned by
  `effect_doc_honesty_pin.rs:28` (absent-string `"the built-in IO
  and Diverge ops"`). A present-tense "what the language does not
  do, now" claim is a contract (a checked promise), not a
  decision-record; the pin already reads it, so its ratifier is
  `effect_doc_honesty_pin.rs`.

Net ledger: **15 contracts** (12 spec + 3 additions), 5 models,
one decision-record journal. The `design_index_pin.rs` clause-2
resolution set is widened to accept `crates/**/src/*.rs` so the
in-source `memory-model` (`uniqueness.rs`) and `tail-calls`
(`lib.rs tail_call_in_non_tail_position_is_rejected`) ratifiers
resolve honestly rather than being mapped to a wrong tests/-level
file.

### OQ7 — the dangling "Iter 13b" cite

`crates/ailang-codegen/src/lib.rs:103` cites "Iter 13b notes in
`DESIGN.md`" — that prose was relocated out of DESIGN.md long ago;
no forward target exists in the tree. Per the honesty rule a
reference to non-existent content is itself a violation. The
comment is rewritten to drop the cite (state the behaviour
directly; no `design/` or journal pointer, because the referenced
notes no longer exist anywhere — inventing a pointer would be
fiction). This is the one reference in bucket (e) that is *deleted,
not retargeted*.
