# audit prose-loop-binders — Milestone-prose-loop-binders tidy (clean)

**Date:** 2026-05-18
**Milestone:** prose-loop-binders (single-iteration)
**Commit range:** `6cbd0fe..c9355d7` (prev close = loop/recur at `6cbd0fe`)
**Status:** CLOSED — clean, carry-on (no fix, no ratify)

## Step 1 — Architect drift review

`ailang-architect` over `6cbd0fe..HEAD`: **clean**, zero drift, zero
debt. Verified against the diff (not journal trust):

- Single hunk in `crates/ailang-prose/src/lib.rs` (the `Term::Loop`
  arm of `write_term`, lines 936–953). The two non-render
  `Term::Loop` sites (`count_free_var`, `subst_var_with_term`) and
  all `Term::Recur` arms are absent from the diff — untouched.
- DESIGN.md and PROSE_ROUNDTRIP.md make **no** claim about how
  prose renders `loop` (grep: no match), so the spec's "no doc
  edit needed" is correct, not a skipped obligation. `DESIGN.md:714`
  `loop(n-1)` is an ordinary recursive-call illustration in
  Decision 8, unrelated to the `Term::Loop` construct — not stale.
- Diff touches only the four named code/fixture files plus expected
  docs (spec/plan/journal/INDEX/roadmap/stats). No carve-out /
  hash-pin / round-trip lockstep bypassed (prose is off the
  Form-A↔JSON round-trip path by construction).
- The `architect_sweeps.sh` Sweep-1 DESIGN.md hits all pre-date
  `6cbd0fe` and are outside this milestone's diff (zero DESIGN.md
  lines changed) — flagged for the record, not attributable here.

Architect recommendation: carry on as planned.

## Step 2 — Bench-regression check

- `bench/compile_check.py` → **exit 0**, 24 metrics, 0 regressed.
- `bench/cross_lang.py` → **exit 0**, 25 metrics, 0 regressed.
  Notably its independent `bench_list_sum.ail_bump_s` reads +1.50%
  (±15% tol) → **ok** — corroborates that check.py's bump_s firing
  is baseline-staleness, not a real bump regression.
- `bench/check.py` → exit 1. First run: 3 regressed
  (`bench_list_sum.bump_s` +13.17%; `latency.implicit_at_rc.p99_9_us`
  +37.30%; `latency.implicit_at_rc.max_us` +114.14%), 4 improved,
  56 stable. Confirmatory identical re-run (no code change):
  `p99_9_us` +10.22% → **ok**, `max_us` +22.17% → **ok** (median
  and p99 within tol on both runs) — the two latency-tail firings
  were single-sample 5-run RC-mode jitter, proven by re-run.
  `bench_list_sum.bump_s` persisted at +11.79% (consistent with
  the +13.17% first run): summary `63 metrics; 1 regressed`.

## Step 3 — Classification

| Item | Class | Rationale |
|------|-------|-----------|
| Architect drift | carry-on | clean — nothing actionable |
| `throughput.bench_list_sum.bump_s` +~12% | carry-on | The already-tracked P2 roadmap todo "`*.bump_s` throughput baseline is stale vs current hardware" — byte-oracle-proven environmental (not codegen) at the 2026-05-16 iteration-discipline-revert audit. Causally impossible to attribute to a projection-only `ailang-prose` change (prose is not in the bench runtime path; architect verified the diff is one render-arm + test fixtures). |
| `latency.implicit_at_rc` p99.9 / max | carry-on | Single-sample 5-run RC-mode tail jitter; vanished on identical re-run with median/p99 always within tolerance. Not a regression; the queued P3 "latency methodology rework" (histogram-based) exists precisely to de-noise this metric family. |

## Step 4 — Resolution

**Carry-on** on every item. No fix iteration, no baseline ratify.

Explicitly **not ratified**: the `*.bump_s` baseline is NOT bumped
here. The P2 roadmap todo scopes a holistic recapture+recalibration
of the entire `*.bump_s` set on current hardware from a known-clean
commit as a dedicated bench-harness iteration; opportunistically
bumping one metric's baseline inside an unrelated projection-only
milestone is exactly the "bump the baseline, the regression is
expected" rationalisation the audit Iron Law forbids, and would
fragment the recapture the P2 todo owns. The pointer stands; the
todo is unchanged.

## Fieldtest applicability

**Not applicable / not dispatched.** `fieldtest` is Boss-dispatched
for a milestone that touched the *authoring* surface — the
fieldtester writes `.ail` Form-A programs and runs them through the
public `ail` CLI. This milestone changed only the Form-B *reading*
projection (`ail prose` output); the Form-A authoring surface, the
typechecker, codegen, and runtime are byte-unchanged. A fieldtester
authoring `.ail` programs would not exercise the prose-render change
at all — there is no friction/bug/spec-gap axis for it to probe.
The two committed whole-file byte-equality `.prose.txt` snapshots +
the live-CLI `ail prose | diff` acceptance checks (iter journal) are
the end-to-end gate for a projection-only milestone.

## Milestone close

The **prose-loop-binders** milestone is **CLOSED, clean**. Architect
drift clear; bench carry-on (sole persistent firing is the tracked
P2 `*.bump_s` environmental staleness, latency-tail proven sampling
noise by re-run). Roadmap P0 entry flipped to closed; no follow-up
iteration spawned.
