Skip to content

ci(runner pools): one pool per Blacksmith Linux size, so a stalled size moves by declaration - #32393

Merged
teamleaderleo merged 5 commits into
mainfrom
lane/runner-pools-per-size
Nov 2, 2026
Merged

teamleaderleo merged 5 commits into
mainfrom
lane/runner-pools-per-size

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Leo-ask: ask-973a915bea

Leo, 2026-10-28: "Where the f***ing are the generalized solution to all these problems that these incessant pins?"

475 runs-on lines on feat-cmux-next end in a literal single-size Blacksmith label (265 at 4 vCPU, 61 at macOS 26, 57 at 8 vCPU, 42 at 2 vCPU, 29 at 32 vCPU, 9 at 16 vCPU and others). A re-run cannot move a literal label, so a stalled size strands every job that names it. On 2026-10-28 that happened to blacksmith-4vcpu-ubuntu-2404 in nightly.yml.

This PR is step 1. It declares one pool per Blacksmith Linux size, plus macos_latest, in .github/runners.json pools:

Pool Members
linux_2 2 vCPU, then 4 vCPU
linux_8 8 vCPU, then 16 vCPU
linux_16 16 vCPU, then 32 vCPU
linux_32 32 vCPU, then 16 vCPU
macos_latest blacksmith-6vcpu-macos-latest

runner_pools.py is unchanged. On its next pass it writes each new key into RUNNER_POOLS, and it moves a key off a member the probe or the janitor marks dead. The follow-up PRs on feat-cmux-next replace each literal last resort with fromJSON(vars.RUNNER_POOLS).<size pool>. A fork pull request keeps its literal fork branch, because a fork's run gets no repository variables. Those PRs land only after this one has merged and the variable carries the keys.

Changed:

  • .github/runners.json adds the five pools.
  • docs/ci-runners.md updates the pool table and fixes the linux row, which now lists 4 vCPU first.
  • tests/test_ci_runner_pools.py checks that each Linux size has its own pool with a member to fail over to.

Tests: tests/test_ci_runner_pools.py (42 OK), test_ci_runner_set, test_ci_queue_janitor, test_ci_simple_pool_picker and test_ci_starved_labels all pass.

Performance

metric before after delta harness
Blacksmith minutes per day unchanged unchanged 0 declaration only; each pool's first member is the size jobs already name, so no job moves until a size stalls

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

Declares one pool per Blacksmith Linux size plus macos_latest in .github/runners.json, so a stalled size moves its jobs by declaration instead of stranding them on a literal label.

Hundreds of runs-on lines end in a literal single-size Blacksmith label; a re-run cannot move a literal label, so when a size stops starting jobs every job that names it is stuck. This adds linux_2, linux_4, linux_8, linux_16, linux_32, and macos_latest, each with a first (preferred) member and a fail-over member. macos_latest fails over to the macOS 26 image. linux_4 is ephemeral-only: it serves secret-bearing and write-token jobs that must not ride the shared linux pool. runner_pools.py is unchanged — it writes the new keys into RUNNER_POOLS on its next pass, and follow-up PRs replace literal labels with fromJSON(vars.RUNNER_POOLS) lookups.

  • Adds a test asserting each Linux size has its own pool with a fail-over member, and adjusts the dead-mark fixture so every pool holds a live member when linux_4 shares the 4 vCPU first slot.
  • The docs/ci-runners.md pool table update moves to the same follow-up change that starts reading the pools.

Written for commit c80b577. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features
    • CI jobs can use Linux runner pools sized from 2 to 32 vCPUs, with alternate runner options available for each size.
    • Added a macOS latest runner option with a macOS 26 fallback.
  • Documentation
    • Updated CI runner guidance to describe size-matched Linux pools and the available macOS options.

…cos_latest

A job measured at one size reads that size's pool (linux_2, linux_8, linux_16,
linux_32) instead of naming the size's label, so a size that stops starting jobs
moves to its next member through runner_pools.py, with no YAML edit. The
reconciler fills every declared pool on its next pass; feat-cmux-next's
workflows start reading the new keys only after that.

Leo-ask: ask-973a915bea

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-04cad32e0d917ebc8a49
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@cursor

cursor Bot commented Nov 2, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 96dfad1 and 4965324.

Files selected for processing: 3
  • .github/runners.json
  • docs/ci-runners.md
  • tests/test_ci_runner_pools.py

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The runner configuration adds Linux pools for five vCPU sizes and a macOS-latest pool. The documentation describes pool selection and member ordering. Tests check Linux pool ordering and update the held-state fixture.

