ci: refuse new GITHUB_TOKEN polling loops on feat-cmux-next
This adds feat-cmux-next's copy of the GITHUB_TOKEN polling scan, the same file as cmux#25203 on main. It runs in ci-guards, in the linux-guard lane.
Why. Workflows that pull requests into feat-cmux-next trigger, and its push workflows, run from feat-cmux-next's own files. A polling loop added there would drain the GITHUB_TOKEN budget that every workflow shares. That budget ran out four times on 2026-10-26 and failed nightly-next promotion, CLA and publish steps.
What it checks. A workflow step is flagged when one loop both sleeps and calls the GitHub API on github.token:
- It counts the script's own shell, Python and JS functions that the loop calls.
- It judges the token as gh does: GH_TOKEN wins over GITHUB_TOKEN, and the innermost scope wins.
- Existing pollers are allowlisted, each with a reason, and a stale entry fails the test.
- This branch's nightly-next-tick.yml coalescer is allowlisted as dead code: the schedule, workflow_run and the tick's own dispatch all run main's copy.
Changed since the last head (Codex BLOCK on b752b2c3):
- The pr_status, gallery-advisory and risk_tier changes are reverted, so the settle re-read after a status write stays.
- The scan is loop-local, counts helper functions, and follows gh's token precedence.
Changed since 887cf997 (Codex BLOCK):
- An API URL held in a variable counts: GITHUB_API_URL, an env value carrying
github.api_urlor api.github.com, or a shell assignment from one. This catches cmux-tui-artifacts' re-check and fleet-compile-check. - A loop that runs a repository script takes on that script's API calls and sleeps, transitively; this catches cmux-next-base-autofix's GhosttyKit wait. Every script a step runs is also read for its own loops.
- The 24 steps it now finds are allowlisted, each with what bounds it: 3 real waits, 3 write pacers, 8 retry-only loops, and 10 steps that never reach the flagged loop (whole-script reads).
Size: the scanner and its tests can't be split (about 900 lines, all in the scanner and its test).
Tests: python3 tests/test_ci_no_github_token_polling.py passes.
Risk: low. The change is test-only.
Agent session: agent session
š¤ Generated with Claude Code