Files
AILang/docs/journals/2026-05-19-iter-bugfix-swarm-rc-alloc-undercount.md
T
Brummel dbd76e5503 fix(ail-embed): GREEN — build.rs tracks runtime/ as rerun-if-changed; M5 swarm leak-proof armed & deterministic
bugfix-swarm-rc-alloc-undercount, GREEN stage. RED is the separate
audit-trail commit 483117d.

Root cause of the m5.2-resume-attempt residual: ail-embed/build.rs
declared cargo:rerun-if-changed only for the kernel .ail + build.rs
itself — NOT the runtime/ C sources ail build --emit=staticlib
compiles into libailang_rt.a. Cargo never re-ran build.rs after the
atomic-counter fix 7bfa11e, so ail-embed kept linking a stale
pre-7bfa11e non-atomic libailang_rt.a; the swarm's concurrent
TLS-NULL host allocs raced the stale non-atomic g_rc_alloc_count++
(frees-stable/allocs-jitter). NOT a second runtime bug and NOT
test-methodology unsoundness — runtime/rc.c at HEAD is correct; the
isolated crates/ail RED was green only because it rebuilds the
staticlib fresh per run.

Fix (ail-embed/build.rs, +7 lines): directory-level
cargo:rerun-if-changed=<repo>/runtime (Cargo recurses mtimes under
the dir). Preferred over a per-file list — the implementer inspected
crates/ail build_staticlib (libailang_rt.a = ar(rc.o, str.o), both
under runtime/) and chose the directory mechanism so any future
runtime source cannot silently re-introduce the same staleness.
Existing kernel/build.rs/AIL_BIN rerun-if-changed lines kept.

Cohesive consequence (in-scope): symbol_fan_swarm_leak_free
un-#[ignore]d — the test BODY is byte-for-byte unchanged (it was
quarantined, never weakened); the module-doc + fn-doc breadcrumbs
rewritten to the resolved build-dep-staleness rationale. It is now
the integration-level acceptance of both 7bfa11e and this fix. Boss
also removed a pre-existing unused `DataFormat` import in swarm.rs
inline (trivial; the file is committed this iter regardless;
warning-clean after).

Boss-verified independently: RED rt_archive_freshness -> GREEN;
swarm determinism 5/5 (symbol_fan_swarm_leak_free +
symbol_fan_swarm_bit_exact GREEN every run, 0 ignored, jitter gone,
Sallocs==Sfrees==12000003); isolated embed_rc_global_stats_race
still GREEN (untouched, runtime untouched); Invariant 1 data-server
count 0; scope = ail-embed/build.rs + ail-embed/tests/swarm.rs +
journal + stats only.

The M5 swarm leak-proof bounce-back is fully resolved end-to-end.
M5 stays open [~]; m5.3 (time-shard + friction-harvest + close-out)
remains. Includes the per-iter journal, stats, and INDEX.md line.
2026-05-19 02:21:47 +02:00

