convention: counter-prefix file naming across docs/specs/, docs/plans/, design/contracts/, design/models/

All 176 files in the four accumulating directories now use a
zero-padded 4-digit counter prefix that reflects creation order
(`NNNN-slug.md`). The counter is assigned per directory in strict
git-log creation order; ties broken alphabetically by original name.
The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is
dropped — the date is recoverable from git log and the counter
carries the ordering.

A file's counter is stable for the life of the file: never reassigned,
never reused, never compacted. Deleted files retire their counter;
subsequent files do not fill the gap. This is the property that lets
cross-references stay literal — refs use the full filename including
the counter (`design/contracts/0007-honesty-rule.md`) so they grep
cleanly and resolve directly without a glob step.

313 cross-references updated across .md/.rs/.toml/.c/.json files
(test pins, include_str! paths, design-INDEX entries, baseline notes,
runtime C comments, inter-contract markdown links incl. bare basename
and `../models/foo.md` forms).

CLAUDE.md gets a new "File-naming convention" section spelling out
the rule and rationale. skills/brainstorm/SKILL.md and
skills/planner/SKILL.md updated so new spec/plan creation produces
counter-prefixed names from the start.

The full test suite (cargo test --workspace) passes.
This commit is contained in:
2026-05-28 13:31:31 +02:00
parent 7b8596cef0
commit 832375f2ac
227 changed files with 785 additions and 751 deletions
@@ -188,7 +188,7 @@ The validation strategy has three layers:
2. **Dry-run on past specs** is optional but useful for prompt
tuning. The agent can be invoked manually on
`docs/specs/2026-05-09-skill-system.md` and other past specs to
`docs/specs/0001-skill-system.md` and other past specs to
surface false-positive and false-negative rates before relying
on it in the live pipeline. Not a hard acceptance criterion.
@@ -402,7 +402,7 @@ relies on as currently-true.
mechanism handles a free-fn body whose specialisation triggers
a class-method specialisation.
10. The canonical-form layer (per
`docs/specs/2026-05-10-canonical-type-names.md`, ct.4 closure)
`docs/specs/0007-canonical-type-names.md`, ct.4 closure)
treats mono Defs as post-typecheck artefacts not in
`CheckedModule.symbols`, so renaming or extending mono symbols
does not affect surface-level hash pins.
@@ -653,7 +653,7 @@ relies on as currently-true.
not an infrastructure extension.
11. The canonical-form layer (per
`docs/specs/2026-05-10-canonical-type-names.md`) treats mono
`docs/specs/0007-canonical-type-names.md`) treats mono
Defs as post-typecheck artefacts not in
`CheckedModule.symbols`, so adding `show__T` and `print__T`
symbols does not affect surface-level hash pins. The four
@@ -38,7 +38,7 @@ context, symmetric to `TypeDef.name`).
Why this is the right shape: the canonical-type-names milestone
explicitly out-of-scoped class-reference fields and named
`MethodNameCollision` as the load-bearing workaround that made bare
class names viable (`docs/specs/2026-05-10-canonical-type-names.md`
class names viable (`docs/specs/0007-canonical-type-names.md`
§"Out of scope: Class names"). This milestone closes that loop. The
workaround was honest about being a workaround; this is the milestone
that retires it.
@@ -413,7 +413,7 @@ If the qualifier names a class not in the workspace
- **Milestone 24 (Show + print rewire).** Re-brainstorms separately
against the post-retirement architecture per the deferral note at
`docs/specs/2026-05-12-24-show-print.md`'s Status header. The
`docs/specs/0022-24-show-print.md`'s Status header. The
re-brainstorm is queued automatically once Iter 3 closes.
- **Overlapping instances within a single class.** Already handled by
@@ -3,7 +3,7 @@
**Date:** 2026-05-13
**Status:** Draft — awaiting user spec review
**Authors:** Brummel (orchestrator) + Claude
**Supersedes:** `docs/specs/2026-05-12-24-show-print.md` for iters 24.2 +
**Supersedes:** `docs/specs/0022-24-show-print.md` for iters 24.2 +
24.3 only. The earlier spec stays as historical context for the
deferral rationale; iter 24.1 shipped against the earlier spec at
`f38bad8` and is unchanged. This document re-derives 24.2 + 24.3 from
@@ -273,7 +273,7 @@ Justification per file:
> and parsed at compile time via `ailang_surface::parse_prelude`. The
> original §C4 (b) framing below is preserved as historical context;
> it documents the doctrine inconsistency that prelude-decouple
> resolved. See `docs/specs/2026-05-14-prelude-decouple.md` and the
> resolved. See `docs/specs/0028-prelude-decouple.md` and the
> per-iter journals 2026-05-14-iter-pd.{1,2,3}.md for the resolution.
**(b) Compile-time-embed carve-outs (one file as of 2026-05-13):**
@@ -21,7 +21,7 @@ all knowledge of the literal module name `"prelude"` from
becomes a pure module-graph + schema-validator with no language-
content awareness.
3. The §C4 (b) compile-time-embed carve-out in
`docs/specs/2026-05-13-form-a-default-authoring.md` becomes empty
`docs/specs/0025-form-a-default-authoring.md` becomes empty
and is struck. The seven §C4 (a) subject-matter-rejection
fixtures remain the only `.ail.json` files in the corpus.
@@ -403,7 +403,7 @@ The milestone closes when ALL of the following hold:
pins above.
5. `bench/check.py`, `bench/compile_check.py`, `bench/cross_lang.py`
are green at unchanged baselines.
6. `docs/specs/2026-05-13-form-a-default-authoring.md` §C4 (b) is
6. `docs/specs/0025-form-a-default-authoring.md` §C4 (b) is
updated: the carve-out list is empty; the section either
deletes the (b) sub-bullet or notes "retired by
prelude-decouple milestone, 2026-05-14".
@@ -1,5 +1,5 @@
> **SUPERSEDED 2026-05-16 by
> `docs/specs/2026-05-16-iteration-discipline-revert.md`.** This
> `docs/specs/0032-iteration-discipline-revert.md`.** This
> milestone was reverted in full (it.1 + it.2 backed out forward;
> it.3 never ran). It is retained as a historical record of the
> attempt and the design-thesis gap it surfaced; it is **not** the
@@ -120,7 +120,7 @@ First-iteration planner scope: **it.1** in full.
## Components
Per-construct touch-point set follows the mut-local milestone
template (`docs/specs/2026-05-15-mut-local.md` §Components): AST+serde
template (`docs/specs/0029-mut-local.md` §Components): AST+serde
→ schema-drift + DESIGN.md §Data-model anchor → Form-A surface
parse+print → round-trip fixture → check arm + diagnostics → codegen
lower + escape → e2e example.
@@ -21,7 +21,7 @@ Root cause being corrected (recorded so a future reader does not
re-derive the same mistake):
- The milestone was scoped from fieldtest finding **F1**
(`docs/specs/2026-05-15-fieldtest-mut-local.md`), which was tagged
(`docs/specs/0030-fieldtest-mut-local.md`), which was tagged
`[friction]` and whose *own* summary table named the honest minimal
action: "tighten DESIGN.md to name the gap — less work, more
honest". It was instead escalated into "retire `tail-app`,
@@ -237,8 +237,8 @@ oracle for every *restored* file).
### Working tree / docs hygiene
- Discard the uncommitted A1 amendment to
`docs/specs/2026-05-15-iteration-discipline.md`
(`git checkout -- docs/specs/2026-05-15-iteration-discipline.md`),
`docs/specs/0031-iteration-discipline.md`
(`git checkout -- docs/specs/0031-iteration-discipline.md`),
then add a **superseded header** to that committed spec pointing to
this one (specs are per-milestone historical records — superseded,
not deleted). The it.1/it.2/it.3 plans under `docs/plans/` and the
@@ -215,8 +215,8 @@ per cost.
addressed), Decision 3 (pure core + effects), Decision 8
(verified tail calls), Decision 9/10 (RC + uniqueness, no
collector), Feature-acceptance criterion.
- `docs/specs/2026-05-15-mut-local.md` — the sealed-mut milestone
- `docs/specs/0029-mut-local.md` — the sealed-mut milestone
whose redundancy §6.3 questions.
- `docs/specs/2026-05-16-iteration-discipline-revert.md` — why
- `docs/specs/0032-iteration-discipline-revert.md` — why
the bundled loop/recur milestone was backed out; §6.2 is the
de-bundled re-attempt.
@@ -306,11 +306,11 @@ from the current `lib.rs` ctx structure. Explicitly **excluded**:
- `docs/DESIGN.md` — Decision 8 (verified tail calls; unchanged),
Roundtrip Invariant, Feature-acceptance criterion, §"Data model".
- `docs/specs/2026-05-16-iteration-discipline-revert.md` — why the
- `docs/specs/0032-iteration-discipline-revert.md` — why the
bundle was reverted; this spec is the de-bundled, gate-passed
re-attempt of its it.1 core only.
- `docs/specs/2026-05-15-iteration-discipline.md` — superseded
- `docs/specs/0031-iteration-discipline.md` — superseded
bundle spec; its it.1 surface is the *shape* reference (its it.2 /
it.3 content is explicitly out of scope here).
- `docs/specs/2026-05-17-llm-surface-discipline.md` §6.2 — the
- `docs/specs/0033-llm-surface-discipline.md` §6.2 — the
principles entry this milestone discharges.
@@ -100,7 +100,7 @@ Five structural commitments:
`"whether the document asserts something exists, works, or
changed that does not"` (both inside
`design_md_present_tense_anchors_present`). This becomes
`contracts/honesty-rule.md`, **rewritten** so the rule states
`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.
@@ -152,32 +152,32 @@ 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/feature-acceptance.md |
| authoring-surface | LLM author / stable | crates/ailang-surface round_trip.rs | contracts/authoring-surface.md |
| roundtrip-invariant | every release / stable | crates/ailang-surface round_trip.rs | contracts/roundtrip-invariant.md |
| memory-model | LLM author / stable | crates/ailang-check/src/uniqueness.rs (in-source mod tests) | contracts/memory-model.md |
| data-model | LLM author / stable | crates/ailang-core/tests/design_schema_drift.rs | contracts/data-model.md |
| 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/frozen-value-layout.md + runtime/rc.c §layout |
| float-semantics | LLM author / stable | crates/ail/tests/eq_float_noinstance.rs | contracts/float-semantics.md |
| typeclasses | LLM author / stable | crates/ail/tests/show_no_instance_e2e.rs | contracts/typeclasses.md |
| str-abi | runtime ABI / stable | crates/ail/tests/e2e.rs (Str path) | contracts/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/tail-calls.md |
| honesty-rule | architect+grounding / stable | crates/ailang-core/tests/docs_honesty_pin.rs | contracts/honesty-rule.md |
| embedding-abi | embedding host / stable | crates/ailang-codegen/tests/embed_record_layout_pin.rs | contracts/embedding-abi.md |
| scope-boundaries | architect+author / stable | crates/ailang-core/tests/effect_doc_honesty_pin.rs | contracts/scope-boundaries.md |
| verification | architect / stable | bench/architect_sweeps.sh | contracts/verification.md |
| 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/rc-uniqueness.md |
| typeclasses | onboarding / evolves | models/typeclasses.md |
| effects | onboarding / evolves | models/effects.md |
| authoring-surface | onboarding / evolves | models/authoring-surface.md |
| pipeline | onboarding / evolves | models/pipeline.md |
| 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
@@ -191,7 +191,7 @@ 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/float-semantics.md`
**A sample contract file** — `design/contracts/0005-float-semantics.md`
(content moved verbatim from DESIGN.md:27002838, header re-levelled
to file root, all decision-record/why-prose stripped to the journal):
@@ -275,7 +275,7 @@ writes that **must fail** to typecheck:
```
- orderability per IEEE-754); see DESIGN.md §\"Float semantics\".",
+ orderability per IEEE-754); see design/contracts/float-semantics.md.",
+ orderability per IEEE-754); see design/contracts/0005-float-semantics.md.",
```
`crates/ailang-check/src/lib.rs:888` (the Show branch):
@@ -283,7 +283,7 @@ writes that **must fail** to typecheck:
```
- the prelude; see DESIGN.md §\"Prelude (built-in) \
- classes\". User types declare their own \
+ the prelude; see design/contracts/typeclasses.md. \
+ the prelude; see design/contracts/0013-typeclasses.md. \
+ User types declare their own \
```
@@ -294,12 +294,12 @@ 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/float-semantics.md"),
+ 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/typeclasses.md"`.
asserted substring becomes `"design/contracts/0013-typeclasses.md"`.
### 3. The four executable retargets (before → after)
@@ -321,7 +321,7 @@ scans all `design/` prose; the verbatim regexes are unchanged.
```rust
- const DESIGN_MD: &str = include_str!("../../../docs/DESIGN.md");
+ const DATA_MODEL: &str = include_str!("../../../design/contracts/data-model.md");
+ const DATA_MODEL: &str = include_str!("../../../design/contracts/0002-data-model.md");
```
The `data_model_section()` slicer (`## Data model``\n## Pipeline`)
@@ -338,7 +338,7 @@ 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/honesty-rule.md` wording in
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.
@@ -361,7 +361,7 @@ The other ~11 reading-list bullets
`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/rc-uniqueness.md` (Decision-9/Boehm narrative);
bencher reads `models/0004-rc-uniqueness.md` (Decision-9/Boehm narrative);
the rest point at `design/INDEX.md` as the spine.
## Components
@@ -408,7 +408,7 @@ rejected" passage, moved whole at `###` granularity. The journals
- **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/float-semantics.md` (or `…/typeclasses.md`) →
`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
@@ -503,8 +503,8 @@ All failure modes fail closed:
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/float-semantics.md` /
`design/contracts/typeclasses.md` in the two NoInstance
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.
@@ -547,64 +547,64 @@ how-the-doc-reached-its-wording.
|---|---|---|
| `## Goal` | 618 | IX preamble |
| `## Project ecosystem` (intro) | 1955 | IX preamble |
| ` ### What this document is — honesty rule` | 5682 | `contracts/honesty-rule.md` (**rewritten**; pins `docs_honesty_pin.rs:70,72`) |
| ` ### What this document is — honesty rule` | 5682 | `contracts/0007-honesty-rule.md` (**rewritten**; pins `docs_honesty_pin.rs:70,72`) |
| `## Project language: English` | 8392 | IX preamble |
| `## Feature-acceptance criterion` | 93164 | `contracts/feature-acceptance.md` |
| `## Feature-acceptance criterion` | 93164 | `contracts/0004-feature-acceptance.md` |
| `## Decision 1: source = data` | 165176 | D |
| `## Decision 2: content-addressed` | 177189 | D |
| `## Decision 3: pure core + effects` | 190204 | `models/effects.md` (pins `effect_doc_honesty_pin.rs` present-anchors — pin reads this file) |
| `## Decision 3: pure core + effects` | 190204 | `models/0002-effects.md` (pins `effect_doc_honesty_pin.rs` present-anchors — pin reads this file) |
| `## Decision 4: HM + refinements` | 205213 | D |
| `## Decision 5: emit LLVM IR as text` | 214229 | D |
| `## Decision 6` intro | 230240 | `contracts/authoring-surface.md` |
| `## Decision 6` intro | 230240 | `contracts/0001-authoring-surface.md` |
| ` (Decision 6 :241243 audit-trail sentence)` | 241243 | D (retired, no successor pin — §Architecture-4) |
| ` ### Why this is opening up` | 245267 | D |
| ` ### Architectural pin: data structure is SoT` | 268297 | `contracts/authoring-surface.md` |
| ` ### Constraints (hard, in priority order)` | 298331 | `contracts/authoring-surface.md` |
| ` ### Candidate notations` | 332471 | `models/authoring-surface.md` |
| ` ### Architectural pin: data structure is SoT` | 268297 | `contracts/0001-authoring-surface.md` |
| ` ### Constraints (hard, in priority order)` | 298331 | `contracts/0001-authoring-surface.md` |
| ` ### Candidate notations` | 332471 | `models/0001-authoring-surface.md` |
| ` ### First choice and rollback plan` | 472486 | D |
| ` ### Implementation outline` | 487519 | D |
| ` ### What this Decision deliberately does not do` | 520536 | D |
| ` ### Form refinements during implementation` | 537589 | D |
| ` ### Form (B) — human prose projection` | 590674 | `models/authoring-surface.md` (the Form-B placeholder present-anchor in `docs_honesty_pin.rs` re-points here) |
| ` ### Form (B) — human prose projection` | 590674 | `models/0001-authoring-surface.md` (the Form-B placeholder present-anchor in `docs_honesty_pin.rs` re-points here) |
| ` ### Empirical addendum` | 675730 | D |
| `## Decision 8: explicit verified tail calls` | 731787 | `contracts/tail-calls.md` |
| `## Decision 9` intro | 788852 | `models/rc-uniqueness.md` |
| ` ### Per-fn arena via stack alloca` | 853913 | `models/rc-uniqueness.md` |
| `## Decision 10` intro | 914977 | `models/rc-uniqueness.md` |
| `## Decision 8: explicit verified tail calls` | 731787 | `contracts/0012-tail-calls.md` |
| `## Decision 9` intro | 788852 | `models/0004-rc-uniqueness.md` |
| ` ### Per-fn arena via stack alloca` | 853913 | `models/0004-rc-uniqueness.md` |
| `## Decision 10` intro | 914977 | `models/0004-rc-uniqueness.md` |
| ` ### Why not other memory models` | 9781014 | D |
| ` ### The LLM-aware sharpening` | 10151122 | `models/rc-uniqueness.md` |
| ` ### Language-design constraints (binding)` | 11231150 | `contracts/memory-model.md` |
| ` ### Schema additions` | 11511312 | `contracts/memory-model.md` |
| ` ### Advisory diagnostics` | 13131351 | `contracts/memory-model.md` |
| ` ### The LLM-aware sharpening` | 10151122 | `models/0004-rc-uniqueness.md` |
| ` ### Language-design constraints (binding)` | 11231150 | `contracts/0008-memory-model.md` |
| ` ### Schema additions` | 11511312 | `contracts/0008-memory-model.md` |
| ` ### Advisory diagnostics` | 13131351 | `contracts/0008-memory-model.md` |
| ` ### Why advisory + suppress instead of inference` | 13521377 | D |
| ` ### Inference algorithm` | 13781393 | `models/rc-uniqueness.md` |
| ` ### Codegen contract` | 13941412 | `contracts/memory-model.md` |
| ` ### Mode metadata is load-bearing for codegen` | 14131509 | `contracts/memory-model.md` |
| ` ### Inference algorithm` | 13781393 | `models/0004-rc-uniqueness.md` |
| ` ### Codegen contract` | 13941412 | `contracts/0008-memory-model.md` |
| ` ### Mode metadata is load-bearing for codegen` | 14131509 | `contracts/0008-memory-model.md` |
| ` ### Adjacent extensions for mutability (out of scope)` | 15101519 | D |
| ` ### What this Decision deliberately does not do` | 15201535 | D |
| `## Decision 11` intro | 15361577 | `models/typeclasses.md` |
| ` ### Form-A schema (JSON authoring surface)` | 15781639 | `contracts/typeclasses.md` |
| ` ### Resolution and monomorphisation` | 16401752 | `models/typeclasses.md` |
| ` ### Cross-module references in synthesised bodies` | 17531823 | `contracts/typeclasses.md` (pins `codegen_import_map_fallback_pin.rs:2`, `polyfn_dot_qualified_branch_pin.rs:2`) |
| ` ### Defaults and superclasses` | 18241855 | `contracts/typeclasses.md` |
| ` ### Diagnostic categories` | 18561917 | `contracts/typeclasses.md` |
| ` ### Method dispatch` | 19181964 | `contracts/typeclasses.md` |
| `## Decision 11` intro | 15361577 | `models/0005-typeclasses.md` |
| ` ### Form-A schema (JSON authoring surface)` | 15781639 | `contracts/0013-typeclasses.md` |
| ` ### Resolution and monomorphisation` | 16401752 | `models/0005-typeclasses.md` |
| ` ### Cross-module references in synthesised bodies` | 17531823 | `contracts/0013-typeclasses.md` (pins `codegen_import_map_fallback_pin.rs:2`, `polyfn_dot_qualified_branch_pin.rs:2`) |
| ` ### Defaults and superclasses` | 18241855 | `contracts/0013-typeclasses.md` |
| ` ### Diagnostic categories` | 18561917 | `contracts/0013-typeclasses.md` |
| ` ### Method dispatch` | 19181964 | `contracts/0013-typeclasses.md` |
| ` ### What the typeclass design explicitly does NOT support` | 19652000 | D |
| ` ### Prelude (built-in) classes` | 20012042 | `contracts/typeclasses.md` (pins `show_no_instance_e2e.rs:47`; Show diagnostic target) |
| ` ### Heap-Str primitives` | 20432088 | `contracts/str-abi.md` (ledger addition — see below) |
| ` ### Prelude (built-in) classes` | 20012042 | `contracts/0013-typeclasses.md` (pins `show_no_instance_e2e.rs:47`; Show diagnostic target) |
| ` ### Heap-Str primitives` | 20432088 | `contracts/0011-str-abi.md` (ledger addition — see below) |
| ` ### What this decision does NOT commit to` | 20892112 | D |
| `## Roundtrip Invariant` (+ 3 `###`s 21522208) | 21132208 | `contracts/roundtrip-invariant.md` (whole block kept together — pins `round_trip.rs:10,72`) |
| `## Roundtrip Invariant` (+ 3 `###`s 21522208) | 21132208 | `contracts/0009-roundtrip-invariant.md` (whole block kept together — pins `round_trip.rs:10,72`) |
| `## Mangling scheme` | 22092218 | **source-link only** (no prose file): behaviour → dropped (code is SoT); any "why" sentence → D |
| `## Convention: qualified cross-module references` | 22192236 | **source-link only** `qualified-xref` (ledger addition): behaviour → dropped; rationale → D |
| `## Env construction` | 22372265 | **source-link only** (no prose file): behaviour → dropped (code is SoT); any "why" sentence → D |
| `## Embedding ABI` intro | 22662333 | `contracts/embedding-abi.md` (pins `docs_honesty_pin.rs:135`) |
| ` ### Frozen value layout (M3 — one-way commitment)` | 23342376 | `contracts/frozen-value-layout.md` + source-link `runtime/rc.c §layout` (dual; pins `embed_record_layout_pin.rs:1`) |
| `## Data model` (+ 4 `###`s) | 23772615 | `contracts/data-model.md` (whole; `design_schema_drift.rs` `include_str!`s it) |
| `## Pipeline` | 26162662 | `models/pipeline.md` |
| `## CLI` | 26632686 | `models/pipeline.md` |
| `## Verification and correctness (across cycles)` | 26872699 | `contracts/verification.md` |
| `## Float semantics` | 27002838 | `contracts/float-semantics.md` (the inline `**Str ABI.**` para at 2802 is **moved to `contracts/str-abi.md`** — the one sentence-level exception, justified below) |
| `## What is not (yet) supported` | 28393020 | `contracts/scope-boundaries.md` (ledger addition — present-tense, honesty-pinned by `effect_doc_honesty_pin.rs:28`) |
| `## Embedding ABI` intro | 22662333 | `contracts/0003-embedding-abi.md` (pins `docs_honesty_pin.rs:135`) |
| ` ### Frozen value layout (M3 — one-way commitment)` | 23342376 | `contracts/0006-frozen-value-layout.md` + source-link `runtime/rc.c §layout` (dual; pins `embed_record_layout_pin.rs:1`) |
| `## Data model` (+ 4 `###`s) | 23772615 | `contracts/0002-data-model.md` (whole; `design_schema_drift.rs` `include_str!`s it) |
| `## Pipeline` | 26162662 | `models/0003-pipeline.md` |
| `## CLI` | 26632686 | `models/0003-pipeline.md` |
| `## Verification and correctness (across cycles)` | 26872699 | `contracts/0014-verification.md` |
| `## Float semantics` | 27002838 | `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` | 28393020 | `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)
@@ -8,7 +8,7 @@
Make the `design/` ledger a browsable wiki: replace informal prose
cross-references between contracts/models (`(see "Str ABI" below)`,
`(see design/contracts/str-abi.md …)`, `see §"Data model"`) with
`(see design/contracts/0011-str-abi.md …)`, `see §"Data model"`) with
**formal, machine-checkable, file-level Markdown links**, and add an
in-tree hard gate that turns a broken cross-link into a same-commit
test failure instead of silent rot.
@@ -27,7 +27,7 @@ The milestone has **no authoring surface**: it changes no `.ail`
program, no language construct, no compiler/checker/codegen path. It
is a documentation-form + Rust-test-infrastructure milestone, the
same category as the immediately-preceding DESIGN.md → design/ split
(`docs/specs/2026-05-19-design-md-rolesplit.md`), whose concrete code
(`docs/specs/0045-design-md-rolesplit.md`), whose concrete code
was likewise the structural Rust pin plus the ledger shape, audited
clean. The no-`.ail` disposition is therefore precedent-governed and
reasoned, not an omission (see Concrete code shapes §"No authoring
@@ -103,11 +103,11 @@ not forks):
the non-durable tier; else **(c)** deleted outright **only if the
reference itself is relitigation residue** (clause-3-class).
Recon-confirmed canonical instance:
`design/models/pipeline.md:61` and
`design/models/authoring-surface.md:180`, both
`design/models/0003-pipeline.md:61` and
`design/models/0001-authoring-surface.md:180`, both
`(see docs/PROSE_ROUNDTRIP.md)`, cite the *prose-mediator cycle /
`ail merge-prose`* — content
`design/contracts/roundtrip-invariant.md` does **not** carry
`design/contracts/0009-roundtrip-invariant.md` does **not** carry
(that contract is the orthogonal hashing / parse-determinism
invariant). (a) is therefore unavailable and the content is real
current behaviour, not relitigation, so the disposition is
@@ -340,16 +340,16 @@ Three real, in-tree references (recon-confirmed line numbers; exact
bytes are the planner's):
```
design/contracts/float-semantics.md:100 (the tidy precedent, still
design/contracts/0005-float-semantics.md:100 (the tidy precedent, still
half-formal: bare root path in prose, not a Markdown link)
- before: … a fresh heap-Str slab at the call site (see
design/contracts/str-abi.md for the dual realisation).
design/contracts/0011-str-abi.md for the dual realisation).
- after: … a fresh heap-Str slab at the call site (see
[Str ABI](str-abi.md) for the dual realisation).
# float-semantics.md and str-abi.md are siblings in
# design/contracts/ ⇒ file-relative target is `str-abi.md`
design/contracts/embedding-abi.md:45 (informal AND stale-direction
design/contracts/0003-embedding-abi.md:45 (informal AND stale-direction
— the exact wart class motivating the milestone: "below" but the
target is a different file)
- before: … layout is **frozen as of M3** (see "Frozen value
@@ -357,7 +357,7 @@ design/contracts/embedding-abi.md:45 (informal AND stale-direction
- after: … layout is **frozen as of M3** (see
[Frozen value layout](frozen-value-layout.md)); …
design/models/pipeline.md:61 + design/models/authoring-surface.md:180
design/models/0003-pipeline.md:61 + design/models/0001-authoring-surface.md:180
(the canonical HOMELESS references — `(see docs/PROSE_ROUNDTRIP.md)`
into the non-durable tier; recon proved roundtrip-invariant.md
does NOT carry the merge-prose-cycle content ⇒ clause-6
@@ -383,7 +383,7 @@ crates/ailang-core/tests/design_index_pin.rs
```
The INDEX table cells stay repo-root-relative
(`design/contracts/str-abi.md`); clause-1 keeps resolving them via
(`design/contracts/0011-str-abi.md`); clause-1 keeps resolving them via
`root().join`. No INDEX content edit, no clause-1 resolver edit.
One resolution rule per *tier* (registry-spine: root-relative;
movable body prose: file-relative), each locally justified — not
@@ -397,7 +397,7 @@ one rule everywhere, by deliberate design.
| `design/contracts/*.md`, `design/models/*.md` | **Modify** — every genuine cross-*file* prose reference rewritten to a file-relative Markdown link; homeless refs retargeted-or-deleted; intra-file "above/below" untouched (out of scope). |
| `design/INDEX.md` | **Untouched** — spine tier, commitment 4. |
| `docs/journals/2026-05-19-design-decision-records.md` | **Untouched** — monolithic append-only relitigation archive; never a link target (commitment 2/7). |
| `design/contracts/honesty-rule.md` | **Modify (prose only)** — one sentence stating cross-references are formal file-relative links into the durable tier (the positive-half companion to the clause-3 sentence it already carries). Pin-safe: the two `docs_honesty_pin.rs` phrases stay verbatim+contiguous. |
| `design/contracts/0007-honesty-rule.md` | **Modify (prose only)** — one sentence stating cross-references are formal file-relative links into the durable tier (the positive-half companion to the clause-3 sentence it already carries). Pin-safe: the two `docs_honesty_pin.rs` phrases stay verbatim+contiguous. |
| `bench/architect_sweeps.sh` | **Untouched** — clause-5 ("does every link resolve into the durable tier?") and Sweep-1 ("does any line carry a history anchor: `Iter <n>`, a date, `**Status:`?") are orthogonal predicates over the same files. A Markdown link `[label](file.md)` contains no Sweep-1 anchor token, so converting prose to links cannot trip Sweep-1; clause-5 shares no regex or scope with it. No sweep change. |
## Data flow
@@ -467,7 +467,7 @@ outcome, not a dodge).
`str-abi.md`), `scope-boundaries.md:88` (splits:
`ailang-core::desugar`
`../../crates/ailang-core/src/desugar.rs` AND "Pipeline" →
`../models/pipeline.md`).
`../models/0003-pipeline.md`).
- **disposition (b):** `pipeline.md:61`,
`authoring-surface.md:180` — the `(see docs/PROSE_ROUNDTRIP.md)`
pointer removed, surrounding `ail merge-prose` prose kept.
@@ -19,7 +19,7 @@ Resolves Gitea issue #4 (`Boehm full retirement`).
The Boehm backend was introduced as a transitional dual-allocator
during the pre-22 RC commitment window. Its standing role per
`design/models/rc-uniqueness.md` was twofold: (a) **production
`design/models/0004-rc-uniqueness.md` was twofold: (a) **production
fallback** before RC was mature; (b) **parity oracle**
differential RC-vs-GC stdout assertions to catch RC bugs cheaply.
Both roles have expired:
@@ -49,11 +49,11 @@ cohesive iteration:
drop fns under non-RC" retargets from `AllocStrategy::Gc` to
`AllocStrategy::Bump`; the M2 staticlib alloc-guard test loses
its gc-arm but keeps its bump-arm.
5. **Design ledger**`design/models/rc-uniqueness.md` excises
5. **Design ledger**`design/models/0004-rc-uniqueness.md` excises
the "Dual allocator — RC canonical, Boehm parity oracle"
section and the Boehm-Choice-block; the per-fn-alloca section's
language generalises from "on top of Boehm" to "on top of the
allocator". `design/models/pipeline.md` drops the
allocator". `design/models/0003-pipeline.md` drops the
`--alloc=gc → libgc` arm of the pipeline diagram and the
accompanying prose. The 1.3× RC-over-bump number is retained
in `rc-uniqueness.md` but reframed as a **bench-health
@@ -247,7 +247,7 @@ Before (`crates/ailang-core/tests/docs_honesty_pin.rs:116-117`):
```rust
assert!(pipeline.contains("`--alloc=gc` selects the transitional Boehm backend"),
"models/pipeline.md must describe Boehm present-tense, not as 'on the path to retirement'");
"models/0003-pipeline.md must describe Boehm present-tense, not as 'on the path to retirement'");
```
After: this assertion is **deleted**, and the
@@ -340,9 +340,9 @@ rewritten to describe the rc/bump pair as the present state.
| E2E RC-feature w/ differential backstop | `crates/ail/tests/e2e.rs``reuse_as_drop_demo` (1475ff), `rc_box_drop` (1602ff), `rc_list_drop` (1628ff), `rc_list_drop_borrow` (1674ff), `pat_extract_partial_drop` (1762ff), `rc_own_param_drop` (1858ff), `rc_drop_iterative_long_list` (1981ff), `rc_pin_recurse_implicit` (2168ff), `rc_let_alias_implicit_param` (2396ff) — **the `stdout_gc` build call and the `assert_eq!(stdout_gc, stdout_rc, ...)` differential line dropped**; the absolute `assert_eq!(stdout_rc.trim(), "<n>")` pin stays; doc-comments cleaned of `--alloc=gc` references |
| E2E staticlib guard | `crates/ail/tests/embed_staticlib_alloc_guard.rs``staticlib_gc_is_rejected` deleted; `staticlib_bump_is_rejected` unchanged; file-level doc-comment updated |
| Bench harness | `bench/run.sh``bench_latency_implicit_gc` arm removed; all `--alloc=gc` build calls removed; comment "decisive number for Decision 10's Boehm-retirement target (1.3x)" → "RC-overhead-vs-bump bench-health gate (1.3× ceiling)"; comment "Boehm-fair Implicit @ gc" arm dropped |
| Design ledger | `design/models/rc-uniqueness.md` — full Boehm sections excised (per "Concrete code shapes" above); 1.3× reframed as bench-health regression gate |
| Design ledger | `design/models/pipeline.md` — pipeline diagram + accompanying prose updated (per above) |
| Design ledger | `design/contracts/embedding-abi.md:43-44` — the present-tense sentence `ail build --emit=staticlib rejects --alloc=gc/--alloc=bump (the shared Boehm collector is not swarm-safe)` is rewritten to drop the gc clause (gc is now a CLI-parser-level unknown-value, not a staticlib-guard rejection) and to reframe the swarm-safety justification: only `--alloc=bump` is rejected by the staticlib guard, on the grounds that bump is a leak-only bench instrument, not the historical Boehm-collector justification |
| Design ledger | `design/models/0004-rc-uniqueness.md` — full Boehm sections excised (per "Concrete code shapes" above); 1.3× reframed as bench-health regression gate |
| Design ledger | `design/models/0003-pipeline.md` — pipeline diagram + accompanying prose updated (per above) |
| Design ledger | `design/contracts/0003-embedding-abi.md:43-44` — the present-tense sentence `ail build --emit=staticlib rejects --alloc=gc/--alloc=bump (the shared Boehm collector is not swarm-safe)` is rewritten to drop the gc clause (gc is now a CLI-parser-level unknown-value, not a staticlib-guard rejection) and to reframe the swarm-safety justification: only `--alloc=bump` is rejected by the staticlib guard, on the grounds that bump is a leak-only bench instrument, not the historical Boehm-collector justification |
| Honesty pin | `crates/ailang-core/tests/docs_honesty_pin.rs` — present-tense Boehm pin deleted; four absence-pins added (per above); test-file doc-comment header updated to drop the Boehm/Decision-9 phrase |
| Bencher agent | `skills/audit/agents/ailang-bencher.md` — the worked example "under heap pressure where Boehm GC has stop-the-world pauses" is rewritten to use an allocator-agnostic hypothesis (RC overhead under a workload that doesn't exercise the rc path is a natural replacement) |
@@ -452,9 +452,9 @@ The milestone closes CLEAN when all of the following hold:
all exit 0 against the existing baseline.
4. The CLI must-fail fixture exits ≠ 0 with the expected stderr
wording.
5. `design/models/rc-uniqueness.md` and `design/models/pipeline.md`
5. `design/models/0004-rc-uniqueness.md` and `design/models/0003-pipeline.md`
describe RC + bump as the present state; the honesty rule
(`design/contracts/honesty-rule.md`) is upheld — no past-tense
(`design/contracts/0007-honesty-rule.md`) is upheld — no past-tense
"Boehm was kept as oracle" narrative remains; Boehm's history
is recorded in the iter's git-log commit body.
6. Issue #4 is closed by the iter commit's `closes #4` trailer.
@@ -22,7 +22,7 @@ Today AILang has two parallel paths for comparison:
with instances for `{Int, Bool, Str}`, plus the polymorphic free-
fn helpers `ne`/`lt`/`le`/`gt`/`ge`. Float and Unit have no Eq/Ord
instance by design (Float: partial orderability per
[float-semantics](../../design/contracts/float-semantics.md);
[float-semantics](../../design/contracts/0005-float-semantics.md);
Unit: oversight that today's `(app == () ())` builtin path hides).
The two paths are redundant — `instance Eq Int` body literally
@@ -56,7 +56,7 @@ at lines 96-98, polymorphic `==` Forall block at lines 109-125,
list-side mirror at lines 303-308) are removed. Surface use of these
names resolves like any other unknown identifier — first via the
class-method-dispatch index per
[method-dispatch](../../design/contracts/method-dispatch.md), which
[method-dispatch](../../design/contracts/0016-method-dispatch.md), which
finds no candidate (the method name is `eq`, not `==`), then via
fn lookup, which also finds none, then fails with the standard
`unknown variable` diagnostic. The diagnostic does NOT special-case
@@ -67,7 +67,7 @@ external users requiring migration.
All `(app eq …)` / `(app compare …)` / `(app ne …)` / `(app lt …)`
/ etc. resolve through the existing class-method-dispatch machinery
documented in
[method-dispatch](../../design/contracts/method-dispatch.md).
[method-dispatch](../../design/contracts/0016-method-dispatch.md).
No new dispatch rule.
**Codegen:** `try_emit_primitive_instance_body` in
@@ -86,7 +86,7 @@ Six new prelude free functions ship for Float comparison:
constraint. Their bodies are intercept-lowered to the corresponding
`fcmp` instruction (`oeq` / `une` / `olt` / `ole` / `ogt` / `oge`),
preserving the bit-exact IEEE semantics
[float-semantics](../../design/contracts/float-semantics.md)
[float-semantics](../../design/contracts/0005-float-semantics.md)
guarantees today for `==` / `<` etc. on Float — the guarantee is
transferred from the deleted operator names to the named Float
fns.
@@ -161,7 +161,7 @@ the call site).
Must produce a typecheck-time diagnostic — `NoInstance Eq Float`
with a follow-up sentence `Float has no Eq instance by design
(partial orderability per design/contracts/float-semantics.md); use
(partial orderability per design/contracts/0005-float-semantics.md); use
float_eq for explicit IEEE-aware comparison`. The diagnostic is the
existing `NoInstance` channel; the Float-aware addendum is the
existing Float-specific hint in `crates/ailang-check/src/lib.rs`
@@ -374,16 +374,16 @@ The milestone touches seven layers, all in one cohesive iter:
from operator-form to method-form. The planner enumerates the
exact set via grep and assigns it as a discrete task.
7. **Contracts** — three updates:
- `design/contracts/float-semantics.md` lines 10-14: the
- `design/contracts/0005-float-semantics.md` lines 10-14: the
guarantees about `+`/`-`/etc. and `==`/`<`/`!=` lowering to
single LLVM instructions are retained for arithmetic but
transferred from `==`/`<`/`!=` to `float_eq`/`float_lt`/`float_ne`/etc.
for the comparison set. The NaN-spelling caveat is unchanged.
- `design/contracts/prelude-classes.md`: instance list extends
- `design/contracts/0017-prelude-classes.md`: instance list extends
with `Eq Unit`; a new paragraph documents the six `float_*` fns
as the Float-comparison surface; the Float-no-Eq/Ord clause
gains a `→ use float_eq` cross-reference.
- `design/contracts/typeclasses.md`: no change. Class schema,
- `design/contracts/0013-typeclasses.md`: no change. Class schema,
dispatch rule, and diagnostics are stable; the milestone only
activates existing machinery for `eq`/`compare` over more
types.
@@ -395,7 +395,7 @@ A surface `(app eq p1 p2)` flows through the existing pipeline:
1. **Parse**`Term::App { fn: Var "eq", args: [p1, p2] }`. No
change from today.
2. **Typecheck** — class-method-dispatch (per
`design/contracts/method-dispatch.md`) consults
`design/contracts/0016-method-dispatch.md`) consults
`method_to_candidate_classes["eq"]``{prelude.Eq}`. Singleton
class survivor; type-driven filter against the workspace
registry for the resolved type:
@@ -404,7 +404,7 @@ A surface `(app eq p1 p2)` flows through the existing pipeline:
- `p1, p2 : Float` → no instance → `NoInstance Eq Float` with
Float-aware hint pointing at `float_eq`.
3. **Mono** — synth produces the instance-body symbol (existing
pass; per `design/contracts/typeclasses.md` invariants 1-3).
pass; per `design/contracts/0013-typeclasses.md` invariants 1-3).
4. **Codegen** — emits a call to the resolved instance fn. For
primitive instances, the body is intercept-lowered to a single
icmp/fcmp/call; `alwaysinline` attribute ensures the call folds
@@ -426,7 +426,7 @@ addendum (lib.rs:860-873) is extended:
```
Eq has no instance at Float — Float has no Eq/Ord instance by
design (partial orderability per design/contracts/float-semantics.md);
design (partial orderability per design/contracts/0005-float-semantics.md);
use float_eq for explicit IEEE-aware comparison.
```
@@ -519,11 +519,11 @@ The milestone ships when all of the following hold:
8. `bench/check.py` exit 0; `bench/compile_check.py` exit 0;
`bench/cross_lang.py` exit 0 (full bench-corpus green against
the post-milestone baseline regenerated by the iter).
9. `design/contracts/float-semantics.md` updated to name `float_eq`
9. `design/contracts/0005-float-semantics.md` updated to name `float_eq`
/ `float_lt` / `float_ne` / etc. as the comparison guarantees
(comparison guarantees on `==`/`<`/`!=` removed; arithmetic
guarantees on `+`/`-`/`*`/`/` unchanged).
10. `design/contracts/prelude-classes.md` updated: `Eq Unit` in the
10. `design/contracts/0017-prelude-classes.md` updated: `Eq Unit` in the
instance list; new section on the six Float-named comparison
fns; the Float-no-Eq/Ord clause carries a `→ use float_eq`
cross-reference.
@@ -75,7 +75,7 @@ single `fcmp` via the codegen intercept with `alwaysinline`.
workspace — Float has no Eq/Ord instance by design (partial
orderability per IEEE-754); use float_eq / float_lt (and siblings
float_ne / float_le / float_gt / float_ge) for explicit IEEE-aware
comparison. See design/contracts/float-semantics.md.
comparison. See design/contracts/0005-float-semantics.md.
```
### `examples/fieldtest/eqord_5_float_eq_must_fail.ail` — Eq at Float rejection (companion)
@@ -155,7 +155,7 @@ single `fcmp` via the codegen intercept with `alwaysinline`.
helper `lt` is reported via its desugar to `compare`), the named-fn
family `float_eq / float_lt (and siblings …)`, the IEEE-754 design
rationale, and the contract path
`design/contracts/float-semantics.md`. An LLM-author who hits this
`design/contracts/0005-float-semantics.md`. An LLM-author who hits this
diagnostic learns the entire replacement surface in one read.
- **Why it's `working`:** this is the milestone's clause-2 evidence —
the diagnostic carries enough information for an LLM that has only
@@ -173,7 +173,7 @@ single `fcmp` via the codegen intercept with `alwaysinline`.
copied the pattern from the existing `eq_ord_user_adt.ail`, not
from the spec.
- **What happened:** the design spec at
`docs/specs/2026-05-20-operator-routing-eq-ord.md:113` writes
`docs/specs/0049-operator-routing-eq-ord.md:113` writes
`(class Eq)` (bare) in the §"Concrete code shapes" north-star
example program. An LLM-author who copies that pattern verbatim
hits the diagnostic:
@@ -194,10 +194,10 @@ single `fcmp` via the codegen intercept with `alwaysinline`.
drift, but it is the highest-information reference an LLM-author
consults when picking up the milestone surface.
- **Recommended downstream action:** tighten the design ledger — fix
the example in `docs/specs/2026-05-20-operator-routing-eq-ord.md`
the example in `docs/specs/0049-operator-routing-eq-ord.md`
(lines 109-133) to use `(class prelude.Eq)`, and consider whether
the same drift exists in `design/contracts/prelude-classes.md` or
`design/models/typeclasses.md`. A single forward-fix doc commit.
the same drift exists in `design/contracts/0017-prelude-classes.md` or
`design/models/0005-typeclasses.md`. A single forward-fix doc commit.
### [friction] `(app compare …)` at Float diagnostic does not acknowledge there is no `float_compare`
@@ -47,7 +47,7 @@ This is a schema-only milestone. Four layers are affected:
4. **Canonical-schema contract + rustdoc layer.** Three rustdoc
strings in production source describe the present-state schema
(rather than implementation history); per the Honesty Rule
(`design/contracts/honesty-rule.md`) they must read truthfully
(`design/contracts/0007-honesty-rule.md`) they must read truthfully
after the rename:
- `crates/ailang-core/src/ast.rs:8` — module-level `//!` enumerating
example field renames.
@@ -58,7 +58,7 @@ This is a schema-only milestone. Four layers are affected:
Plus the canonical data-model contract document itself, which
ships fenced JSON blocks describing the schema verbatim:
- `design/contracts/data-model.md:142-147` — the `Term::Lam`
- `design/contracts/0002-data-model.md:142-147` — the `Term::Lam`
fenced-JSON schema block.
The data-model contract IS the canonical schema documentation
@@ -219,7 +219,7 @@ the surrounding fixture content is untouched.
| `crates/ailang-surface/src/parse.rs:81` | Module-level `//!` rustdoc — substitute the new tag spelling. |
| `crates/ailang-check/src/lib.rs:1707` | `///` rustdoc — substitute the new tag spellings. |
| `crates/ailang-core/src/workspace.rs:1925-1926` | In-source JSON-literal in `ct1_validator_walks_lam_embedded_types` (function at L1911): same two key renames. |
| `design/contracts/data-model.md:142-147` | Fenced JSON-block in the canonical data-model contract: same two key renames. |
| `design/contracts/0002-data-model.md:142-147` | Fenced JSON-block in the canonical data-model contract: same two key renames. |
| `examples/test_loop_binder_captured_by_lambda.ail.json` | Same two key renames (2 occurrences total of the two tags, one per line). |
| `experiments/2026-05-12-cross-model-authoring/master/examples/fn_with_lambda.ail.json` | Same two key renames (2 occurrences total). |
| `crates/ailang-surface/src/{print,parse}.rs` (code) | **No change.** Form-A never used these tag names — only `parse.rs:81` rustdoc above. |
@@ -229,8 +229,8 @@ Historic / frozen documents NOT migrated (per Honesty Rule
analogue: these describe state at the time of writing, not the
present state):
- `docs/plans/2026-05-10-23.3-...md`,
`docs/plans/2026-05-09-22b3-monomorphisation.md`,
`docs/plans/2026-05-09-22c-user-class-e2e.md`, `docs/plans/24.2.md`
`docs/plans/0003-22b3-monomorphisation.md`,
`docs/plans/0005-22c-user-class-e2e.md`, `docs/plans/0056-24.2.md`
— embed old tag names in example JSON blocks.
- `experiments/2026-05-12-cross-model-authoring/master/spec.md`,
`experiments/2026-05-12-cross-model-authoring/rendered/*.md`,
@@ -303,7 +303,7 @@ The milestone is GREEN if:
`serde_json::to_value(&Term::Lam{...})` emits the keys
`"param-types"` and `"ret-type"` (and NOT the old camelCase),
AND extends the existing fenced-block anchor sweep to assert
that `design/contracts/data-model.md` contains the new tag
that `design/contracts/0002-data-model.md` contains the new tag
spellings inside the `Term::Lam` fenced JSON block. The home
is `design_schema_drift.rs` (not `schema_coverage.rs`, which is
a corpus-coverage walker) because that file already operates as
@@ -323,7 +323,7 @@ literal swap at compile time with no runtime cost path.
1. Tag-rename change in `crates/ailang-core/src/ast.rs:492,494` is
landed and observable in serialisation output.
2. All four code call-sites (`workspace.rs` JSON-literal + two
`.ail.json` fixtures + `design/contracts/data-model.md` fenced
`.ail.json` fixtures + `design/contracts/0002-data-model.md` fenced
JSON block) carry the new tag names verbatim.
3. All three rustdoc strings (`ast.rs:8`, `parse.rs:81`,
`check/lib.rs:1707`) describe the new tag spellings.
@@ -338,7 +338,7 @@ literal swap at compile time with no runtime cost path.
## Feature-acceptance gate
Per `design/contracts/feature-acceptance.md`, three clauses must
Per `design/contracts/0004-feature-acceptance.md`, three clauses must
hold. This milestone's gate evaluation:
- **Clause 1 — an LLM author naturally produces code that uses the
@@ -3,7 +3,7 @@
**Date:** 2026-05-28
**Status:** Draft — awaiting user spec review
**Authors:** Brummel (orchestrator) + Claude
**Reference:** `design/models/kernel-extensions.md` for the
**Reference:** `design/models/0007-kernel-extensions.md` for the
architectural whitepaper. This spec covers the *first* of three
milestones implementing the kernel-extensions design: the
language-level mechanisms (this milestone), the `raw-buf` base
@@ -182,7 +182,7 @@ for hash-pin sites is mandatory (per the
(e.g. a hypothetical `std_math.factorial` that doesn't have a
receiver type). No retirement of the module-scope mechanism
itself.
- Class method dispatch (see [method-dispatch](../../design/contracts/method-dispatch.md))
- Class method dispatch (see [method-dispatch](../../design/contracts/0016-method-dispatch.md))
is orthogonal. `(app show x)` continues to type-dispatch via the
Show instance; this is not type-scoped namespacing.
- `term-ctor` and `pat-ctor` continue to use bare ctor names
@@ -651,7 +651,7 @@ Milestone closes when:
7. Hash pins refreshed in both `crates/ailang-core/tests/hash_pin.rs`
and `crates/ailang-surface/tests/prelude_module_hash_pin.rs`,
each with an Honesty-Rule provenance comment.
8. The whitepaper `design/models/kernel-extensions.md` is
8. The whitepaper `design/models/0007-kernel-extensions.md` is
updated: sections describing prep.1, prep.2, prep.3 transition
from forward-looking ("will resolve…") to present-state
("resolves…") where appropriate; STATUS header updated to