Skip to content

ci: keep queued nightly controls on the fleet - #30108

Merged
teamleaderleo merged 2 commits into
feat-cmux-nextfrom
lane/nightly-queued-controls-fleet
Nov 1, 2026
Merged

teamleaderleo merged 2 commits into
feat-cmux-nextfrom
lane/nightly-queued-controls-fleet

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

NEXT nightly run 41269080663 queued its TUI resolver and recovery finder on Blacksmith 16 vCPU while no runner started. When their early placement is empty or stale, these two secret-free jobs now request the existing GCP JIT fleet pool. Valid current-attempt fleet Linux and owned-mini placements still take precedence. Other tracks and fork routing keep their existing behavior.

Leo: “FOR OUR NIGHTLIES ARE THEY END TO END ON OUR FLEET? WE CAN'T BE RELYING ON BLACKSMITH THAT CUTS OUT”.

This is the immediate two-job repair requested ahead of the larger admission change. It never treats missing placement as permission for paid work. The recorded 180-second no-start overflow mechanism remains in #30085. This change does not cancel or rerun an existing nightly; a newer source can build alongside it. No signing job, environment, credential, or permission changes.

Prior art: #29864 supplies early placement and #30042 preserves fleet placement when the routing API quota fails. Their empty-output fallback still selected Blacksmith; this fixes that last branch. #30085 is this lane's held admission implementation. #30081 and #30098 own signing and publication routing and are unchanged.

Validation: 65 routing, nightly policy and fork tests pass. Both new default-route assertions fail against base efbe429 (Blacksmith 16 instead of fleet Linux). The shell guard's eight failing selectors are byte-for-byte identical to base; neither changed selector is flagged. These jobs do no compilation, so compilation caches are not involved.

Performance

Metric Before After Evidence
Blacksmith default for the two NEXT controls without placement 2 jobs 0 jobs evaluated workflow expressions
Blacksmith minutes/day not measured not measured live routing measurement follows deployment

Changelog

none

Agent session: agent session
🤖 Generated with Claude Code


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


Summary by cubic

Keeps the two nightly-next control jobs (resolve-nightly-cmux-tui-client and find-nightly-next-recovery) on the fleet when their early placement is empty or stale, instead of letting them fall through to Blacksmith.

  • Changes the runs-on expression so an empty or stale placement plus the nightly-next track resolves to cmux-fleet-linux-x64.
  • Valid current-attempt fleet and mini placements still take precedence; other tracks and fork routing keep their existing behavior.
  • Adds tests covering run-attempt, placement, and track combinations, plus a fleet-linux fallback case for the two jobs.

HQ#5804 (GCP JIT startup installs gh) has merged. As a fail-safe for VMs made before it, both jobs now run scripts/ci/nightly-steps/ensure-gh.sh on Linux before their first gh call: it installs gh from apt, falls back to the cli.github.com apt repo, and fails the step with a clear error rather than letting the finder crash with FileNotFoundError.

Written for commit 60f6989. Summary will update on new commits.

View guided diff Turn on auto-fix

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/test_ci_nightly_off_blacksmith.py">

<violation number="1" location="tests/test_ci_nightly_off_blacksmith.py:96">
P2: This new assertion pins the classic `nightly` track to `blacksmith-16vcpu-ubuntu-2404` through `LINUX_RUNNER`. That conflicts with the repo rule that nightly jobs never take Blacksmith labels, and the new test now enforces that route. If the classic track is intentionally out of scope, drop this assertion so the test does not lock in Blacksmith routing.</violation>
</file>

<file name=".github/workflows/nightly.yml">

<violation number="1" location=".github/workflows/nightly.yml:3153">
P2: With the new fleet branch ahead of the Blacksmith tail, these two jobs no longer fall back to Blacksmith when no fleet runner starts. Confirm that the 180-second overflow in `portable_job_placement.py` still reaches them, or add a fallback that the overflow switch can change.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

with self.subTest(job=name, attempt=attempt, placement=placement_attempt):
self.assertEqual(evaluate(expression, context), "cmux-fleet-linux-x64")
context["needs.decide.outputs.track"] = "nightly"
self.assertEqual(evaluate(expression, context), "blacksmith-16vcpu-ubuntu-2404")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This new assertion pins the classic nightly track to blacksmith-16vcpu-ubuntu-2404 through LINUX_RUNNER. That conflicts with the repo rule that nightly jobs never take Blacksmith labels, and the new test now enforces that route. If the classic track is intentionally out of scope, drop this assertion so the test does not lock in Blacksmith routing.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At tests/test_ci_nightly_off_blacksmith.py, line 96:

<comment>This new assertion pins the classic `nightly` track to `blacksmith-16vcpu-ubuntu-2404` through `LINUX_RUNNER`. That conflicts with the repo rule that nightly jobs never take Blacksmith labels, and the new test now enforces that route. If the classic track is intentionally out of scope, drop this assertion so the test does not lock in Blacksmith routing.</comment>

