runtime: put el_runtime.c on a ratchet, and actually run the guards #161
Reference in New Issue
Block a user
Delete Branch "fix/runtime-growth-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stacked on #160 — base is
fix/runtime-shim-retire. Merge #160 first, then this retargets todevcleanly. This PR's own diff is 8 files.Root cause
Same two causes as #160 — a temporary shim nobody retired, kept growing by a false instruction in the instruction file — but this PR addresses the part that let it go unnoticed for 3.5 months.
scripts/check-single-runtime.shguards againstel_runtime.cbeing COPIED. It was written after a lagging fork shipped to prod and dropped learnedhebbedges. Nothing guarded against it GROWING. So it grew: 10,607 → 20,527 lines, +94% in 3.5 months — the whole time under an explicit commit-message promise that it was a temporary shim about to be deleted.And the copy guard was never wired in. Its own footer described the CI wire-in as a TODO, and the TODO had never been done — the script existed but ran in no workflow and no hook. It had caught nothing for as long as it has been in the tree.
What changed
lang/runtime/BUDGET— a ratchet, not a limit.max_lines 20527— set at the current size with no headroom. The file cannot grow by one line.max_engram_fns 279— top-levelengram_*/eg_*/cog_*definitions inel_runtime.c. ~47.5% of the file is engram code and engram already owns six sibling.cfiles, so this is the scoreboard for moving it out.scripts/check-runtime-growth.sh— enforces the ratchet, plus three invariants that keep the multi-file runtime honest:.cinlang/runtime/is inSOURCESor explicitly platform-optional. An unaccounted.cis compiled by nothing and is silently dead code.install.sh's hardcoded download list matchesSOURCES. It cannot call the helper — it runs where there is no checkout — so that copy is checked, not trusted. This is precisely the duplicate that drifted before.Both guards now actually run — early steps in
ci-dev.yaml,ci-stage.yaml,sdk-release.yaml, and in.githooks/pre-commit.The failure message is the point
The guard that existed said what was wrong but not where the code should go — which makes it easy to "fix" by arguing with the guard, or by raising the number. This one names the destination, and prints the
nmcommand that proves the argument is already settled:Placement is a link-time concern; the shipped compiler already links from ten translation units. So it names the six concern files, then
SOURCES(one line), thenc_sourcein a program'smanifest.el. Every runtime file exceptel_runtime.cis deliberately uncapped — that is where code is supposed to go.Negative controls
Per
lang/AGENTS.mdstep 5, each was shown FAILING, not merely passing:+1line toel_runtime.c20528/20527, over by 1+1engram fn, net-zero lines280/279lang/runtime/el_stray.cengram_store.cremoved frominstall.shOnly in SOURCES: engram_store.cel_runtime.ctruncated to 20,000 linesmax_linesto 20000"el_runtime.cis byte-identical after the controls (git statusclean). This PR changes zero lines of it.Before / after
install.shvsSOURCESdriftlang/runtime/*.clang/runtime/el_runtime.cWhat remains
Stage 3: move engram code out of
el_runtime.cinto the six sibling files — ~9,700 lines, ~279 functions.max_engram_fnsis the scoreboard; the guard prints the new number to ratchet to after each move.Recommended next, not attempted: make
elcemit#include el_seed.hand dropelb's hardcoded runtime path, finishing the 2026-05-03 migration. Correct long-term fix, but it touches codegen and self-hosting.Coordination
Does not touch
engram/src/server.el,peripheral/, orelp/.lang/AGENTS.mdedit is confined to the Layer 2 section, away from PR #157's "Rebuilding the Compiler" block.scripts/check-single-runtime.sh guards against el_runtime.c being COPIED — it was written after a lagging fork shipped to prod and dropped learned hebb edges. Nothing guarded against it GROWING. So it grew: 10,607 -> 20,527 lines, 94% in 3.5 months, the whole time under an explicit commit-message promise that it was a temporary shim about to be deleted. Worse, the copy guard was never wired in. Its own footer described the CI wire-in as a TODO, and the TODO had never been done — the script existed but ran nowhere, in no workflow and in no hook, so it had caught nothing for as long as it has been in the tree. A guard that does not run is a comment. This adds the missing guard and runs both. * lang/runtime/BUDGET — a RATCHET, not a limit. max_lines is set at the current 20,527 with NO headroom: the file cannot grow by one line. A second cap, max_engram_fns (279), counts top-level engram_/eg_/cog_ definitions in it — ~47.5% of the file is engram code and engram already owns six sibling .c files, so this is the scoreboard for moving it out. Both may only go DOWN. * scripts/check-runtime-growth.sh — enforces the ratchet, and three invariants that keep the multi-file runtime honest: every .c in lang/runtime/ is either in SOURCES or explicitly platform-optional (an unaccounted .c is compiled by nothing and is silently dead); install.sh's hardcoded download list matches SOURCES (it cannot call the helper — it runs where there is no checkout — so that copy is checked, not trusted); and an advisory nudge to lower the budget when you have earned it. * Both guards now run as early steps in ci-dev.yaml, ci-stage.yaml and sdk-release.yaml, and in .githooks/pre-commit. The failure message is the point. The guard that existed said what was wrong but not where the code should go, which makes it easy to "fix" by arguing with the guard. This one names the destination: the concern-owning .c, or a new .c plus one line in SOURCES, or c_source in a program's manifest.el — and it prints the `nm` command that proves placement is link-time and that the shipped compiler already links from ten translation units. Every runtime file except el_runtime.c is deliberately uncapped, because that is where code is supposed to go. Proven with negative controls, per lang/AGENTS.md step 5 — each shown FAILING: * +1 line to el_runtime.c -> FAIL (20528/20527) * +1 engram fn, net-zero lines -> FAIL (280/279) * a new unaccounted lang/runtime/*.c -> FAIL * engram_store.c removed from install.sh -> FAIL, names the missing file * el_runtime.c truncated to 20,000 lines -> PASS + "lower max_lines to 20000" * baseline, tree unmodified -> OK, and both guards green el_runtime.c is byte-identical after the controls; this commit changes zero lines of it.