Skip to content

Fleet admission reads the merge queue: CI success from merge_group runs on R, branch fact from the push of R (PR 1 of 2) - #11238

Merged
gunbai-bot[bot] merged 6 commits into
mainfrom
session/deep-otter-836
Sep 13, 2026
Merged

gunbai-bot[bot] merged 6 commits into
mainfrom
session/deep-otter-836

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

PR 1 of 2. This PR has no prerequisite. PR 2 (the cut) is separately gated, on this PR, on #11250 (the consumed-row owner charge), and on live admissions through the push route.

Why

GitHub's merge queue is on for main. The required floor (gunbc.witness_floor_workflow) now runs on the queue's composed sha as a merge_group run, and the concurrency group and cancel policy for that come from #10981 and #11052. After a queue merge, the push-on-main floor run re-runs the sha the queue just proved.

A census over three queue landings (table below) found exactly two products the push-on-main run has that the merge_group run on the same sha does not:

  1. Fleet desired-state admission. fleet-desired.yml (gunbc.fleet_desired_admission_workflow) triggers on workflow_run of witnesses on main. gunbc.fleet_revision_acceptance DefaultBranchRevisionObserved requires originating_event == push. A merge_group run (head_branch gh-readonly-queue/...) never triggers admission and cannot satisfy it. This PR re-sources it.
  2. The consumed-admission refusal. The namespace-wave-admission phase (namespace_wave_admission wave_admission_refusal) refuses consumed rows only where base == head or the roster is touched. Every push-on-main run failed it on the two gunbc#11156 rows, while the merge_group runs printed the same rows and ended ADMITTED. That product is Namespace wave admission: the owner's merge_group run owes its consumed rows' deletion follow-up (carrier for the push-on-main cut) #11250's subject, not this PR's.

An earlier revision of this body said "exactly one" and "nothing else is push-unique". That was a static reading of the workflow, which cannot see a phase whose verdict depends on the event; the landing census corrected it to the two above. Everything else matched on the observed runs:

  • heal-generated-artifacts runs on pull_request only, and was skipped on every observed run.
  • The build, floor and aggregator jobs and the 8 artifact names are identical per run, with no write-back to main.

So the push-on-main run cannot be cut until both products live elsewhere. This PR moves the first; #11250 moves the second; the cut itself is PR 2.

What changes (propositions unchanged, producers re-sourced)

RequiredCiSucceeded and DefaultBranchRevisionObserved stay one proposition each, and admit_fleet_revision's exact-revision join is unchanged. Only their producers gain a second binding.

  • gunbc.fleet_revision_acceptance accept_required_ci_merge_group_runs: CI success for R, read from the floor's merge_group runs on R. Checks run in this order:
    1. Partial page: refuses as RequiredCiMergeGroupRunsTruncated.
    2. Event scope, required of the response: a returned list containing any non-merge_group run refuses as RequiredCiRunsNotEventScoped. This establishes what the response contains, not whether the request carried the selection.
    3. Identity: the floor workflow on R, else RequiredCiMergeGroupRunAbsent.
    4. Epoch.
    5. Attempt history: a matching run with run_attempt > 1 refuses as RequiredCiRunAttemptHistoryUnestablished. The list carries only each run's latest attempt, so an earlier failure, or a later cancel hiding one, would otherwise vanish. This is decided before non-verdict snapshots drop.
    6. Agreement: queued, in-progress, cancelled and skipped runs are dropped. If every remaining verdict is Success, the fold admits. A Success beside any other verdict refuses as RequiredCiContradictoryRuns, carrying both id sets. Only failures refuse as RequiredCiMergeGroupRunsNotSuccess.
  • Provenance, stated: WorkflowRun carries no repository members, so this producer does not repeat the old producer's repository and head-repository checks per run. Its repository warrant is the request admit_fleet_desired_from_push_wet addresses to gunbc.repository. A bare caller-supplied WorkflowRunList does not independently establish provenance.
  • extdeps.github.workflow_runs ListForRef gains GitHub's event query input. The admission read passes merge_group. gunbc.pr_base_freshness pull_request_run_started_at passes pull_request, which is what its name always meant.
    • Request-boundary coverage is a temporary coverage frontier.
      • It remains unbuilt behind a documented substrate limitation: extdeps.transports.rest replay fixtures match on an input digest the host computes from per-parameter value_hash limbs (content_hash_service_inputs), which .dag cannot author.
      • It is not structurally impossible, not a permanent ceiling, and not established by the response witness.
      • Residual: an unscoped request whose complete response happens to contain only merge_group runs is indistinguishable to the response guard.
      • Closes on: an executing, enrolled control of the production request binding, where the realized event=merge_group passes and removing or misbinding it is discriminated at that boundary. A digest helper, or a declared harness, does not close it.
  • observe_default_branch_push: the branch fact from the push event itself (ref == refs/heads/<default branch>, repository, decoded after). No run of anything is consulted.
  • extdeps.github.push_event PushRefUpdate: ref, after and repository.full_name of the cited webhook payload.
  • gunbc.fleet_desired_admission:
    • admit_fleet_desired_from_push_wet reads the payload, judges the branch fact, then reads github.WorkflowRuns.ListForRef for R and runs the fold.
    • The actuation tail (decision → CAS action) is factored into fleet_desired_actuate_accepted_wet, so both routes share it byte-for-byte.
  • gunbc.fleet_desired_admission_workflow:
    • adds push: branches [main];
    • adds one decide step per route, selected by github.event_name;
    • gives the push step alone GITHUB_TOKEN, and the job actions: read.
    • Nothing else in the workflow changes. Its opening annotation is rewritten, because "at merge time there is no floor conclusion" is false for queued merges.

