Summary
Every GC gate that runs on macos-14 has produced zero results on main for over a day. They are not failing and not cancelled — they never reach a runner. The Ubuntu-hosted gates in the same repo run normally, which localises this to macOS runner capacity rather than to any workflow's configuration.
Measured 2026-08-11:
| workflow |
runner |
successful main runs in last 24h |
| gc-ratchet |
macos-14 |
0 |
| tls-budget |
macos-14 |
0 |
| gc-root-dominance |
ubuntu-latest |
17 |
gc-ratchet's last successful run on main was 2026-08-09. Of its 30 most recent main runs, 27 are queued and 3 completed. The oldest still-queued run was created at 05:24 and was still waiting ~10 hours later.
Queue depth is repo-wide across the macOS gates:
Security Audit 9 queued
gc-native-roots 9
GC Root Dominance 9
GC Ratchet 9
TLS Budget 8
GC Ptr<Shape> OFF-arm witness 8
Why this is worse than a slow gate
Two days of GC-heavy merges landed with the GC gates dark. #7799, #7809, #7812, #7834 and #7839 all touch the collector, the allocation path, or write barriers. gc-ratchet is the primary defence for exactly that surface, and it has not run on main since before any of them merged.
The consequence is already visible: #7843 reports 7 gating rows genuinely red on main (proven code-drift, not host, by a pin-binary/main-binary A/B on one host, bisected to at-or-before #7812). Nobody saw them, because the gate that would have said so never ran. Separately, two probes widely believed red (04_dead_after_deep_stack, 11_collect_at_depth) turn out to be green — a stale belief that also survived because there was no signal to correct it.
This is not the concurrency bug, and that matters
gc-ratchet.yml's concurrency block is already correct and carries a long comment documenting two prior attempts (#7205): a shared group with unconditional cancel-in-progress cancelled three consecutive main runs; scoping cancel-in-progress to pull requests did not fix it either, because GitHub allows at most one pending run per group. The current config keys the group on github.sha for push events, so no two main runs can contend.
That fix worked, and the failure mode simply moved. Runs no longer cancel each other — they queue instead, and never drain. The gate is dark either way. This is a third variant of CLAUDE.md's "four ways a gate can be unable to fail": not continue-on-error, not missing from required contexts, not cancelled — starved.
Suggested directions
- Move what can move to
ubuntu-latest. gc-root-dominance already does and is unaffected. Anything that does not genuinely need macOS semantics (Mach-O, _tlv_get_addr, the Darwin allocator) is a candidate.
- Reduce macOS trigger frequency on
main — for instance, run the macOS arm on a schedule plus tag pushes rather than every merge, so the queue can drain. A gate that runs four times a day and completes is worth more than one that runs on every merge and never does.
- Check the account's macOS concurrency limit against the current merge cadence. Six workflows × every merge, at 40+ minutes queued each, may simply exceed it.
- Whatever is chosen, alert on staleness: "no successful
main run in N hours" should be visible, because the current failure is silent by construction — an empty result set looks identical to a healthy one that nobody has looked at.
Found by
Investigating why gc-ratchet's red rows (#7843) went unnoticed for two days during a GC-heavy merge window.
Summary
Every GC gate that runs on
macos-14has produced zero results onmainfor over a day. They are not failing and not cancelled — they never reach a runner. The Ubuntu-hosted gates in the same repo run normally, which localises this to macOS runner capacity rather than to any workflow's configuration.Measured 2026-08-11:
mainruns in last 24hmacos-14macos-14ubuntu-latestgc-ratchet's last successful run onmainwas 2026-08-09. Of its 30 most recentmainruns, 27 arequeuedand 3 completed. The oldest still-queued run was created at 05:24 and was still waiting ~10 hours later.Queue depth is repo-wide across the macOS gates:
Why this is worse than a slow gate
Two days of GC-heavy merges landed with the GC gates dark. #7799, #7809, #7812, #7834 and #7839 all touch the collector, the allocation path, or write barriers.
gc-ratchetis the primary defence for exactly that surface, and it has not run onmainsince before any of them merged.The consequence is already visible: #7843 reports 7 gating rows genuinely red on
main(proven code-drift, not host, by a pin-binary/main-binary A/B on one host, bisected to at-or-before #7812). Nobody saw them, because the gate that would have said so never ran. Separately, two probes widely believed red (04_dead_after_deep_stack,11_collect_at_depth) turn out to be green — a stale belief that also survived because there was no signal to correct it.This is not the concurrency bug, and that matters
gc-ratchet.yml'sconcurrencyblock is already correct and carries a long comment documenting two prior attempts (#7205): a shared group with unconditionalcancel-in-progresscancelled three consecutivemainruns; scopingcancel-in-progressto pull requests did not fix it either, because GitHub allows at most one pending run per group. The current config keys the group ongithub.shafor push events, so no twomainruns can contend.That fix worked, and the failure mode simply moved. Runs no longer cancel each other — they queue instead, and never drain. The gate is dark either way. This is a third variant of CLAUDE.md's "four ways a gate can be unable to fail": not
continue-on-error, not missing from required contexts, not cancelled — starved.Suggested directions
ubuntu-latest.gc-root-dominancealready does and is unaffected. Anything that does not genuinely need macOS semantics (Mach-O,_tlv_get_addr, the Darwin allocator) is a candidate.main— for instance, run the macOS arm on a schedule plus tag pushes rather than every merge, so the queue can drain. A gate that runs four times a day and completes is worth more than one that runs on every merge and never does.mainrun in N hours" should be visible, because the current failure is silent by construction — an empty result set looks identical to a healthy one that nobody has looked at.Found by
Investigating why
gc-ratchet's red rows (#7843) went unnoticed for two days during a GC-heavy merge window.