fix(ci): use shared runner state only for the first capacity look
A busy shared document can be read repeatedly while DEV landing placement waits, so the picker never notices a runner becoming idle. The archive picker has the opposite problem: it bypasses the shared reader and always calls the repository runner endpoint, even with its state binding present.
Use the archive document for its first look only, preserving its repository-only registration scope. After a wait, read live. Add an explicit use_state=False option to the shared runner listing and use it for DEV placement after the first look. Missing or invalid documents retain the existing API fallback. In the busy-to-idle regression, DEV placement previously returned no compile after 60 seconds; it now places the compile after the first 30-second recheck.
Follow-up to #31876's Opus review. Its workflow bindings and the five-minute reader age remain in place.
Performance
| metric | before | after | delta | harness or run link |
|---|---|---|---|---|
| routing-App runner-list requests/h at 1000 idle archive picks/h with fresh state | 1000 | 0 | -1000 (-100%) | same synthetic idle document through base/head ios_internal_runner.main |
| time to place a DEV compile when capacity becomes idle at the first recheck | no compile after 60 s | placed at 30 s | restores placement | same busy-document/live-idle main-entrypoint regression with injected clock |
Busy rechecks intentionally spend live runner-list requests to observe changed capacity. The table isolates the idle archive path; it does not claim total installation traffic.
Observed / Not run
All 8 archive picker, 23 DEV placement, 11 shared-state reader/scoping, and 7 DEV landing workflow tests pass. Four main-entrypoint regressions fail on test-only commit 837ba603e777 and pass with the fix. They cover idle-state API avoidance, busy-to-idle live recheck, repository-only archive scope, invalid-state fallback and DEV placement after a wait. git diff --check passes. No application build is needed for these picker reads.
Changelog
none
Agent session: agent session
![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
Fixes picker wait loops that kept reusing a stale shared runner-state document, so capacity changes are now noticed after a wait.
- The archive picker reads the shared state document only for its first look; subsequent rechecks read the live runner API.
- DEV placement also uses the shared document only for its first look and rechecks live after waiting.
- Adds a
use_state=Falseoption to the shared runner listing for live rechecks. - Missing or invalid documents keep the existing API fallback.
- The busy-to-idle regression previously placed no compile after 60 seconds; it now places it after the first 30-second recheck.