Changes: Runner Pool Definitions

Layer / File(s) Summary
Declare runner pools
.github/runners.json
Adds Linux pools for 2, 4, 8, 16, and 32 vCPU workloads with ordered fallback members. Adds a macOS-latest pool with macOS 26 as its fallback.
Document and validate runner pools
docs/ci-runners.md, tests/test_ci_runner_pools.py
Documents size-based Linux pool selection and pool member ordering. Adds checks for Linux pool ordering and updates the held-state fixture.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Feature

Suggested reviewers: lawrencecchen

Merge Risk: Low · previous review 49653

The new pools are declared, but workflows do not yet use the size-specific keys. Mark that migration as pending so operators do not expect size-pool failover to reroute existing jobs. This is a bounded documentation issue.

Pre-merge checks: Passed 24 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 24 passed
Check name Status Explanation
Title check Passed The title names the main change: one runner pool per Blacksmith Linux size, so a stalled size can fail over by declaration. The changeset adds size-specific pools (linux_2, linux_4, linux_8, linux_16,…
Description check Passed The description follows the template structure. It has a Summary that states the problem (literal single-size labels strand jobs when a size stalls) and the resulting behavior (pools with preferred an…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Cmux Cloud Persistent Session And Early Input Passed PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff adds CI runner-pool declarations, documentation, and tests. It does not …
Cmux Swift Actor Isolation Passed The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The authoritative diff contains no Swift files or production Swift changes, so the Swif…
Cmux Swift Blocking Runtime Passed The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The authoritative diff contains no Swift files or Swift runtime synchronization changes…
Cmux Browser Automation Off-Main Passed PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It does not change Sources/TerminalController.swift, `ControlCommandExecutionPo…
Cmux Expensive Synchronous Load Passed The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The reviewed diff contains no Swift files or production agent-history loading changes, …
Cmux Cache Substitution Correctness Passed PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no production Swift, TypeScript, or JavaScript changes, and no …
Cmux No Hacky Sleeps Passed PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It introduces no TypeScript, JavaScript, shell, or production runtime delay. The …
Cmux Algorithmic Complexity Passed PASS: The PR changes only runner configuration, documentation, and Python test code. It adds fixed-size pool member declarations and test assertions; it does not add or modify production Swift, TypeSc…
Cmux Swift Concurrency Passed The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift code, so it does not introduce or expand any legacy Swift co…
Cmux Swift @Concurrent Passed The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift files or Swift code, so the @concurrent check is not appli…
Cmux Swift Package Boundaries Passed PASS. The pull request changes only runner configuration, CI documentation, and Python tests. It introduces no Swift production changes, so the Swift package-boundary rule does not apply.
Cmux Swiftpm Lockfiles Passed PASS: The PR changes only runner configuration, CI documentation, and runner-pool tests. It changes no SwiftPM package, Xcode project, .gitignore, workflow, dependency declaration, or `Package.resol…
Cmux Swift Logging Passed The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift files and adds or changes no logging statements. The Swift l…
Cmux User-Facing Error Privacy Passed The diff changes internal CI runner configuration, CI documentation, and tests only. It adds Blacksmith pool names and routing details, but the rule explicitly allows provider names in internal CI too…
Cmux Full Internationalization Passed The diff changes only .github/runners.json, CI operational documentation, and tests. The added pool names, runner labels, comments, and why fields are literal CI/configuration tokens, and `docs/ci…
Cmux Swiftui State Layout Passed PASS. The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift or SwiftUI changes, so the SwiftUI state/layout failur…
Cmux Architecture Rethink Passed PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift architecture changes, so the Swift architectural rethi…
Cmux Swift Auxiliary Window Close Shortcuts Passed PASS. The reviewed diff changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It contains no Swift changes and no standalone cmux-owned window code, so the au…
Cmux Source Artifacts Passed PASS. The PR changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff adds runner configuration, durable documentation, and test coverage. It adds no lo…
Cmux No Test Or Debug Seam In Production Source Passed PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It changes no Swift file under a production Sources/ path, so it introduces no …
Full details: Title check

Explanation

The title names the main change: one runner pool per Blacksmith Linux size, so a stalled size can fail over by declaration. The changeset adds size-specific pools (linux_2, linux_4, linux_8, linux_16, linux_32) and macos_latest in .github/runners.json, with matching docs and tests. The title does not mention macos_latest or the ephemeral-only linux_4 pool, but those are secondary to the main change.

Full details: Description check

Explanation

The description follows the template structure. It has a Summary that states the problem (literal single-size labels strand jobs when a size stalls) and the resulting behavior (pools with preferred and fail-over members, moved by declaration). It has a Testing section that names the commands run and the results. It has a Changelog-style entry only implicitly; the template asks for a Changelog section (none for internal-only CI changes) and a Proof section, and neither appears. The checklist is also omitted. The Summary and Testing content is substantive, so the description is mostly complete. The missing Changelog and Proof sections are non-critical for an internal CI change, but the author should add a Changelog line of 'none' and a Proof line explaining why no screenshots apply.

Resolution

Add a Changelog section with 'none' because this is an internal CI change. Add a Proof section with one line stating that no user-visible change exists (CI only). Delete checklist lines that do not apply. Consider adding a '### Observed / Not run' split under Testing, as the template asks for bug-fix PRs.

Full details: Cmux Cloud Persistent Session And Early Input

Explanation

PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff adds CI runner-pool declarations, documentation, and tests. It does not change Cloud terminal creation, cmux-tui transport, manual renderer admission, input routing, snapshots, authentication, revision fences, or leases.

Full details: Cmux Swift Actor Isolation

Explanation

The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The authoritative diff contains no Swift files or production Swift changes, so the Swift actor isolation check is not applicable.

Full details: Cmux Swift Blocking Runtime

Explanation

The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The authoritative diff contains no Swift files or Swift runtime synchronization changes, so this check is not applicable.

Full details: Cmux Browser Automation Off-Main

Explanation

PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It does not change Sources/TerminalController.swift, ControlCommandExecutionPolicy.swift, browser socket commands, worker routing, or policy tests. Therefore it does not introduce or worsen the specified browser automation off-main violations.

Full details: Cmux Expensive Synchronous Load

Explanation

The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The reviewed diff contains no Swift files or production agent-history loading changes, so this check is not applicable.

Full details: Cmux Cache Substitution Correctness

Explanation

PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no production Swift, TypeScript, or JavaScript changes, and no persistence, history, undo, or snapshot cache substitution.

Full details: Cmux No Hacky Sleeps

Explanation

PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It introduces no TypeScript, JavaScript, shell, or production runtime delay. The changed test fixture contains no new sleep or timer.

Full details: Cmux Algorithmic Complexity

Explanation

PASS: The PR changes only runner configuration, documentation, and Python test code. It adds fixed-size pool member declarations and test assertions; it does not add or modify production Swift, TypeScript, JavaScript, shell, or runtime algorithms covered by the complexity rules. No prohibited collection scans, rescans, joins, or hot-path sorting/filtering are introduced.

Full details: Cmux Swift Concurrency

Explanation

The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift code, so it does not introduce or expand any legacy Swift concurrency pattern.

Full details: Cmux Swift `@Concurrent`

Explanation

The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift files or Swift code, so the @concurrent check is not applicable.

Full details: Cmux Swiftpm Lockfiles

Explanation

PASS: The PR changes only runner configuration, CI documentation, and runner-pool tests. It changes no SwiftPM package, Xcode project, .gitignore, workflow, dependency declaration, or Package.resolved file, so the SwiftPM lockfile conditions do not apply.

Full details: Cmux Swift Logging

Explanation

The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift files and adds or changes no logging statements. The Swift logging rule therefore has no applicable violation.

Full details: Cmux User-Facing Error Privacy

Explanation

The diff changes internal CI runner configuration, CI documentation, and tests only. It adds Blacksmith pool names and routing details, but the rule explicitly allows provider names in internal CI tools, operator diagnostics, docs, and tests. No changed user-facing error, alert, API body, command output, recovery copy, secret, credential, token, or payload dump has a concrete path to a cmux end user.

Full details: Cmux Full Internationalization

Explanation

The diff changes only .github/runners.json, CI operational documentation, and tests. The added pool names, runner labels, comments, and why fields are literal CI/configuration tokens, and docs/ci-runners.md is operational documentation not shown to end users. No Swift UI text, app catalog, web UI text, locale registry, or message entries changed.

Full details: Cmux Swiftui State Layout

Explanation

PASS. The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift or SwiftUI changes, so the SwiftUI state/layout failure conditions do not apply.

Full details: Cmux Architecture Rethink

Explanation

PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff contains no Swift architecture changes, so the Swift architectural rethink criteria do not apply.

Full details: Cmux Swift Auxiliary Window Close Shortcuts

Explanation

PASS. The reviewed diff changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It contains no Swift changes and no standalone cmux-owned window code, so the auxiliary-window close-shortcut rule does not apply.

Full details: Cmux Source Artifacts

Explanation

PASS. The PR changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. The diff adds runner configuration, durable documentation, and test coverage. It adds no logs, screenshots, recordings, temporary or cache directories, dependency checkouts, build output, or broad scratch directories.

Full details: Cmux No Test Or Debug Seam In Production Source

Explanation

PASS: The pull request changes only .github/runners.json, docs/ci-runners.md, and tests/test_ci_runner_pools.py. It changes no Swift file under a production Sources/ path, so it introduces no production test or debug seam.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 1 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@blacksmith-sh

blacksmith-sh Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_every_depth_fetch_checks_for_a_shallow_checkout (main.NoShallowDevFetchTests.t
est_every_depth_fetch_checks_for_a_shallow_checkout)/
test_every_depth_fetch_checks_for_a_shallow_checkout (main.NoShallowDevFetchTests.t
est_every_depth_fetch_checks_for_a_shallow_checkout)
View Logs

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

@cmux-bot

cmux-bot Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

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

Probably yours: CI fast guards failed: a guard step failed, FAIL 1.3s workflow-guard-tests / ci: Validate scripts keep full clones full.

CI failed on c80b577a0c (run 41467655936 attempt 1): 1 code.

Job Verdict Why
CI fast guards code a guard step failed
Matched log lines
CI fast guards: FAIL    1.3s  workflow-guard-tests / ci: Validate scripts keep full clones full

Not re-run automatically: CI fast guards is not a machine failure.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

CI fast guards failed on c80b577a0c (https://github.com/manaflow-ai/cmux/actions/runs/41467655936). It does not block the merge; a red guard merged into main breaks it for every open PR.

Validate scripts keep full clones full (red on main too, not this PR)

Main has failed this step since #32137 by @teamleaderleo (self-merged) (#32187). Merge main again once the fix lands there.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

Merge receipt for c80b577a0c, merged 2026-11-02 15:24:11 UTC

  • Not verified at merge: ci-status (failure), CI fast guards (failure), linux-preflight (failure)
  • Verified: backend migrations applied, CI timing, Fast static checks, guards (6), merge freeze, plan, web-validation
  • Skipped by policy: apply-production, apply-staging, browser, Claude wrapper regressions, close lapsed freezes, Dogfood build #​${{ github.event.pull_request.number }}, GhosttyKit release check, macos, macOS admission gate, remote-daemon, suite-coverage, ui-tests, and 4 more
  • Full suite: runs on main after merge.

Labeled merged-unverified: if main breaks near this merge, look here first.

@coderabbitai coderabbitai 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.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread docs/ci-runners.md Resolved
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at 4965324

Checked: runner_pools.py spec/parse/reconcile with the six new pools, linux_4 vs feat's linux_ephemeral / LINUX_RUNNER mirror / spill / overflow switch, the dead-mark fixture change, macos_latest failover. Ran test_ci_runner_pools (42 OK), runner_label_policy, runner_set, capability_resolver, fork_runner_routing, simple_pool_picker, self_hosted_guard.sh.

Follow-ups: probe/janitor evidence for the 2, 8 and 32 vCPU Linux labels (so those pools move on a stall); linux_4 in the queue-aware spill; fold linux_4 and feat's linux_ephemeral into one when that reaches main.

…eading the pools

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-04cad32e0d917ebc8a49
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at c80b577

The only change since the reviewed head 4965324 reverts docs/ci-runners.md (the pool table moves to the feat-cmux-next PR), so this PR is CI data only: .github/runners.json and tests/test_ci_runner_pools.py. test_ci_runner_pools passes.

Follow-ups: as in the receipt above.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

recheck

@teamleaderleo
teamleaderleo merged commit 0e0cc6f into main Nov 2, 2026
43 of 48 checks passed
@teamleaderleo
teamleaderleo deleted the lane/runner-pools-per-size branch November 2, 2026 15:24
@github-actions github-actions Bot added the merged-unverified A judging check was not green at merge; see the merge receipt comment label Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-unverified A judging check was not green at merge; see the merge receipt comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant