fix(verifier): always load ROADMAP SCs regardless of PLAN must_haves
The verifier's Step 2 previously used Option A (PLAN frontmatter must_haves) exclusively when present, skipping Option B (ROADMAP SCs). This allowed planners to define a subset of must_haves, silently bypassing roadmap Success Criteria verification. Now ROADMAP SCs are always loaded first (Step 2a), PLAN must_haves are merged on top (Step 2b), and a merge step (Step 2c) ensures plan-authored must_haves can add but never subtract from the roadmap contract. Addresses #1418 (Gap 2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -88,13 +88,21 @@ Extract phase goal from ROADMAP.md — this is the outcome to verify, not the ta
|
||||
|
||||
In re-verification mode, must-haves come from Step 0.
|
||||
|
||||
**Option A: Must-haves in PLAN frontmatter**
|
||||
**Step 2a: Always load ROADMAP Success Criteria**
|
||||
|
||||
```bash
|
||||
PHASE_DATA=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" roadmap get-phase "$PHASE_NUM" --raw)
|
||||
```
|
||||
|
||||
Parse the `success_criteria` array from the JSON output. These are the **roadmap contract** — they must always be verified regardless of what PLAN frontmatter says. Store them as `roadmap_truths`.
|
||||
|
||||
**Step 2b: Load PLAN frontmatter must-haves (if present)**
|
||||
|
||||
```bash
|
||||
grep -l "must_haves:" "$PHASE_DIR"/*-PLAN.md 2>/dev/null
|
||||
```
|
||||
|
||||
If found, extract and use:
|
||||
If found, extract:
|
||||
|
||||
```yaml
|
||||
must_haves:
|
||||
@@ -110,25 +118,20 @@ must_haves:
|
||||
via: "fetch in useEffect"
|
||||
```
|
||||
|
||||
**Option B: Use Success Criteria from ROADMAP.md**
|
||||
**Step 2c: Merge must-haves**
|
||||
|
||||
If no must_haves in frontmatter, check for Success Criteria:
|
||||
Combine all sources into a single must-haves list:
|
||||
|
||||
```bash
|
||||
PHASE_DATA=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" roadmap get-phase "$PHASE_NUM" --raw)
|
||||
```
|
||||
1. **Start with `roadmap_truths`** from Step 2a (these are non-negotiable)
|
||||
2. **Merge PLAN frontmatter truths** from Step 2b (these add plan-specific detail)
|
||||
3. **Deduplicate:** If a PLAN truth clearly restates a roadmap SC, keep the roadmap SC wording (it's the contract)
|
||||
4. **If neither 2a nor 2b produced any truths**, fall back to Option C below
|
||||
|
||||
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.
|
||||
**CRITICAL:** PLAN frontmatter must-haves must NOT reduce scope. If ROADMAP.md defines 5 Success Criteria but the plan only lists 3 in must_haves, all 5 must still be verified. The plan can ADD must-haves but never subtract roadmap SCs.
|
||||
|
||||
**Option C: Derive from phase goal (fallback)**
|
||||
|
||||
If no must_haves in frontmatter AND no Success Criteria in ROADMAP:
|
||||
If no Success Criteria in ROADMAP AND no must_haves in frontmatter:
|
||||
|
||||
1. **State the goal** from ROADMAP.md
|
||||
2. **Derive truths:** "What must be TRUE?" — list 3-7 observable, testable behaviors
|
||||
|
||||
Reference in New Issue
Block a user