fix(#4774): plan-criteria R4 requires the pipe not to be doubled — a logical-OR fallback is handled, not swallowed (#4877)

* test(#4774): failing-first — R4 must not read a logical-OR fallback as a pipeline stage

* fix(#4774): R4 requires the pipe not to be doubled — a logical-OR fallback is a handled failure, not a swallowed one

Also corrects the rows-3/4 test's makeCriteriaPlan usage (second arg is the
<verify> block, not a second criteria line).

* chore(#4774): backfill changeset PR number (4877)

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-09-19 15:38:16 -04:00
committed by GitHub
parent a87b83d485
commit 4fe2837ab5
3 changed files with 116 additions and 1 deletions

View File

@@ -922,8 +922,15 @@ function scanQuantitativeCriteria(content: string): { errors: string[]; warnings
// Not a markdown table: the negated-pipe class matches a SHELL pipeline
// stage boundary (git before the next `|`), the same shape the
// #429/#968 scanners use; there is no table row to parse.
// #4774: the lookahead keeps `||` — a logical OR, the construct that
// HANDLES the failure (e.g. the `git cat-file -e <sha> || echo missing`
// ghost-control idiom, reachable here when prose apostrophes leave the
// segment's quote state unclosed) — quiet, while `|` and `|&` (a real
// pipeline stage, stderr-merged or not) still warn. Accepted trade-off:
// a QUOTED `||` literal ahead of a real pipe (``git grep 'a||b' f | wc -l``)
// also goes quiet — the lookahead cannot reach past the doubled pipe.
// allow-adhoc-markdown: shell pipeline stage boundary, not a table cell (#4024)
if (/\bgit\s+[a-z][^\n|]*\|/.test(seg)) {
if (/\bgit\s+[a-z][^\n|]*\|(?!\|)/.test(seg)) {
record(
warnings,
'R4',