Surface CI hang-cancels in monitor-tick check (11) - #3933
Conversation
🔍 Reviewer: CorrectnessVerdict: APPROVE Summary: Full reviewCycle 1 (no prior Function logic (
Test-verification gate (kind: bug-fix) — satisfied:
Neither gap blocks: the covered paths include every returned literal plus the boundary and one fail-open case. Readability / error handling: doc comment is thorough and accurately describes each literal and the fail-open rule. No error paths swallowed. |
🔍 Reviewer: RiskVerdict: APPROVE Summary: Change is internal monitor/admin tooling (shell + markdown) with no parity/observable surface impact. Alarm-fatigue regression risk is explicitly mitigated by the supersede/manual classification; cross-shell portability was verified. No blocking risk. Full reviewCycle 1 (no prior
Scope discipline: the Fail-open trade-off (accepted): an unreadable |
Review: Bounce-Back Cycle 1Reason: CI failed (unrelated, will rebase) Reviewer A: APPROVE — Both agent reviewers APPROVE and there are no external change requests, so the only red signal is CI. Failing check: This is unrelated to the diff: the PR changes only Routing back to |
Do: Mode B — CI re-trigger (no code change)Both agent reviewers APPROVE and there are no inline review threads to address. The bounce-back was solely the flaky A rebase on Routing back to |
Review: Bounce-Back Cycle 1Reason: CI failed (unrelated, will rebase) Reviewer A (Correctness): APPROVE — Both agent reviewers APPROVE and there are no external change requests, so the only red signal is CI. Failing check:
|
Add classify_ci_cancel TAP cases to scripts/test-monitor-skill-snippets.sh asserting a no-successor CI cancel at its job timeout-minutes cap classifies as hang-cancel (CI-not-green), while supersede/manual cancels and the failure path stay unchanged. Fails on current main: the function is absent, so the harness aborts with "classify_ci_cancel: command not found". Refs #3823 Co-authored-by: Claude Code <claude-code@anthropic.com>
A CI job wall-clock-killed at its timeout-minutes cap resolves conclusion `cancelled`, not `failure`, so monitor-tick check (11) — which keyed only on `failure` — scored it `ci: all green`. Per #3768 that is the worse of the two testnet-shard modes: `if: failure()` never fires, the #3289 diagnostics dump is destroyed, and `--log-failed` is empty, so the monitor was blind exactly where the evidence is thinnest. Add a pure, unit-tested `classify_ci_cancel` to monitor-decisions.sh that maps a job outcome to not-cancel / supersede-cancel / hang-cancel / manual-cancel, distinguishing a reportable hang (no successor, duration >= job timeout-minutes) from a routine concurrency supersede (avoiding the #3653 alarm-fatigue regression). Rewire check (11a)/(11b)/REPORTING RULE and the `ci:` status line around it, read the immutable per-job conclusion (closing the run-level non-monotonicity a retry would otherwise cause), and add the no-auto-rerun rule for hang-cancels. Refs #3823 Co-authored-by: Claude Code <claude-code@anthropic.com>
7edf77f to
c27b892
Compare
Do: Mode B — rebased on current main (resolved TAP-plan conflict)Both agent reviewers APPROVE with no inline review threads to address. The prior bounce-back was the flaky
Force-pushed the rebased branch ( |
tomerweller
left a comment
There was a problem hiding this comment.
Rebased on current main and resolved the TAP-plan conflict (now 486). Ready for re-review.
🔍 Reviewer: CorrectnessVerdict: APPROVE Summary: Re-review of the rebased head ( Full reviewCycle 2 (prior Independent verification on the rebased head (merged with
Function logic — correct:
Test-verification gate (kind: bug-fix) — satisfied:
Readability / error handling: doc comment accurately describes each literal and the fail-open rule; no error paths swallowed. |
🔍 Reviewer: RiskVerdict: APPROVE Summary: Re-review of the rebased head. Change is internal monitor/admin tooling (shell + markdown) with no parity/observable-surface impact. The #3653 alarm-fatigue regression is explicitly mitigated by the supersede/manual classification; cross-shell portability holds. No blocking risk; no new concern class discovered. Full reviewCycle 2 (prior
Scope discipline: Fail-open trade-off (accepted): unreadable timeout on a no-successor cancel biases toward a false |
✅ MergedCommit: 129190c Follow-up issues filed for unaddressed inline review comments: none (no unresolved inline threads on the PR) |
Closes #3823
Summary
monitor-tick check (11) keyed exclusively on conclusion
failure, so a CI job wall-clock-killed at itstimeout-minutescap — which resolvescancelled, notfailure— was scoredci: all green. Per #3768 that is the worse of the two testnet-shard failure modes: because the job endscancelled,if: failure()never fires, the #3289 watchdog diagnostics dump is destroyed, and--log-failedis empty. This PR teaches the monitor to detect it.A pure, unit-tested
classify_ci_cancel(scripts/lib/monitor-decisions.sh) maps a job outcome tonot-cancel/supersede-cancel/hang-cancel/manual-cancel, distinguishing a reportable hang (no superseding run and duration ≥ the job'stimeout-minutescap) from a routine concurrency supersede — so widening the predicate does not recreate the #3653 alarm fatigue. Check (11a)/(11b)/REPORTING RULE and theci:status line are rewired around it; (11b) now reads the immutable per-job conclusion, closing the run-level non-monotonicity a retry would otherwise cause (#3823 comment 6). Hang-cancels are explicitly excluded from auto-rerun (#3768: the rerun burns another full runner slot and lands identically).Downstream blind spots in
quickstart-retry.ymland the diagnostics-upload step (issue comments 4–6) are OUT of scope per triage — this PR fixes only the monitor's detection.Plan reference
Converged Plan comment
Test plan
scripts/test-monitor-skill-snippets.sh— 485/485 TAP (was 478; +7 newclassify_ci_cancelcases + structural SKILL.md-references assertion)scripts/test-shell-lib-cross-shell.sh— 41/41 (new fn sources+runs clean under bash and zsh; no bashisms)bash -non both modified shell files; direct zsh call returnshang-cancelRegression test (kind: bug-fix)
scripts/test-monitor-skill-snippets.sh—classify_ci_cancelcases T63aa–T63agac93aad— verified FAILED: the function is absent on main, so the harness aborts withclassify_ci_cancel: command not found(set -euo pipefail); (11b)'sselect(.conclusion == "failure")returns empty for a cancelled job (scored green)7edf77f— the CI: the ~55-min quickstart testnet step-8 hang recurred on #3765 attempt 4 — #3289's step-level timeout-minutes: 25 did not fire, and the job cancel destroyed the watchdog dump it was built to capture #3768 fixture (cancelled no 3300 2700) returnshang-cancel; supersede/manual/failure paths unchangedDeviations from plan
None.
🤖 Generated with Claude Code