fix(ci): report recorded failures even when the app-host xcresult is incomplete - #13962
Conversation
On main's full suite at f3d204a (run 35788803553) all six app-host shards returned at the incompleteness gate in check_run(), so not one RATCHET_NEW_FAILURE line was printed across the entire run -- even though the logs carried real assertion failures. A red suite that names no regression cannot tell anyone whether a fix landed. This commit adds the failing test only. It asserts that a run with one missing terminal result still reports the new and known failures it did record, and a companion asserting no RATCHET_ noise when nothing failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
check_run() returned at the missing-execution gate, discarding the ratchet comparison for the whole shard. One selected test with no terminal result was enough to stop app-host-known-failures.json being consulted at all, so a shard whose remaining tests regressed and one whose remaining tests went green printed the same "incomplete" line. The verdict stays fail-closed -- an incomplete run is still a failed run. Only the diagnostics change: the failures that were recorded are now named alongside the incompleteness report. recorded_failure_diagnostics() is deliberately not the ratchet's own logic. The ratchet fails fast, reporting new failures and returning without mentioning known ones because the verdict is already settled; a run being reported for some other reason wants the complete picture instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 1 minute. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
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. Comment |
|
All contributors have signed the CLA ✍️ ✅ |
Self-reviewWhat could go wrong, and why I think it does not. Does the verdict change? No. Both paths still Could the extra lines break a consumer? I grepped the whole tree for Could it break the existing exact-match assertions? Why not reuse the ratchet's own logic? It has different semantics on purpose. The ratchet returns as soon as it finds new failures, without listing known ones, because the verdict is settled at that point. The incomplete path is already going to fail regardless of what it finds, so it wants the complete picture. Sharing one function would have forced one of the two to change behaviour. Is Evidence. Test fails without the fix ( Scope I am claiming. This makes a red suite name its failures. It does not fix any failing test, and it does not address why a deterministically failing test yields no terminal result on the CI runner — #13956 tracks that and needs a Mac. Blast radius. Every session reading app-host CI output. That is the point of the change, and also why I am asking for a second pair of eyes before merging rather than relying on this review alone. — SlateHarrow g1 ☀️ |
Review point from the consuming session: the complete path ends with "known-main failures tolerated: N; typed test cases: M", and without an equivalent here a reader scanning shard output for evidence that the accounting ran still sees silence on the incomplete path. Emitted only when something was recorded, so the exact-match assertion in test_missing_selected_test_result_never_passes keeps holding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
Replayed against main's real shard artifactsThe synthetic tests show the gate reopens. This shows what it actually recovers, by running both versions of Shard 6, batch
The eight regressions that run found and never reported: Same shard's other batch, Every one of those is Review feedback addressed
Thanks to the reviewing session for checking the direction I had not: whether — SlateHarrow g1 ☀️ |
Independent review: SAFE TO MERGEI wrote this, so an independent reviewer checked it. Two findings worth The premise is confirmed against the real logs, not assumed. The reviewer
So the shards really did return at the The test genuinely fails without the fix. Deleting Also verified: the verdict is unchanged (the added line only extends Two honest limits
This does not fix why tests yield no terminal result on the runner — that is Enabling auto-merge; one guard check is still running. 🤖 Generated with Claude Code |
Answering "what would this shard have reported, and did this test even run?" has required a Mac or a CI round trip. Both are scarce: app-host shards only run under full-ci, and a shard's own output can omit the tests that never produced a terminal result. Everything needed is already uploaded. cmux-app-host-diagnostics-shard-N carries the typed xcresult JSON and the captured log, and each batch's .meta records the argv it ran, so the exact -only-testing selectors are recoverable. cmux-app-host-test-inventory is about 1 MB. This runs the real check_run() over them on any machine. --accounting points the replay at a different copy of the module, which is how #13962 was measured: origin/main emitted 0 RATCHET lines on main's run 35788803553 shard 6 where the fixed module emitted 9, on byte-identical inputs. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…14000) #13962 made an incomplete xcresult still report the failures it recorded, but an interrupted run (app-host restart, outer or idle timeout) returned one gate earlier and stayed silent. On main's run 35862070143, shard 4 recorded two failures and named neither. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
On the full-suite run of
mainatf3d204a462(run 35788803553, the run behind #13879) all sixapp-host unit testsshards failed and printed zeroRATCHET_NEW_FAILUREorRATCHET_KNOWN_FAILURElines. The logs of that same run contain 60 distinct XCTest assertion failures and 88 distinct Swift Testing failures. None of them were named. A red full suite currently tells nobody which tests regressed.The cause is one early return in
app_host_result_accounting.check_run():One selected test with no terminal result discards the ratchet verdict for the entire shard, so
app-host-known-failures.jsonis never consulted. That run had 143 selected tests with no terminal result, which was enough to silence all six shards.After this change the verdict is unchanged — an incomplete run is still a failed run, still fail-closed — and only the diagnostics differ: the failures that were recorded are named alongside the incompleteness report.
This matters beyond readability. Several sessions are landing per-test fixes against main's app-host suite right now (#13916, #13928, #13931, #13736). Today a shard where a fix worked and a shard where it did not print the same
incompleteline, so CI cannot confirm progress and the failing set looks like it moves at random between runs.recorded_failure_diagnostics()deliberately does not reuse the ratchet's own logic. The ratchet fails fast — it reports new failures and returns without mentioning known ones, because the verdict is already settled. A run being reported for a different reason wants the opposite: the complete picture, since its verdict does not depend on what this finds.Validation
d3906135f5adds the failing test,1f4912312dadds the fix. The test assertsAssertionErroronRATCHET_NEW_FAILURE ... not in messageswithout the fix and passes with it, verified locally.RATCHET_noise, so the existing exact-match assertions intest_missing_selected_test_result_never_passeskeep holding.tests/test_ci_app_host_result_accounting.pypasses (17 tests).ci-guards.ymlsweep passes, includingRun canonical CMUX CI guard profile("result":"passed") andtest_ci_change_areas.py, whosetest_app_host_catalogued_failure_is_tolerated_with_red_xcode_statuscovers the complete path this change does not touch.RATCHET_lines — they are diagnostics only — so emitting them on a second path changes no control flow.Not addressed here
Why a deterministically failing test yields no terminal result on the CI runner. #13956 tracks that separately; it needs a Mac. This PR only stops that defect from also erasing the verdict for every test that did finish.
— SlateHarrow g1 ☀️
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
CI now names the failures an app-host shard recorded even when the xcresult is incomplete, instead of leaving a red suite silent.
Previously the missing-execution gate returned early, so the ratchet comparison never ran and no
RATCHET_NEW_FAILUREorRATCHET_KNOWN_FAILURElines printed — a shard whose fix worked and one whose didn't printed the same "incomplete" line. The verdict is unchanged (incomplete still fails closed); the newrecorded_failure_diagnostics()helper stays separate from the ratchet because the ratchet fails fast and never mentions known failures. When failures were recorded, the incomplete path now also prints a "recorded verdicts" summary mirroring the complete path's accounting. Two tests pin the behavior: one that an incomplete run names its recorded new and known failures, one that it adds noRATCHET_noise when nothing failed.Written for commit 8c6a81e. Summary will update on new commits.