69de3bca236aafb53d5ececf72448d092a4bced3
1 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e58b5e1721 |
fix(#1364): decisions adopt markdown-sectionizer seam + fail-loud coverage gate (epic #1372 T1) (#1386)
* test(#1364,#1365): add decisions regression tests (fail-first proof) Adds tests/decisions.test.cjs with: - #1364 recall tests: parseDecisions from markdown-header + em-dash bullets (these FAIL on pre-T1 code, proving the bug is present before the fix) - #1365 fail-loud tests: check.decision-coverage-plan must return passed:false for decision-shaped but 0-extracted content (FAIL pre-T1, gate silently passed) - extractDecisions outcome enum tests (could-not-parse/none-present/parsed) - Parser QA matrix: CRLF, unicode headings, fenced-code suppression, both bullet forms - Boundary/threshold tests at limit-1 (0), limit (1) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1364,#1365): adopt markdown-sectionizer seam in decisions.cts; add fail-loud gate #1364 — Recall: decisions.cts now uses the seam's extractTaggedBlocks and collectSection for the markdown-header fallback path. Em-dash bullet form (- **D-NN — title** body) is now recognised alongside the existing colon form. #1365 — Fail-loud: adds extractDecisions() returning a typed DecisionExtraction { decisions, outcome } where outcome is 'parsed' | 'none-present' | 'could-not-parse'. The blocking gate (cmdDecisionCoveragePlan) now treats could-not-parse as passed:false with a format-mismatch reason instead of the prior silent passed:true/skip. gap-checker runGapAnalysis surfaces 'extracted 0 of N — possible format mismatch' for could-not-parse instead of 'No requirements or decisions to check'. parseDecisions remains a thin delegate over extractDecisions, so all existing callers are unaffected. Seam adoption: stripFencedCode (seam), extractTaggedBlocks(content,'decisions') (seam), collectSection(content, /decisions?/i, {levelBounded,stripFences}) (seam). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1364,#1365): tighten could-not-parse, parse-miss fail-loud, curly-quote discretion, gap-checker FIX D FIX A: empty <decisions> scaffolds and all-prose sections no longer return could-not-parse; outcome is none-present unless the block/section contains a \bD- token or a parse-miss, preventing false blocks on legitimate phases. FIX B: parseDecisionLines now tracks parse-misses (D-NN-shaped bullets that fail both regexes); extractDecisions returns could-not-parse when parseMisses>0 even if some decisions parsed — silent drops no longer mask format errors. FIX C: curly-quote normalization regex now includes actual U+2018/U+2019 characters so '### Claude's Discretion' (curly apostrophe) correctly yields trackable:false (regression vs pre-T1 behavior). FIX D: gap-checker runGapAnalysis surfaces the decision could-not-parse format-mismatch signal independently of whether requirements items exist — previously masked inside `if (items.length === 0)`. Adds 14 behavioral regression tests (fail-first verified manually before fixes). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1365): fail-loud gate on parse-miss regardless of covered decisions Change the `could-not-parse` guard in `cmdDecisionCoveragePlan` and `cmdDecisionCoverageVerify` from `decisions.length === 0 && outcome === 'could-not-parse'` to fire on `outcome === 'could-not-parse'` alone. Previously a CONTEXT.md with a valid D-01 (covered by the plan) plus a malformed D-02 (parse-miss) would skip the guard (length === 1), proceed to coverage, find D-01 covered, and silently return passed:true — hiding the D-02 parse-miss entirely. Adds a gate-level fail-first test that places D-01 into a ## Must Haves section (DESIGNATED_HEADINGS_RE match) so coverage of D-01 would pass on its own, proving the only path to passed:false is the parse-miss fix. Also adds the matching verify-side advisory assertion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(#1364,#1365): add Fixed changeset (pr:0 placeholder) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1364): backfill changeset PR number (1386) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |