832375f2ac
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.
619 lines
24 KiB
Markdown
619 lines
24 KiB
Markdown
# pd.3 — retire prelude.ail.json + carve-out cleanup — Implementation Plan
|
|
|
|
> **Parent spec:** `docs/specs/0028-prelude-decouple.md`
|
|
>
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement`
|
|
> to run this plan. Steps use `- [ ]` checkboxes for tracking.
|
|
|
|
**Goal:** Close the prelude-decouple milestone by deleting
|
|
`examples/prelude.ail.json` from the working tree and sweeping the
|
|
remaining `include_str!` consumers + spec text + carve-out inventory
|
|
that depended on it. After this iter the only on-disk source of the
|
|
prelude is `examples/prelude.ail`, the form-a-default-authoring spec's
|
|
§C4 (b) carve-out category is empty, and a new pin test guarantees the
|
|
JSON file stays gone.
|
|
|
|
**Architecture:** Pure deletion + adapt iter. Two `include_str!` of
|
|
`prelude.ail.json` survive pd.2: (a) the migrate-bare-cross-module-refs
|
|
defensive include in `crates/ail/src/main.rs:472-484` (a documented
|
|
no-op — the inserted entry is unconditionally skipped by the loop's
|
|
`if mod_name == "prelude" && path.as_os_str().is_empty() { continue; }`
|
|
guard at lines 500-505); (b) the cross-form-identity preflight test
|
|
in `crates/ailang-surface/tests/prelude_module_hash_pin.rs` (which the
|
|
spec explicitly scoped as pd.2-only — its purpose was to ratify pd.3's
|
|
load-bearing assumption, which it did at hash `3abe0d3fa3c11c99`).
|
|
Both must go before the JSON file. Plus one in-mod test in
|
|
`crates/ailang-core/src/workspace.rs` (~line 2654 area, pd.2-introduced)
|
|
re-points from inline `serde_json::from_str(include_str!("prelude.ail.json"))`
|
|
to `ailang_surface::parse_prelude()` via the existing core→surface
|
|
dev-dep edge.
|
|
|
|
**Tech Stack:** `ail` CLI (one block delete + lockstep skip-branch
|
|
delete), `ailang-surface/tests/` (one test fn + supporting bytes
|
|
delete + new carve-out pin), `ailang-core` (one in-mod test re-point),
|
|
`ailang-core/tests/carve_out_inventory.rs` (list + comment update),
|
|
`docs/specs/0025-form-a-default-authoring.md` (§C4 (b) status
|
|
note), `examples/prelude.ail.json` (deleted).
|
|
|
|
---
|
|
|
|
**Files this plan creates or modifies:**
|
|
|
|
- Create: `crates/ailang-surface/tests/prelude_decouple_carve_out_pin.rs` —
|
|
asserts `examples/prelude.ail.json` does NOT exist on disk.
|
|
- Modify: `crates/ailang-surface/tests/prelude_module_hash_pin.rs` — delete
|
|
the `prelude_ail_and_json_parse_to_identical_module` fn and its
|
|
supporting `PRELUDE_JSON` const + `PRELUDE_AIL` orphan-import
|
|
+ the `const _: &str = PRELUDE_AIL;` shape-pin. Trim the module
|
|
doc-comment to describe only the surviving long-term hash anchor.
|
|
- Modify: `crates/ailang-core/src/workspace.rs` — re-point the in-mod
|
|
test that uses `include_str!("../../../examples/prelude.ail.json")`
|
|
(around line 2654 area; pd.2 introduced this as a replacement for the
|
|
deleted `load_prelude()` call) to `ailang_surface::parse_prelude()`
|
|
via the core→surface dev-dep edge.
|
|
- Modify: `crates/ail/src/main.rs:472-505` — delete the defensive
|
|
`include_str!` block (472-484) AND its lockstep skip-branch (500-505,
|
|
the comment + the `if mod_name == "prelude" && path.as_os_str().is_empty()
|
|
{ continue; }` guard). The guard is dead-code without the synthetic
|
|
insert.
|
|
- Modify: `crates/ailang-core/tests/carve_out_inventory.rs` — drop the
|
|
`"prelude.ail.json"` entry from the EXPECTED list (line 25); rewrite
|
|
the doc-comment block (lines 6-11) to "Seven carve-outs" and "§C4 (a)
|
|
subject-matter: 7 fixtures (canonical-form rejection / unbound /
|
|
class-def rejection); §C4 (b) compile-time-embed: retired by
|
|
prelude-decouple milestone, 2026-05-14"; update the header sentence
|
|
at line 2 from "eight" to "seven".
|
|
- Modify: `docs/specs/0025-form-a-default-authoring.md:270-311`
|
|
— add a "Status: RETIRED 2026-05-14 by prelude-decouple milestone"
|
|
marker at the top of §C4 (b) and a one-paragraph epitaph at the
|
|
bottom; preserve the original §C4 (b) text below as historical
|
|
context. Upstream callouts (lines 232-236, 462-465, 477-484) stay as
|
|
historical references — their "as of 2026-05-13" temporal qualifiers
|
|
preserve correctness.
|
|
- Delete: `examples/prelude.ail.json` (the milestone's primary
|
|
artefact retirement).
|
|
|
|
---
|
|
|
|
### Task 1: Re-point the in-mod test in `workspace.rs` from `include_str!("prelude.ail.json")` to `ailang_surface::parse_prelude()`
|
|
|
|
**Files:**
|
|
- Modify: `crates/ailang-core/src/workspace.rs` — the in-mod test that
|
|
inlined `serde_json::from_str(include_str!("prelude.ail.json"))` as a
|
|
pd.2 replacement for the deleted `load_prelude()` call. Per recon, the
|
|
reference is at lines 2654 / 2656 (inside `#[cfg(test)] mod tests`).
|
|
|
|
The dev-dep edge `ailang-core → ailang-surface` (declared in
|
|
`crates/ailang-core/Cargo.toml`'s `[dev-dependencies]`) is reachable
|
|
from in-mod tests when surface is consumed via fully-qualified path
|
|
in the test body, but the lib-test-target compilation cycle blocks
|
|
top-level `use ailang_surface::*;` lines. Use the fully-qualified
|
|
`ailang_surface::parse_prelude()` at the call site to avoid the import
|
|
issue (per pd.2's experience).
|
|
|
|
- [ ] **Step 1: Read the existing in-mod test to confirm shape**
|
|
|
|
Open `crates/ailang-core/src/workspace.rs`, navigate to lines 2640-2670.
|
|
Identify the test fn that contains the `include_str!("../../../examples/prelude.ail.json")`
|
|
and `serde_json::from_str` pair. Per the pd.2 journal this is
|
|
`build_workspace_accepts_assembled_modules_and_runs_validation` (and
|
|
possibly one sibling using the same pattern; check for both occurrences
|
|
at lines 2654 and 2656).
|
|
|
|
If the line numbers shifted post-pd.2 (very possible given pd.2's
|
|
deletions), use:
|
|
|
|
```bash
|
|
git grep -n 'include_str!.*prelude\.ail\.json' crates/ailang-core/src/workspace.rs
|
|
```
|
|
|
|
- [ ] **Step 2: Verify `ailang_surface` is reachable from in-mod tests**
|
|
|
|
Read `crates/ailang-core/Cargo.toml` `[dev-dependencies]`. Confirm
|
|
`ailang-surface = { path = "../ailang-surface" }` is present (per
|
|
brainstorm-recon: yes).
|
|
|
|
This is sanity-checking; if absent, **STOP** — pd.2 was wrong about the
|
|
edge existing and the migration target needs revisiting.
|
|
|
|
- [ ] **Step 3: Replace the inlined `serde_json::from_str` with
|
|
`ailang_surface::parse_prelude()`**
|
|
|
|
In each affected test fn body, replace the pattern:
|
|
|
|
Old (per pd.2 journal):
|
|
```rust
|
|
let prelude: Module = serde_json::from_str(include_str!(
|
|
"../../../examples/prelude.ail.json"
|
|
)).expect("embedded prelude must parse");
|
|
```
|
|
|
|
New:
|
|
```rust
|
|
let prelude = ailang_surface::parse_prelude();
|
|
```
|
|
|
|
The `Module` type annotation can drop because `parse_prelude` returns
|
|
`Module` directly. The import line for `Module` (if newly orphan)
|
|
either stays or is removed depending on other test bodies in the same
|
|
mod.
|
|
|
|
- [ ] **Step 4: Run the affected tests to verify they still pass**
|
|
|
|
Run: `cargo test -p ailang-core build_workspace_accepts_assembled_modules_and_runs_validation`
|
|
|
|
(And the second test name if recon surfaces one — Step 1 will have
|
|
named it.)
|
|
|
|
Expected: PASS. The semantic content is unchanged (same prelude
|
|
Module, just constructed via the canonical post-pd.2 path).
|
|
|
|
- [ ] **Step 5: Run the full core test suite**
|
|
|
|
Run: `cargo test -p ailang-core`
|
|
Expected: all green.
|
|
|
|
---
|
|
|
|
### Task 2: Delete the cross-form-identity preflight + supporting bytes
|
|
|
|
**Files:**
|
|
- Modify: `crates/ailang-surface/tests/prelude_module_hash_pin.rs` — delete
|
|
the `prelude_ail_and_json_parse_to_identical_module` test fn (lines
|
|
22-43 per recon), the `PRELUDE_JSON` const (line 20), the
|
|
`PRELUDE_AIL` orphan import (line 18 — keep `parse_prelude` only),
|
|
the `const _: &str = PRELUDE_AIL;` shape-pin (line 60), and trim
|
|
the module doc-comment (lines 1-15) to describe only the surviving
|
|
long-term hash anchor.
|
|
|
|
- [ ] **Step 1: Delete the cross-form-identity test fn + its supporting bytes**
|
|
|
|
Edit `crates/ailang-surface/tests/prelude_module_hash_pin.rs`. Delete:
|
|
|
|
- Lines 1-15: the module doc-comment block (will be replaced in Step 2).
|
|
- Line 18: the import `use ailang_surface::{parse_prelude, PRELUDE_AIL};`
|
|
— replace with `use ailang_surface::parse_prelude;` (PRELUDE_AIL no
|
|
longer consumed).
|
|
- Line 20: `const PRELUDE_JSON: &str = include_str!(...);`
|
|
- Lines 22-43: the entire `#[test] fn prelude_ail_and_json_parse_to_identical_module`
|
|
body.
|
|
- Lines 59-60: the shape-pin comment + `const _: &str = PRELUDE_AIL;`.
|
|
|
|
The surviving content is the `prelude_parse_yields_canonical_hash` test
|
|
fn (post-edit lines will be ~3-15).
|
|
|
|
- [ ] **Step 2: Replace the module doc-comment with the surviving-only version**
|
|
|
|
At the top of the file, insert:
|
|
|
|
```rust
|
|
//! pd.2/pd.3 (`prelude-decouple` milestone): pin the canonical
|
|
//! identity of the parsed prelude as a literal hex hash. Updates
|
|
//! intentionally on prelude-content changes (record the why in the
|
|
//! per-iter journal); accidental drift trips immediately.
|
|
//!
|
|
//! pd.2 also carried a `prelude_ail_and_json_parse_to_identical_module`
|
|
//! cross-form-identity preflight that compared `parse(prelude.ail)`
|
|
//! against `serde_json::from_str(prelude.ail.json)`. The preflight
|
|
//! discharged its purpose at pd.2 close (PASSED at hash
|
|
//! `3abe0d3fa3c11c99`) and was retired in pd.3 alongside the
|
|
//! `prelude.ail.json` file.
|
|
```
|
|
|
|
- [ ] **Step 3: Run the surviving test**
|
|
|
|
Run: `cargo test -p ailang-surface --test prelude_module_hash_pin`
|
|
Expected: `prelude_parse_yields_canonical_hash` PASSES (still pinning
|
|
hash `3abe0d3fa3c11c99`); the deleted `prelude_ail_and_json_parse_to_identical_module`
|
|
no longer appears in the suite.
|
|
|
|
If the hash assertion fails, the prelude content has changed since
|
|
pd.2 close — investigate. With no source-edit between pd.2 commit and
|
|
pd.3 task 2, the hash MUST be unchanged.
|
|
|
|
- [ ] **Step 4: Verify orphan imports are clean**
|
|
|
|
Run: `cargo build -p ailang-surface --tests 2>&1 | grep -E '(warning|error)' | head -10`
|
|
Expected: no `unused import` warnings on the edited file. If `Module`
|
|
or any other type was the only consumer of an import line that now has
|
|
no consumer, drop the line.
|
|
|
|
---
|
|
|
|
### Task 3: Delete the defensive include in `crates/ail/src/main.rs` + its lockstep skip-branch
|
|
|
|
**Files:**
|
|
- Modify: `crates/ail/src/main.rs` — two adjacent code blocks inside
|
|
the `Cmd::MigrateBareCrossModuleRefs` arm: the defensive include +
|
|
insert at lines 472-484, and the skip-branch at lines 500-505.
|
|
|
|
- [ ] **Step 1: Delete the defensive include block**
|
|
|
|
Edit `crates/ail/src/main.rs`. Delete lines 472-484 (verify with
|
|
`git grep -n 'Include the embedded prelude' crates/ail/src/main.rs`):
|
|
|
|
```rust
|
|
// Include the embedded prelude (so the implicit fallback
|
|
// matches the loader's behaviour).
|
|
let prelude_json: &str = include_str!(
|
|
"../../../examples/prelude.ail.json"
|
|
);
|
|
let prelude: Module = serde_json::from_str(prelude_json)
|
|
.expect("embedded prelude must parse");
|
|
if !modules.contains_key("prelude") {
|
|
modules.insert(
|
|
"prelude".to_string(),
|
|
(PathBuf::new(), prelude),
|
|
);
|
|
}
|
|
```
|
|
|
|
Block-locals `prelude_json` and `prelude` are never read after their
|
|
binding scope ends; deletion is safe.
|
|
|
|
- [ ] **Step 2: Delete the lockstep skip-branch**
|
|
|
|
Same file, locate the loop body. Delete the comment + guard at lines
|
|
500-505:
|
|
|
|
```rust
|
|
// Pass 2: rewrite each module's bare cross-module refs.
|
|
// Skip the synthetic prelude entry (no path to write to).
|
|
let mut rewritten = 0usize;
|
|
for (mod_name, (path, m)) in modules.iter_mut() {
|
|
if mod_name == "prelude" && path.as_os_str().is_empty() {
|
|
continue;
|
|
}
|
|
```
|
|
|
|
becomes:
|
|
|
|
```rust
|
|
// Pass 2: rewrite each module's bare cross-module refs.
|
|
let mut rewritten = 0usize;
|
|
for (mod_name, (path, m)) in modules.iter_mut() {
|
|
```
|
|
|
|
The `mod_name` binding is no longer read inside the loop after the
|
|
guard's removal (verify by reading the next ~15 lines). If the
|
|
unused binding generates a warning, change to `for (_, (path, m)) in
|
|
modules.iter_mut() {`.
|
|
|
|
- [ ] **Step 3: Verify the subcommand still compiles**
|
|
|
|
Run: `cargo check -p ail 2>&1 | head -20`
|
|
Expected: clean. No new warnings on `main.rs`.
|
|
|
|
- [ ] **Step 4: Spot-test the migrate subcommand (optional sanity check)**
|
|
|
|
Run: `cargo run -p ail -- migrate-bare-cross-module-refs --help 2>&1 | head -10`
|
|
Expected: prints help text successfully (the binary builds and the
|
|
subcommand enumerates).
|
|
|
|
The subcommand's substantive behaviour (rewriting bare cross-module
|
|
refs across a directory of `.ail.json` files) hasn't been exercised
|
|
since the canonical-type-names milestone; no in-tree fixtures are
|
|
known to need rewriting today, so a deeper test is out of scope.
|
|
|
|
---
|
|
|
|
### Task 4: Update `carve_out_inventory.rs` — drop §C4 (b)
|
|
|
|
**Files:**
|
|
- Modify: `crates/ailang-core/tests/carve_out_inventory.rs` — three
|
|
edits: header sentence count (line 2), comment block (lines 6-11),
|
|
EXPECTED list (line 24-25 area).
|
|
|
|
- [ ] **Step 1: Update the header sentence**
|
|
|
|
Edit `crates/ailang-core/tests/carve_out_inventory.rs`. Change line 2
|
|
from:
|
|
|
|
```
|
|
//! spec. Asserts that exactly the eight named carve-out files exist
|
|
```
|
|
|
|
to:
|
|
|
|
```
|
|
//! spec. Asserts that exactly the seven named carve-out files exist
|
|
```
|
|
|
|
- [ ] **Step 2: Rewrite the carve-out comment block (lines 6-11)**
|
|
|
|
Old:
|
|
```
|
|
//! Eight carve-outs at iter form-a.1 close:
|
|
//! - §C4 (a) subject-matter: 7 fixtures (canonical-form rejection / unbound / class-def rejection).
|
|
//! - §C4 (b) compile-time-embed: 1 fixture (prelude.ail.json).
|
|
//!
|
|
//! When the prelude-embed-refactor milestone retires §C4 (b), this
|
|
//! test's pass-count drops to seven and `EXPECTED` is re-published.
|
|
```
|
|
|
|
New:
|
|
```
|
|
//! Seven carve-outs post prelude-decouple (2026-05-14):
|
|
//! - §C4 (a) subject-matter: 7 fixtures (canonical-form rejection / unbound / class-def rejection).
|
|
//! - §C4 (b) compile-time-embed: retired 2026-05-14 by milestone
|
|
//! prelude-decouple; the prelude is now embedded as `prelude.ail`
|
|
//! in `ailang-surface` and parsed at compile time via
|
|
//! `ailang_surface::parse_prelude`.
|
|
```
|
|
|
|
- [ ] **Step 3: Drop the `"prelude.ail.json"` entry from EXPECTED**
|
|
|
|
Edit lines around 24-25. Delete:
|
|
|
|
```rust
|
|
// §C4 (b) — compile-time-embed
|
|
"prelude.ail.json",
|
|
```
|
|
|
|
If the comment "// §C4 (b) — compile-time-embed" is on its own line
|
|
above the entry, delete the comment too (it has no other content
|
|
beneath it after this edit).
|
|
|
|
- [ ] **Step 4: Run the test — should now PASS against the post-pd.3 corpus**
|
|
|
|
Run: `cargo test -p ailang-core --test carve_out_inventory`
|
|
Expected: PASS — but note this test STILL READS `examples/prelude.ail.json`
|
|
because the file hasn't been deleted yet (Task 7). The EXPECTED list
|
|
no longer contains it, so the assertion `matches_carve_outs` will FAIL
|
|
saying "unexpected file: prelude.ail.json". That's expected at this
|
|
task — it goes green only after Task 7 deletes the file.
|
|
|
|
If you want intermediate green between this task and Task 7, swap the
|
|
task order (Task 7 before Task 4). The plan's order keeps the test
|
|
edits adjacent and defers the file-system mutation to last; either
|
|
order is correct.
|
|
|
|
---
|
|
|
|
### Task 5: Update `docs/specs/0025-form-a-default-authoring.md` §C4 (b)
|
|
|
|
**Files:**
|
|
- Modify: `docs/specs/0025-form-a-default-authoring.md:270-311` —
|
|
add a "Status: RETIRED" marker at top of §C4 (b) and a one-paragraph
|
|
epitaph at the bottom; preserve the original text as historical
|
|
context.
|
|
|
|
The spec is a historical document about the closed form-a-default-authoring
|
|
milestone; the convention is to retire sections in place rather than
|
|
delete them, so future readers tracing back the prelude-embed-refactor
|
|
milestone's prerequisites can find the original framing.
|
|
|
|
Per the recon, upstream callouts at lines 232-236, 462-465, 477-484
|
|
stay as historical references — their "as of 2026-05-13" temporal
|
|
qualifiers preserve correctness.
|
|
|
|
- [ ] **Step 1: Insert a status marker at the top of §C4 (b)**
|
|
|
|
Edit `docs/specs/0025-form-a-default-authoring.md`. Find the
|
|
`**(b) Compile-time-embed carve-outs (one file as of 2026-05-13):**`
|
|
heading (line 270 area). Insert immediately above:
|
|
|
|
```markdown
|
|
> **Status: RETIRED 2026-05-14 by milestone prelude-decouple.** The
|
|
> §C4 (b) compile-time-embed carve-out is empty post that milestone;
|
|
> the prelude is now authored exclusively as `examples/prelude.ail`
|
|
> 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/0028-prelude-decouple.md` and the
|
|
> per-iter journals 2026-05-14-iter-pd.{1,2,3}.md for the resolution.
|
|
```
|
|
|
|
- [ ] **Step 2: Verify the spec still reads coherently**
|
|
|
|
Read the §C4 (b) section top-to-bottom (lines ~268-315 post-insert).
|
|
Confirm the new status marker reads as a forward-pointer to the
|
|
resolution and the original text reads as the historical motivation.
|
|
The intent: a future reader seeing "the prelude is the only file
|
|
authored as JSON" understands that statement as past-tense and finds
|
|
the resolution one click away.
|
|
|
|
No other edits in this task. Upstream callouts (lines 232-236, 462-465,
|
|
477-484) stay verbatim because their qualifiers ("as of 2026-05-13",
|
|
"one file as of 2026-05-13") remain truthful as historical statements.
|
|
|
|
---
|
|
|
|
### Task 6: Create the carve-out retirement pin
|
|
|
|
**Files:**
|
|
- Create: `crates/ailang-surface/tests/prelude_decouple_carve_out_pin.rs`
|
|
— single `#[test]` fn asserting `examples/prelude.ail.json` does NOT
|
|
exist on disk.
|
|
|
|
- [ ] **Step 1: Write the test**
|
|
|
|
Create `crates/ailang-surface/tests/prelude_decouple_carve_out_pin.rs`:
|
|
|
|
```rust
|
|
//! pd.3 (`prelude-decouple` milestone): pin that
|
|
//! `examples/prelude.ail.json` does NOT exist on disk. Surfaces
|
|
//! immediately if the file is recreated by accident or a future
|
|
//! refactor reverts the embed-source swap.
|
|
//!
|
|
//! Companion to the `examples_ail_json_inventory_matches_carve_outs`
|
|
//! test in `crates/ailang-core/tests/carve_out_inventory.rs`: that
|
|
//! one asserts the carve-out list is exactly seven; this one
|
|
//! asserts the eighth (retired) file specifically does not exist.
|
|
//! Either test detects an accidental re-introduction; this one
|
|
//! pinpoints the file by name in the error message.
|
|
|
|
use std::path::Path;
|
|
|
|
#[test]
|
|
fn prelude_ail_json_does_not_exist_on_disk() {
|
|
let path = Path::new("../../examples/prelude.ail.json");
|
|
assert!(
|
|
!path.exists(),
|
|
"examples/prelude.ail.json must NOT exist after the prelude-\
|
|
decouple milestone (closed 2026-05-14). The prelude is now \
|
|
embedded as prelude.ail in ailang-surface. If you intentionally \
|
|
re-introduced this file, you must also: (a) remove this pin, \
|
|
(b) restore the §C4 (b) entry in carve_out_inventory.rs, \
|
|
(c) revert the §C4 (b) status marker in \
|
|
docs/specs/0025-form-a-default-authoring.md, and \
|
|
(d) record the rationale in a per-iter journal."
|
|
);
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 2: Run the test — must FAIL today**
|
|
|
|
Run: `cargo test -p ailang-surface --test prelude_decouple_carve_out_pin`
|
|
Expected: FAIL because `examples/prelude.ail.json` still exists. The
|
|
test is RED-on-purpose at this point; Task 7 turns it GREEN by
|
|
deleting the file.
|
|
|
|
If the test PASSES at this step, the file is already gone from the
|
|
working tree — investigate (was it deleted in an earlier task by
|
|
mistake? Recon should not have permitted that).
|
|
|
|
---
|
|
|
|
### Task 7: Delete `examples/prelude.ail.json`
|
|
|
|
**Files:**
|
|
- Delete: `examples/prelude.ail.json` — the milestone's primary artefact
|
|
retirement.
|
|
|
|
- [ ] **Step 1: Verify zero remaining production / test consumers**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
git grep -n 'include_str!.*prelude\.ail\.json' -- '*.rs'
|
|
```
|
|
|
|
Expected: NO matches. (Tasks 1-3 cleared all three.)
|
|
|
|
```bash
|
|
git grep -n 'prelude\.ail\.json' -- '*.rs' | grep -vE '(//|//!|/\*)'
|
|
```
|
|
|
|
Expected: NO matches outside comments / doc-comments / string-literals
|
|
in test fixtures. The non-`include_str!` references should all be
|
|
either documentation, comments, or path-string constructions in tests
|
|
(which fail gracefully on missing files).
|
|
|
|
If any reference appears as a file-system access (read/open/etc), STOP
|
|
and migrate it before proceeding.
|
|
|
|
- [ ] **Step 2: Delete the file**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
rm examples/prelude.ail.json
|
|
```
|
|
|
|
(Plain shell delete; not `git rm`. The file will appear as a deletion
|
|
in `git status`. The Boss's commit step stages the deletion via
|
|
`git add` of the path or `git add -u`.)
|
|
|
|
- [ ] **Step 3: Run the carve-out retirement pin — must now PASS**
|
|
|
|
Run: `cargo test -p ailang-surface --test prelude_decouple_carve_out_pin`
|
|
Expected: PASS — `prelude.ail.json` no longer exists.
|
|
|
|
- [ ] **Step 4: Run the carve-out inventory test — must now PASS**
|
|
|
|
Run: `cargo test -p ailang-core --test carve_out_inventory`
|
|
Expected: PASS — `EXPECTED` is exactly seven names, and exactly seven
|
|
files exist under `examples/*.ail.json`.
|
|
|
|
- [ ] **Step 5: Run the full workspace test suite**
|
|
|
|
Run: `cargo test --workspace`
|
|
Expected: all tests green.
|
|
|
|
---
|
|
|
|
### Task 8: Bench regressions + final acceptance
|
|
|
|
**Files:** none directly.
|
|
|
|
- [ ] **Step 1: Run regression baselines**
|
|
|
|
Run: `python bench/check.py && python bench/compile_check.py && python bench/cross_lang.py`
|
|
Expected: all three exit 0. pd.3 changes are file-system + spec text
|
|
+ test deletion + dead-code cleanup; no codegen, no runtime, no
|
|
typecheck-result deltas.
|
|
|
|
If `check.py` fires the same `bench_list_sum.bump_s` envelope-noise
|
|
as in pd.1 / pd.2 / earlier audits, treat as established noise (per
|
|
the prior 13-audit pattern) — pd.3 cannot be the source.
|
|
|
|
- [ ] **Step 2: Confirm milestone-level acceptance**
|
|
|
|
Per the parent spec (§Acceptance criteria):
|
|
|
|
1. `examples/prelude.ail.json` is removed from the working tree —
|
|
verified by Task 7 Step 3.
|
|
2. `cargo build --workspace` succeeds with no `include_str!` of
|
|
`prelude.ail.json` — verified by Task 7 Step 1.
|
|
3. `git grep -l '"prelude"' crates/ailang-core/src/` returns zero
|
|
matches — already true post-pd.2; spot-check now to confirm pd.3
|
|
didn't regress.
|
|
4. `cargo test --workspace` is green — verified Task 7 Step 5 + Task 8 Step 1.
|
|
5. Baselines green at unchanged values — verified Task 8 Step 1.
|
|
6. `docs/specs/0025-form-a-default-authoring.md` §C4 (b) is
|
|
updated — verified by Task 5.
|
|
7. CLAUDE.md and `docs/DESIGN.md` reviewed — spot-check now.
|
|
|
|
For item 7:
|
|
|
|
```bash
|
|
git grep -n 'prelude\.ail\.json' CLAUDE.md docs/DESIGN.md
|
|
```
|
|
|
|
Expected: NO production-doctrine assertions; only historical references
|
|
acceptable. If a CLAUDE.md sentence still asserts that core embeds the
|
|
prelude, edit it to reflect the post-milestone state.
|
|
|
|
```bash
|
|
git grep -n 'authors write `\.ail`' CLAUDE.md
|
|
```
|
|
|
|
Expected: this sentence is consistent with the post-milestone state
|
|
(authors write `.ail` for ALL files now, including prelude — no
|
|
exception). If the wording still names a prelude exception, edit it to
|
|
drop the exception.
|
|
|
|
- [ ] **Step 3: Confirm zero literal-`"prelude"` strings in core/src/**
|
|
|
|
Run: `git grep '"prelude"' crates/ailang-core/src/`
|
|
Expected: NO matches (already true post-pd.2; pd.3 is purely
|
|
file-system + downstream test/spec adjustments, no core/src/ source
|
|
edits).
|
|
|
|
If any match appears in production code, STOP — pd.3 should not have
|
|
modified core's src/ source.
|
|
|
|
---
|
|
|
|
## Out of scope for pd.3
|
|
|
|
The following are NOT part of this milestone and MUST NOT be touched:
|
|
|
|
- The `WorkspaceLoadError::ReservedModuleName` variant declaration in
|
|
`crates/ailang-core/src/workspace.rs` — stays per spec (generic
|
|
shape, no literal `"prelude"`).
|
|
- The `crates/ail/src/main.rs:1220-1229` `W::ReservedModuleName`
|
|
match-arm in `workspace_error_to_diagnostic` — variant tag preserved,
|
|
no edit.
|
|
- The `ailang-check` and `ailang-codegen` implicit-prelude resolution
|
|
paths (`crates/ailang-check/src/lib.rs:143` area, codegen iter 23.2.4
|
|
behaviour) — these consume the prelude module from a populated
|
|
workspace, do not embed prelude bytes, and were explicitly listed as
|
|
out-of-scope in the parent spec.
|
|
- The 3 cargo doc warnings on dangling `[`load_workspace`]` references
|
|
(in `Workspace` and `Registry` rustdoc) noted as known debt in the
|
|
pd.2 journal — pre-existing baseline; unrelated to pd.3 scope.
|
|
- Audit (Boss-dispatched after pd.3 closes — separate skill invocation
|
|
per `skills/audit/SKILL.md`).
|