Repository navigation
Rework CI floor allocation: bound concurrency to the live container cgroup memory limit, retire the static per_shard scalar - #5877
Merged
Conversation
Replace the stale-per_shard → silent-OOM path with a construction wall: spawn_width = min(cpu_bound, confirmed_safe_width) where confirmed_safe_width=2 is a committed integer reflecting the largest concurrency confirmed to fit within the runner cap (VmHWM=6.0 GiB at width=2 on an 8 GiB runner). The old formula (floor(budget / per_shard_committed)) was the failure mode: per_shard_committed drifted low (2.1 GiB at real 3.0 GiB) → formula picked width=3 → 3 × 3.0 = 9 GiB > 8 GiB cap → exit-137 (three recurrences). The new formula: if budget <= 0: conservative_fallback (unchanged) if budget < per_shard_committed: width=1 (single-shard guard) else: min(cpu_bound, confirmed_safe_width) per_shard_committed is now vestigial in the width path — its role reduced to the width=1 guard (budget too small for even one shard) and the ResourceEnvelope memory estimate. The Disposition on gunbc_ci_floor_per_shard_rss_source is updated to mark this explicitly. confirmed_safe_width is a Scaffold dissolving to resource-aware-scheduler Node B/C (docs/plans/resource-aware-scheduler.md) when Runnable.cost.space replaces it. It is NOT container-scaling (confirmed_safe=2 on a 16 GiB box still gives width=2 — that's honest; wider requires a confirmed larger run). Witnesses: - witness_floor_confirmed_safe_width_bounds_actual_width: cap budget → width ≤ 2 - witness_floor_ceiling_clamps_stale_per_shard: stale 2.1 GiB raw=3 > safe, capped=2 ≤ safe - witness_per_shard_fits_within_confirmed_safe_shards: 3 GiB × 2 ≤ 8 GiB cap Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…art a line) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
Re:
In other words: one witness tests the implementation; the other tests the mathematical invariant the implementation is supposed to maintain. That said, the inline clamp duplicates some logic and your point that the second witness could pass while the function is broken stands. Will tighten in a follow-up once CI is green. — sent from sharp-cat-505 |
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Jun 28, 2026
Drop the abandoned v1_interpreter.rs bulk-eviction (PR #5886 closed: sustained-RSS only, did not move the per-shard resolve peak). Record the Lever C design outcome in the plan .dag authority + regenerate the .md projection (main_wet): - §2 finding (floor consumes the resolved Node tree, not type_env/func_env; teeth-proven) and extend-not-fork (aligns to v2 ResolvedTree/InferredTree, no new type); - the v2-surviving root is a frontier-bounded RETENTION POLICY over InferredTree.facts (OWED at v2 00_compile, which holds it whole today); - A3-default conditional with an explicit flip-to-A1 trigger (implement v1 frontier-evict only if a residual per-shard peak survives over cap after the cheaper fixes — alloc-clamp #5877 landed + Rc-shared sigs #5884 pending). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
briansrls
pushed a commit
that referenced
this pull request
Jun 28, 2026
…und; A3-default + flip trigger) (#5892) * WIP: Lever C: stream/evict resolved-module envs (representation-minimization * WIP: Lever C: stream/evict resolved-module envs (representation-minimization * Lever C: evict resolved-module envs the interpreter never reads Project each TypedModule into a fresh one keeping module/items/item_registry but pointing type_env/func_env at shared empty singletons, so the floor path releases the never-read envs once the source ResolvedGraph drops. Remove probe scaffold; untrack scratchpad. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * WIP: Lever C: stream/evict resolved-module envs (representation-minimization * WIP: Lever C: stream/evict resolved-module envs (representation-minimization * Restore clean #5886 (revert teeth perturbation; items/item_registry kept, only envs evicted) The teeth perturbation (items emptied) was auto-committed/pushed; it served its purpose as the discriminating control (rust_tests RED with items evicted vs GREEN with only type_env/func_env evicted), proving the reflection path consumes items/item_registry. Restoring the intended change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * WIP: Lever C: stream/evict resolved-module envs (representation-minimization * Lever C (item 2): record design-note disposition in the plan authority Drop the abandoned v1_interpreter.rs bulk-eviction (PR #5886 closed: sustained-RSS only, did not move the per-shard resolve peak). Record the Lever C design outcome in the plan .dag authority + regenerate the .md projection (main_wet): - §2 finding (floor consumes the resolved Node tree, not type_env/func_env; teeth-proven) and extend-not-fork (aligns to v2 ResolvedTree/InferredTree, no new type); - the v2-surviving root is a frontier-bounded RETENTION POLICY over InferredTree.facts (OWED at v2 00_compile, which holds it whole today); - A3-default conditional with an explicit flip-to-A1 trigger (implement v1 frontier-evict only if a residual per-shard peak survives over cap after the cheaper fixes — alloc-clamp #5877 landed + Rc-shared sigs #5884 pending). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Lever C: record RESOLVED A3 verdict in the plan note (measured, not data-gated) Official call (manager stern-moth-225): A3, robust. Post-#5873-cutover floor measurement (claim_executor per-shard VmHWM × spawn_width=2, sccache excluded): co-resident 5.98 GiB, 1.82 GiB UNDER the ~7.8 GiB safety threshold below the 8 GiB host cap, +0.7% vs the 5.94 GiB pre-cutover baseline (noise). The cheaper fixes already hold the floor under cap; frontier-evict is NOT written into the doomed v1 seed — the ~4 GiB prize is captured durably in v2 streaming-infer. Flip-to-A1 trigger kept documented but marked UN-tripped (re-auditable if the corpus grows). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the stale-per_shard → silent-OOM failure mode (3 recurrences: #5867 context, #5875 refresh).
Root cause:
spawn_width = min(shard_count, hw_threads, floor(budget / per_shard_committed)). The budget term already reads the live cgroup memory.max. Butper_shard_committed(a static ByteSize scalar) drifts low as the corpus grows — the last staleness was 2.1 GiB at real 3.0 GiB, giving width=3, 3×3.0=9 GiB > 8 GiB cap → exit-137.Construction wall: Replace the
floor(budget / per_shard_committed)term with an honest 3-case formula:budget ≤ 0→ conservative fallback width (unchanged)budget < per_shard_committed→ width=1 (single-shard guard: budget too small for even one shard)min(cpu_bound, confirmed_safe_width)gunbc_ci_floor_confirmed_safe_width = 2is a new committed integer: the largest concurrency confirmed safe (VmHWM=6.0 GiB at width=2 with 8 GiB runner cap, 2 GiB headroom, main HEAD 6461042). Staleper_shard_committedcan no longer raise width beyond this ceiling — the failure mode is structurally closed.Honest labeling: This is NOT container-scaling.
confirmed_safe=2on a 16 GiB box still gives width=2 (conservative but correct). Width scales up only when a larger confirmed run updates the integer. The proper scaling path is resource-aware-scheduler Node B/C (docs/plans/resource-aware-scheduler.md) whereRunnable.cost.spacereplaces this scaffold.per_shard_committed role: Vestigial in the width formula (width=1 guard + ResourceEnvelope memory estimate). Marked in
gunbc_ci_floor_per_shard_rss_sourceDisposition.confirmed_safe_widthis a Scaffold dissolving tostd.realization_schedule.Runnablewhen Node B/C lands.Residual risk (documented, not fixed here):
per_shard_committedis not fully inert — it still drives case 2 (single-shard guard). Both scalars can therefore go stale: if a single shard's real peak exceeds the runner cap whileper_shard_committedlags low, case 2 won't fire ANDconfirmed_safe_width=2still permits width=2 → latent OOM. This is the same staleness class one level up. The dissolution trigger (resource-aware-scheduler Node B/C, live per-shard measurement) covers both. The[calibration]hygiene line must be checked against BOTH scalars when staleness is suspected, not justconfirmed_safe_width.Changed files
dsl/gunbc/ci_floor_measurement.dag— addgunbc_ci_floor_confirmed_safe_width: Int = 2+ Scaffold disposition; update per_shard source disposition to mark it vestigial in width pathsrc/v2/workflow/ci_floor_plan.dag— replacegunbc_ci_floor_spawn_width_for_budgetwith 3-case formula; simplifygunbc_ci_floor_run_envelopetoparallel_run_demand_envelope(width, committed_per_shard); add 2 new witnessessrc/v2/test/claim/ci_floor_plan_witness_test.dag— import + call new witnesses in newtest fn ci_floor_confirmed_safe_width_ceiling_witnessesdsl/test/claim/ci_floor_measurement_per_shard_test.dag— importconfirmed_safe_width; addwitness_confirmed_safe_width_is_positive_and_small+witness_per_shard_fits_within_confirmed_safe_shardsTest plan
cargo test --workspace(no Rust changes; floor witness correctness proven below)witness_floor_confirmed_safe_width_bounds_actual_width: 8 GiB budget → width=2 ≤ confirmed_safe=2 ✓witness_floor_ceiling_clamps_stale_per_shard: stale 2.1 GiB → raw_width=3 > safe=2; capped=min(3,2)=2 ≤ safe=2 ✓witness_per_shard_fits_within_confirmed_safe_shards: 3226056704 × 2 = 6452113408 ≤ 8589934592 ✓🤖 Generated with Claude Code