# embedding-abi-m5.tidy — milestone-close doc-honesty drift — Implementation Plan > **Parent spec:** `docs/journals/2026-05-19-audit-embedding-abi-m5.md` > (the M5 milestone-close audit; this tidy resolves its DRIFT items). > > **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement` > to run this plan. Steps use `- [ ]` checkboxes for tracking. **Goal:** Reconcile the three doc-honesty drift items the M5 milestone-close audit found — DOC/COMMENT-ONLY, pin-safe, zero language/checker/codegen/schema/runtime-behaviour change. **Architecture:** Two `docs/DESIGN.md` prose edits (drop the retired-M4 forward-reference; reconcile the "no shared mutable runtime state" claim with the now-atomic global RC-stats fallback) and one `runtime/rc.c` comment-only honesty fix (the stale "two unconditional `++`" performance aside). All three sites are recon- verified OUTSIDE every pinned/hashed region; the existing pin tests staying green before AND after is the mechanical proof the edits move no pinned byte. Mirrors the M2.tidy `a80d495` / M3.tidy `63d7d60` precedent: pin-safe doc/comment-only, single cohesive commit, pins are the coverage (no RED test, no audit/fieldtest gate). **Tech Stack:** Markdown (`docs/DESIGN.md`), C comments (`runtime/rc.c`). Verification: `cargo test -p ailang-core` (`design_schema_drift`, `docs_honesty_pin`, `effect_doc_honesty_pin`) + `cargo test -p ailang-codegen --test embed_record_layout_pin`. --- **Files this plan creates or modifies:** - Modify: `docs/DESIGN.md:2287-2298` — §"Embedding ABI": reconcile the "no shared mutable runtime state … data-race-free, sanitiser-verified" parenthetical with the now-atomic global RC-stats fallback (edit-2) - Modify: `docs/DESIGN.md:2354-2360` — §"Free (host side)": drop the retired-M4 forward-reference (edit-1) - Modify: `runtime/rc.c:88` — the 18g.0-block "two unconditional `++`" performance aside, comment-text only (edit-3) Recon-verified pin verdicts (do not re-derive): - DESIGN.md:2354-2360 — OUTSIDE: ends at line 2360, *before* the `## Data model` boundary (line 2362) that is the only region `crates/ailang-core/tests/design_schema_drift.rs:28-37` scans; no honesty-pin substring matches it. - DESIGN.md:2287-2298 — OUTSIDE: far above the line-2362 data-model boundary; the one §"Embedding ABI" honesty-pin (`docs_honesty_pin.rs:135`) pins the *line-2299* `bare`-scalar sentence — adjacent but distinct; this edit must not disturb line 2299. - runtime/rc.c:88 — pin-inert: the frozen-IR pin (`crates/ailang-codegen/tests/embed_record_layout_pin.rs`) asserts generated LLVM IR, never rc.c comment text (M3.tidy `63d7d60` precedent: comment-only rc-runtime edit, IR pins byte-identical before/after). --- ### Task 1: `docs/DESIGN.md` doc-honesty (edit-1 + edit-2) Both edits are in the same file on the same doc-honesty axis and change together → one task. **Files:** - Modify: `docs/DESIGN.md:2287-2298` (edit-2) - Modify: `docs/DESIGN.md:2354-2360` (edit-1) - [ ] **Step 1: Read the two edit regions to get exact wrapped bytes** Run: `sed -n '2287,2300p;2354,2361p' docs/DESIGN.md` Expected: the §"Embedding ABI" M2-ctx paragraph (incl. the `no shared mutable runtime state — the swarm artefact is data-race-free, sanitiser-verified` parenthetical, and the *following* line 2299 beginning `Export parameters are written **bare**:`) and the §"Free (host side)" paragraph ending `… an additive M4 concern, not a contradiction of this freeze.` This is the exact hard-wrapped text the Edit `old_string` must match. - [ ] **Step 2: Apply edit-1 — drop the retired-M4 forward-reference** In `docs/DESIGN.md` §"Free (host side)" (~:2354-2360), replace the exact sentence (it is hard-wrapped across ~2 lines in the file; match the file's wrapping): OLD (semantic content to locate; match the file's exact wrap): > A record with boxed fields (`Str`/`List`/nested record) is **not** > an M3 type (rejected by the export gate); a recursive typed-free > for that shape is an additive M4 concern, not a contradiction of > this freeze. NEW (M4 is retired 2026-05-18 — present-tense current fact, no dead forward-reference; re-wrap to DESIGN.md's ~70-col hard-wrap): > A record with boxed fields (`Str`/`List`/nested record) is **not** > an M3 embedding type — the export gate rejects it, so the boundary > never crosses a value that would need a recursive typed-free. The > freeze covers exactly the all-scalar single-constructor record. - [ ] **Step 3: Apply edit-2 — reconcile the concurrency claim** In `docs/DESIGN.md` §"Embedding ABI" (~:2287-2298), replace the exact sentence (hard-wrapped in the file; match its wrap). The edit is confined to this sentence and must NOT touch line 2299 (`Export parameters are written **bare**: …`, separately pinned by `docs_honesty_pin.rs:135`): OLD (semantic content to locate; match the file's exact wrap): > The host links one `ailang_ctx_t` per OS worker thread and the > runtime accounts RC alloc/free into it (no shared mutable runtime > state — the swarm artefact is data-race-free, sanitiser-verified). NEW (accurate present-tense; the per-ctx hot path is unshared, the one shared datum is the atomic global stats fallback — re-wrap to ~70-col): > The host links one `ailang_ctx_t` per OS worker thread and the > runtime accounts RC alloc/free into it: the per-allocation hot path > (the per-ctx counters and the per-object refcount header) is > non-atomic by design and never shared — a box never crosses a > thread (`Ctx: !Send`) and each `ailang_ctx_t` is > single-thread-per-ctx. The one datum a multi-threaded host shares > is the global RC-stats fallback counter (used when no ctx is > bound); it is atomic-relaxed so the swarm's leak accounting is > exact. The swarm artefact is data-race-free, sanitiser-verified. - [ ] **Step 4: Verify DESIGN.md pins still green (pin-safety proof)** Run: `cargo test -p ailang-core --test design_schema_drift --test docs_honesty_pin --test effect_doc_honesty_pin 2>&1 | grep 'test result:'` Expected: every line `test result: ok. … 0 failed` (≥3 result lines). GREEN here is the mechanical proof both DESIGN.md edits are outside every hashed/pinned byte (the data-model slice + the line-2299 bare-scalar honesty pin are untouched). A FAIL means a pinned byte moved — hard stop, the edit strayed into a pinned region. - [ ] **Step 5: Verify line 2299 (the adjacent pinned sentence) is byte-unchanged** Run: `grep -n 'Export parameters are written \*\*bare\*\*' docs/DESIGN.md` Expected: exactly one hit; its line content is byte-identical to its pre-edit form (the recon-pinned `docs_honesty_pin.rs:135` substring). Confirms edit-2 stayed within the M2-ctx paragraph and did not disturb the adjacent separately-pinned line. --- ### Task 2: `runtime/rc.c:88` comment-only honesty fix Separate file, comment-text only, same honesty axis → its own task. **Files:** - Modify: `runtime/rc.c:88` - [ ] **Step 1: Read the 18g.0 comment block for exact bytes** Run: `sed -n '80,106p' runtime/rc.c` Expected: the 18g.0 stats-counter comment block, incl. line 88 `* and adds only two unconditional \`++\` operations to the hot path —` and the adjacent already-corrected "Atomic (relaxed): …" paragraph (~:93-106) the new wording must stay consistent with. - [ ] **Step 2: Apply edit-3 — fix the stale "two unconditional `++`" aside** In `runtime/rc.c` replace the exact comment fragment (lines ~88): OLD: > ` * and adds only two unconditional \`++\` operations to the hot path —` > ` * negligible relative to the libc malloc/free already on each path,` NEW (accurate: one counter bump per op; relaxed-atomic on the global null-ctx fallback, plain `++` on the per-ctx path — consistent with the adjacent :93-106 block): > ` * and adds only one counter bump per alloc/free on the hot path —` > ` * a relaxed atomic add on the global null-ctx fallback, a plain` > ` * \`++\` on the per-ctx path — negligible relative to the libc` > ` * malloc/free already on each path,` Comment-text only. Do NOT touch any code line, the adjacent :93-106 atomic paragraph, or the :45-55 file-header "Threading:" paragraph (both already correct from `bugfix-rc-global-stats-race`). - [ ] **Step 3: Verify rc.c change is comment-only + IR pin green** Run: `git diff -U0 runtime/rc.c | grep -E '^[+-]' | grep -vE '^(\+\+\+|---)' | grep -vE '^[+-]\s*\*' | grep -vE '^[+-]\s*$'` Expected: empty output — every changed line is a `*`-prefixed C comment line (no code line changed). Run: `cargo test -p ailang-codegen --test embed_record_layout_pin 2>&1 | grep 'test result:'` Expected: `test result: ok. … 0 failed` — the frozen-IR pin is byte-identical (it asserts generated IR, not rc.c comments; M3.tidy precedent). --- ### Task 3: Consolidated doc-only + scope gate **Files:** (none — verification only) - [ ] **Step 1: Whole doc-only gate green (all pins, both crates)** Run: `cargo test -p ailang-core --test design_schema_drift --test docs_honesty_pin --test effect_doc_honesty_pin 2>&1 | grep -c 'test result: ok'` then `cargo test -p ailang-codegen --test embed_record_layout_pin 2>&1 | grep 'test result:'` Expected: the first prints `3` (three ok result lines, 0 failed across the three ailang-core pin suites); the second `test result: ok. … 0 failed`. Together: every pin that reads DESIGN.md or the frozen IR is green → the prose/comment edits moved no pinned byte (the M2.tidy/M3.tidy "pins are the coverage" gate). - [ ] **Step 2: Diff scope is exactly the three content sites + iter artefacts** Run: `git status --porcelain` Expected: modified `docs/DESIGN.md` + `runtime/rc.c` only as content changes, plus the (untracked) iter journal `docs/journals/2026-05-19-iter-embedding-abi-m5.tidy.md` and stats `bench/orchestrator-stats/2026-05-19-iter-embedding-abi-m5.tidy.json`. **Zero** change to any `crates/**` source, `examples/**`, `ail-embed/**`, `Cargo.toml`, `bench/baseline.json`, or any `*.ail`/`*.rs` file. Mechanically confirms doc/comment-only. - [ ] **Step 3: No behaviour change — workspace still builds** Run: `cargo build --workspace 2>&1 | tail -1` Expected: `Finished \`dev\` profile …` (a comment-only rc.c change + markdown edits cannot affect compilation; this confirms it). --- ## Self-review (planner Step 5) 1. **Spec coverage.** Audit DRIFT item `[medium]` DESIGN.md:2358-2360 stale-M4 → Task 1 edit-1. `[medium]` DESIGN.md §"Embedding ABI" concurrency-claim silence → Task 1 edit-2. `[low]` rc.c:88 "two unconditional `++`" → Task 2 edit-3. The architect's "one tidy, same honesty axis, do not split" → one plan, one cohesive commit (Task 1+2 are the content; Task 3 is the gate). All three charter items covered; nothing else in scope (doc-only). 2. **Placeholder scan.** No "TBD/TODO/implement later/similar to/add appropriate". The OLD/NEW prose blocks are exact verbatim content, not placeholders. 3. **Type/name consistency.** Paths (`docs/DESIGN.md`, `runtime/rc.c`), test targets (`design_schema_drift`, `docs_honesty_pin`, `effect_doc_honesty_pin`, `embed_record_layout_pin`), line anchors (2287-2298, 2354-2360, rc.c:88, line 2299) — identical across tasks and verification. 4. **Step granularity.** Each step is one read / one edit / one command; all 2-5 min. 5. **No commit steps.** None. Work stays in the working tree; Boss commits the cohesive tidy. 6. **Pin/replacement substring contiguity.** The verification greps (`grep 'Export parameters are written **bare**'`, `grep 'test result:'`, the comment-only `git diff` filter) assert over file/command output, NOT over a verbatim replacement body this plan writes. Recon explicitly verified the pinned substrings (`docs_honesty_pin.rs:135` line-2299 bare-scalar; the data-model-slice schema anchors; the IR-byte pins) are NOT inside either NEW prose block — no presence-pin/verbatim-edit collision. Task 1 Step 5 explicitly guards the one adjacency risk (line 2299 must stay byte-identical). 7. **Compile-gate vs deferred-caller.** No signature/code change at all (doc + C-comment only). Task 3 Step 3's `cargo build --workspace` gate is trivially satisfiable (no code touched); not a deferred-caller hazard. 8. **Verification filter strings resolve.** `--test design_schema_drift` / `--test docs_honesty_pin` / `--test effect_doc_honesty_pin` / `--test embed_record_layout_pin` are recon-verified existing runnable targets (recon built them `--no-run`); `grep -c 'test result: ok'` expects the explicit count `3` (not "≥0"), and the bare-scalar / comment-only greps assert explicit non-empty / empty output, so "nothing ran" cannot masquerade as success. No filter resolves to zero tests.