Repository navigation
srv1 over-commit: runner width and conservation verdict now charge srv1 the same; srv1-13 stays committed - #12339
Merged
Merged
Conversation
…on verdict charges Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…licate literal Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ize; witnesses read the one runner charge Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ledger-Repair-Judged: docs/design-rung-drops.md Heal-Candidate-Run: 36234386395
… saturation witness reads the production width; regenerate srv1 sudoers Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 26, 2026
briansrls
added this pull request to the merge queue
Sep 27, 2026
This was referenced Sep 27, 2026
Closed
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.
Root cause of srv1 being refused as OVER-COMMITTED on main (found in #12335). One defect: srv1's runner width and the conservation verdict charged srv1 differently. After this PR both charges agree.
The chain (DESIGN §6b)
Two derivations charge srv1's usable RAM (502.24 GiB, measured MemTotal), and they disagreed in two places:
gunbc.runner_slot_allocationenvelope_final) subtracted overhead (16 GiB), sessions (52 GiB), control plane (0) and the oomd floor (31.39 GiB), but not the served-deployment slices. The verdict (gunbc.fleet_host_budgethost_allocation_verdict, reached throughgunbc.ci_runner_placement) charges them (gunbc.live_deploy.served_slice_charge, since Approval broker: own serve module, unit and slice, extracted from roadmap_serve (cutover stages 1-2) #11667). So width sized the runner pool into memory the verdict had already given away.gunbc_microvm_shakedown_slot_charge(28 GiB slot + 16 + 8 GiB controller slice = 52 GiB). The verdict chargedslots × 26 GiB, counting it as one ordinary slot. That undercharged by 26 GiB, in the direction that hides demand.History: #11716 (cores_per_slot = 1) made memory the binding axis. #12015 (served 32 → 50 GiB) tipped srv1 over: 14 × 26 + 52 + 50 + 16 + 31.39 ≈ 513 GiB > 502.24 GiB. #12328 (served → 87 GiB: roadmap 53, broker 10, repository convergence 24) put it further over. The model was wrong, not the fleet.
Fix: both charges now agree
envelope_after_control_plane), with its own refusal arm when the allowance is unmeasured.host_runner_pool_charge(gunbc.runner_slot_allocation) is the one answer to "what do this host's committed runners cost its budget". On the shakedown host it is (slots − 1) fleet slots plusgunbc_microvm_shakedown_slot_charge; elsewhere it is unchanged.ci_runner_placementpasses it to the verdict, and the conservation witness helpers read it too, instead of re-multiplying slots × 26 GiB.At the head: srv1 width is 11 (main derives 14). The verdict charges 10 × 26 + 52 + 87 + 16 + 31.39 ≈ 498.4 GiB ≤ 502.24 GiB, so srv1 derives, with under 4 GiB spare. The next served-slice or session raise will refuse srv1 again, and that is the model's honest answer.
one_more_slot_than_memory_admits_refuses_on_every_host: red without the shakedown charge, green with itLabelled runs of
test.claim.host_allocation_conservation, same local gunbc:committed_width_fits_on_every_host_with_an_established_chargeis red (the over-commit itself).committed_width_fits...is green too.srv1-13 stays committed (operator ruling via the parent session, 2026-09-26)
With the width at 11, membership enumerated
1..width, so the #12011 microVM shakedown slot srv1-13 fell outside the committed population, although the width had already charged it first. It is now a committed member by its authored identity. srv1's population is fleet slots 1..10 plus srv1-13 (gunbc.runner_slot_allocationhost_committed_identities_at/host_fleet_slot_indices). The fleet range skips index 13, so a width ≥ 14 cannot name it twice. Every enumerator now reads that one answer: slot membership, provisioning (desired_runner_slot_members), the Actions units (runner_instance_names), and the microVM network rosters (converge and apply). No live state is renamed: the unit, cell slice and allocation-store key stay srv1-13.Operator heads-up: at the next converge, Actions runners srv1-11, srv1-12 and srv1-14 retire. On main srv1 ran srv1-01..12 and srv1-14 as Actions runners plus srv1-13; after this it runs srv1-01..10 plus srv1-13. The regenerated
provisioning/srv1/gunbc-ghrunner.sudoersshows exactly that: 9 grant lines removed, all for srv1-11/12/14, with the srv1-13 fabric-cell grants untouched. It supersedes the CI auto-heal regeneration (33710d2), which was taken at the previous head, before srv1-13 was kept.New witness
srv1_shakedown_slot_is_committed_by_identity_above_the_fleet_range: srv1-13 is a committed fabric member, width−1 is a committed Actions slot, and width is not a member. Control: at 175c6ae (membership 1..width) the same witness returnsfalse; at this head it returnstrue.Two provisioning witnesses encoded the bug and are corrected:
only_the_fabric_hosts_lose_provisioning_targetsread "srv1 loses nothing, fabric count 0", which held only while srv1-13 was outside the width; andan_observed_host_plans_the_missing_slots. srv1 now gives up one slot to its shakedown member.Saturation witness (was red on main)
saturation_refuses_rather_than_reporting_the_ceiling's roomy arm compared the conservation search against the test-localderived_width_with_charge, which has neither a served term nor the shakedown charge. It now compares against the productionhost_memory_admitted_width, which is exactly the "width and verdict agree" property. Red at 175c6ae, green at this head.New witnesses
the_shakedown_host_runner_charge_carries_the_shakedown_slot_at_its_real_size(slot allocation): on srv1 the charge is the shakedown charge plus fleet slots, strictly above the old product; srv3 is unchanged; 0 slots charge 0. The widths are supplied, so the row does not move with the live width.the_shakedown_charge_separates_conserves_from_oversubscribed(conservation, at the verdict interface with every term supplied): on a 485 GiB host shaped like srv1, the old charge conserves and the real charge is refused.srv1_derives_with_the_shakedown_slot_charged_at_its_real_size(placement): the live plan derives srv1 at its derived width. This is the inhabitance claim on the real path. Limit, stated honestly: srv1 conserves under both charges today, so deleting the placement wiring would not turn this row red.one_more_slot...and the supplied-value control above are what discriminate.The srv1 pin (DESIGN §5: oracle, not a change detector)
runner_slot_allocation_memory_admissions_differ_by_host_classpins srv1 at 11. Its comment derives that value by hand from cited input rows, independently of the fold. It went red once already, on merging main (#12328: 12 → 11), which is the alarm it exists to raise. The duplicate srv1 literal in..._committed_widths_are_the_minimum_over_axesis removed; that test already asserts committed == memory-admitted. The old 15 was stale.Evidence (local gunbc built from 212206e; later commits change
.dagand the regenerated sudoers only)All 19 witness files that reach the touched paths were run at this tree and at 175c6ae (the file list: tests referencing membership, provisioning, runner units, microVM network rosters, placement, runner charge or width). Results:
saturation_refuses_rather_than_reporting_the_ceiling,srv1_shakedown_slot_is_committed_by_identity_above_the_fleet_range, and the two corrected provisioning rows.fabric_cell_converge_witness_test(srv3/srv4 family),witness_population_tracks_the_slot_roster,the_production_shaped_srv1_observation_splits_on_the_scope_alone,srv4_sccache_prereq_pins_version_and_digest, 2 inrunner_service_activation_witness_test,the_fabric_members_are_authored_identities_not_a_top_index_rule,a_retired_incarnation_is_owned_and_plans_removal. The parent session is routing these.Consequence (reported to the parent session, not actuated)
srv1's derived runner width drops 14 → 11 (Actions 1..10 + srv1-13). At the next converge, Actions srv1-11, srv1-12 and srv1-14 retire. No live host was touched by this PR.
🤖 Generated with Claude Code