Skip to content

ci: stop counting queue time on cancelled jobs as runner minutes - #14187

Merged
teamleaderleo merged 2 commits into
manaflow-ai:mainfrom
teamleaderleo:ci/cancelled-run-waste
Sep 24, 2026
Merged

teamleaderleo merged 2 commits into
manaflow-ai:mainfrom
teamleaderleo:ci/cancelled-run-waste

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The CI health report (run 35948904357) listed iroh-v2 client, cli-pipe-regressions, Claude wrapper regressions and macOS compile admission as the top "cancelled after ≥5 min of macOS work" offenders. Each of those sampled jobs never got a runner. They waited in the macOS queue and were cancelled when a newer push superseded the run.

The Actions API stamps started_at = created_at on a job cancelled while queued, with runner_id: 0, an empty runner name and no steps. The report took completed_at - started_at as runner minutes, so queue wait showed up as burned runner time. Now such a job has zero minutes, and its wait until the cancel counts as queue wait. That also makes the queue percentiles more honest: those jobs used to show 0 minutes of queue.

What the data says (report window 2026-09-23 20:37 to 2026-09-24 02:37 UTC)

Real runner minutes on cancelled jobs, versus queue-only time that the old report counted as minutes:

Job cancelled jobs runner min queue-only min
iroh-v2 / client 7 0 334
ci / cli / cli-pipe-regressions 52 21 1022
ci / Claude wrapper regressions 41 3 728
ci / macOS compile admission 89 321 2648
  • The iroh-v2 cancels are concurrency supersession on the same PR (the group is already keyed per PR). Path filters are correct: every run in the window came from a branch that touched workers/iroh-v2/**, CmuxIrxTransport, or the workflow file.
  • The compile admission minutes that did run were all pull_request supersessions, 1 to 28 min in. ci: gate macOS admission on fast Linux jobs through needs instead of a fixed sleep #14134 (merged 04:31 UTC, after this window) replaced the fixed 180 s debounce with a needs-gate, so the next snapshots are its before/after.
  • cmux-tui-testbox-warmup.yml is not waste: the job is the Testbox session, and its cleanup cancels the run on purpose. Documented in docs/ci/health-report.md.
  • test-depot.yml no longer exists on main (ci: route focused tests to one front door, and half of them to 12 vCPU #14067). 4 of its 5 cancelled tests jobs in the window also never got a runner.

Test plan

  • python3 -m unittest tests.test_ci_health_report (78 tests), including a new case built from the real run 35941162262 job payload
  • Re-scored the window's 197 cancelled ci.yml runs plus the iroh-v2 and testbox runs through the patched job_rows (table above)

🤖 Generated with Claude Code


Summary by cubic

Stops counting queue time on cancelled jobs as runner minutes in the CI health report.

Jobs cancelled before a runner picked them up now get zero minutes; GitHub stamps their started_at at creation, so the old report counted the entire queue wait as burned runner time. Their wait still counts as queue wait, and skipped jobs are unaffected.

Bug Fixes

  • Detects never-runner jobs via runner_id: 0, an empty runner name, and no steps.
  • Re-scoring the sampled macOS cancelled jobs shows most of their time was queue-only, not runner minutes.
  • Documents the Testbox warmup exception and the matching queue p90 bump, and adds a test based on a real queued-cancel job.

Written for commit 446a0e5. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Jobs cancelled before a runner starts now show zero runner minutes, with time spent waiting counted as queue wait instead.
  • Documentation
    • Clarified that queue-wait figures for cancelled jobs are lower bounds and may raise the reported macOS p90 without indicating a real regression.
    • Explained that cancelled minutes for Testbox warmup runs reflect the VM session, not runner work.

A job cancelled before any runner picked it up comes back from the Actions
API with started_at stamped at created_at, runner_id 0 and no steps. The
health report took started -> completed as runner minutes, so a job that
waited 53 minutes for a macOS runner and was then superseded showed up as
53 cancelled runner minutes and topped "Cancelled after >=5 min of macOS
work". Such jobs now have zero minutes and their wait counts as queue wait.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 9441890f-2999-449c-9dbc-93cb583b1677

📥 Commits

Reviewing files that changed from the base of the PR and between 23c0ce2 and 446a0e5.

📒 Files selected for processing (3)
  • docs/ci/health-report.md
  • scripts/ci/ci_health_report.py
  • tests/test_ci_health_report.py
 ___________________________________________________________________________________________________________________________________
< Don't use manual procedures. A shell script or batch file will execute the same instructions, in the same order, time after time. >
 -----------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo enabled auto-merge (squash) September 24, 2026 08:39
@teamleaderleo
teamleaderleo merged commit 2b6ca4c into manaflow-ai:main Sep 24, 2026
46 of 48 checks passed
rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 24, 2026
ff6c6dc ci: stop restoring an iOS GhosttyKit cache nothing saves (manaflow-ai#14189)
2827231 ci: seed DerivedData on the 12 vCPU macOS 26 pool (manaflow-ai#14188)
ae46aa9 Let Computer Use toggles save past unrelated cmux.json issues (manaflow-ai#14183)
a785270 test: fail loudly when portal rendering authority denies a fixture's tab id (manaflow-ai#13937)
9a1dea0 test: pin which terminal tabs get an agent mark after manaflow-ai#14062 (manaflow-ai#14177)
91bcb28 test: run the change-area tests in parallel workers (manaflow-ai#14193)
6d203e8 test: await the geometry publish in the equalize-splits shortcut case (manaflow-ai#13916)
48f1adf ci: balance the guard legs the macOS gate waits on (manaflow-ai#14186)
38117cd test: settle the split's reparent-focus suppression before focus feedback (manaflow-ai#14049)
a12a0b8 ci: neutralize Swift sources without a per-character loop (manaflow-ai#14169)
2b6ca4c ci: stop counting queue time on cancelled jobs as runner minutes (manaflow-ai#14187)
2837f22 test: stop gating terminal focus on key status the app host cannot grant (manaflow-ai#13948)
23c0ce2 test: give each detect-step run its own cmux-ci scratch files (manaflow-ai#14185)
a13ea28 ci: skip Mac lanes that bundled scripts and guard-only lints cannot fail (manaflow-ai#14179)
b59f34f ci: restore Swift packages and a compilation cache for iOS uploads (manaflow-ai#14180)
bcca243 profiling: poll child processes every 0.1 s instead of every second (manaflow-ai#14170)
76d6176 refactor: move 45 leaf browser files into CmuxBrowser (manaflow-ai#14092)
bf13034 test: fail the Desktop drop fast instead of restarting the app host (manaflow-ai#14076)
51d486b ci: start guards and web beside Fast static checks (manaflow-ai#14176)

# Conflicts:
#	.github/workflows/ci-guards.yml
#	.github/workflows/ci.yml
#	.github/workflows/ios-appstore-upload.yml
#	.github/workflows/ios-testflight.yml
#	.github/workflows/nightly.yml
#	.github/workflows/seed-derived-data.yml
#	.github/workflows/test-ios.yml
teamleaderleo added a commit that referenced this pull request Sep 25, 2026
A scripts/ci helper any routed job could reach selected every area, macOS,
web and Release included, wherever it ran. The walk that decided it also
followed comments, docstrings and the routing tables that list helpers as
data, so most helpers reached the `changes` job and forced everything. A
ci-macos.yml edit above `jobs:`, such as a new workflow_call input, did too.

- ci_helper_areas() replaces ci_helper_reaches_routed_lane(): a helper
  selects the areas that gate the routed jobs running it (ci-macos.yml jobs
  by the same rules as a job edit, ci-web.yml web, the CLI lane cli, a Linux
  job the areas its `if:` reads). Routing, status and other Mac jobs still
  run every area. Comments, docstrings and the three routing tables no
  longer count as running a helper.
- A ci-macos.yml workflow_call input edit reaches only the jobs that read
  the input, unless the workflow env reads it; a comment-only edit changes
  no job.

Replayed on the 20 CI-only PRs of 2026-09-23/24 that do not edit ci.yml or
ci-macos.yml, 5 drop from every area to none or macOS+CLI (#14326, #14312,
#14299, #14187: none; #14309, #14250: macOS+CLI), one of them drops web.
#14318's ci-macos.yml input edit would select macOS+CLI, not Release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Sep 25, 2026
…#14339)

* ci: route CI helper and ci-macos.yml edits to the lanes that run them

A scripts/ci helper any routed job could reach selected every area, macOS,
web and Release included, wherever it ran. The walk that decided it also
followed comments, docstrings and the routing tables that list helpers as
data, so most helpers reached the `changes` job and forced everything. A
ci-macos.yml edit above `jobs:`, such as a new workflow_call input, did too.

- ci_helper_areas() replaces ci_helper_reaches_routed_lane(): a helper
  selects the areas that gate the routed jobs running it (ci-macos.yml jobs
  by the same rules as a job edit, ci-web.yml web, the CLI lane cli, a Linux
  job the areas its `if:` reads). Routing, status and other Mac jobs still
  run every area. Comments, docstrings and the three routing tables no
  longer count as running a helper.
- A ci-macos.yml workflow_call input edit reaches only the jobs that read
  the input, unless the workflow env reads it; a comment-only edit changes
  no job.

Replayed on the 20 CI-only PRs of 2026-09-23/24 that do not edit ci.yml or
ci-macos.yml, 5 drop from every area to none or macOS+CLI (#14326, #14312,
#14299, #14187: none; #14309, #14250: macOS+CLI), one of them drops web.
#14318's ci-macos.yml input edit would select macOS+CLI, not Release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: close the routing review's under-selection gaps

- An input key with a trailing comment still opens its own input; a
  flow-style or unreadable one at that indent answers every job.
- A Linux job reads area outputs anywhere in its block (folded or step
  conditions), maps outputs derived from macOS to macOS, and runs every
  area when it waits on another job or reads an output this cannot place.
- The routing tables' imports still run a helper; only their path lists
  are dead ends.
- A helper the Swift package lane runs selects every area, since that lane
  is chosen by package path.
- `#!` lines are not comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant