iter remove-mut-var-assign.tidy: form_a.md grammar deletion + audit close

Milestone-close audit for remove-mut-var-assign (48e7774..07f0802).

Architect drift: one [high] — crates/ailang-core/specs/form_a.md
still documented the full mut/var/assign construct (EBNF 286-288,
prose 308-328, dangling `like mut` at 332). The spec named it for
deletion; the iter missed it. Root cause = the recon-undercount
class (4th recurrence) plus a Boss error: a plan-time grep checked
only docs/form_a.md (dir-scoped), got "No such file", and that
unverified non-existence claim propagated into the recon brief —
the real file is crates/ailang-core/specs/form_a.md. A stale doc
never compile-fails so the implement compile-sweep could not catch
it. Fixed inline as a Boss .tidy (CLAUDE.md context-already-loaded
carve-out; full review discipline kept — tree-wide verified zero
construct residue except the roadmap entry naming the milestone
itself; grammar now reads coherently reuse-as -> loop -> recur).

Bench causally exonerated: HEAD vs 48e7774 bench binaries
cmp-byte-identical (the -2520-line removal alters zero bytes of the
firing fixtures' machine code). check.py exit 1's 3 firings are the
tracked P2 bump_s environmental staleness + single-sample -n5
max_us jitter (explicit_at_rc.max_us +108% -> -2.30% ok on
identical-code rerun). PRISTINE met on the merits; NO baseline
ratify (Iron Law + spec foreclosure).

Roadmap: P0 refreshed (audit clean, fieldtest remains); the
ailang-plan-recon P2 escalated in place to a structural
recon-contract defect (2 named gaps + concrete fix); a new distinct
P2 filed for the check.py *.max_us -n5 3-for-3 false-positive.
This commit is contained in:
2026-05-18 11:19:48 +02:00
parent 07f080256c
commit 4837871ddf
4 changed files with 172 additions and 46 deletions
+62 -21
View File
@@ -46,11 +46,17 @@ work progresses.
alloca machinery kept (loop reuses it) + renamed `binder_allocas`,
shared `Term::Lam` escape guard keeps its `loop` half. Explicitly
decoupled from Stateful-islands (separate, deferred). Spec
approved + planned + implemented (605/0, loop/recur
non-regression green, removal made executable); milestone-close
`audit` then `fieldtest` (surface-touching) remain.
approved + planned + implemented (605/0, loop/recur non-regression
green, removal made executable); milestone-close `audit` clean —
architect `[high]` (a spec-named in-tree grammar doc the iter
missed) fixed in `.tidy`, bench causally exonerated (HEAD vs
pre-milestone binaries `cmp`-byte-identical; the 3 `check.py`
firings are the tracked P2 `bump_s` staleness + the new P2
`max_us` `-n 5` false-positive — no ratify). Only `fieldtest`
(surface-touching) remains before close.
- context: `docs/specs/2026-05-18-remove-mut-var-assign.md`;
`docs/journals/2026-05-18-iter-remove-mut-var-assign.1.md`
`docs/journals/2026-05-18-iter-remove-mut-var-assign.1.md`;
`docs/journals/2026-05-18-audit-remove-mut-var-assign.md`
- [x] **\[milestone\]** Prose `loop` binders — projection redesign —
CLOSED 2026-05-18. Form-B prose now renders loop binders as a
@@ -315,23 +321,37 @@ work progresses.
intra-crate links). All predate the design-md-consolidation
milestone; treat as a one-off sweep.
- context: JOURNAL 2026-05-10 ("Audit close: design-md-consolidation").
- [ ] **\[todo\]** `ailang-plan-recon` cross-crate-caller-undercount
countermeasure — the recon agent hand-lists exhaustive-`match`/caller
sites and has under-counted the true blast radius **three times in
one milestone** (loop-recur.1 walker arms, loop-recur.2 cross-module
`synth` callers, loop-recur.tidy implicit). Each was caught only by
the implement orchestrator's compile-driven sweep, not by the plan.
The pattern is structural: a hand-enumerated site list for a
workspace-wide signature/exhaustive-match change is inherently
lossy. Tighten `skills/planner/agents/ailang-plan-recon.md` so that
for any signature-change / additive-enum-variant scope the recon
REPORTS the compile-driven enumeration command as the authoritative
site set (and frames its own hand-list as advisory), rather than
presenting the hand-list as complete. No language change; an
agent-definition discipline fix.
- context: loop/recur milestone-close audit (architect `[low]`,
2026-05-18); pairs with the planner Step-5 items 7+8 added the
same milestone (those scrub the *plan*; this scrubs the *recon*).
- [ ] **\[todo\]** `ailang-plan-recon` site-undercount countermeasure
(P2, **escalated** — now a structural recon-contract defect, no
longer a single-milestone curiosity) — the recon agent hand-lists
the change blast radius and has under-counted it **four times across
two milestones, through a different site type each time**:
loop-recur.1 walker arms, loop-recur.2 cross-module `synth` callers,
loop-recur.tidy implicit, and now remove-mut-var-assign.1 (in-source
`mod tests` fns + a drift-pin fn + 5 orphaned `.ail.json` carve-outs
+ a non-enumerated `codegen_import_map_fallback_pin.rs` E0599) **plus
a spec-named doc the recon was told did not exist**
(`crates/ailang-core/specs/form_a.md` — the spec listed it for
deletion; a Boss plan-time grep checked only `docs/form_a.md`,
concluded "no such file", and propagated that into the recon brief;
caught only at milestone-close audit). Two distinct gaps: (a) the
compile-driven sweep catches exhaustive-`match`/caller misses but
**not** non-compile-checked sites (docs, fixtures, drift pins) —
those need a separate "every spec-named path is verified to exist
and is handled" cross-check; (b) a recon brief must never inherit an
unverified "X does not exist" — existence claims feeding a recon are
themselves load-bearing and must be tree-wide, not dir-scoped.
Tighten `skills/planner/agents/ailang-plan-recon.md`: for any
signature-change / enum-variant / removal scope the recon REPORTS
the compile-driven enumeration as the authoritative code-site set
(hand-list advisory) AND emits a spec-named-path existence table
(every path the spec names, `ls`-verified, with its handling task).
No language change; an agent-definition discipline fix.
- context: loop/recur close audit (architect `[low]`, 2026-05-18) +
remove-mut-var-assign close audit (architect `[high]` form_a.md +
`[medium]` process-drift, 2026-05-18); pairs with planner Step-5
items 7+8 (those scrub the *plan*; this scrubs the *recon* and the
*recon brief*).
- [ ] **\[todo\]** `design_schema_drift.rs` fidelity widening —
current test checks anchor *presence* anywhere in DESIGN.md;
the audit found that `[high]` schema gaps in §"Data model"
@@ -399,6 +419,27 @@ work progresses.
recalibrate the `bump_s` baseline+tolerance pair (or widen the
tolerance) so the noise floor stops tripping `check.py` exit 1.
Pure bench-harness recalibration; no language change.
- [ ] **\[todo\]** `check.py` RC-latency `*.max_us` is a structural
false-positive at `-n 5` — **distinct** from the `*.bump_s`
staleness above (different metric family, different root cause).
`latency.{explicit,implicit}_at_rc.max_us` is the single worst of
~5000 samples over only 5 runs, dominated by OS scheduling / THP /
IRQ jitter on a shared host, not allocator behaviour. It has fired
a false `REGRESSION` on **three consecutive no-runtime-change
milestones** (iteration-discipline-revert, prose-loop-binders,
remove-mut-var-assign) and vanished on identical-code re-run every
time (remove-mut-var-assign close: HEAD vs `48e7774` bench binaries
`cmp`-byte-identical, `explicit_at_rc.max_us` collapsed
+108%→-2.30% ok by rerun3) — a ~3-for-3 false-positive rate on null
changes, while the median/p99/p99.9 of the same benchmarks held
across all re-runs. Pick one mitigation: drop `*.max_us` from the
gating set (keep median/p99/p99.9, which are the trustworthy
signal), or raise `-n` substantially for the tail metrics, or pin
the latency arm to an isolated cpuset. Pure bench-harness change;
no language change.
- context: remove-mut-var-assign close audit, bencher localisation
(2026-05-18) — byte-identical-binary causal exoneration + the
3-milestone false-positive history.
- context: `docs/journals/2026-05-16-audit-iteration-discipline-revert.md`
(the bencher localisation evidence).
- [x] **\[todo\]** `check_in_workspace` per-module overlay narrowing —