98 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iter bugfix-swarm-rc-alloc-undercount — build.rs missed runtime/ as a rerun-if-changed input
**Date:** 2026-05-19
**Started from:** 483117d39be6a38333cb5fae8c4b5b96e108d1c2
**Status:** DONE
**Tasks completed:** 1 of 1
## Summary
The M5 swarm leak-proof `symbol_fan_swarm_leak_free` was
non-deterministic: `Σfrees` stable-exact (12000003) every run while
`Σallocs` was short by a jittering amount in ~1/3 of runs. The
m5.2-resume-attempt journal framed this as a *residual runtime
defect* distinct from `7bfa11e` (the atomic-global-counter fix). The
`debug` cycle root-caused it instead to a build-dependency
completeness gap, not a runtime bug: `ail-embed/build.rs` declared
`cargo:rerun-if-changed` only for the kernel `.ail` and `build.rs`
itself — NOT the `runtime/` C sources that
`ail build --emit=staticlib` compiles into `libailang_rt.a`. Cargo
therefore never re-ran `build.rs` after `7bfa11e` landed, so
`ail-embed` kept linking a stale pre-`7bfa11e` non-atomic
`libailang_rt.a` whose `g_rc_alloc_count++` raced the M5 swarm's
concurrent TLS-NULL host allocs (the isolated 8×2M pure-global RED
`embed_rc_global_stats_race` structurally could not model this
because it never touches the stale ail-embed archive — it links the
workspace runtime fresh). `runtime/rc.c` at HEAD was already correct;
the entire production fix is one line in the build script.
The fix adds a directory-level
`println!("cargo:rerun-if-changed={}", repo.join("runtime").display())`.
Confirmed by inspecting `crates/ail/src/main.rs::build_staticlib`
(lines 2519-2534): `libailang_rt.a = ar(rc.o, str.o)` where the
sources are exactly `runtime/rc.c` + `runtime/str.c`, both under
`runtime/`. The directory-level mechanism (Cargo recurses mtimes
under a tracked directory) is preferred over enumerating individual
files precisely because a per-file list would silently re-introduce
the same staleness for any future runtime source (e.g. a new
`runtime/foo.c`). Existing rerun-if-changed lines (kernel `.ail`,
`build.rs`, `AIL_BIN`) were kept. The build.rs edit triggers its own
`rerun-if-changed=build.rs`, which relinks the archive from the
current atomic `runtime/rc.c` — the RED's self-bootstrapping
mechanism.
The cohesive, in-scope consequence: `symbol_fan_swarm_leak_free` is
un-`#[ignore]`d (the `#[ignore]` attribute and its reason string
removed; the test BODY is byte-for-byte unchanged — it was
quarantined, never weakened). The two surviving doc breadcrumbs
(module-doc bullet, fn-doc) are rewritten to present-tense-resolved
with the accurate build-dependency-staleness rationale and the
corrected journal reference. This test is now the integration-level
acceptance of both `7bfa11e` and the build-dependency fix; the leak Σ
balances deterministically (`Σallocs == Σfrees == 12000003`) across 6
consecutive runs.
## Per-task notes
- iter bugfix-swarm-rc-alloc-undercount.1: added directory-level
`cargo:rerun-if-changed=<repo>/runtime` to `ail-embed/build.rs`
(existing kernel/`build.rs`/`AIL_BIN` lines kept); un-`#[ignore]`d
`symbol_fan_swarm_leak_free` in `ail-embed/tests/swarm.rs` (body
verbatim) and corrected its module-doc + fn-doc breadcrumbs to the
resolved build-dep-staleness rationale. RED
`rt_archive_freshness` went 0-lock-insn → GREEN (≥2 lock insns,
matches fresh cross-check). Gate-2 determinism: 6/6 runs, both
`symbol_fan_swarm_leak_free` and `symbol_fan_swarm_bit_exact`
GREEN every run, 0 failed / 0 ignored.
## Concerns
(none)
## Known debt
- (resolved) `ail-embed/tests/swarm.rs` carried a pre-existing
`warning: unused import: data_server::records::DataFormat` (present
since the m5.2 split at `b724cd1`; `DataFormat` is used only by
`swarm_runner.rs`, never the test). The orchestrator correctly did
not chase it under the minimal-fix constraint; the Boss removed the
dead import inline at commit time (trivial mechanical edit per the
CLAUDE.md carve-out — `swarm.rs` was being committed this iter
regardless, and leaving a warning in the now-final, no-longer-
quarantined M5 leak-proof file is its own debt). `cargo test
--manifest-path ail-embed/Cargo.toml` is warning-clean for this
crate after removal.
## Blocked detail
(n/a — DONE)
## Files touched
- ail-embed/build.rs
- ail-embed/tests/swarm.rs
## Stats
bench/orchestrator-stats/2026-05-19-iter-bugfix-swarm-rc-alloc-undercount.json