Expected refusal on pushes without queue evidence

A push whose revision has no qualifying merge_group run refuses with RequiredCiMergeGroupRunAbsent: "no qualifying merge-group run of the required floor was observed for revision R in the complete queried result". An operator's admin-bypass merge or a direct push is one scenario that produces that absent evidence. The refusal reports the absence and never diagnoses a cause.

During the transition, the workflow_run route can still admit such a revision once its push-on-main floor goes green. After PR 2 it cannot. A re-run merge_group landing also refuses (RequiredCiRunAttemptHistoryUnestablished) until attempt history is joined; the fleet advances on the next landing.

Transition (accepted by the lane manager)

Both routes stay live between this PR and PR 2, so each queued landing runs two admission jobs. The CAS makes the second one AlreadyConverged. Runner claims are briefly up, not flat. PR 2 lands once three live landings have admitted through the push route. It cuts the witnesses push trigger for main and deletes the workflow_run route in the same change.

Live evidence: three queue landings

Each landing is a merge_group run and a push-on-main run on the same sha.

landing merge_group run concluded push run created push-floor fleet-desired
PR 11156 d7b7ab96 34734025053 success 03:49:07Z 34736430057 03:49:36Z failure refused (floor red)
PR 11172 3b747abd 34736430682 success 04:48:57Z 34738796445 04:49:26Z failure refused (floor red)
PR 11143 a6ae1af6 34738796806 success 05:42:52Z 34740995720 05:43:19Z failure refused (floor red)
  • Ordering assumption held on all three: the queue pushed exactly the tested sha, 27–29s after its merge_group run concluded.
  • Same work on both runs: jobs (build, floor, aggregator; heal skipped) and the 8 artifact names are identical.
  • The push run produced exactly two things the merge_group run did not. The first is the fleet-desired trigger, which this PR re-sources. The second is the consumed-admission red, which is Namespace wave admission: the owner's merge_group run owes its consumed rows' deletion follow-up (carrier for the push-on-main cut) #11250's subject.
  • Fleet impact: every push floor was red on consumed-row debt, so the fleet ref advanced on none of them. The push route admits a queue-proven revision regardless (lane manager agreed: the debt is roster hygiene, and the revision is proven by its merge_group run). A push-on-main floor verdict never enters the agreement fold: the read is scoped to merge_group runs, and the fold refuses any other event.

Witnesses

dag/test/claim/fleet/fleet_desired_merge_queue_admission_witness_test.dag exercises fleet_desired_accepted_from_push, the same composition the wet entry runs.

  • Positive controls: a single success admits; two successes admit; a cancelled run beside a success admits.
  • Refusals:
    • success + failure refuses with both ids, in either order;
    • failures only;
    • no merge_group run;
    • a pull_request run offered as a merge_group run;
    • a success on another sha;
    • another workflow's run;
    • no verdict yet;
    • a truncated page;
    • a wrong epoch;
    • a merge_group success with a push to another ref;
    • a bare branch name as ref;
    • another repository;
    • a payload missing after.
  • Added for the hold repairs:
    • a_qualifying_success_beside_a_push_run_refuses_as_an_unscoped_read;
    • a_rerun_success_whose_earlier_attempt_is_unobserved_refuses (same run, different attempt);
    • a_later_cancelled_attempt_is_judged_before_non_verdicts_are_dropped;
    • the_absent_unconcluded_and_unscoped_refusals_claim_only_what_they_establish, covering the three refusal texts.
  • Emitted routing: a check that each event reaches its own entry.

Executed: the original 19 rows are planned-and-passed on required floor run 34740987623. The rows added for the hold repairs run on this head's floor.

Receipts

This change touches dag/gunbc, dag/extdeps, one dag/test witness file, and the generated fleet-desired.yml. That it adds no compiler source does not by itself establish that every downstream composition receipt stays current for the added test declarations. No such receipt is claimed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X

gunbc-ci-auto-heal and others added 4 commits September 13, 2026 04:24
…rge_group runs on R, the branch fact from the push of R

