fix(verifier): use ROADMAP Success Criteria instead of deriving truths from Goal (#538)
The verifier was deriving verification truths from the vague one-line Goal field, allowing partial implementations to pass. Now extracts Success Criteria as a structured array from `roadmap get-phase` and uses them directly as truths, with Goal derivation as fallback for older ROADMAPs without Success Criteria. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -86,9 +86,25 @@ must_haves:
|
||||
via: "fetch in useEffect"
|
||||
```
|
||||
|
||||
**Option B: Derive from phase goal**
|
||||
**Option B: Use Success Criteria from ROADMAP.md**
|
||||
|
||||
If no must_haves in frontmatter:
|
||||
If no must_haves in frontmatter, check for Success Criteria:
|
||||
|
||||
```bash
|
||||
PHASE_DATA=$(node ~/.claude/get-shit-done/bin/gsd-tools.js roadmap get-phase "$PHASE_NUM" --raw)
|
||||
```
|
||||
|
||||
Parse the `success_criteria` array from the JSON output. If non-empty:
|
||||
1. **Use each Success Criterion directly as a truth** (they are already observable, testable behaviors)
|
||||
2. **Derive artifacts:** For each truth, "What must EXIST?" — map to concrete file paths
|
||||
3. **Derive key links:** For each artifact, "What must be CONNECTED?" — this is where stubs hide
|
||||
4. **Document must-haves** before proceeding
|
||||
|
||||
Success Criteria from ROADMAP.md are the contract — they take priority over Goal-derived truths.
|
||||
|
||||
**Option C: Derive from phase goal (fallback)**
|
||||
|
||||
If no must_haves in frontmatter AND no Success Criteria in ROADMAP:
|
||||
|
||||
1. **State the goal** from ROADMAP.md
|
||||
2. **Derive truths:** "What must be TRUE?" — list 3-7 observable, testable behaviors
|
||||
|
||||
@@ -882,12 +882,19 @@ function cmdRoadmapGetPhase(cwd, phaseNum, raw) {
|
||||
const goalMatch = section.match(/\*\*Goal:\*\*\s*([^\n]+)/i);
|
||||
const goal = goalMatch ? goalMatch[1].trim() : null;
|
||||
|
||||
// Extract success criteria as structured array
|
||||
const criteriaMatch = section.match(/\*\*Success Criteria\*\*[^\n]*:\s*\n((?:\s*\d+\.\s*[^\n]+\n?)+)/i);
|
||||
const success_criteria = criteriaMatch
|
||||
? criteriaMatch[1].trim().split('\n').map(line => line.replace(/^\s*\d+\.\s*/, '').trim()).filter(Boolean)
|
||||
: [];
|
||||
|
||||
output(
|
||||
{
|
||||
found: true,
|
||||
phase_number: phaseNum,
|
||||
phase_name: phaseName,
|
||||
goal,
|
||||
success_criteria,
|
||||
section,
|
||||
},
|
||||
raw,
|
||||
|
||||
@@ -59,9 +59,25 @@ Returns JSON: `{ truths: [...], artifacts: [...], key_links: [...] }`
|
||||
|
||||
Aggregate all must_haves across plans for phase-level verification.
|
||||
|
||||
**Option B: Derive from phase goal**
|
||||
**Option B: Use Success Criteria from ROADMAP.md**
|
||||
|
||||
If no must_haves in frontmatter (MUST_HAVES returns error or empty):
|
||||
If no must_haves in frontmatter (MUST_HAVES returns error or empty), check for Success Criteria:
|
||||
|
||||
```bash
|
||||
PHASE_DATA=$(node ~/.claude/get-shit-done/bin/gsd-tools.js roadmap get-phase "${phase_number}" --raw)
|
||||
```
|
||||
|
||||
Parse the `success_criteria` array from the JSON output. If non-empty:
|
||||
1. Use each Success Criterion directly as a **truth** (they are already written as observable, testable behaviors)
|
||||
2. Derive **artifacts** (concrete file paths for each truth)
|
||||
3. Derive **key links** (critical wiring where stubs hide)
|
||||
4. Document the must-haves before proceeding
|
||||
|
||||
Success Criteria from ROADMAP.md are the contract — they override PLAN-level must_haves when both exist.
|
||||
|
||||
**Option C: Derive from phase goal (fallback)**
|
||||
|
||||
If no must_haves in frontmatter AND no Success Criteria in ROADMAP:
|
||||
1. State the goal from ROADMAP.md
|
||||
2. Derive **truths** (3-7 observable behaviors, each testable)
|
||||
3. Derive **artifacts** (concrete file paths for each truth)
|
||||
|
||||
Reference in New Issue
Block a user