Skip to content

ci: keep cmux-next fast tier off dead side queues - #28249

Merged
teamleaderleo merged 36 commits into
feat-cmux-nextfrom
lane/fast-tier-rescue-28140
Oct 31, 2026
Merged

teamleaderleo merged 36 commits into
feat-cmux-nextfrom
lane/fast-tier-rescue-28140

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

The fast tier could fall through to an unavailable side label when placement found no idle Mac. It now uses a current-attempt owned allocation or the Blacksmith cascade. Bot attempt 2 honors its freshly allocated owned runner. GUI and session routes also require an online runner.

The shared label_full_or_dead adapter reads per-label gates from the pool artifact or CI_FLEET_GATES, checks each label timestamp, and detects saturated owned pools, stale/missing readings after a three-minute wait, Blacksmith cap/backlog, and 30-minute no-start outages. The cascade preserves queued nightly work's priority. fleet_jobs, gateway_runner, and the client filter remain available for the separate fleet-client implementation; full Mac jobs retain their Mac routes.

Rescue discovers unmarked side-lane runs, recovers missing cmux-next PR associations, and detects queued jobs even when a sibling failed. Active runs at an open PR's current head remain intact: GitHub cannot retry them while active, and retrying a downstream job would retain upstream placement. The watcher reports that limitation; completed runner refusals retain the supported failed-job retry. This change improves admission and detection but does not claim to relocate already queued active PR jobs.

Request: "Fix the class, not one job." Recovery constraint: "Only re-dispatches, no cancels of an open PR's run at its head."

Design: https://github.com/manaflow-ai/cmuxterm-hq/issues/5123#issuecomment-6515215902

Placement reads have a 90-second deadline that request error handlers cannot swallow. A timeout clears partial outputs and emits a default Mac placement; checkout, token minting, and watch upload are bounded within the job deadline. The observed #28460 placement had already completed its script and cleanup before GitHub reported a timeout, so this hardening does not claim to repair that runner acknowledgement failure.

When every admissible Mac target is excluded and no fleet client is enabled, the fast tier preserves the base owned queue and still runs. It neither skips required tests nor bypasses nightly/outage exclusions onto Blacksmith. #28391 adds client-only fleet execution for this deferred case after this PR lands.

Validation at 7d085f9774ae25f43b89b1954f7d10fb80203985: all 525 affected tests pass on the fleet (https://github.com/manaflow-ai/cmux/actions/runs/41114380935), and independent gpt-6-astra router review returned SHIP with no blocking findings. Expired Blacksmith outage/capacity data is tested independently of fresh owned gates, and placement carries the observation clock consistently through its admission checks.

Previously compared base warnings: release-notary's DigestTests.test_the_repository_highlights_validate and SigningHooksInStepWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check failed identically on head run 41080623573 and base run 41071719011 (test_reds.py: own=false). The unrelated action-export-area job hit its five-minute timeout during checkout before running checks; a retry has been requested.

The routing, health adapter, and regression tests stay together because workflow placement and rescue share the admission contract. The fleet client is a separate execution mechanism in #28391.

Risk: admission depends on fleet health freshness; missing readings favor overflow once a queue has waited three minutes. Live-run recovery is limited by the no-cancellation constraint and Actions' retry API.

Agent session: agent session

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_log2']/
CoreFoundation, missing 1: ['_log2']
View Logs
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)/
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)
View Logs
test_the_ten_first_party_gpl_crates_are_named_exactly (main.AppCrateLicenseGate.tes
t_the_ten_first_party_gpl_crates_are_named_exactly)/
test_the_ten_first_party_gpl_crates_are_named_exactly (main.AppCrateLicenseGate.tes
t_the_ten_first_party_gpl_crates_are_named_exactly)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review d9f7c20: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr28249 -f ref=lane/fast-tier-rescue-28140 -f platform=macos -f backend_mode=local

web and size checks: green

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): BLOCK at 93cd38d

BLOCK

  1. tree/scripts/ci/owned_pool_rescue.py:1371-1385 calls POST /actions/jobs/{job_id}/rerun while the workflow is still running and the job is queued. The same module documents that GitHub rejects job reruns for an in-progress run (around line 1041), so this path will fail and leave the stuck job queued instead of moving it.

  2. tree/scripts/ci/owned_pool_rescue.py:1289-1294 only recovers missing pull_requests for WATCH_RUN_ID dispatches. The normal workflow_run path and sweeper call target_from_event directly (1473), so a cmux-next run with an omitted PR list is discarded as “does not name exactly one pull request” and never reaches the new rescue logic.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): BLOCK at bf35c37