Re-sources the two propositions of gunbc.fleet_revision_acceptance onto the
merge queue without changing them or their exact-revision join. The workflow_run
route stays as a second admissible source until the witnesses push-on-main run
is cut.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
…nal literal none

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
…e gunbc run argv

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
…low (heal-provided bytes, run 34738862591)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Floor red on run 34740987623 is not this diff. Diagnosis below, recorded before re-running.

  • What refused: the only blocking adjudication is COMPLETED-OVER-COST-REQUIREMENT on v2.test.claim.affected_set_universe.affected_set_universe_gate_processes_match_declared_gates: cpu 508ms against a 500ms budget, verdict pass. claims_failed=0, unexpected_failures=0.
  • Same work as on main: eval_steps=2884 here, and the same 2884 on main's floor runs 34738796806 and 34740995720. Main measured observed_cpu_ms=427 and 390 for it (observed_wall_ms=1433 / 1085).
  • Host pressure: this run's host was page-thrashing through claim evaluation (heartbeat: stall ~270k major faults/min at 7% user cpu), and the claim's wall was 3856ms. The overrun is host contention on an untouched claim, not a cost change.
  • This PR's witnesses: all 19 test.claim.fleet_desired_merge_queue_admission_witness_test rows are planned-and-passed / enrolment_margin admitted on this run.

Re-running the failed jobs.

gunbc-ci-auto-heal and others added 2 commits September 13, 2026 08:22
… history, render only established facts

(A) extdeps.github.workflow_runs ListForRef takes the event query input; the
admission read passes merge_group and the fold refuses a response carrying any
non-merge_group run (the realized request has no replay harness yet).
pr_base_freshness passes pull_request, which its function always meant.
(B) A matching run with run_attempt > 1 refuses as
RequiredCiRunAttemptHistoryUnestablished, decided before non-verdicts drop.
(C) The absent and unconcluded refusals state only what their predicates
establish. The provenance warrant of the new producer is stated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
…te request-boundary coverage as a temporary frontier

C.1 RequiredCiRunsNotEventScoped reports what the returned list contains,
not a diagnosis of the request; the text control now covers that arm.
C.2 The unconcluded witness's annotation states the fact tested.
A: request-boundary coverage is a temporary coverage frontier with its
substrate limitation, residual, and closure criterion stated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 13, 2026
Merged via the queue into main with commit 653ac63 Sep 13, 2026
4 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/deep-otter-836 branch September 13, 2026 12:57
gunbai-bot Bot pushed a commit that referenced this pull request Sep 15, 2026
…nded sha

The merge queue runs the required floor on its COMPOSED revision, and that
revision is the one that lands -- measured, not assumed: the merge_group runs
whose head_sha is 4f30460 and fe85902 are
the commits main carries afterwards. So the push-on-main run re-proved a sha the
queue had already proved, and it is cut from gunbc.witness_floor_workflow
witness_floor_triggers. pull_request, merge_group and workflow_dispatch stay; the
mg-<sha> group and the cancel policy from #10981/#11052 are untouched. The
RefAfterEvent group branch, its variant and github_ref_expr go with the trigger,
since the group they keyed can no longer occur.

Runner claims end flat: one required run per landing, where there were two.

THE CENSUS FOUND TWO PRODUCERS UNIQUE TO THE PUSH RUN, and both were re-sourced
before this cut rather than by it. Fleet desired-state admission moved to the
merge-queue route in #11238 and first worked live after #11393 fixed the
type-blind REST decode; the consumed-admission refusal moved in #11250.
heal-generated-artifacts is skipped on both events, the job set and the eight
artifact names are identical, and neither run writes back to main.

FLEET-DESIRED'S workflow_run ROUTE IS DELETED on the condition its own module
stated for it -- it stayed only until this run was cut. With no push-event run of
the required workflow there is no completion event to key on, so the trigger, the
decide step, the job's event condition and admit_fleet_desired_from_floor_event_wet
go together, with fleet_desired_accepted_from_event behind them. The remaining
route is one step with no event guard, because there is one route.

THE WITNESSES ARE RE-AIMED, NOT DROPPED. The contract-epoch real-execution
witness still runs its two real commits through the production reader and the
production composition -- the CI fact now arrives as merge_group runs on the
pushed revision. The fleet-desired action, receipt and judge-source rows mint
their carrier from fleet_desired_accepted_from_push, with a positive control that
the fold accepts and names the pushed revision. Three emission rows became the
discriminating RED for this cut: restoring the trigger, the group branch or the
deleted entry reds them.

gunbc.rung_drop main_per_commit_floor_verdict IS RETIRED BY ITS OWN TRIGGER. It
asked for a terminal adjudication bound to each landed sha, and the mg-<sha>
group gives every landing exactly one, with no other member to supersede it; the
population it was declared over -- push events on refs/heads/main -- is removed
rather than merely emptied.

NOT IN THIS CHANGE, AND NAMED RATHER THAN LEFT TO BE FOUND: gunbc.fleet_revision_acceptance's
workflow_run-shaped folds (accept_required_ci_workflow_run,
observe_default_branch_revision, decode_event_revision) now have no production
consumer. Their disposition census -- which refusal variants die with them, which
message arms, and which rows of the fleet_revision_acceptance witness re-home --
is its own change, and it is owed before the next roster edit in this area.

Operator sign-off for the job-roster change is cited in this lane's brief.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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