nightly: unread runners queue the app build on the owned pool, not Blacksmith macOS
Leo: "we just need the nightlies bro"
Problem
Run 41203691245 was the first nightly-next tip that included #29366, after about three hours with no tip build. Its pick-nightly-build-runner got a 403 rate limit on /actions/runners:
nightly build runner: owned: none (owned runners could not be read live, so no owned label is waited on)
nightly build runner: route: blacksmith-6vcpu-macos-26
build-nightly-app then sat queued on blacksmith-6vcpu-macos-26 and nothing started it. Meanwhile the nightly slot pool (glaeda-nightly-std-xcode-26.6, now on nine minis after HQ#5641) was ready to take it.
Change
nightly_build_runner.py: when the runners cannot be read (the token's API budget is spent, or there is no routing token), owned becomes the first watched owned label from OWNED_LABELS (unread_owned_route()). That is the nightly slot pool, a label many runners carry and the rescue watches and moves. With no watched owned label the pick still falls back to Blacksmith. Fleet first: Blacksmith is capped, paid overflow since 2026-10-30.
Tests
tests/test_nightly_build_runner.py: the three tests that expected Blacksmith on an unread read now expect the owned pool, and a new test checks that with no watched label the pick still takes Blacksmith. All 36 pass. The related routing suites (cascade, sign runner, trusted routing, train) pass too. test_ci_signing_owned_mac's hook-list failure is the base red that #29332 fixes.
Risk: low. It changes only the case where the picker could not read the runners.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Nightly app builds now queue on the owned slot pool when the runner picker can't read the runners, instead of a Blacksmith macOS label that may sit stalled.
Fixes run 41203691245, where a 403 rate limit on /actions/runners queued the first tip build after a three-hour red on blacksmith-6vcpu-macos-26 while the nightly pool had nine minis ready. When runners can't be read (API budget spent or no routing token) and the caller opts in, the picker uses the first watched owned label ā a many-runner pool the rescue watches and moves. Only nightly.yml's build pick opts in, and only while the CI_PR_POOL_OWNED kill switch is on; the train picker and verify picks still take Blacksmith on an unread pool. With no watched owned label the pick falls back to Blacksmith as before, and the owned-pool rescue now also recognizes the nightly slot label.