cmux-next fast gates: the crash-class rules are the fifth gate, red only for findings the PR adds

Merged
TE
16d ago
+265-4

The cmux-next crash-class rules become the fifth cmux-next fast gate. They fail a pull request only for findings it adds (coord-deputy, 2026-10-21).

cmux-next-crash-class.yml runs three checks: the crash-class concurrency rules (scripts/ci/crash-class-gate.sh), unrecognized selectors from super calls (check-objc-selectors.py) and the Chromium Objective-C contract (check-cef-objc-contract.py). None of them was a fast gate, so autoland and the merge hook never waited on them. The crash-safety rules chief-sidebar-2 asked about are already covered: the prepush gate runs check-crash-safety.sh on every changed CmuxNext and cmux-tui file and fails only on findings the PR adds.

What it does. New scripts/ci/crash_class_fast_gate.py, run by cmux_next_fast_gates.py on the merge with BASE's exported tree:

  • Concurrency: crash-class-gate.sh --pr, the same as its workflow. It already fails only for findings in files the PR changes, or for a change to its rules. The merge's first parent is BASE on both the pull_request merge ref and a dispatch's --no-ff merge, which is what pr_owned_findings.py reads.
  • Selectors and CEF contract: these check the whole tree. Each runs on the merge. When it fails there, the merge's copy runs again with --root on BASE's tree, and only failures the merge adds fail the gate. Failures are keyed without line numbers, so moved code is not new, but a second copy of a base failure is.
  • Every check runs even after one fails. A check that ends with neither its ok exit nor a failure line (a traceback) is red, because nothing can be compared.

Time. On a real merge of this branch into feat-cmux-next on huge-blue, the gate took 20 s, all green. The fast-gates step was about 40 s (crash ratchet 29 s, web lint 8 s), so it is now about 60 s.

Test

ef14c8a1a266 is the red commit:

python3 tests/test_crash_class_fast_gate.py     # FAILED (failures=9, errors=1): the script does not exist
python3 tests/test_cmux_next_fast_gates.py      # (at the fix) checks run() passes the fifth gate BASE's tree

Green at the head: test_crash_class_fast_gate.py 10 OK, test_cmux_next_fast_gates.py 25 OK.

tests/test_crash_class_fast_gate.py runs the gate in a temporary repository whose three checks print the findings listed in their tree. Cases:

  • all green: the base is not read;
  • a concurrency red stands, run with --pr;
  • a base failure on another line passes;
  • an added failure fails and is named;
  • a second copy of a base failure fails;
  • a merge or base crash fails;
  • every check runs after one fails;
  • the gate runs the same three scripts as the workflow.

It is wired into cmux-next-guards.yml's tooling tests.

Observed / Not run

  • Observed: the tests above, red then green. The real gate on a local --no-ff merge of this branch into feat-cmux-next (20 s, all ok). prepush-gate.py: no new violations.
  • Not run: a real failure of the selector or contract checks against a real base. The fake-check tests cover the comparison. This PR's own cmux-next fast gates run is the first CI run of the gate.

Changelog

none

Agent session: huge-blue

🤖 Generated with Claude Code


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


Summary by cubic

Makes the cmux-next crash-class rules the fifth cmux-next fast gate, so autoland and the merge hook now wait on them. The gate fails only for findings the PR adds.

How it gates

  • The concurrency rules run via crash-class-gate.sh --pr, already scoped to files the PR changes.
  • The selector and CEF contract checks run on the merge; when red there, they rerun against BASE's exported tree and only new findings fail, keyed without line numbers so moved code is not new.
  • Every check runs even after a failure; a check ending in a traceback is red because nothing can be compared.
  • Adds crash_class_fast_gate.py and 10 tests wired into cmux-next-guards.yml; the gate took 20 s on a real merge.