Commit Graph

14 Commits

Author SHA1 Message Date
Tom Boucher
7956d324c5 feat(sdk): flag UAT files that produce no extractable items (#3184)
Cycle 14 of ~15: a UAT file present but empty of headings,
orphans, and placeholders now emits NO_ITEMS_EXTRACTED rather
than reporting passed=false with reasons=[] (which was
indistinguishable from missing-files).
2026-05-18 23:30:39 -04:00
Tom Boucher
b116bb07b9 feat(sdk): flag bracketed-placeholder result values (#3184)
Cycle 13 of ~15: 'result: [pending]' (template placeholder
copy-pasted without being filled) was previously dropped by
the \w+ regex. Now flagged as BRACKETED_PLACEHOLDER.
De-conflicted against ORPHAN_ITEM_MISSING_RESULT so an item
with a bracketed result doesn't double-report.
2026-05-18 23:30:38 -04:00
Tom Boucher
f78f26688b feat(sdk): flag headings missing the result field (#3184)
Cycle 12 of ~15: heading-without-result-line was previously
silently dropped by the regex — meaning a phase with an
unfilled UAT item could falsely pass the predicate. We now
scan for orphan headings and emit ORPHAN_ITEM_MISSING_RESULT
so the operator's typo / unfilled-template is surfaced.
2026-05-18 23:30:38 -04:00
Tom Boucher
d7aa4ce6e3 feat(sdk): merge frontmatter human_verification items into roster (#3184)
Cycle 11 of ~15: reuses parseVerificationFrontmatterItems from
uat.ts. Frontmatter-declared manual-verification items roll
into the same items[] roster and emit HUMAN_VERIFICATION_NEEDED
reasons so passed=false is justified, not silent.
2026-05-18 23:30:38 -04:00
Tom Boucher
29a48d8a78 feat(sdk): emit CASE_MISMATCH reason for non-canonical pass casing (#3184)
Cycle 10 of ~15: a captured 'result:' value that lowercases to
'pass' but isn't literally 'pass' now produces a CASE_MISMATCH
reason rather than a generic NON_PASS_RESULT — so operators can
distinguish a real non-pass from a likely typo.
2026-05-18 23:30:38 -04:00
Tom Boucher
42cc42de8b feat(sdk): accept bold-prefixed **result:** key (#3184)
Cycle 9 of ~15: regex now matches both bare 'result:' and
bold-prefixed '**result:**' forms. Requester used the bold
form in the issue text; canonical template uses bare. Both
are equally valid; predicate is form-agnostic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:38 -04:00
Tom Boucher
7c1ffb4131 feat(sdk): strip blockquote-prefixed lines before UAT item scan (#3184)
Cycle 8 of ~15: adds blockquote-line stripping pass. Quoted
documentation snippets no longer pollute the item roster.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:38 -04:00
Tom Boucher
47a7412164 feat(sdk): strip HTML comment regions before UAT item scan (#3184)
Cycle 7 of ~15: adds HTML-comment stripping pass. Operator
notes inside <!-- ... --> no longer pollute the item roster.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:38 -04:00
Tom Boucher
3c0490c021 feat(sdk): strip fenced code blocks before UAT item scan (#3184)
Cycle 6 of ~15: adds fenced-block stripping pass to
stripMarkdownInjection. Docs-and-examples inside code fences
no longer pollute the item roster.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:38 -04:00
Tom Boucher
a38fa6c7a6 feat(sdk): strip frontmatter region before UAT item scan (#3184)
Cycle 5 of ~15: introduces stripMarkdownInjection helper.
First pass strips the YAML frontmatter region so injected
'### N. item' patterns inside frontmatter literal blocks
cannot be mistaken for real UAT items.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:38 -04:00
Tom Boucher
1a27780443 feat(sdk): empty phase dir surfaces NO_UAT_FILES reason (#3184)
Cycle 4 of ~15: phase dir present but no *-HUMAN-UAT.md files
now returns a typed NO_UAT_FILES reason instead of an empty
reasons array (which prior cycles used as a 'shouldn't happen'
fallback).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:38 -04:00
Tom Boucher
c1664e52ae feat(sdk): missing phase dir surfaces NO_PHASE_DIR reason (#3184)
Cycle 3 of ~15: when resolvePhaseDir returns null, predicate
returns a typed NO_PHASE_DIR reason. Previously the empty
reasons array was indistinguishable from other failure modes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:37 -04:00
Tom Boucher
0ff6b4cc88 feat(sdk): non-pass UAT items emit NON_PASS_RESULT reason (#3184)
Cycle 2 of ~15: introduces REASON_CODE frozen enum and UatReason
typed shape. Non-pass items (result not literally 'pass') now
contribute a typed reason instead of being invisible to callers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:37 -04:00
Tom Boucher
3efb39e321 feat(sdk): isPhaseUatPassed walking skeleton (#3184)
Cycle 1 of ~15: minimal end-to-end predicate. One phase dir, one
UAT file, one pass result. No injection stripping, no orphan
detection, no CLI registration yet — those follow in subsequent
commits per TDD discipline.

Also exports resolvePhaseDir from phase-list-queries.ts (was
private) so the new predicate can reuse it without duplication.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:30:37 -04:00