# cc-triage: skip below-floor versions #1739 (W1h)

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.

## Real-run evidence job timeout

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.

## Try it interactive

supported_floor candidate version

Implements the same `compareSemver` used in `cc-release-watch.mjs` — numeric-tuple compare, no prerelease handling needed (CC versions are `X.Y.Z`).

## Decision matrix

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)

## Why a sentinel field instead of dropping the entry

Two reasons:

- cc-release-watch emits every unsnapshotted version into the gaps file as a recovery hatch (W1b). Dropping below-floor entries from cc-triage's output would re-introduce the silent-loss bug W1b fixed.
- `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.

## Files changed

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

## Verification

- tests/integration/test-cc-triage.sh — 27 / 27 passed (8 new W1h assertions)
- tests/integration/test-cc-release-watch.sh — 21 / 21 passed (no regression)
- `npm run typecheck` — clean
- `npm run test:security` — 14 / 14 passed