Skip to content

ci: stop buying a universal Release build for CI janitors and reporters - #13912

Merged
teamleaderleo merged 2 commits into
mainfrom
ci/infra-helper-routing
Sep 23, 2026
Merged

teamleaderleo merged 2 commits into
mainfrom
ci/infra-helper-routing

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Editing scripts/ci/queue_janitor.py, triage-radar.py, notify-indexnow.py or ten similar helpers selects macOS, web, agent-session-web and a universal Release build. Each runs only in a Linux workflow and none is read by the Xcode product — they were simply unclassified, so they hit the fail-open default the way the two transport helpers did before #13895.

Resulting behavior

                                      before                                      after
queue_janitor.py        macos=T web=T agent_session=T release=T    all false
triage-radar.py         macos=T web=T agent_session=T release=T    all false
web_subareas.py         macos=T web=T agent_session=T release=T    web=T, rest false
detect_ci_change_areas.py                    (unchanged)           macos=T web=T release=T
cmux_unit_test_shard.py                      (unchanged)           macos=T web=T release=T

web_subareas.py needs both halves

It is ci-web.yml's subarea router, so it keeps the web area through is_web_change while dropping macOS and Release. Neutralizing it without that second edit would stop running web validation on the web router itself — a false negative. test_web_subarea_router_keeps_web_without_macos pins that.

Editing it still exercises every web subarea, because the helper lists itself in its own ALL_SUBAREA_INPUTS (web_subareas.py:56-59).

Deliberately excluded

  • detect_ci_change_areas.py, detect_linux_guard_changes.py, workflow_guard_groups.py — these decide routing. They should keep native coverage rather than certify themselves.
  • cmux_unit_test_shard.py, xcodebuild_noninteractive.py — real macOS build inputs, referenced from macOS workflows.
  • cache_restore_receipt.py — reached from macOS jobs through the cache-restore composite action (.github/actions/cache-restore/action.yml:88).
  • test_execution_registry.py — dropped from the carveout after review. scripts/ci/run_python_test_lane.py:13 imports it and ci-macos.yml runs that lane helper on a macOS runner at four call sites (:1975, :1993, :2002, :2003), so it does execute on a Mac. Same indirect reachability as the two above; an earlier revision of this PR classified it by mistake.
  • CLA.md — prose, but the CLA guard reads it.

test_routing_policy_and_build_helpers_still_run_macos pins all seven excluded paths, so the carveout cannot silently widen across that boundary. test_operational_ci_helpers_skip_product_areas pins all thirteen carved-out helpers.

Linux guard coverage is unaffected

Guard routing takes macos as an input, so this was the thing worth checking rather than assuming. detect_linux_guard_changes.py resolves linux_guard_tests=true for these paths with --macos true and --macos false; only ghosttykit_release drops, which is correct when no macOS build runs.

Tradeoff

A helper added later is still unclassified and still fails open — expensive, never wrong. This narrows fourteen known files rather than changing the default. For why the default itself should stay fail-open, see #13905: 72.0% of changes genuinely select macOS.

Validation

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Given the initial reject/non-acceptance tag, confidently handling this further edited as working iterations. Since no major constraints.

Written for commit 7e495f1. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • CI now avoids running macOS and release-build checks for operational maintenance changes that do not affect those builds.
    • Changes to web-area routing continue to trigger web checks without triggering macOS or release-build checks.
    • Added coverage to verify these CI routing behaviors.

Editing scripts/ci/queue_janitor.py, triage-radar.py, notify-indexnow.py or
eleven similar helpers selected macOS, web, agent-session-web and a universal
Release build. Each of them runs only in a Linux workflow and none is read by
the Xcode product; they were simply unclassified, so they hit the fail-open
default the way the two transport helpers did before #13895.

Classify the operational set -- janitors, census and reporting, registry
validation, R2 canaries, build diagnostics -- as control-plane-only.

scripts/ci/web_subareas.py needs both halves: it is ci-web.yml's subarea
router, so it keeps the web area through is_web_change while dropping macOS
and Release. Neutralizing it without that second edit would stop running web
validation on the web router itself.

Deliberately excluded: detect_ci_change_areas.py, detect_linux_guard_changes.py
and workflow_guard_groups.py. Those decide routing, so they should keep native
coverage rather than certify themselves. cmux_unit_test_shard.py and
xcodebuild_noninteractive.py are real macOS build inputs.

Linux guard coverage is unaffected: guard routing takes macos as an input but
resolves linux_guard_tests=true either way; only ghosttykit_release drops,
which is correct when no macOS build runs.

Measured with classify_files() over the last 357 first-parent commits on main,
this frees 8 changes from both macOS and the Release build.

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

coderabbitai Bot commented Sep 23, 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: a722775c-7c2f-451b-a5be-752ff46d4d2f

📥 Commits

Reviewing files that changed from the base of the PR and between af221f0 and 7e495f1.

📒 Files selected for processing (2)
  • scripts/ci/detect_ci_change_areas.py
  • tests/test_ci_change_areas.py
 ____________________________________________________
< Losing sleep over your code, so you don't have to. >
 ----------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • 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.

@github-actions

Copy link
Copy Markdown
Contributor

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

Review caught that the previous commit's carveout comment was false for one
file. scripts/ci/run_python_test_lane.py imports test_execution_registry, and
ci-macos.yml runs that lane helper on a macOS runner at four call sites, so the
registry module does execute on a Mac.

That is the same indirect reachability that keeps cache_restore_receipt.py (via
the cache-restore composite action) and xcodebuild_noninteractive.py (via
run-app-host-xcodebuild.sh) out of the carveout. Treating it differently was an
inconsistency, not a judgement.

Drop it from CI_CONTROL_PLANE_ONLY, correct the comment to say no workflow runs
these on a macOS runner directly or through a wrapper, and record why the
registry module is excluded.

Also close the two test gaps the review found: the operational test covered ten
of the helpers rather than all of them, and the boundary test pinned two of the
six exclusions the description claimed. Both now cover the full set, including
the file dropped here, so a future widening across this boundary reddens.

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

Copy link
Copy Markdown
Collaborator Author

Independent agent review — Thornquay 💠

I wrote this change, so the review below was done by a separate agent told to falsify it. It returned merge with changes, and it was right. Pushed as 7e495f1469.

The defect it found. The carveout comment claimed all fourteen helpers "run only in a Linux workflow." That is false for one of them: scripts/ci/run_python_test_lane.py:13 does from test_execution_registry import load_registry, and ci-macos.yml runs that lane helper on blacksmith-6vcpu-macos-15 at :1975, :1993, :2002 and :2003. So test_execution_registry.py executes on a Mac.

What makes that a real miss rather than a judgement call: this PR already excluded cache_restore_receipt.py and xcodebuild_noninteractive.py for precisely this reason — reachable from a macOS job through a wrapper or composite action. I checked indirect reachability for those two and did not apply the same check to the registry module. Same risk class, opposite treatment.

It would not have been a silent hole — ci.yml:395 puts the file in the claude_wrapper case list, which keeps a required macOS lane — but nothing pinned that, so the safety rested on an incidental entry in an unrelated case statement. That is the fail-open→fail-closed transition this PR is supposed to avoid creating.

Fixed: dropped it (14 → 13), corrected the comment to say no workflow runs these on a macOS runner directly or through a wrapper, and recorded why the registry module is out.

Two test gaps it also found, both closed: the operational test covered ten of the helpers rather than all of them, and the boundary test pinned two of the six exclusions the description claimed to pin. Both now cover the full set including the dropped file, verified to redden under two independent widenings (extending the frozenset to all scripts/ci/*.py, and relaxing forces_all_areas).

Independently confirmed from the review:

  • Guard coverage is untouched: detect_linux_guard_changes.py returns linux_guard_tests=true for all of them with --macos true and --macos false; only ghosttykit_release drops, correctly.
  • The web_subareas.py two-part change is load-bearing. Without the is_web_change entry it goes fully neutral, and ci.yml:799-801 gates the web job on web/agent_session_web, so ci-web.yml would never wake to validate its own subarea router. Dropping agent_session_web is correct: ci-web.yml:329 gates that lane on its own input and does not depend on web-subarea-scope.
  • verify-r2-canary.py, r2-canary-cloudflare.py and notify-indexnow.py keep independent PR coverage through path-filtered triggers in ci-artifact-transport.yml and indexnow-tests.yml, which routing cannot affect.

Not acting on, deliberately: the review noted that web_subareas.py now partially certifies itself, and the test pinning it runs in the ci guard group while that path resolves to preflight — so a PR editing only that file would not run its own pin. That is real but pre-existing and wider than this change; it belongs in its own issue rather than scope creep here.

Validation after the fix: all 132 registered linux-guard tests pass, 0 failures. Like #13905 this classifies as routing-policy-only, so no macOS lane runs against it — the claim is about routing, not compilation.

@teamleaderleo
teamleaderleo enabled auto-merge (squash) September 23, 2026 06:17
@teamleaderleo
teamleaderleo merged commit 94fc7e8 into main Sep 23, 2026
38 of 40 checks passed
rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 23, 2026
ca867b7 ci(ios): bound the xcodebuild test invocation so a teardown wedge fails fast (manaflow-ai#13927)
9ffbb6a ci: compile the E2E test product once, in its own job (manaflow-ai#13908)
827f614 ci: let the macOS 15 and 26 pools share one Swift package cache (manaflow-ai#13925)
b79a83b Price GPT-6 models in coderouter API-equivalent estimates (manaflow-ai#13892)
ff20a22 Expose in-flight drag intent to custom JavaScript sidebars (manaflow-ai#13841)
3344583 Capture Cloud Desktop click destinations before queued opens (manaflow-ai#13897)
ac041c1 test(ios): assert the letterbox a daemon-push shrink actually produces (manaflow-ai#13920)
ce1c55c Catch guard-group drift between ci.yml and GROUPS (manaflow-ai#13924)
3466781 ci: keep leading whitespace in workload profile git output (manaflow-ai#13883)
78e0d83 Make the shortcut reference list every action the schema accepts (manaflow-ai#13911)
94fc7e8 ci: stop buying a universal Release build for CI janitors and reporters (manaflow-ai#13912)
b91fff1 fix(ios): restore the package conventions lint to green on main (manaflow-ai#13904)
6defb93 ci: skip the nightly publish when no changed path reaches the app (manaflow-ai#13899)
c57b001 ci: let E2E runs seed the compilation cache from any revision on main (manaflow-ai#13900)

# Conflicts:
#	.github/workflows/nightly.yml
#	.github/workflows/perf-activation.yml
#	.github/workflows/test-depot.yml
#	.github/workflows/test-e2e.yml
#	.github/workflows/test-ios.yml
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