# 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.
