Skip to content

Required CI: withdraw the four v1-judged lanes; the gate is emit-build alone (operator ruling 2026-10-09) - #13658

Merged
gunbai-bot[bot] merged 13 commits into
integration/v1-closeoutfrom
session/smart-gull-336
Oct 10, 2026
Merged

gunbai-bot[bot] merged 13 commits into
integration/v1-closeoutfrom
session/smart-gull-336

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

The ruling this carries

Operator, 2026-10-09 (the brief to this session, the v2 half of the v1 withdrawal; neat-wolf-604 holds the v1 half): "v1 is effectively bankrupt due to memory instability - i want to go back to pure v2 native compiler development - that means deleting most of our current CI jobs", and "i suggest we bankrupt the current CI first".

This is the bankruptcy. It is a replacement migration cut at the root (DESIGN §3): the lanes are deleted, not retuned, because a v1 lane made survivable is investment in the implementation the ruling retires.

What changes

gunbc.compiler_gate_workflow (→ .github/workflows/witnesses.yml) goes from five lanes to one.

deleted job what it judged through
floor the rostered witnesses (claim_executor --required-ci --required-lane witnesses) the v1 interpreter
generated stage0 mirrors (--required-lane build), registry drift + repair chain, clippy the seed's own Rust
rust-unit-tests cargo test -p v1-compiler --lib v1
seed the compiler pair built once for the three above —

Kept: the emit-and-build steps, as ONE required job named witnesses (second-round ruling: "collapse emit-build plus the aggregate into one required job named witnesses"). The seed emits v2.compiler.compile and v2.cli.compile_cli, cargo builds the emitted crates, the built binaries are started against their controls (gunbc.emitted_subject_build_gate). The job carries the id the ruleset requires, so its own check is the required context: the aggregate job and the whole derived lane roster (CompilerGateLaneRow, standings, the env block and shell conditionals folded from them) are deleted — with one job there is nothing to join. A second required job is a roster growth the operator signs off, and brings the fold back with it. Fork pull requests now carry no witnesses check (the job is fleet-guarded) rather than the excused green the aggregate printed.

Fresh emission and build, every run (same ruling: "requires fresh emission/build of both retained products and refuses a restored final-product hit. Ordinary Cargo reuse may remain"). The native product store's steps — job-private root, the two WIF federations, the save — left the job, and every subject step passes GUNBC_NATIVE_PRODUCT_REUSE=fresh (gunbc.emitted_subject_build_gate native_product_reuse_env_name/_fresh_value, pinned to the runner's constants by the witness). Under fresh the runner (native_lane_runner prepare_emitted_compiler_for_entry) consults no store, commits nothing, refuses a run that also binds GUNBC_NATIVE_CACHE_ROOT (NativeProductReuseRefused — a contradiction, not a miss), and prints one FRESH PRODUCT RECEIPT line per product: realization=fresh, the product key's six axes (source closure, producer compiler, target, toolchain, build configuration, lens contract), the emitted closure identity, the seed executable's sha256 and the built executable's sha256. Cargo's own dependency reuse inside the job's checkout is untouched. The job's permissions carry no id_token.

