From 44ced513dc1d4e6783acabd9bc432a17d2465c0e Mon Sep 17 00:00:00 2001 From: Brummel Date: Mon, 18 May 2026 21:42:52 +0200 Subject: [PATCH] =?UTF-8?q?plan:=20embedding-abi-m3.tidy=20=E2=80=94=20rec?= =?UTF-8?q?oncile=20M3-audit=20[medium]+[low]=20doc-honesty=20drift=20(3?= =?UTF-8?q?=20tasks,=20pin-safe=20parenthetical-only=20edit=20+=20comment-?= =?UTF-8?q?only=20fix,=20M2.tidy=20precedent)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plans/embedding-abi-m3.tidy.md | 247 ++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 docs/plans/embedding-abi-m3.tidy.md diff --git a/docs/plans/embedding-abi-m3.tidy.md b/docs/plans/embedding-abi-m3.tidy.md new file mode 100644 index 0000000..47073b7 --- /dev/null +++ b/docs/plans/embedding-abi-m3.tidy.md @@ -0,0 +1,247 @@ +# Embedding ABI — M3.tidy — Implementation Plan + +> **Parent spec:** `docs/specs/2026-05-18-embedding-abi-m3.md` +> (the milestone whose §"Embedding ABI" surface this reconciles); +> scoping source-of-truth: `docs/journals/2026-05-18-audit-embedding-abi-m3.md`. +> +> **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement` +> to run this plan. Steps use `- [ ]` checkboxes for tracking. + +**Goal:** Reconcile the two M3-audit doc-honesty DRIFT items — +a self-contradicting M1-era parenthetical in DESIGN.md §"Embedding +ABI" and a stale forwarder-body comment — to present-tense current +state, pin-safe, with zero language/checker/codegen behaviour change. + +**Architecture:** Two independent, surgical text edits. (1) +`docs/DESIGN.md:2300-2301` — replace *only* the parenthetical +`(modes apply only to heap-shaped types, which the scalar-only rule +above forbids at an export boundary anyway)`, which now contradicts +the M3 frozen-layout SSOT (a single-ctor record IS an accepted +export type) and the `(own/borrow (con T))` mode contract; the +`docs_honesty_pin.rs:135`-pinned sentence words on `:2299-2300` +(`norm()`-whitespace-collapsed) are kept verbatim-present. (2) +`crates/ailang-codegen/src/lib.rs:608-610` — a comment-only honesty +fix (no test pins it; the IR byte-pins assert generated code, not +source comments). The four standing pins bracket both edits green. + +**Tech Stack:** `docs/DESIGN.md`, `crates/ailang-codegen/src/lib.rs` +(comment only); regression gates in `ailang-core` +(`docs_honesty_pin`, `design_schema_drift`) and `ailang-codegen` +(`embed_record_layout_pin`, `embed_staticlib_lowering`). + +--- + +## Files this plan creates or modifies + +- Modify: `docs/DESIGN.md:2300-2301` — replace the contradicted M1-era parenthetical only (pinned sentence words on `:2299-2300` untouched; `:2302` kept) +- Modify: `crates/ailang-codegen/src/lib.rs:608-610` — forwarder-body comment honesty (comment-only, no IR change) +- Test (gate, unmodified): `crates/ailang-core/tests/docs_honesty_pin.rs` — `form_a_scalar_param_carveout_present_and_old_rule_absent` stays GREEN (pinned sentence words survive) +- Test (gate, unmodified): `crates/ailang-core/tests/design_schema_drift.rs` — stays GREEN (no schema-drift anchor moves) +- Test (gate, unmodified): `crates/ailang-codegen/tests/embed_record_layout_pin.rs` + `embed_staticlib_lowering.rs` — stay GREEN (comment edit changes no IR) + +--- + +## Task 1: Reconcile the contradicted DESIGN.md parenthetical (`[medium]`) + +The stale clause is strictly the parenthetical spanning the back of +`:2300` and the front of `:2301`. The pinned sentence +("Export parameters are written **bare**: a scalar type carries no +`own`/`borrow` mode", `docs_honesty_pin.rs:135`, `norm()`-collapsed) +occupies `:2299` + the front of `:2300` and MUST keep all its words +(planner Step-5 item-6: presence-pin vs. verbatim-edit collision — +the M2.tidy discipline). The edit replaces only the parenthetical's +words; it does not touch `:2299`, the pinned-sentence words on +`:2300`, the `. The` connective, or `:2302`. + +**Files:** +- Modify: `docs/DESIGN.md:2300-2301` +- Test: `crates/ailang-core/tests/docs_honesty_pin.rs` (gate, unmodified) + +- [ ] **Step 1: Baseline — the pin is GREEN before the edit** + +Run: `cargo test -p ailang-core --test docs_honesty_pin form_a_scalar_param_carveout_present_and_old_rule_absent -- --exact` +Expected: PASS, `1 passed` (the pinned "written **bare**" sentence +present; baseline before the edit). + +Run: `grep -n 'modes apply only to heap-shaped types' docs/DESIGN.md` +Expected: one hit on line `2300` (confirms the stale clause is +present and located exactly where recon mapped it; if the line +number differs, re-locate before editing — the edit is by verbatim +string, not line number, so a shift is non-fatal but must be noted). + +- [ ] **Step 2: Replace only the parenthetical (verbatim edit)** + +In `docs/DESIGN.md`, the current text of lines `:2300-2301` is +exactly (two lines, soft-wrapped): + +``` +`own`/`borrow` mode (modes apply only to heap-shaped types, which the +scalar-only rule above forbids at an export boundary anyway). The +``` + +Replace that exact two-line block with: + +``` +`own`/`borrow` mode (a single-constructor record export parameter, +by contrast, carries `own`/`borrow` — the ownership contract the +frozen value layout below specifies). The +``` + +This (a) keeps the pinned-sentence words `own`/`borrow` mode` +contiguous with `:2299`'s `Export parameters are written **bare**: a +scalar type carries no` (the `norm()` pin only needs the *words* +present, in any wrapping — verified: `docs_honesty_pin.rs:21-26`); +(b) removes exactly the false clause (post-M3 the export boundary +*accepts* a single-ctor record — a heap-shaped type — so "the +scalar-only rule above forbids" is no longer true and contradicted +`:2280-2284` + the mode contract at `:2345-2351`); (c) replaces it +with the present-tense truth that points at the new SSOT; (d) +preserves the `. The` connective and `:2302` +`canonical M1 export shape:` untouched (audit did not flag `:2302`; +scope discipline — fix only the flagged contradiction). + +- [ ] **Step 3: The stale clause is gone, the pin still GREEN** + +Run: `grep -n 'scalar-only rule above forbids' docs/DESIGN.md` +Expected: no output (the contradicted clause is removed). + +Run: `cargo test -p ailang-core --test docs_honesty_pin` +Expected: PASS, `5 passed` — in particular +`form_a_scalar_param_carveout_present_and_old_rule_absent` stays +GREEN (the pinned sentence's words survived the edit). **If RED: +STOP, restore the file (`git checkout -- docs/DESIGN.md`), and +re-scope the edit to leave every pinned-sentence word in place — +do not push past a RED pin (planner Step-5 item-6).** + +- [ ] **Step 4: No schema-drift anchor moved** + +Run: `cargo test -p ailang-core --test design_schema_drift` +Expected: PASS, `8 passed` — the parenthetical is prose, not a +JSON-schema-drift anchor; the count is byte-unchanged from the +recon-confirmed baseline. + +--- + +## Task 2: Honesty-fix the stale forwarder-body comment (`[low]`) + +`crates/ailang-codegen/src/lib.rs:608-610` is a comment-only block +inside the `Target::StaticLib` arm asserting the gate guarantees +`Int`/`Float`-only — false post-M3 (a gate-guaranteed single-ctor +record lowers to `ptr`). Recon tree-wide-grep-confirmed **no test +pins this comment text**; the byte-pin and forwarder-IR pin assert +emitted IR, not source comments, so this edit changes no generated +code. First code/IR line is `:618` — `:608-610` are comment-only. + +**Files:** +- Modify: `crates/ailang-codegen/src/lib.rs:608-610` +- Test: `crates/ailang-codegen/tests/embed_record_layout_pin.rs` + `embed_staticlib_lowering.rs` (gate, unmodified) + +- [ ] **Step 1: Baseline — the IR pins are GREEN before the edit** + +Run: `cargo test -p ailang-codegen --test embed_record_layout_pin --test embed_staticlib_lowering` +Expected: PASS, `1 passed` + `3 passed` (the byte-pin +`heap_box_layout_is_frozen_8_plus_n_times_8_tag_at_0_fields_from_8` +and the forwarder-IR pins +`staticlib_emits_forwarder_no_main` / +`staticlib_record_forwarder_is_ptr_passthrough` / +`executable_target_still_emits_main` — the guard that generated +code is untouched by a comment edit). + +- [ ] **Step 2: Replace the stale comment (verbatim edit)** + +In `crates/ailang-codegen/src/lib.rs`, the current text of lines +`:608-610` is exactly: + +``` + // The check-side gate (Task 4) guarantees every param + // and the ret are `Int`/`Float`; map Int→i64, + // Float→double. M1 scalar fns have no captured env, so +``` + +Replace that exact three-line block with: + +``` + // The check-side export gate guarantees every param and + // the ret are `Int`/`Float` or a single-constructor + // record of those (M3); map Int→i64, Float→double, a + // record → ptr. Scalar fns have no captured env, so +``` + +(Honesty-only: the gate now accepts a single-ctor scalar record → +`ptr`; the trailing "…have no captured env, so" continuation on +`:610`'s tail is preserved as a clause start for the unchanged +following line. Removed the stale `M1` qualifier on the env clause +in passing — it is the *same* sentence the gate-rule fix rewrites, +so it is in-scope contiguous text, not scope creep.) + +- [ ] **Step 3: Generated code is byte-unchanged (IR pins GREEN)** + +Run: `cargo test -p ailang-codegen --test embed_record_layout_pin --test embed_staticlib_lowering` +Expected: PASS, `1 passed` + `3 passed` — identical to Step 1; a +comment edit emits no IR delta. **If any IR pin goes RED the edit +touched code, not just a comment — STOP and restore +(`git checkout -- crates/ailang-codegen/src/lib.rs`).** + +- [ ] **Step 4: The crate still builds + full codegen suite GREEN** + +Run: `cargo test -p ailang-codegen 2>&1 | tail -1` +Expected: the final line shows `test result: ok` with `0 failed` +(comment-only change; the whole codegen crate is unaffected). + +--- + +## Task 3: Milestone-close verification gate + +Not a code change — the consolidated proof that the tidy removed the +drift and moved nothing else. + +**Files:** none (verification only). + +- [ ] **Step 1: Both stale phrases are gone tree-wide** + +Run: `grep -rn 'scalar-only rule above forbids' docs/DESIGN.md ; grep -n 'guarantees every param' crates/ailang-codegen/src/lib.rs` +Expected: no output from either grep (both audit-flagged stale +fragments removed). + +- [ ] **Step 2: The four standing pins + workspace GREEN** + +Run: `cargo test -p ailang-core --test docs_honesty_pin --test design_schema_drift -p ailang-codegen --test embed_record_layout_pin --test embed_staticlib_lowering` +Expected: PASS — `docs_honesty_pin` 5, `design_schema_drift` 8, +`embed_record_layout_pin` 1, `embed_staticlib_lowering` 3 (every +count identical to the recon-confirmed baseline; the tidy moved no +pin). + +Run: `cargo test --workspace 2>&1 | grep -oE '[0-9]+ passed' | awk '{s+=$1} END{print s" passed across "NR" suites"}'` +Expected: `639 passed across 77 suites` (the M3-DONE baseline, +byte-unchanged — a docs/comment tidy adds no tests and regresses +none; if the number differs from 639 the tidy had an unintended +behaviour effect — STOP and investigate). + +- [ ] **Step 3: The diff is exactly two files, no behaviour change** + +Run: `git diff --stat` +Expected: exactly `docs/DESIGN.md` (a few lines) and +`crates/ailang-codegen/src/lib.rs` (3 comment lines) changed — no +`.ail`, no fixture, no test, no schema, no other source. (The +journal + INDEX line are Boss-added at commit, not implement-tree.) + +--- + +## Notes for the implement orchestrator + +- **No audit/fieldtest gate after this tidy.** The four pins ARE the + regression coverage (the M2.tidy precedent: a docs/test-string + tidy's guard is the docs_honesty_pin + the IR pins, Boss-verified + before and after — no fresh architect/bench). Record in the + per-iter journal that this closes the M3 audit's `[medium]`+`[low]` + drift and that bench was already carry-on (causally exonerated at + the audit, NO ratify). +- **Pin-safety is the whole point of Task 1.** The pinned sentence + shares a physical line with the stale clause; the only safe edit + is *replace the parenthetical, keep every pinned word*. A + free-rewrite of the `:2299-2302` line range is a plan violation — + Step 3's RED→STOP→restore is mandatory, not advisory. +- **Boss-only-commits / main-sacrosanct.** Leave both edits + the + per-iter journal + stats uncommitted in the working tree; the + Boss inspects `git diff`, commits the tidy, flips roadmap M3 + `[~]`→`[x]`, and adds the INDEX.md line.