ci: the overflow watch and nightly control jobs never wait on Blacksmith Linux
Merged
TE
8d ago+74+74+01234567890123456789-9-9-0123456789
On 2026-10-28, from about 20:00Z to 21:15Z, Blacksmith stopped starting jobs on every Linux size (2, 4, 8, 16 and 32 vCPU) across the org. Blacksmith macOS kept starting jobs within seconds, and status.blacksmith.sh reported all systems operational. Two parts of our own CI made the outage worse:
- The overflow switch couldn't decide. Run 40758329180 queued its probe (4 vCPU Linux) and its watch (16 vCPU Linux) at 20:07:53Z. The watch was waiting on the same pool the probe tests. That run held the workflow's concurrency group, so the scheduled runs at 20:09, 20:20, 20:34, 20:43 and 20:52 were replaced while pending. Nothing was decided until Blacksmith came back at 21:15Z.
- The nightly-next tick and the feed watch had nowhere else to run. Both are pinned to
blacksmith-2vcpu-ubuntu-2404.
Changes:
- Overflow watch. It now always runs on
blacksmith-6vcpu-macos-26, or onCI_CONTROL_RUNNERwhen that is set. Forks getmacos-26. It already ran on that label while overflow was off: run 40755571607 today at 19:41Z. The probe still tests Blacksmith Linux, so the watch has to sit on another pool to judge it. The old 16 vCPU branch is removed. - Concurrency group. The overflow workflow keeps its single fixed group. The switch's variable writes and its record delete are separate calls, so two watches must never run at once. Once a watch starts, it decides within
CI_CLOUD_PROBE_MINUTESor force-cancels its own run, so it can't hold the group for long. - New
CI_CONTROL_RUNNERvariable. It is unset by default, so nothing changes until someone sets it. When set, it moves the tick'srequestjob and the feed watch'swatchjob off Blacksmith Linux. To support a macOS value, the tick's gh cache shim hashes withshasum -a 256wheresha256sumis missing. ci-health-report and ci-repo-variables now report the variable, and the live runs-on check reads it. promote-nightly-nextis unchanged. It holds the release App credentials, and only a literal ephemeral label may carry them.- Docs. docs/ci-runners.md covers all of the above. It also states what this does not fix: a nightly's Linux cross-builds still wait for Blacksmith Linux, or for the
LINUX_RUNNERbreak-glass.
Risk: low. With the variable unset, the only behavior change is that the overflow watch takes a 6 vCPU macOS slot where it used to take a 16 vCPU Linux one, for about a minute every 10 minutes. The tick and the feed watch have not yet run on macOS. The docs say to check the first run after setting the variable.
Tests, all passing locally:
- test_ci_cloud_overflow_switch: watch runs-on and the fixed group
- test_ci_nightly_off_blacksmith: the CI_CONTROL_RUNNER branch and the portable hash
- test_ci_runs_on_values
- test_runner_label_policy
- test_ci_fork_runner_routing
- test_ci_signing_keychain_is_deleted_before_bundle_code
- test_ci_repo_variable_defaults
- test_nightly_delivery_concurrency
- test_nightly_promotion_admission
- test_ci_actionlint_covers_every_workflow
- test_ci_guard_workflow_structure
- test_ci_quota_hold_gate
- test_ci_self_hosted_guard.sh
- actionlint on every changed workflow
🤖 Generated with Claude Code
Agent session: agent session
Summary by CodeRabbit
- Chores
- CI runner selection can be configured for overflow monitoring and nightly checks; existing fallback runners remain available when no override is set.
- Nightly checks can generate SHA-256 cache keys using either of the common checksum utilities.
- Overflow monitoring continues to use a fixed concurrency group, with overlapping runs prevented.
- Documentation
- Updated CI runner guidance to describe runner overrides, fallback behavior, and overflow-monitoring details.