<file context>
@@ -78,6 +78,33 @@ def code_lines(path: Path):
+                    with self.subTest(job=name, attempt=attempt, placement=placement_attempt):
+                        self.assertEqual(evaluate(expression, context), "cmux-fleet-linux-x64")
+                        context["needs.decide.outputs.track"] = "nightly"
+                        self.assertEqual(evaluate(expression, context), "blacksmith-16vcpu-ubuntu-2404")
+                        context["github.repository_owner"] = "fork-owner"
+                        self.assertEqual(evaluate(expression, context), "ubuntu-24.04")
</file context>

needs: decide
if: needs.decide.outputs.should_build == 'true' && (github.event_name != 'schedule' || github.event.schedule == '47 8 * * *')
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_linux_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_linux_runner || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_mini_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_mini_runner || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }}
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_linux_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_linux_runner || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_mini_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_mini_runner || needs.decide.outputs.track == 'nightly-next' && 'cmux-fleet-linux-x64' || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: With the new fleet branch ahead of the Blacksmith tail, these two jobs no longer fall back to Blacksmith when no fleet runner starts. Confirm that the 180-second overflow in portable_job_placement.py still reaches them, or add a fallback that the overflow switch can change.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .github/workflows/nightly.yml, line 3153:

<comment>With the new fleet branch ahead of the Blacksmith tail, these two jobs no longer fall back to Blacksmith when no fleet runner starts. Confirm that the 180-second overflow in `portable_job_placement.py` still reaches them, or add a fallback that the overflow switch can change.</comment>

<file context>
@@ -3150,7 +3150,7 @@ jobs:
     needs: decide
     if: needs.decide.outputs.should_build == 'true' && (github.event_name != 'schedule' || github.event.schedule == '47 8 * * *')
-    runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_linux_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_linux_runner || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_mini_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_mini_runner || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }}
+    runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_linux_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_linux_runner || needs.decide.outputs.early_attempt == format('{0}', github.run_attempt) && contains(needs.decide.outputs.early_mini_jobs, ' resolve-nightly-cmux-tui-client ') && needs.decide.outputs.early_mini_runner || needs.decide.outputs.track == 'nightly-next' && 'cmux-fleet-linux-x64' || vars.LINUX_RUNNER == 'blacksmith-16vcpu-ubuntu-2404' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404' }}
     permissions:
       contents: read
</file context>

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

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

Review d5c773b: 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=pr30108 -f ref=lane/nightly-queued-controls-fleet -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base c06e62a; does not block

Shipped in:

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

blacksmith-sh Bot commented Nov 1, 2026

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_no_runner_picker_returns_a_hosted_mac (main.NoHostedMacInNightlies.test_no_run
ner_picker_returns_a_hosted_mac)/
test_no_runner_picker_returns_a_hosted_mac (main.NoHostedMacInNightlies.test_no_run
ner_picker_returns_a_hosted_mac)
View Logs

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high): SHIP at 60f6989

Diff is only the two NEXT resolver/recovery fallback selectors plus tests. Precedence, fork/track guard and no-secrets are all correct; 65 focused tests and diff-check pass. The existing self-hosted guard failure is an unrelated base red. Its HOLD prerequisite, HQ#5804 (gh on GCP JIT startup), merged as 80ada0f8.

@teamleaderleo teamleaderleo removed the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high): SHIP at 60f6989. Focused routing, nightly, trusted and fork tests pass; no blocking finding.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at 60f6989

BLOCK at 60f6989

Visual verdict: no images; Leo tries the build

  1. [P1] [blocking] .github/workflows/nightly.yml:5568 — Provision gh before enabling this fallback. The PR explicitly identifies HQ#5804 as the prerequisite that supplies gh on GCP JIT runners. Without it, empty or stale placement now selects a runner where the recovery finder fails: find-nightly-next-recovery.py invokes gh directly, and the preceding budget wrapper only warns when it is missing. I reproduced FileNotFoundError: 'gh'. Deploy that prerequisite first or install gh before the finder runs; otherwise this breaks the previously working recovery job.

Validation: all 97 relevant routing, placement, nightly policy, and fork tests passed. These do not exercise the runner image.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

…inder call it

The fleet-linux fallback can land these jobs on a GCP JIT VM that predates
HQ#5804's startup script and has no gh; find-nightly-next-recovery.py then
crashes with FileNotFoundError. Install gh (distro, then cli.github.com apt
repo) before the budget wrapper, and fail with a clear error if it can't.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-fc739fd2f4e557ae7189
@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

Reviewer: codex gpt-6.1-sol xhigh, fast tier.

SHIP at d5c773b

Visual verdict: no images; Leo tries the build

No correctness, regression, security, or test failures found in the changed paths. Focused routing, nightly policy, YAML, and shell checks pass.

Follow-ups: none

@teamleaderleo teamleaderleo removed the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@teamleaderleo
teamleaderleo merged commit 559ab05 into feat-cmux-next Nov 1, 2026
163 of 171 checks passed
@teamleaderleo
teamleaderleo deleted the lane/nightly-queued-controls-fleet branch November 1, 2026 04:33
@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026

This branch was previously deployed

1 inactive deployment
ci-routing-agent — d5c773b9 Deployed Nov 1, 2026 by teamleaderleo via cmux-tui tree preflight #93606
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