Files
AILang/docs/journals/2026-05-18-audit-remove-mut-var-assign.md
T
Brummel 4837871ddf 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.
2026-05-18 11:19:48 +02:00

5.4 KiB
Raw Blame History

audit — remove-mut-var-assign milestone close

Date: 2026-05-18 Scope: 48e7774..07f0802 (prev close → the single terminal iter) Outcome: CLEAN after one inline .tidy fix; bench causally exonerated; two P2 roadmap todos filed/strengthened. Fieldtest remains (surface-touching milestone).

Step 1 — Architect drift review

[high]crates/ailang-core/specs/form_a.md (EBNF 286-288, prose 308-328, dangling like mut at 332). The live in-tree Form-A grammar reference still documented the full mut/var/ assign construct. The spec (Components #2, Architecture table row 2) explicitly named "form_a.md" for deletion; the schema-vs-doc honesty invariant the milestone advertises was broken. Root cause = the recon-undercount class (4th recurrence), and specifically a Boss error: at plan time the Boss grepped docs/form_a.md (dir-scoped), got "No such file", concluded "form_a.md does not exist", and propagated that unverified non-existence claim into the recon brief. The file lives at crates/ailang-core/specs/form_a.md and is actively maintained (form-a.tidy edited it) — not frozen historical record. A compile-driven sweep cannot catch this: a stale doc never produces E0004/E0061.

Resolution — inline Boss .tidy, not planner+implement. Rationale (CLAUDE.md "When NOT to delegate": context already loaded, an agent would redo all milestone reading for a ~40-line single-file doc deletion whose design was already settled by the approved spec): deleted the three EBNF productions (keeping reuse-aslooprecur), the three mut/var/assign prose bullets, and reworded the surviving loop bullet so its "right-folded into Term::Seq" no longer back-references the deleted mut. Full review-and-commit discipline kept (no discipline shed for the carve-out): verified tree-wide that the only remaining Term::Mut/Term::Assign/MutVar strings in crates/ + docs/DESIGN.md + docs/roadmap.md are the roadmap entry describing the milestone itself (not residue), and form_a.md's two remaining mut/var substrings are the unrelated [unbound-var] / reuse-as-source-not-bare-var diagnostic names. Grammar + notes read coherently after the cut.

[medium] — process-drift, recon-undercount 4th recurrence. The existing loop-recur.tidy P2 (ailang-plan-recon cross-crate-caller-undercount) is demonstrably insufficient: the class now recurs through a new site type each time (test bodies, drift pins, carve-out files, and now a spec-named non-compiled doc + an unverified existence claim feeding the recon brief). Escalated that P2 in place — broadened from "cross-crate caller" to a structural recon-contract defect with two named gaps (non-compile-checked spec-named sites; unverified "X does not exist" claims inheriting into a recon brief), and a concrete agent-definition fix (compile-driven enumeration as authoritative code-site set plus an ls-verified spec-named-path existence table). Not a code defect; an agent-discipline fix, parked P2.

Step 2 — Bench-regression

bench/check.py exit 1 (3 firings); compile_check.py exit 0 (24/24 stable — no check-time tax, consistent with a pure removal); cross_lang.py exit 0 (25/25 stable, incl. the independent bench_list_sum.ail_bump_s +2.95% ok).

check.py firings: throughput.bench_list_sum.bump_s +12.51%; latency.explicit_at_rc.max_us +108.38%; latency.implicit_at_rc.max_us +66.46%. All medians/p99 stable.

Bencher localisation — causal exoneration (decisive). Built ail at HEAD and at pre-milestone 48e7774; the three firing-relevant bench binaries (list_sum_bump, lat_expl_rc, lat_impl_rc) are cmp-byte-identical across the milestone. The 2520-line removal diff does not alter one byte of these fixtures' machine code (none contain mut); no causal mechanism exists. By elimination every firing is non-code-caused.

Per-firing verdict: bump_s = the tracked P2 environmental staleness (stable ~+1114% across 4 runs, byte-identical binary, cross_lang corroborates); both *.max_us = single-sample -n 5 jitter (explicit_at_rc.max_us collapsed +108%→-2.30% ok by an identical-code rerun3; implicit_at_rc.max_us swings 477→1172→843→756 on the identical binary while its median holds +3.1…3.9%).

Resolution: PRISTINE met on the merits. NO baseline ratify. The Iron Law forbids ratifying noise into the baseline and the spec explicitly forecloses opportunistic ratification here; the non-pristine exit code is bench-harness noise, not a code defect, and does not block close. Filed a new, distinct P2 (separate from the *.bump_s staleness P2): check.py RC-latency *.max_us at -n 5 is a structural false-positive — 3-for-3 on consecutive no-runtime-change milestones — recommending drop max_us from gating / raise -n / cpuset-pin (mitigation choice left to a future iteration).

Step 3/4 — Classification & resolution

Item Class Outcome
form_a.md construct doc fix inline Boss .tidy (this commit)
recon-undercount 4th recurrence process-drift P2 escalated in place (roadmap)
bump_s +12.51% carry-on tracked P2 (no ratify)
*.max_us ×2 carry-on new P2 filed (no ratify)

Milestone audit CLEAN post-tidy. Next pipeline step: fieldtest (the removal is a user-visible Form-A surface change — mut/var/assign no longer lex; an LLM author must now reach for let/if/loop/recur).