Skip to content

srv1 over-commit: runner width and conservation verdict now charge srv1 the same; srv1-13 stays committed - #12339

Merged
briansrls merged 10 commits into
mainfrom
session/zesty-moth-868
Sep 27, 2026
Merged

briansrls merged 10 commits into
mainfrom
session/zesty-moth-868

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

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:

  1. Served slices. The width envelope (gunbc.runner_slot_allocation envelope_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_budget host_allocation_verdict, reached through gunbc.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.
  2. Shakedown slot. Width reserved the microVM shakedown slot at its real gunbc_microvm_shakedown_slot_charge (28 GiB slot + 16 + 8 GiB controller slice = 52 GiB). The verdict charged slots × 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

  • The served-deployment claim is the sixth subtraction in the envelope (envelope_after_control_plane), with its own refusal arm when the allowance is unmeasured.
  • A new 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 plus gunbc_microvm_shakedown_slot_charge; elsewhere it is unchanged. ci_runner_placement passes 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 it

Labelled runs of test.claim.host_allocation_conservation, same local gunbc:

  • origin/main 7f4c23f: green, but committed_width_fits_on_every_host_with_an_established_charge is red (the over-commit itself).
  • served-slice fix only (44526a8): red. At width 11 + 1 = 12, 12 × 26 = 312 GiB still conserves (≈ 498.4 GiB), because the shakedown slot was undercharged, so "one more slot than memory admits" was not refused.
  • this head (both charges agree): green. 12 slots now charge 11 × 26 + 52 = 338 GiB, which is ≈ 524 GiB > 502.24 GiB, so it refuses. 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_allocation host_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.sudoers shows 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 returns false; at this head it returns true.

Two provisioning witnesses encoded the bug and are corrected: only_the_fabric_hosts_lose_provisioning_targets read "srv1 loses nothing, fabric count 0", which held only while srv1-13 was outside the width; and an_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-local derived_width_with_charge, which has neither a served term nor the shakedown charge. It now compares against the production host_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_class pins 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_axes is removed; that test already asserts committed == memory-admitted. The old 15 was stale.

Evidence (local gunbc built from 212206e; later commits change .dag and 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:

  • Newly green here: saturation_refuses_rather_than_reporting_the_ceiling, srv1_shakedown_slot_is_committed_by_identity_above_the_fleet_range, and the two corrected provisioning rows.
  • No new reds.
  • Pre-existing reds, identical at 175c6ae and unrelated to srv1's width: 5 in 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 in runner_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.
  • CI on 175c6ae failed only at the generated-artifact check (the sudoers file), so it never ran the witnesses. This head carries the regenerated file.

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

Brian Searls and others added 2 commits September 26, 2026 05:31
…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>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 26, 2026 08:59
Brian Searls and others added 4 commits September 26, 2026 09:00
…ize; witnesses read the one runner charge

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title Runner envelope subtracts the served-deployment slices the conservation verdict charges (srv1 over-commit root cause) srv1 over-commit: runner width and conservation verdict now charge srv1 the same (served slices + shakedown slot) Sep 26, 2026
gunbai-bot Bot and others added 3 commits September 26, 2026 11:13
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>
@gunbai-bot gunbai-bot Bot changed the title srv1 over-commit: runner width and conservation verdict now charge srv1 the same (served slices + shakedown slot) srv1 over-commit: runner width and conservation verdict now charge srv1 the same; srv1-13 stays committed Sep 26, 2026
@briansrls
briansrls added this pull request to the merge queue Sep 27, 2026
Merged via the queue into main with commit 96e6331 Sep 27, 2026
5 checks passed
@briansrls
briansrls deleted the session/zesty-moth-868 branch September 27, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant