fix(review-loop-run): counts parses count-by-severity block with scope + format branches (2026-09-13 fix, 40/40 tests)
Was live via ~/sbin symlink but never committed. Baseline for bug 5352fe72. Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
This commit is contained in:
@@ -56,7 +56,14 @@ review-loop-run --help
|
||||
|
||||
`status` scans `<dir>/*-r*-stdout.txt`; a file whose last line matches `^exit=` is `done`, else `running`; counts come from `counts`.
|
||||
|
||||
`counts` parses a result file with three fallbacks: a markdown table row `| CRITICAL | <n>`, a list line `- **CRITICAL:** <n>` / `CRITICAL: <n>`, or (failing both) the number of headings containing `CRITICAL`/`HIGH` — the same for HIGH/MEDIUM/LOW.
|
||||
`counts` parses the review's own count-by-severity block first, never bare numbers scattered through the file (a finding heading like "## Finding 3 — HTTP 404 on ..." or "### MEDIUM: ..." must not be misread as a count):
|
||||
|
||||
1. **Locate the scope.** Find the *last* line matching `/count.*severity|severity.*count|summary/i` and take from that heading up to the next `#`-heading (or EOF). If no such heading exists, the scope is the last 40 lines of the file.
|
||||
2. **Extract per severity, within scope only.** For each of CRITICAL/HIGH/MEDIUM/LOW, take the *last* match in scope of any of: `SEV: n`, `SEV = n`, `- SEV: n`, `**SEV**: n` (markdown emphasis markers around/inside the label are stripped before matching, so `**SEV:**` also matches), `| SEV | n |`, `SEV (n)`, or `n SEV` (word-boundary). A severity with no match in scope is 0 for this pass.
|
||||
3. **Fallback (derived).** Only if scope step 2 finds *no* severity at all (no count block present anywhere), fall back to counting lines that START with the severity word — `^\s*(#+\s*)?(\*\*)?(CRITICAL|HIGH|MEDIUM|LOW)\b` followed by `:`, `—`, or `-` — one count per finding line, never bare numbers elsewhere. Append a literal ` (derived)` marker to the output in this case.
|
||||
4. Missing severity → 0. Output stays `CRITICAL=n HIGH=n MEDIUM=n LOW=n` (plus the optional trailing `(derived)` marker); exit 4 iff CRITICAL+HIGH>0, else 0.
|
||||
|
||||
Fixtures: `tests/fixtures/review-loop-run/{bullet-list,table,inline-bold,heading-numbers,no-count-block}.md` cover, respectively: a bullet-list count block, a markdown-table count block, an inline `**HIGH**: 2` style block, a file with "HTTP 404" and a bare number in headings alongside a correct trailing count-by-severity table (regression case for the 2026-09-13 MEDIUM=404/HIGH=11 mis-parse), and a file with no count block at all (derived fallback from finding headings).
|
||||
|
||||
## Templates (per `--kind`)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user