BLOCK

  1. [P1] scripts/ci/owned_pool_rescue.py:1566 — PR recovery runs outside the adoption error handler. If the commit-to-PR lookup exhausts its retries, the exception terminates the entire sweeper, including unrelated watches. Reproduced locally with a failing lookup. Catch failures per run and allow later adoption retries.

  2. [P2] scripts/ci/owned_pool_rescue.py:699 — READ_ERRORS misses RuntimeError, which the snapshot downloader raises for HTTP download failures. Such failures terminate the watch instead of treating health as unavailable and rescuing the queued job. Reproduced with artifact download failed (410).

  3. [P2] .github/workflows/cmux-next.yml:2661 — The routing change leaves two CI guard tests failing: tests/test_ci_next_macos_cascade.py:1144 and tests/test_ci_side_lane_placement.py:1166. The 323-test run reports both failures. Update the expectations and placement fixtures to match the intended fast-tier behavior.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (independent Codex gpt-6.1-sol, high, via the review router; full diff from merge base 97133a4 to this head): BLOCK at be77727.

[P2] .github/workflows/cmux-next.yml:2668 - Bot attempt 2 ignores freshly assigned owned capacity. rerun_main() assigns an idle mini through owned_jobs, emits no runner, and clears retry_runner. The new owned branch excludes bot retries, so fast-tier falls through to Blacksmith even when that pool is stalled and a mini is available. Route freshly assigned owned jobs to the selected side label on bot attempt 2.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 9161731

Independent gpt-6-astra review: SHIP. No blocking findings or non-blocking notes. All 530 tests across the five affected test modules passed; routing, timeout fallback, and active-PR preservation match the stated behavior.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at d9f7c20

Independent full-range review 0eda1f3..d9f7c20. Reviewer: "SHIP ... No blocking findings. Focused CI tests passed: 530 tests." Visual verdict N/A: CI-only change.

@teamleaderleo
teamleaderleo merged commit 38c2c9a into feat-cmux-next Oct 31, 2026
149 of 158 checks passed
@teamleaderleo
teamleaderleo deleted the lane/fast-tier-rescue-28140 branch October 31, 2026 01:35
teamleaderleo added a commit that referenced this pull request Oct 31, 2026
…ft-test-rerun-routing