Ordinary Cargo reuse, bound (the "may remain" half of the ruling). The isolation step wipes $RUNNER_TEMP/cargo on every run, so the seed build was fully cold: 3m38s on run 37976254311 for registry download plus 113 crates. The already-modelled gunbc.fleet_workflow_steps ci_cache_cargo_step (actions/cache v5.1.0, admitted; paths = the isolated home's registry index/cache/git db plus target/, key = cargo-ci-<os>-<arch>-hashFiles(**/Cargo.lock, rust-toolchain.toml)) sat on the deleted seed job behind a keyed-miss condition; it is now ci_cache_cargo_step_under(condition) and the witnesses job binds it unconditionally after the isolation step. It caches the SEED's build and dependencies only — the two products are built in a private probe root the cache never sees, and the gate witness asserts no store marker reaches the job. What it recovers is measured by the first two runs (each runner slot has its own $RUNNER_TEMP path, so Cargo fingerprints keyed on absolute paths may rebuild across slots); nothing here asserts a number. Levels the ruling closes: no cache of the emission (the interpreter's 21 min, 57% of a PR run — that is the later materialization ruling) and no sccache on the product-crate builds (a served rustc output is a restored product compile under another name). The 6 min the old key derivation + store transfer cost per run is deleted outright under fresh, not cached.

One declared drop, gunbc.rung_drop v1_required_lanes_withdrawn (§4b(3)), with its population stated member by member — the witnesses, the stage0 mirrors and every registry-rostered generated artifact (witnesses.yml and DESIGN.md included), the lint, the v1 unit tests, module resolution outside the two emitted closures, and the downstream consumers (no merge-queue compiler-pair candidate; fleet admission under a new epoch). Its trigger names the capability: a binary built from an emission of v2 judging that population on the required path, member by member. What does not retire it is stated: returning any v1 lane, a partial native row, a run off the required path, a count where an identity join belongs.

gunbc.rung_drop rust_unit_tests_off_pull_requests → Superseded (its text said the unit lane still blocks at the queue; it runs nowhere now; trigger did not fire; loss holder is the new row). No other drop is amended: required_gate_bankruptcy, witness_floor_off_the_required_gate, required_lanes_do_not_resolve_product_layer_modules, v1_integration_tests_deleted_from_the_unit_lane name capabilities a native lane can still fire.

gunbc.required_ci_contract_epoch → 2026-10-09.1. The name witnesses now carries a materially different contract (what a success entitles a consumer to conclude), which is exactly the case that module says to bump for; gunbc.fleet_revision_acceptance therefore cannot admit a revision judged under the old contract as the new one or vice versa.

Consumers repaired rather than left dangling:

  • gunbc.required_lane_resolution_census_live: the floor/generated rows left with their jobs; the census now does not hold by design and is the instrument that re-derives the drop's module population (gunbc test //gunbc/instruments:required-lane-resolution-census).
  • gunbc.documentary_refs: DESIGN §3's typed "inside the required gate" reference repointed from v2.workflow.required_floor required_gate_prefixes (the deleted floor's roster) to gunbc.emitted_subject_build_gate emitted_subject_build_rows.
  • gunbc.design_document Building & checks: the local-checks row (clippy and the v1 unit tests are now local-only), the hook row, and the CI row (what a green required context does and does not say).
  • gunbc.contributor_onboarding_path run-witnesses: the floor is no longer "the corpus lane the merge gate runs".
  • Five gunbc.recurring_failure_mode rows cited deleted declarations as typed evidence; each now cites the surviving authority (required_floor_runs_at_its_memory_ceiling also records that its lane was deleted rather than given headroom, and that the class outlives the lane: emit-build runs in the same slot class and nothing adjudicates its peak either).
  • gunbc.runner_slot_allocation gunbc_runner_slot_allocation_wall_holds: the wall's three floor conjuncts (MemoryHigh ≥ the floor's minimum viable budget and ≥ its measured uncensored peak, guarded by the uncensored check) are withdrawn with the floor — they related the slot to a tenant that no longer runs in it — and its swap conjunct is inverted by the ruling (it required MemorySwapMax above MemoryMax; it now requires exactly zero). The slot's demand oracle from here is the first cold required run's MEMORY RECEIPT, a declared frontier in the wall's note. gunbc.rung_drop slot_row_pinned_below_demonstrated_demand_unrefused (the drop about that conjunct's blind spot) is Superseded under the same ruling with v1_required_lanes_withdrawn as its loss holder. test.claim.runner.runner_slot_allocation_witness_test re-pins the row to 22/21/0 by the 2026-10-09 ruling, deletes the dead-tenant claim (the floor's own relation lives in floor_demand_witness_test), and re-pins its two width alarms to the derivation's answers under the smaller slot (srv1 11 → 12, srv3/srv4 17 → 21 — the same growth the regenerated sudoers show).
  • test.claim.compiler_gate_emit_build_lane_witness_test / compiler_gate_workflow_witness_test: claims over the deleted jobs removed; the blocking set is asserted as exactly emit-build at identity grain; a new RED asserts the four withdrawn variables (RUST_UNIT_TESTS, SEED, FLOOR, GENERATED) reach neither gate surface, so a partial revert of this cut reds.
  • Regenerated projections (one main_wet over the merged tree, fixed point verified by main): witnesses.yml (the envelope requirement on both subject steps — the bind input withheld by the declared drop — and the envelope lines in the notice), DESIGN.md, docs/design-rung-drops.md, docs/onboarding.md, .gitattributes (the deleted heal-publish path leaves the generated-artifact merge list), .github/workflows/fleet-converge.yml (the closeout's authority fix projected), tools/fabric_ci_fci1_bounded_execution_context.env (the fci1 context follows the slot: 22/21 GiB), and provisioning/srv{1,3,4}/gunbc-ghrunner.sudoers — a consequence worth reading: a 22 GiB slot fits more slots per host than a 26 GiB one, so the derived slot rosters grow (srv1 gains srv1-10/srv1-11); these are desired-state projections, and applying them to hosts is the converge effect the post-landing conditions already name.

The memory envelope is part of the verdict (the relayed REQUEST_CHANGES on #13641: "MemorySwapMax=0 and a fixed hard memory maximum; a lower compiler abort/trip threshold; a peak and swap receipt; no larger-runner retry"). Three layers, each modelled, and one of them a declared drop after the first required run that asked for it:

  1. The fleet slot — gunbc.runner_slot_desired goes 26/25 GiB + 32 GiB swap → MemoryMax 22 GiB, MemoryHigh 21 GiB, MemorySwapMax 0 (the desired state; applying it to hosts is a converge/manual effect, not this PR's).
  2. The envelope requirement on every subject step — each step passes GUNBC_MEMORY_ENVELOPE_REQUIRED=slot (gunbc.emitted_subject_build_gate native_step_memory_envelope_env_name / _slot_value): gunbc test refuses a run that no cgroup memory.max binds (MemoryEnvelopeAbsent), reads the bounding cgroup before the producer, and at exit prints MEMORY RECEIPT grain=slot cgroup=… limit_max=… peak_bytes=… high_events_delta=… max_events_delta=… oom_kills_delta=… swap_current_bytes=… — the event counters as the difference over the step, because the slot's cgroup outlives it — and refuses the run on any OOM kill the step added, any swap charged, or an unreadable swap counter, even over a producer that held. "No thrashing, ever" is therefore enforced on every required run at the slot's grain, today, before the host converge.
  3. The per-step trip — modelled, derived, and waiting on a fleet fact. native_step_memory_trip is a ByteSize DERIVED from the slot's MemoryHigh less a declared one-GiB headroom (the_trip_sits_inside_the_slot_envelope executes the derivation; its mutation control is receipted below), and gunbc test binds it as the step's own cgroup through GUNBC_BIND_MEMORY_CGROUP_BYTES (the governor's existing bind). The first required run that passed it (38002497388, head a4b8f788) refused in four seconds: MemoryCgroupBindRefused — the cgroup2 tree is not writable. Two host facts: memory_governor apply_memory_cgroup_bind creates its leaf at the cgroup root (a container-root design; the bind had never been requested on the fleet — main's witnesses.yml never carried it), and a fleet job runs as the setpriv'd job user under a root unit. Nothing fell, so this is not a rung drop (an earlier revision of this head declared one; review of that revision called it a §4b(2) stall wearing the §4b(3) carrier, correctly). It is a fleet fact, gunbc.runner_slot_desired gunbc_runner_slot_job_cgroup_ownership = JobOwnsNoBoundedCgroup, which native_step_memory_inputs(ownership) consumes: a job that owns no bounded cgroup is handed the slot requirement alone; a job that does is handed the requirement and the bind at the trip. The climb is rostered as gunbc.guarantee_stall native_step_trip_awaits_fleet_job_cgroup_stall (current Mitigatable, ceiling MechanicallyPreventable, grounding: unit delegation with DelegateSubgroup=, a per-job cgroup staged at the trip by the root JIT wrapper, the governor's already-bound arm; trigger: a required step observed inside a bounded cgroup at the trip on each host class). Flipping the fact when the fleet earns it returns the bind to every subject step with no other edit; a claim exercises both arms by supplied value, the live claim reads the live row and asserts the bind KEY is absent, and the failure notice is a function of the same fact. Escalated to the operator as the fork it is (host-first vs. slot-grain now); this is the approved arm.

The decision is a .dag fold, the Rust its mirror. gunbc.memory_envelope owns the requirement (EnvelopeNotRequested | EnvelopeSlotRequired | EnvelopeRequirementUnreadable), the grain, memory_envelope_decision(bind, requirement, numeric_max_binds) and memory_envelope_verdict(oom_kills_delta, swap_current, swap_peak_rose) over supplied inputs — the sibling of gunbc.memory_cgroup_binding — and test.claim.memory_envelope_witness_test reaches every arm by supplied value, including the RED the first revision of this head could not reach: a slot requirement over a process no numeric memory.max binds REFUSES (MemoryEnvelopeAbsent) instead of running as bounded. The seed's memory_envelope_decision / memory_envelope_violated mirror it arm for arm with unit tests; the shells resolve the bounding cgroup through the governor's binding_cap_cgroup_dir walk (which reads max as unset — never the peak locator), read memory.swap.max / .current / .peak (modeled as extdeps.linux.cgroup_v2_memory MemorySwapMax / MemorySwapPeak) before and after the producer, and label the peak by whether it rose during the step. The slot's memory.swap.max is reported, not required: the ruling's MemorySwapMax=0 is the converge that follows this landing, and until then a step that swaps is refused by observation (resident at exit, or a swap peak that rose) — and a swap peak the kernel cannot show under a cgroup whose memory.swap.max is not zero is a violation too, never read as "did not rise" (RED_an_unobservable_swap_peak_refuses_unless_the_swap_limit_is_zero, in both the .dag witness and the Rust tests).

The seed growth (the mirror rows and the host-reading shells in target_invocation_host.rs and floor_memory_supervisor.rs) is admitted under the v1 PURPOSE test and receipted as gunbc.memory_envelope_receipt_seed_growth (lane v1-hand-queue-drain; trigger: the retained CLI evaluating the .dag fold directly, and the native door receiving the cgroup readings as values) — the row review 78391 asked for.

heal-publish deleted (same ruling: "no no-op job left running on every PR"): .github/workflows/heal-publish.yml, gunbc.heal_publisher_workflow, its registry variant (every exhaustive match fixed forward) and its witness file are gone; gunbc.auth.heal_publisher_federation keeps the pool's model with the workflow path as a retired literal — the pool is dead, not deleted, recorded as an external-estate obligation. heal.yml (manual) stays. Review 78398's finding — the manual route still seals and uploads the candidate the deleted publisher consumed, so "nothing sealed one" is false for it — is right, and is answered off this head (the operator approved exactly 75bd66f0 for the fold): the freeze-and-declare commit (the route a named frozen member of v1_required_lanes_withdrawn's population; header, drop wording and DESIGN CI row aligned; regen/verify re-run green) is on followups/smart-gull-336, with the latent-red repairs the same ruling routes to runtime tasks, for a post-fold PR.

Base is integration/v1-closeout (neat-wolf-604 folds this head; #13641 is the only closeout PR into main), and this branch carries a merge of that branch so the diff is clean against it; the gate authority took this side (the #13346 slice-cost step stays a local-only command, per ruling). This PR's own green run is therefore a workflow_dispatch of witnesses.yml on this branch, not a pull_request run.

What the required context establishes from here

Green means: the seed emitted both retained v2 closures, both emitted crates built, and the built binaries passed their controls. Nothing else. No witness is evaluated, no module outside those two closures is resolved, no generated artifact is compared with its authority — this PR's own regen included, which is why its drift verify was run locally and is receipted below.

A verdict joins this gate as a row of emitted_subject_build_rows judged by a binary built from the seed's emission (the green set + one frontier target from the operator's plan), never as a lane that hands the corpus to the v1 interpreter.

Sizing, by instrument

The producer is the witnesses job of any run of this workflow (named emit-build before this change). Receipt from the last green merge-queue run before this change, 37939840454 (gh run view 37939840454 --json jobs): emit-build 57 min wall (seed build 4 min, self-host 27 min, v2-native-cli 23 min, product save 2.5 min). The deleted lanes on that run: seed 5 min → floor 50 min (the critical path), generated 15 min, rust-unit-tests 7 min. So the wall per landing is unchanged (emit-build was already the longest lane); what is removed is three fleet slots per run (~77 slot-minutes) and the one process that ran at its slot's memory.high (gunbc.recurring_failure_mode required_floor_runs_at_its_memory_ceiling).

Deliberately not in this PR

  • (superseded within this PR: the memory envelope IS carried here, per the second-round ruling — the slot model, the per-step trip, the receipt and the no-retry notice, described above. What stays outside the PR is the host effect: enforcing the slot on srv1/srv2 is a converge run, and the first cold required run after the fold is what records the phase peaks.)
  • No new native lane and no frontier roster. The job roster stays closed to growth; the native green set / one-frontier-target job lands as rows of emitted_subject_build_rows once the operator's plan is agreed.
  • (superseded within this PR: heal-publish is deleted here, per the second-round ruling.)
  • PR Remove quadratic remainder copying from code-point/octet slicing in both realizations (skip/take/get/count to their contracts; Value drop no longer walks a shared slice; cost controls enrolled) #13346's repo_self_slice_cost_control_command step (a cargo test -p v1-stage0-runtime control on the generated lane, on neat-wolf-604's closeout branch) is not carried over: it is a v1 unit test and joins the withdrawn population's unit-test member. When the closeout branch takes this cut's side on the two files, that declaration is dangling and should be deleted there.

Evidence, third round (final head 75bd66f0: this branch + integration/v1-closeout d9368e89; seed built from this tree)

All on srv1 under systemd-run --user --scope -p MemorySwapMax=0 with a hard MemoryMax per run (28 GiB regen/verify, 18 GiB per witness).

  • Full chain on the merged tree with option B and the review's fixes (61523aa0+): regeneration tools.generated_artifact_gate main_wet 678 s exit 0, fixed-point verify main 690 s exit 0; 26 witness files — green: compiler_gate_emit_build_lane_witness_test 28/28, compiler_gate_workflow_witness_test 4/4, memory_envelope_witness_test 10/10, memory_cgroup_binding_witness_test 11/11, guarantee_stall_witness_test 11/11, action_use_admission 35/35, documentary_refs 4/4, rung_drop_{amendment,declaration,shared_capability,standing_partition,superseded_standing} 4/6/7/4/8, heal_candidate 12/12, floor_demand 29/29, floor_cold_build_receipt 8/8, ci_budget_tree 13/13, github_app_registry 54/54, gcp_estate_convergence_binding 4/4, gcp_iam_bootstrap 23/23, runner_group_restriction_ensure 10/10, runner_slot_enforcement_grounding 11/11, seed_growth_admission 9/9, seed_growth_change_population 7/7. Red: the two latent main reds (fci1_bounded_execution_context 1/2, heal_publication_boundary 11/34) and runner_slot_allocation_witness_test 28/34 — this PR's: the slot wall and its witness still asserted the 26/25 GiB row and the floor's demand against it; repaired as described under What changes (floor conjuncts withdrawn with the floor, swap required zero, the floor-fit drop superseded, the witness re-pinned).
  • Short chain on the final tree (75bd66f0's content): regeneration 677 s exit 0, verify 682 s exit 0; the eleven touched witnesses green — compiler_gate_emit_build_lane 28/28, runner_slot_allocation 33/33, memory_envelope 12/12, guarantee_stall 11/11, floor_demand 29/29, seed_growth_admission 9/9, runner_slot_enforcement_grounding 11/11, rung_drop_{declaration,standing_partition,superseded_standing} 6/4/8, documentary_refs 4/4.
  • Seed unit tests (cargo test -p v1-compiler --lib memory_envelope_tests, local): 9/9, including RED_a_slot_requirement_with_no_numeric_max_refuses_as_absent, RED_an_unobservable_swap_peak_refuses_unless_the_swap_limit_is_zero and RED_an_applied_or_existing_bind_over_no_numeric_max_refuses_at_its_grain; cargo clippy -p v1-compiler --bin gunbc -- -D warnings clean.
  • Required workflow on this head: witnesses.yml dispatched on 75bd66f0 — run id and the MEMORY RECEIPT lines are appended below when it completes (the previous head's run, 38002497388, is the four-second MemoryCgroupBindRefused this construction answers).

Required run on 75bd66f0: 38016653087 — green (witnesses job 02:21–02:57, 36 min; seed built with the Cargo cache warm; both subject steps fresh, both discriminating reds established since a dispatch runs the fault experiment). The slot-grain receipts, verbatim — note the slot is still the unconverged 26/25 GiB + 32 GiB-swap row, which the receipt says (limit_max, swap_max), and the step was refused on none of OOM, resident swap or a swap-peak rise:

gunbc test: MEMORY RECEIPT grain=slot cgroup=/sys/fs/cgroup/system.slice/system-actions\x2drunner.slice/actions-runner@srv3-14.service limit_max=27917287424 limit_high=26843545600 swap_max=34359738368 peak_bytes=17159725056 (peak: rose from 6402211840 during this step) high_events_delta=0 max_events_delta=0 oom_kills_delta=0 swap_current_bytes=0 swap_peak_delta=0
gunbc test: MEMORY RECEIPT grain=slot cgroup=/sys/fs/cgroup/system.slice/system-actions\x2drunner.slice/actions-runner@srv3-14.service limit_max=27917287424 limit_high=26843545600 swap_max=34359738368 peak_bytes=17208037376 (peak: rose from 17159725056 during this step) high_events_delta=0 max_events_delta=0 oom_kills_delta=0 swap_current_bytes=0 swap_peak_delta=0

The self-host step's peak rose from 6.4 GB to 17.2 GB inside the step and the CLI step added almost nothing above it — the first phase-peak numbers the ruling asked a cold run to record, at the slot grain; the per-step grain follows the fleet fact.

Evidence, second round (merged tree cf657e6e = this branch + integration/v1-closeout a9254527; seed 65bef5c9)

  • Local, container seed (65bef5c9), merged tree cf657e6e: test.claim.compiler_gate_emit_build_lane_witness_test 26/26 PASS (gunbc run --claim-run, 17.4 GB peak RSS). Mutation control over a scratch copy with native_step_memory_headroom = byte_size(0): 25 PASS / 1 FAIL, the one red being exactly the_trip_sits_inside_the_slot_envelope — the claim discriminates on the derivation it names and on nothing else.

Two files in that batch are red on pristine origin/main too, under the merged seed AND under an older seed (8653f654, main's tree) — latent reds no required lane ever executed, not this PR's: test.claim.fabric.fci1_bounded_execution_context_witness_test fci1_context_derives_the_runner_workload_envelope expects an envelope basis in gunbc.runner_slot_allocation while gunbc.fabric.fci1_bounded_execution_context declares it in gunbc.runner_slot_desired (a stale expectation); and test.claim.heal_publication_boundary_witness_test 23/34 red. Left for their owners; recorded here because this is the only place anything records them now.

The third latent red, test.claim.required_lane_claim_agreement_witness_test w_no_projected_ledger_denies_a_lane_the_roster_requires, is the lane-roster fork the one-job cut leaves standing: gunbc.witness_floor_lanes required_lanes_roster still rosters build/floor/… as required while gunbc.compiler_gate_workflow compiler_gate_merge_path_job_ids answers [witnesses], and twelve modules consume the old roster (the gate, the ruleset, the floor workflow, two drops, a failure-mode row, both v2 workflow modules). Cutting it is the required-lane-roster-after-the-one-job-cut runtime task the ruling names, not a fixture repair; it is recorded here so the fork is named rather than discovered. The other two latent reds (fci1, publication boundary) are repaired on followups/smart-gull-336.

Two reds in test.claim.floor.floor_demand_witness_test WERE this PR's (green on main): both joined the withdrawn floor's 2026-09-19 receipts to the live slot row (held ≤ memory_max, armed == memory_high), which the ruling moved. Repaired by carrying the envelope the receipts were taken under as the floor's own rows (gunbc.floor_demand gunbc_floor_pinned_memory_max/_high) and joining to those — the floor is frozen and runs in no slot, so a join to the live row would assert a relation between a dead instrument and a slot it never inhabited.

Evidence, first round (local, with the seed built from this tree)

Seed gunbc built from this tree (cargo build --release -p v1-compiler --bin gunbc, 113 crates compiled, gunbc --version = this base sha); every run below used that binary. Because nothing on the required path judges any of this any more, these are the receipts:

  • Regeneration: tools.generated_artifact_gate main_wet over the whole registry, exit 0; it rewrote witnesses.yml, DESIGN.md, docs/design-rung-drops.md and (after a second main_wet_one) docs/onboarding.md; every other rostered artifact came out byte-identical. The run's VmHWM was 15.8 GB against the 7.55 GiB that module's own note cites for 2026-08-31 — recorded here as a growth receipt, not acted on.
  • Drift verify at this head: tools.generated_artifact_gate main (the deleted lane's verify argv), exit 0.
  • Witness files, each run with gunbc run --claim-run --entry <file> on srv1 inside systemd-run --user --scope -p MemoryMax=20G -p MemorySwapMax=0 (the operator's envelope discipline — no swap, a kill is a receipt; none was killed):
    • test.claim.compiler_gate_workflow_witness_test 7/7
    • test.claim.compiler_gate_emit_build_lane_witness_test 38/38 (the control on pristine origin/main, same binary: 36/39 — see the next bullet)
    • test.claim.documentary_refs_witness_test 4/4 · rung_drop_superseded_standing_witness_test 8/8 · rung_drop_standing_partition_witness_test 4/4 · contributor_onboarding_path_witness_test 18/18 · fleet.fleet_revision_acceptance_witness_test 9/9 · contract_identity.required_ci_epoch_real_execution_witness_test 4/4 · required_lane_resolution_census_witness_test 8/8
    • test.claim.required_lane_claim_agreement_witness_test 4/5: w_no_projected_ledger_denies_a_lane_the_roster_requires is RED, and the control — the same file, same binary, on pristine origin/main (d0f2067) — is red on the same claim. Pre-existing, and its roster authority is itself stale: gunbc.witness_floor_lanes required_lanes_roster still names required-witnesses-build/-floor, lanes deleted long before this PR, while the failure-modes ledger quotes the negation phrase as an example (recurring_failure_mode stale_claim_survives_its_own_correct_edit) and names those lanes in nine rows, and the check conjoins the two at document grain. Not touched here; handed to the roadmap program as required-lane-roster-after-the-one-job-cut.
  • Three claims in that witness file were already red on origin/main (control run, same file, same binary, pristine main at d0f2067): the_lane_binds_one_step_per_subject_above_the_prelude asserted length(steps) == 6 + rows + 1, a count the lane outgrew when the native-product steps landed (main's emit-build job has 13 steps) — it is now an identity join on step names; the_established_lanes_still_block listed four lanes while seed had joined the blocking set on 2026-10-06; and w_RED_the_deleted_unit_test_lane_reaches_neither_surface asserted the absence of a lane that had returned. All three are green here because the roster they describe is now one row. That this file could sit red on main with the required context green is the drop's population made concrete: it is outside the floor's gate prefixes, so no required run ever executed it.

Review pointers

  • DESIGN §3 (delete-first; the deletion is the census only over what a run compiles — so the consumers are enumerated above by name), §4b(3) (the drop, its trigger named as a capability, loss and trigger at the same grain), §5 (no escape hatch: the lanes are deleted, not toggled off), §6 (name the instrument).
  • The witnesses.yml diff is large and mechanical; read compiler_gate_lane_rows, compiler_gate_workflow.jobs, and expected_compiler_gate_yml's conjunct list in the authority instead.

🤖 Generated with Claude Code

…d alone (operator ruling 2026-10-09)

The operator's v1 withdrawal: v1 is no longer a validation authority, and
the one use left to the seed is emitting v2. gunbc.compiler_gate_workflow
drops `floor`, `generated`, `rust-unit-tests` and `seed`; the `witnesses`
aggregate reads the one remaining lane, `emit-build`, through the same
folded roster (one row). The GateArmSkippedOnPullRequest arm leaves with
its only inhabitant.

The loss is one declared drop, gunbc.rung_drop v1_required_lanes_withdrawn,
stated member by member (witnesses, stage0 mirrors and every generated
artifact, lint, v1 unit tests, module resolution outside the two emitted
closures, the downstream consumers), with a trigger that names the
capability: a binary built from an emission of v2 judging that population
on the required path. rust_unit_tests_off_pull_requests is Superseded (its
lane runs nowhere; trigger did not fire; the new row holds the loss).

gunbc.required_ci_contract_epoch moves to 2026-10-09.1: the name `witnesses`
now carries a materially different contract.

Consumers repaired rather than left dangling: the lane-resolution census
roster (the census now does not hold by design and is the instrument that
re-derives the drop's module population), DESIGN section 3's typed
required-gate reference (gunbc.documentary_refs, now
emitted_subject_build_rows), the Building & checks rows, the onboarding
path's run-witnesses step, five recurring_failure_mode evidence rows that
cited deleted declarations, and the two gate witness files (the blocking
set is asserted as exactly emit-build; a new RED asserts the four
withdrawn variables reach neither gate surface).

Projections regenerated by tools.generated_artifact_gate main_wet (the run
peaked at 15.8 GB RSS, against the 7.55 GiB that module's own note cites
for 2026-08-31): witnesses.yml, DESIGN.md, docs/design-rung-drops.md,
docs/onboarding.md; every other rostered artifact came out byte-identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot changed the base branch from main to integration/v1-closeout October 9, 2026 20:24
gunbc-ci-auto-heal added 2 commits October 9, 2026 20:33
…deletion (pre-merge, projections not yet regenerated)
…e authority and its projections: this branch's side; projections regenerated in the next commit)
gunbc-ci-auto-heal and others added 7 commits October 9, 2026 21:15
…nvelope rows; managed_host Superseded arm (pre-regen)
…l-336: managed_host takes the closeout's arm; projections this side, regenerated next
…_workflow no longer imports the deleted script-row refusal API

6ee1d21 (integration/v1-closeout) removed fleet_desired_candidate_fetch_script_row and candidate_scripts_refusal from gunbc.fleet_desired_candidate but left their consumer, so every entry whose closure reaches the generated-artifact registry refused to resolve (regen, verify, five gate witnesses). This is origin/main's shape of the file: the admission workflow emits its YAML directly again.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…item 3); witness claim the_trip_sits_inside_the_slot_envelope
…tree

One main_wet of tools.generated_artifact_gate over this branch merged with
integration/v1-closeout a925452 (regen 632 s, verify 693 s, both exit 0,
on srv1 under capped MemorySwapMax=0 scopes), nine artifacts:

- witnesses.yml: both subject steps carry GUNBC_BIND_MEMORY_CGROUP_BYTES
  (the derived trip, 20 GiB) and the failure notice carries the envelope
  lines (what 137 means, no larger runner and no retry, the MEMORY RECEIPT).
- DESIGN.md, docs/design-rung-drops.md: the CI row and the drop roster.
- .gitattributes: the deleted heal-publish.yml leaves the generated-artifact
  merge list.
- fleet-converge.yml: the closeout's authority fix projected.
- tools/fabric_ci_fci1_bounded_execution_context.env: the fci1 context
  follows the slot (22/21 GiB).
- provisioning/srv{1,3,4}/gunbc-ghrunner.sudoers: a 22 GiB slot fits more
  slots per host than a 26 GiB one, so the derived rosters grow (srv1 gains
  srv1-10 and srv1-11). Desired state; applying it is the converge effect.

The witness batch on the same tree: 16 files, green except the two latent
reds already recorded in the PR (fci1_bounded_execution_context: a stale
envelope-basis expectation; heal_publication_boundary: 23/34).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Re review 78388 (cursor, on 94464b12) — all three findings verified against the tree and addressed in the pushed head a4b8f788:

  1. Live witnesses.yml missing the memory bind and 2. DESIGN.md / docs/design-rung-drops.md behind their authorities — true at 94464b12: those were the pre-regeneration projections (the commit said so), because the regeneration could not run on the merged tree: integration/v1-closeout did not resolve (the incomplete Floor judges base-revision facts with the base revision's own compiler #13453 revert in gunbc.fleet_desired_admission_workflow, completed in 94464b12 and taken onto the closeout as 00989b9e; then three more incomplete deletions in 02_parse, body_lowering_fold and fleet_converge_workflow, fixed on the closeout at a9254527). With the closeout tip merged, the regeneration (tools.generated_artifact_gate main_wet) and its fixed-point verify (main) ran on srv1 under capped scopes; the projections in this head are their output, and the subject steps now carry GUNBC_BIND_MEMORY_CGROUP_BYTES with the envelope lines in the failure notice.

  2. native_step_memory_trip_bytes as a bare Int — true, and the fix is stronger than a ByteSize twin: the trip is no longer authored at all. gunbc.emitted_subject_build_gate declares one ByteSize headroom (native_step_memory_headroom, 1 GiB) and derives native_step_memory_trip() as the slot's MemoryHigh (gunbc.runner_slot_desired) less that headroom through std.realization_width byte_size_saturating_sub, so the slot stays the single authority for the envelope's numbers and a step cannot be bound above the slot that holds it. The witness the_trip_sits_inside_the_slot_envelope executes the derivation (0 < trip < MemoryHigh < MemoryMax; red at zero headroom or a headroom reaching the throttle line). The emitted env value is unchanged (20 GiB), so the workflow bytes do not move for this item.

— sent from smart-gull-336

gunbc-ci-auto-heal and others added 3 commits October 9, 2026 23:56
…ip withheld by the declared drop native_step_trip_awaits_fleet_job_cgroup; slot-grain receipt in gunbc test; seed-growth receipt (pre-regen)
…ssion/smart-gull-336

# Conflicts:
#	.github/workflows/fleet-converge.yml
#	.github/workflows/witnesses.yml
#	docs/design-rung-drops.md
… fleet fact; the envelope decision is a .dag fold the seed mirrors

The first required run that passed GUNBC_BIND_MEMORY_CGROUP_BYTES
(38002497388 on a4b8f78) refused in four seconds: MemoryCgroupBindRefused,
the cgroup2 tree is not writable. memory_governor apply_memory_cgroup_bind
creates its leaf at the cgroup ROOT (a container-root design; the bind had
never been requested on the fleet) and a fleet job runs as the setpriv'd
job user under a root unit, so no job process can create the bound. The
operator approved the slot-grain arm (escalation 2026-10-09).

gunbc.memory_envelope (new) owns the decision and the verdict as folds over
supplied inputs -- the sibling of gunbc.memory_cgroup_binding -- and
test.claim.memory_envelope_witness_test reaches every arm by supplied value,
including the RED an inline decision could not: a slot requirement over a
process no numeric memory.max binds REFUSES (MemoryEnvelopeAbsent) rather
than running as bounded. The seed mirrors it arm for arm with unit tests;
the shells resolve the bounding cgroup through binding_cap_cgroup_dir (never
the peak locator), read memory.swap.max/.current/.peak (modeled in
extdeps.linux.cgroup_v2_memory) before and after the producer, print a
slot-grain MEMORY RECEIPT with event deltas and the peak labelled by whether
it rose, and refuse the run on any OOM kill or swap.

gunbc.emitted_subject_build_gate carries two envelope inputs and ONE
decision over them, native_step_memory_inputs(ownership): every subject step
REQUIRES the slot envelope (GUNBC_MEMORY_ENVELOPE_REQUIRED=slot, the
projection of EnvelopeSlotRequired) and the bind input at the derived trip
is withheld while gunbc.runner_slot_desired gunbc_runner_slot_job_cgroup_ownership
is JobOwnsNoBoundedCgroup. That is a fleet fact, not a rung drop -- nothing
on the required path ever held the trip -- so the climb is rostered as
gunbc.guarantee_stall native_step_trip_awaits_fleet_job_cgroup_stall
(grounding: unit delegation with DelegateSubgroup=, a per-job cgroup staged
by the root JIT wrapper, the governor's already-bound arm). The workflow and
the failure notice consume the fact; the witness exercises both arms by
supplied value, reads the live row, and asserts the bind KEY is absent.

The slot wall follows the ruling too: gunbc.runner_slot_allocation
gunbc_runner_slot_allocation_wall_holds drops its three floor conjuncts (a
slot sized to a tenant that no longer runs in it) and requires
MemorySwapMax == 0 instead of a swap above the maximum; the floor-fit drop
slot_row_pinned_below_demonstrated_demand_unrefused is Superseded with
v1_required_lanes_withdrawn as its loss holder; the slot witness re-pins the
row to 22/21/0 and its width alarms to the smaller slot's derivation
(srv1 12, srv3/srv4 21). The slot's demand oracle from here is the first
cold required run's MEMORY RECEIPT, a declared frontier.

The trip stays a ByteSize derived from the slot (review 78388 item 3). The
seed growth is receipted as gunbc.memory_envelope_receipt_seed_growth
(review 78391). The design document's CI row and the slot row's note say
the same.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

Head 75bd66f0 changes the envelope's shape after the first fleet run, and the PR body's memory envelope section is rewritten to match. Short version for reviewers of earlier heads:

  • What the fleet said. Run 38002497388 (head a4b8f788) refused in four seconds at the first subject step: MemoryCgroupBindRefused — the cgroup2 tree is not writable. The governor's bind creates its leaf at the cgroup root (never exercised on the fleet before: main's witnesses.yml never carried the input), and a fleet job is the setpriv'd job user under a root unit. Escalated to the operator; the slot-grain arm was approved.
  • What the steps carry now. GUNBC_MEMORY_ENVELOPE_REQUIRED=slot on both subject steps: gunbc test refuses a run that no cgroup with a numeric memory.max binds (resolved through the governor's binding_cap_cgroup_dir walk — max is unset, not a large number), reads the bounding cgroup before the producer, and refuses at exit on any OOM kill the step added, any swap resident, or a swap peak that rose. The bind input is withheld while the fleet fact gunbc.runner_slot_desired gunbc_runner_slot_job_cgroup_ownership is JobOwnsNoBoundedCgroup; the climb is rostered as gunbc.guarantee_stall native_step_trip_awaits_fleet_job_cgroup_stall (a stall, not a drop: nothing on the required path ever held the trip).
  • The decision is a .dag fold the seed mirrors. gunbc.memory_envelope + test.claim.memory_envelope_witness_test (every arm by supplied value, including RED_a_slot_requirement_with_no_numeric_max_refuses_as_absent); the Rust mirror has unit tests. An adversarial review workflow over the first draft of this head found the inline version admitted an unlimited cgroup as Bounded{slot} (it located the cgroup by memory.peak presence) — that is the defect this construction removes, and the reason the decision is no longer inline.
  • Receipts (regen fixed point, 26 witness files on srv1 under capped scopes, the dispatched witnesses.yml run) are in the PR body's evidence section.

— sent from smart-gull-336

@gunbai-bot

gunbai-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

Folded into #13641 at exact head 75bd66f (operator ruling; run 38016653087 green). Merge second parent verified.

@gunbai-bot
gunbai-bot Bot merged commit 0f6dfa7 into integration/v1-closeout Oct 10, 2026
1 check passed
@gunbai-bot
gunbai-bot Bot deleted the session/smart-gull-336 branch October 10, 2026 03:15
@gunbai-bot

gunbai-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

Re review 78398 (cursor, on 75bd66f0) — verified; the finding is right and is answered without moving this head:

  • Fact. gunbc.heal_workflow (heal.yml, workflow_dispatch) still seals a repair candidate and uploads the artifact the deleted publisher consumed, so "nothing sealed one" was false for the manual route, and its header still described a publisher that no longer exists.
  • Disposition: freeze and declare, not cut (the arm the review offered; the operator also confirmed tonight that a proper regen comes later). The route's subject — a repair candidate for a regenerated projection — returns the day a native regen instrument joins the required path with a publisher row beside it, so under DESIGN §3's carve-out it stays frozen (no new investment, no new rows) and the loss is declared: a named member of v1_required_lanes_withdrawn's population (with the publisher's revalidation hook expected_healed_sha on witnesses.yml named as unused for the same span), the workflow header states the freeze, the drop's parenthetical reads "nothing on the required path seals one any more", and the DESIGN CI row says the same. Regen fixed point re-verified on srv1 with that edit (regen 674 s / verify 622 s, exit 0; the fourteen touched witnesses green).
  • Why it is not on this head. The operator's written ruling approves Required CI: withdraw the four v1-judged lanes; the gate is emit-build alone (operator ruling 2026-10-09) #13658 for the closeout fold at exactly 75bd66f0, whose dispatched witnesses.yml run 38016653087 is green, so this branch moves no further. The freeze commit (authored, verified) lands in a post-fold follow-up PR from followups/smart-gull-336, together with the latent-red repairs the same ruling routes to runtime tasks (the fci1 envelope-basis expectation; the publication-boundary fixture, whose 23 reds were one stale producer path — witnesses.yml where heal.yml has sealed since the Phase A split).

— sent from smart-gull-336

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.

0 participants