Smallest-diff fix: cc-triage.mjs now reads shared/cc-support.json at startup and skips the LLM call for any version below supported_floor. Marks the entry with below_floor: true; the workflow's existing jq 'select(.gap_score >= 10)' filter naturally skips entries with empty features[], so issue filing already does the right thing.
cc-watch run 25632103449 (2026-05-10) attempted to triage every unsnapshotted version — W1b's snapshot-presence filter exposed 100+ ancient versions. The job hit GH Actions' cancellation timeout before finishing.
cc-triage: extracting features from 2.0.59... cc-triage: extracting features from 2.0.60... cc-triage: extracting features from 2.0.61... [... 100+ iterations ...] ##[error]The operation was canceled.
Implements the same compareSemver used in cc-release-watch.mjs — numeric-tuple compare, no prerelease handling needed (CC versions are X.Y.Z).
| Condition | Action | features[] | parse_failed | below_floor |
|---|---|---|---|---|
| version < supported_floor | SKIP LLM | [] | (unset) | true |
| version >= supported_floor, snapshot present | CALL LLM | extracted | false | (absent) |
| version >= floor, LLM fails twice | CALL LLM | [] | true | (absent) |
| cc-support.json missing/malformed | CALL LLM (legacy) | extracted | false | (absent) |
Two reasons:
parse_failed means "LLM tried and failed" — that's a retryable state via --retry-failed. Below-floor is a policy decision, not a failure. Conflating them would cause --retry-failed to repeatedly burn LLM calls on ancient versions.| Path | Change |
|---|---|
| scripts/cc-triage.mjs | Add compareSemver + readSupportedFloor helpers; per-version loop sets below_floor: true and skips callClaude for sub-floor entries |
| tests/integration/test-cc-triage.sh | New Test 8 covering W1h: below-floor entry skipped (no LLM call, no parse_failed), above-floor entry processed normally, no flag leak between entries |
npm run typecheck — cleannpm run test:security — 14 / 14 passed