You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dynamics consumer memory growth exceeds the existing flatness limit before next release #1623
The next-release consumer wave fails dynamics' existing memory-flatness check against EigenScript candidate 96bbbb543fdbfe01e809eee09e7c67986085ed1d. Dynamics source is merged 52dd7d200ae1ac04dd33cdeb3e0a976af8343567. Mouse interaction checks now pass; this is separate from dynamics#47's wrapper ownership repair.
The unchanged gate allows at most 25,600 KB growth between its cold-process endpoints and an absolute peak of 204,800 KB. The wave observed static growth 45,952 KB and toggle growth 35,200 KB, failing flatness while remaining below the absolute ceiling.
A bounded diagnostic using the unchanged tests/bif_ui.eigs, direct owning binaries, static mode and requested BIF_TICKS 30/300 produced:
All eight calls exited 0 with empty stderr, exact existing work counters (1 build, 1 series, 4000 points, 4 markers), and full stdout matching within each runtime. Source/binary identities and process cleanup were independently audited. The excess persists without default JIT or the counting wrapper. These are requested tick budgets, not independently measured rendered-frame counts. One cold pair per condition does not establish repeatability, an unbounded leak, or allocation attribution. The pin/current reports differ at two observer flags; no cross-version semantic equivalence is claimed.
Done when:
Attribute the increased peak growth to a source interval and mechanism using bounded ordinary measurements.
Repair the responsible implementation while retaining the existing workload and acceptance thresholds.
Pass the normal dynamics memory gate, including its middle endpoint and toggle arm, and the complete consumer wave on the final candidate.
Preserve the failing observations and verify owning runtime profiles, actual work and process cleanup.
Local evidence: release-blockers-20261003/1590-consumer-96-wave2-logs/run.ruYNUy/dynamics.log, dynamics-memory-eight-v3/, and critic-dynamics-memory-eight-v3.md. Runtime PR #1616 remains draft pending acceptance. No release cut is authorized.
Thanks for filing. Labelled needs-triage because it has no area: label yet. The scheme is area:<subsystem> (runtime-vm, jit, concurrency, observer, memory, trace-tape, packages, http, gfx, embed, docs, ci, gates, lint-tooling, consumer, aot, stdlib) plus a kind (kind:*, or the stock bug/enhancement) — add the ones that fit if you know them, and a maintainer will confirm and drop needs-triage. See CONTRIBUTING.md, "Reporting Bugs".
Consumer-wave re-run on a candidate containing #1629: memory gate PASSES
Candidate:v0.44.0 = 01bbf7ea843e04aa779199a105cdc0802271c241. This is also current main: git rev-list --count v0.44.0..origin/main = 0. dynamics pins the same tag: dynamics#49 merged as f20a0a5 and sets .devcontainer/DockerfileEIGS_REF=v0.44.0.
(45a71e1d is the merge commit of #1629, "gc: retire sole-pin candidates between full cycle scans".)
The original wave measured 96bbbb54, a stale pre-rebase head of the #1616 branch that doesn't contain #1629. It was the wrong candidate.
Method (mirrors runtime's bisect measurements)
Fresh clone at 01bbf7ea, make gfx CC=gcc. That's the same build as the dynamics devcontainer.
dynamics at mainf20a0a5, clean tree. tests/test_bif_mem.sh was not modified: sha256 f789ca14…, GROWTH_KB=25600, CEILING_KB=204800, VCAP=1500000.
Same setup as CI and runtime's runs: DISPLAY unset, so the gate uses xvfb-run -a, and every process pinned to 4 CPUs with taskset -c 0-3. A GitHub runner has 4 vCPUs. Every leg is a cold process: GNU time %M peak RSS under ulimit -v 1500000.
A: 8 full runs of the unchanged gate. Each run measures static and toggle at 30/100/300 frames, and growth is peak(300) − peak(30). Each run also includes both planted faults.
B: 6 interleaved cold pairs (30 vs 300 frames) per cell, for static/toggle × default/forced-VM (EIGS_JIT_OFF=1). These use runtime's unchanged measure.sh / run_pairs.sh method, with the order rotated each round.
Control: runtime's 96bbbb54 build ran through the same unchanged gate, interleaved at rounds 2, 5 and 8. This shows the instrument still catches the regression on this box today.
A. Unchanged gate, 8 runs on v0.44.0 (KB; peaks at 30 / 100 / 300 frames)
run
static peaks
static growth
toggle peaks
toggle growth
exit
planted faults caught
1
128,676 / 132,048 / 132,308
3,632
128,492 / 130,944 / 132,596
4,104
0
both
2
129,428 / 131,160 / 132,692
3,264
127,968 / 130,696 / 131,748
3,780
0
both
3
129,216 / 132,424 / 132,992
3,776
127,872 / 130,028 / 131,256
3,384
0
both
4
129,144 / 131,132 / 131,656
2,512
128,628 / 130,332 / 132,316
3,688
0
both
5
129,028 / 130,924 / 132,416
3,388
128,584 / 130,644 / 132,872
4,288
0
both
6
129,584 / 131,868 / 131,788
2,204
128,552 / 130,512 / 131,944
3,392
0
both
7
129,072 / 131,852 / 132,544
3,472
128,656 / 130,788 / 132,444
3,788
0
both
8
128,884 / 131,792 / 132,100
3,216
128,804 / 131,572 / 131,852
3,048
0
both
min / median / max
2,204 / 3,326 / 3,776
3,048 / 3,734 / 4,288
8/8 PASS
Limit is 25,600 KB, so the worst run is under 17% of it. The highest peak in any leg was 132,992 KB, against the 204,800 KB ceiling. Structure counters held in every leg (built=1, series=1, points=4000, markers=4).
Control: stale 96bbbb54, same gate, same box, same session:
run
static growth
toggle growth
exit
ctrl2
46,692
34,580
1 (FAIL)
ctrl5
46,592
35,704
1 (FAIL)
ctrl8
46,440
35,644
1 (FAIL)
This matches the wave's 45,952 / 35,200 and runtime's 6 of 6 cold-pair failures.
B. Cold pairs, v0.44.0: peak RSS at 30 → 300 frames = growth (KB)
round
static, default
static, forced VM
toggle, default
toggle, forced VM
1
128,800 → 131,520 = 2,720
129,160 → 132,196 = 3,036
127,852 → 132,128 = 4,276
128,080 → 131,728 = 3,648
2
129,232 → 131,716 = 2,484
129,656 → 131,212 = 1,556
127,904 → 132,624 = 4,720
128,880 → 131,908 = 3,028
3
128,900 → 132,084 = 3,184
128,876 → 132,308 = 3,432
128,292 → 132,864 = 4,572
128,208 → 131,644 = 3,436
4
128,780 → 132,316 = 3,536
129,824 → 132,484 = 2,660
129,040 → 132,064 = 3,024
127,172 → 131,804 = 4,632
5
128,668 → 132,248 = 3,580
129,104 → 131,904 = 2,800
128,316 → 131,844 = 3,528
128,332 → 131,844 = 3,512
6
129,012 → 132,312 = 3,300
129,000 → 132,140 = 3,140
128,632 → 131,980 = 3,348
127,580 → 132,084 = 4,504
min / med / max
2,484 / 3,242 / 3,580
1,556 / 2,918 / 3,432
3,024 / 3,902 / 4,720
3,028 / 3,580 / 4,632
0 of 24 pairs went over 25,600 KB. All 48 processes exited 0 with empty stderr, BIF-UI-OK, and the exact work counters.
Full dynamics suite on v0.44.0 (CI order, same setup)
test_lint, test_smoke, test_lab, test_orbit_hist, test_bifurcation, test_orbit_oracle, test_orbit_mouse (16 checks, all three planted faults caught) and test_bif_mem: 8/8 PASS.
Independent check: dynamics main CI on the v0.44.0 pin (run 37298446691, push, f20a0a5) is green. Its gate logged static growth 1,288 KB and toggle growth 2,016 KB.
On this 8-CPU box, running with all 8 CPUs visible makes any build abort with eigenscript: out of memory (requested 80 bytes) under the gate's ulimit -v 1500000. That happens on v0.44.0 too, and the gate then reports rc=134 FAIL. With 7 or fewer CPUs it runs. The likely cause is per-thread address-space reservation in the software renderer. Runtime's runs and this one were pinned to 4 CPUs, the same as a GitHub runner. This is a dynamics gate portability caveat and doesn't affect this verdict.
Verdict
PASS. On a candidate containing #1629, the unchanged dynamics memory gate passes 8 of 8 runs, middle endpoint and toggle arm included. All 24 cold pairs (static and toggle, default and forced-VM) are at least 5× under the 25,600 KB flatness limit. The stale 96bbbb54 still fails on the same box. The full dynamics suite passes. Closing as fixed by #1629 (45a71e1d, shipped in v0.44.0).
Activity
github-actions commentedon Oct 4, 2026
Thanks for filing. Labelled
needs-triagebecause it has noarea:label yet. The scheme isarea:<subsystem>(runtime-vm, jit, concurrency, observer, memory, trace-tape, packages, http, gfx, embed, docs, ci, gates, lint-tooling, consumer, aot, stdlib) plus a kind (kind:*, or the stockbug/enhancement) — add the ones that fit if you know them, and a maintainer will confirm and dropneeds-triage. See CONTRIBUTING.md, "Reporting Bugs".InauguralPhysicist commentedon Oct 6, 2026
Consumer-wave re-run on a candidate containing #1629: memory gate PASSES
Candidate:
v0.44.0=01bbf7ea843e04aa779199a105cdc0802271c241. This is also currentmain:git rev-list --count v0.44.0..origin/main= 0. dynamics pins the same tag: dynamics#49 merged asf20a0a5and sets.devcontainer/DockerfileEIGS_REF=v0.44.0.Containment:
(
45a71e1dis the merge commit of #1629, "gc: retire sole-pin candidates between full cycle scans".)The original wave measured
96bbbb54, a stale pre-rebase head of the #1616 branch that doesn't contain #1629. It was the wrong candidate.Method (mirrors runtime's bisect measurements)
01bbf7ea,make gfx CC=gcc. That's the same build as the dynamics devcontainer.mainf20a0a5, clean tree.tests/test_bif_mem.shwas not modified: sha256f789ca14…,GROWTH_KB=25600,CEILING_KB=204800,VCAP=1500000.DISPLAYunset, so the gate usesxvfb-run -a, and every process pinned to 4 CPUs withtaskset -c 0-3. A GitHub runner has 4 vCPUs. Every leg is a cold process: GNUtime %Mpeak RSS underulimit -v 1500000.EIGS_JIT_OFF=1). These use runtime's unchangedmeasure.sh/run_pairs.shmethod, with the order rotated each round.96bbbb54build ran through the same unchanged gate, interleaved at rounds 2, 5 and 8. This shows the instrument still catches the regression on this box today.A. Unchanged gate, 8 runs on v0.44.0 (KB; peaks at 30 / 100 / 300 frames)
Limit is 25,600 KB, so the worst run is under 17% of it. The highest peak in any leg was 132,992 KB, against the 204,800 KB ceiling. Structure counters held in every leg (built=1, series=1, points=4000, markers=4).
Control: stale
96bbbb54, same gate, same box, same session:This matches the wave's 45,952 / 35,200 and runtime's 6 of 6 cold-pair failures.
B. Cold pairs, v0.44.0: peak RSS at 30 → 300 frames = growth (KB)
0 of 24 pairs went over 25,600 KB. All 48 processes exited 0 with empty stderr,
BIF-UI-OK, and the exact work counters.Full dynamics suite on v0.44.0 (CI order, same setup)
test_lint,test_smoke,test_lab,test_orbit_hist,test_bifurcation,test_orbit_oracle,test_orbit_mouse(16 checks, all three planted faults caught) andtest_bif_mem: 8/8 PASS.Independent check: dynamics
mainCI on the v0.44.0 pin (run 37298446691, push,f20a0a5) is green. Its gate logged static growth 1,288 KB and toggle growth 2,016 KB.Environment note (not a #1623 issue)
On this 8-CPU box, running with all 8 CPUs visible makes any build abort with
eigenscript: out of memory (requested 80 bytes)under the gate'sulimit -v 1500000. That happens on v0.44.0 too, and the gate then reports rc=134 FAIL. With 7 or fewer CPUs it runs. The likely cause is per-thread address-space reservation in the software renderer. Runtime's runs and this one were pinned to 4 CPUs, the same as a GitHub runner. This is a dynamics gate portability caveat and doesn't affect this verdict.Verdict
PASS. On a candidate containing #1629, the unchanged dynamics memory gate passes 8 of 8 runs, middle endpoint and toggle arm included. All 24 cold pairs (static and toggle, default and forced-VM) are at least 5× under the 25,600 KB flatness limit. The stale
96bbbb54still fails on the same box. The full dynamics suite passes. Closing as fixed by #1629 (45a71e1d, shipped in v0.44.0).