Both behaviours hold: rerun_main() writes #28249's `runner` (only for
freshly allocated owned jobs) and `deferred_runner`, and this PR's free
GUI/session routes and sized gui_overflow; main() writes #28249's
`deferred_runner` beside this PR's sized gui_overflow, after the cascade
places. Tests keep #28249's fast-tier rerun expectation and this PR's
GUI-job overflow expectation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-cabecb079fe356666905
cmux-bot Bot pushed a commit that referenced this pull request Oct 31, 2026
… hook 49b5d9f5 (#29154)

nightly-guards / workflow-guard-tests / release-notary is red on every
feat-cmux-next push and PR. Three causes, all in this one job:

1. RunsOnFallbackTests (first red a7b6a61, "legacy sign and deltas run on
   owned Macs only"). That commit ended sign-nightly-identity-legacy,
   verify-nightly-identity-legacy and generate-nightly-deltas on
   vars.CI_SIDE_LANE_RUNNER, a reserved lane (#28249 forbids a terminal reserved
   variable: an unset or offline lane is one dead queue), and dropped the legacy
   sign's Blacksmith picked label. Fix in the workflow: each chain now ends on
   the owned std pool literal 'glaeda-std-xcode-26.6' after the side lane, so it
   stays on owned Macs (no Blacksmith, Lawrence 2026-10-30) and never ends on a
   reserved variable. The re-run test keeps build-sign-notarize-nightly's
   Blacksmith alternate rule; the legacy sign and verify now get the owned form
   of the same rule (an owned pick holds only on the attempt that picked it).
   The exact-string pins a7b6a61 added (test_nightly_sign_runner,
   test_ci_nightly_off_blacksmith, test_nightly_universal_build.sh) pin the new
   ending.
2. test_ci_warm_sources (hidden behind 1 in the same step): 13 jobs drifted from
   .github/warm-sources.json (stable-next.yml, chromium staleness, acpmux tests,
   test-compile plan, cmux-tui cargo caches, the removed Blacksmith twin).
   The four cmux-tui lines are the same as #28818.
3. SigningHooksInStepWithGlaedaTests: glaeda 1cd373c3 (#1768) released runner
   hook 49b5d9f5 at 06:22Z. Its sha256 matches scripts/glaeda-cmux-runner-hook
   on glaeda main and glaeda-disk pins it as newest; the change lengthens the
   signing drain wait and keeps the claim and leftover checks. Same line as the
   sync PR #29029.

Ran on this VM, every release-notary step of ci-guards.yml: all pass except
license compliance (no ghostty-next submodule here) and the arm64-only track
(no lipo on Linux), which pass in CI on the base.
lawrencecchen added a commit that referenced this pull request Oct 31, 2026
…kle key; stable-next jobs in runners.json (#29261)

* base red: release-notary RunsOnFallbackTests, warm sources and glaeda hook 49b5d9f5

nightly-guards / workflow-guard-tests / release-notary is red on every
feat-cmux-next push and PR. Three causes, all in this one job:

1. RunsOnFallbackTests (first red a7b6a61, "legacy sign and deltas run on
   owned Macs only"). That commit ended sign-nightly-identity-legacy,
   verify-nightly-identity-legacy and generate-nightly-deltas on
   vars.CI_SIDE_LANE_RUNNER, a reserved lane (#28249 forbids a terminal reserved
   variable: an unset or offline lane is one dead queue), and dropped the legacy
   sign's Blacksmith picked label. Fix in the workflow: each chain now ends on
   the owned std pool literal 'glaeda-std-xcode-26.6' after the side lane, so it
   stays on owned Macs (no Blacksmith, Lawrence 2026-10-30) and never ends on a
   reserved variable. The re-run test keeps build-sign-notarize-nightly's
   Blacksmith alternate rule; the legacy sign and verify now get the owned form
   of the same rule (an owned pick holds only on the attempt that picked it).
   The exact-string pins a7b6a61 added (test_nightly_sign_runner,
   test_ci_nightly_off_blacksmith, test_nightly_universal_build.sh) pin the new
   ending.
2. test_ci_warm_sources (hidden behind 1 in the same step): 13 jobs drifted from
   .github/warm-sources.json (stable-next.yml, chromium staleness, acpmux tests,
   test-compile plan, cmux-tui cargo caches, the removed Blacksmith twin).
   The four cmux-tui lines are the same as #28818.
3. SigningHooksInStepWithGlaedaTests: glaeda 1cd373c3 (#1768) released runner
   hook 49b5d9f5 at 06:22Z. Its sha256 matches scripts/glaeda-cmux-runner-hook
   on glaeda main and glaeda-disk pins it as newest; the change lengthens the
   signing drain wait and keeps the claim and leftover checks. Same line as the
   sync PR #29029.

Ran on this VM, every release-notary step of ci-guards.yml: all pass except
license compliance (no ghostty-next submodule here) and the arm64-only track
(no lipo on Linux), which pass in CI on the base.

* test(ci): a Sparkle-key job on an owned Mac must hold the whole mini (red: generate-nightly-deltas)

tests/test_ci_signing_owned_mac.py now treats a job that holds a Sparkle
private key as a signing job, and checks a signing job whose runs-on has no
ephemeral route (owned only) even when it reads no owned pick. Rule 4 (the
keychain delete) stays for jobs that make a keychain.

Red on 340f771 (PR #29154 head, base 7bda8ef): test_workflows fails
with four findings for nightly.yml generate-nightly-deltas: not in
SIGNING_JOBS, no claim gate first, no signing-runner-claim.sh step, and the
Sparkle keys in job-level env. Run 41180899369 ran it on cmux14-glaeda-2
beside other jobs (glaeda class isolated).

* fix(ci): generate-nightly-deltas holds the whole Mac before the Sparkle key; stable-next jobs in runners.json

generate-nightly-deltas held the Sparkle private keys (job-level env) on an
owned mini beside other jobs, with no claim (glaeda class isolated; run
41180899369 on cmux14-glaeda-2). It now does what sign-nightly-identity-legacy
does:

- runs-on: the signing picker's drained mini on this attempt (sign_owned,
  under the same attempt guard), then the owned nightly slot, the side lane
  and the owned std pool. This is a placement output, so the routing table no
  longer reports a bypass.
- its first step is the same claim gate (a YAML alias of the legacy sign's),
  and signing-runner-claim.sh runs from the workflow commit before any secret.
- the three Sparkle keys move from the job env into the one step that signs.
- it is in SIGNING_JOBS (tests/test_ci_signing_owned_mac.py and
  scripts/ci/signing_runner.py). glaeda must list it in its SIGNING_JOBS too
  (the exclusive class); until then the gate refuses it on an owned Mac and
  the run publishes no deltas (they are optional; the full DMG and appcast
  are not affected).

runners.json: the five stable-next.yml macOS jobs get their classes, with a
picker_followup each (fixed labels, as the routing table now reports).

Tests (Linux VM): test_ci_signing_owned_mac, test_runner_routing_table,
test_nightly_step_coverage, test_workflow_file_size (489988 < 490000 bytes),
test_nightly_sign_runner, test_nightly_trusted_routing,
test_ci_runs_on_fallback, test_ci_warm_sources, test_nightly_universal_build,
test_nightly_sparkle_key, test_generate_nightly_deltas: all pass.

---------

Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — d9f7c20a Deployed Oct 31, 2026 by teamleaderleo via wait for same-key tree publisher #86041
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:high Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant