fix: requirements tracking chain — strip brackets, add requirements field to plans and summaries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson
2026-02-16 12:21:59 -06:00
parent 915d026ef3
commit cbf809417a
8 changed files with 89 additions and 6 deletions

View File

@@ -68,9 +68,10 @@ Same methodology (goal-backward), different timing, different subject matter.
**Process:**
1. Extract phase goal from ROADMAP.md
2. Decompose goal into requirements (what must be true)
3. For each requirement, find covering task(s)
4. Flag requirements with no coverage
2. Extract requirement IDs from ROADMAP.md `**Requirements:**` line for this phase (strip brackets if present)
3. Verify each requirement ID appears in at least one plan's `requirements` frontmatter field
4. For each requirement, find covering task(s) in the plan that claims it
5. Flag requirements with no coverage or missing from all plans' `requirements` fields
**Red flags:**
- Requirement has zero tasks addressing it

View File

@@ -345,6 +345,7 @@ wave: N # Execution wave (1, 2, 3...)
depends_on: [] # Plan IDs this plan requires
files_modified: [] # Files this plan touches
autonomous: true # false if plan has checkpoints
requirements: [] # Requirement IDs this plan addresses (from ROADMAP)
user_setup: [] # Human-required setup (omit if empty)
must_haves:
@@ -410,6 +411,7 @@ After completion, create `.planning/phases/XX-name/{phase}-{plan}-SUMMARY.md`
| `depends_on` | Yes | Plan IDs this plan requires |
| `files_modified` | Yes | Files this plan touches |
| `autonomous` | Yes | `true` if no checkpoints |
| `requirements` | Yes | Requirement IDs this plan addresses (from ROADMAP) |
| `user_setup` | No | Human-required setup items |
| `must_haves` | Yes | Goal-backward verification criteria |
@@ -450,6 +452,9 @@ Only include what Claude literally cannot do.
## The Process
**Step 0: Extract Requirement IDs**
Read ROADMAP.md `**Requirements:**` line for this phase. Strip brackets if present (e.g., `[AUTH-01, AUTH-02]` → `AUTH-01, AUTH-02`). Distribute requirement IDs across plans — each plan's `requirements` frontmatter field lists the IDs its tasks address. Every requirement ID must appear in at least one plan.
**Step 1: State the Goal**
Take phase goal from ROADMAP.md. Must be outcome-shaped, not task-shaped.
- Good: "Working chat interface" (outcome)

View File

@@ -3196,7 +3196,7 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
);
if (reqMatch) {
const reqIds = reqMatch[1].split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
const reqIds = reqMatch[1].replace(/[\[\]]/g, '').split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
let reqContent = fs.readFileSync(reqPath, 'utf-8');
for (const reqId of reqIds) {

View File

@@ -1825,6 +1825,79 @@ describe('phase complete command', () => {
assert.ok(req.includes('| API-01 | Phase 2 | Pending |'), 'API-01 should remain Pending');
});
test('handles requirements with bracket format [REQ-01, REQ-02]', () => {
fs.writeFileSync(
path.join(tmpDir, '.planning', 'ROADMAP.md'),
`# Roadmap
- [ ] Phase 1: Auth
### Phase 1: Auth
**Goal:** User authentication
**Requirements:** [AUTH-01, AUTH-02]
**Plans:** 1 plans
### Phase 2: API
**Goal:** Build API
**Requirements:** [API-01]
`
);
fs.writeFileSync(
path.join(tmpDir, '.planning', 'REQUIREMENTS.md'),
`# Requirements
## v1 Requirements
### Authentication
- [ ] **AUTH-01**: User can sign up with email
- [ ] **AUTH-02**: User can log in
- [ ] **AUTH-03**: User can reset password
### API
- [ ] **API-01**: REST endpoints
## Traceability
| Requirement | Phase | Status |
|-------------|-------|--------|
| AUTH-01 | Phase 1 | Pending |
| AUTH-02 | Phase 1 | Pending |
| AUTH-03 | Phase 2 | Pending |
| API-01 | Phase 2 | Pending |
`
);
fs.writeFileSync(
path.join(tmpDir, '.planning', 'STATE.md'),
`# State\n\n**Current Phase:** 01\n**Current Phase Name:** Auth\n**Status:** In progress\n**Current Plan:** 01-01\n**Last Activity:** 2025-01-01\n**Last Activity Description:** Working\n`
);
const p1 = path.join(tmpDir, '.planning', 'phases', '01-auth');
fs.mkdirSync(p1, { recursive: true });
fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan');
fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary');
fs.mkdirSync(path.join(tmpDir, '.planning', 'phases', '02-api'), { recursive: true });
const result = runGsdTools('phase complete 1', tmpDir);
assert.ok(result.success, `Command failed: ${result.error}`);
const req = fs.readFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), 'utf-8');
// Checkboxes updated for phase 1 requirements (brackets stripped)
assert.ok(req.includes('- [x] **AUTH-01**'), 'AUTH-01 checkbox should be checked');
assert.ok(req.includes('- [x] **AUTH-02**'), 'AUTH-02 checkbox should be checked');
// Other requirements unchanged
assert.ok(req.includes('- [ ] **AUTH-03**'), 'AUTH-03 should remain unchecked');
assert.ok(req.includes('- [ ] **API-01**'), 'API-01 should remain unchecked');
// Traceability table updated
assert.ok(req.includes('| AUTH-01 | Phase 1 | Complete |'), 'AUTH-01 status should be Complete');
assert.ok(req.includes('| AUTH-02 | Phase 1 | Complete |'), 'AUTH-02 status should be Complete');
assert.ok(req.includes('| AUTH-03 | Phase 2 | Pending |'), 'AUTH-03 should remain Pending');
assert.ok(req.includes('| API-01 | Phase 2 | Pending |'), 'API-01 should remain Pending');
});
test('handles phase with no requirements mapping', () => {
fs.writeFileSync(
path.join(tmpDir, '.planning', 'ROADMAP.md'),

View File

@@ -20,6 +20,7 @@ wave: N # Execution wave (1, 2, 3...). Pre-computed at plan
depends_on: [] # Plan IDs this plan requires (e.g., ["01-01"]).
files_modified: [] # Files this plan modifies.
autonomous: true # false if plan has checkpoints requiring user interaction
requirements: [] # Requirement IDs this plan addresses (from ROADMAP)
user_setup: [] # Human-required setup Claude cannot automate (see below)
# Goal-backward verification (derived during planning, verified after execution)
@@ -129,6 +130,7 @@ After completion, create `.planning/phases/XX-name/{phase}-{plan}-SUMMARY.md`
| `depends_on` | Yes | Array of plan IDs this plan requires. |
| `files_modified` | Yes | Files this plan touches. |
| `autonomous` | Yes | `true` if no checkpoints, `false` if has checkpoints |
| `requirements` | Yes | Requirement IDs this plan addresses (from ROADMAP) |
| `user_setup` | No | Array of human-required setup items (external services) |
| `must_haves` | Yes | Goal-backward verification criteria (see below) |

View File

@@ -29,7 +29,7 @@ Decimal phases appear between their surrounding integers in numeric order.
### Phase 1: [Name]
**Goal**: [What this phase delivers]
**Depends on**: Nothing (first phase)
**Requirements**: [REQ-01, REQ-02, REQ-03]
**Requirements**: [REQ-01, REQ-02, REQ-03] <!-- brackets optional, parser handles both formats -->
**Success Criteria** (what must be TRUE):
1. [Observable behavior from user perspective]
2. [Observable behavior from user perspective]

View File

@@ -38,6 +38,8 @@ patterns-established:
- "Pattern 1: description"
- "Pattern 2: description"
requirements-completed: [] # Requirement IDs addressed by this plan (from PLAN frontmatter)
# Metrics
duration: Xmin
completed: YYYY-MM-DD

View File

@@ -322,7 +322,7 @@ If user_setup exists: create `{phase}-USER-SETUP.md` using template `~/.claude/g
<step name="create_summary">
Create `{phase}-{plan}-SUMMARY.md` at `.planning/phases/XX-name/`. Use `~/.claude/get-shit-done/templates/summary.md`.
**Frontmatter:** phase, plan, subsystem, tags | requires/provides/affects | tech-stack.added/patterns | key-files.created/modified | key-decisions | duration ($DURATION), completed ($PLAN_END_TIME date).
**Frontmatter:** phase, plan, subsystem, tags | requires/provides/affects | tech-stack.added/patterns | key-files.created/modified | key-decisions | requirements-completed (from PLAN.md requirements field) | duration ($DURATION), completed ($PLAN_END_TIME date).
Title: `# Phase [X] Plan [Y]: [Name] Summary`