specweave 0.23.8 → 0.23.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +7 -7
- package/CLAUDE.md +391 -1338
- package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
- package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cleanup-cache.js +63 -0
- package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +40 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/migrate-config.d.ts +22 -0
- package/dist/src/cli/commands/migrate-config.d.ts.map +1 -0
- package/dist/src/cli/commands/migrate-config.js +149 -0
- package/dist/src/cli/commands/migrate-config.js.map +1 -0
- package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
- package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
- package/dist/src/cli/helpers/async-project-loader.js +351 -0
- package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.js +187 -0
- package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +112 -60
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts +26 -2
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.js +197 -132
- package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
- package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
- package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
- package/dist/src/cli/helpers/progress-tracker.js +202 -0
- package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
- package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
- package/dist/src/config/types.d.ts +14 -14
- package/dist/src/core/cache/cache-manager.d.ts +119 -0
- package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
- package/dist/src/core/cache/cache-manager.js +304 -0
- package/dist/src/core/cache/cache-manager.js.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.js +160 -0
- package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
- package/dist/src/core/config/config-manager.d.ts +135 -0
- package/dist/src/core/config/config-manager.d.ts.map +1 -0
- package/dist/src/core/config/config-manager.js +341 -0
- package/dist/src/core/config/config-manager.js.map +1 -0
- package/dist/src/core/config/config-migrator.d.ts +102 -0
- package/dist/src/core/config/config-migrator.d.ts.map +1 -0
- package/dist/src/core/config/config-migrator.js +367 -0
- package/dist/src/core/config/config-migrator.js.map +1 -0
- package/dist/src/core/config/index.d.ts +10 -0
- package/dist/src/core/config/index.d.ts.map +1 -0
- package/dist/src/core/config/index.js +10 -0
- package/dist/src/core/config/index.js.map +1 -0
- package/dist/src/core/config/types.d.ts +216 -0
- package/dist/src/core/config/types.d.ts.map +1 -0
- package/dist/src/core/config/types.js +32 -0
- package/dist/src/core/config/types.js.map +1 -0
- package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
- package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
- package/dist/src/core/progress/cancelation-handler.js +111 -0
- package/dist/src/core/progress/cancelation-handler.js.map +1 -0
- package/dist/src/core/progress/import-state.d.ts +71 -0
- package/dist/src/core/progress/import-state.d.ts.map +1 -0
- package/dist/src/core/progress/import-state.js +96 -0
- package/dist/src/core/progress/import-state.js.map +1 -0
- package/dist/src/core/progress/progress-tracker.d.ts +139 -0
- package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
- package/dist/src/core/progress/progress-tracker.js +223 -0
- package/dist/src/core/progress/progress-tracker.js.map +1 -0
- package/dist/src/init/architecture/types.d.ts +6 -6
- package/dist/src/integrations/ado/ado-client.d.ts +25 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +67 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
- package/dist/src/integrations/jira/jira-client.d.ts +32 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +81 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.d.ts +104 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.js +178 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +20 -0
- package/plugins/specweave/agents/architect/AGENT.md +100 -602
- package/plugins/specweave/agents/pm/AGENT.md +96 -597
- package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
- package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
- package/plugins/specweave/commands/check-hooks.md +257 -0
- package/plugins/specweave/commands/migrate-config.md +104 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
- package/plugins/specweave/hooks/post-task-completion.sh +225 -228
- package/plugins/specweave/hooks/post-write-spec.sh +207 -31
- package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +5 -7
- package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
- package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
- package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
- package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
- package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
- package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
- package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
- package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
- package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
- package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +228 -6333
package/CLAUDE.md
CHANGED
|
@@ -10,1631 +10,684 @@ For **contributors to SpecWeave itself** (not users).
|
|
|
10
10
|
|
|
11
11
|
## 🚨 CRITICAL SAFETY RULES
|
|
12
12
|
|
|
13
|
-
### 0.
|
|
13
|
+
### 0. Think-Then-Act Discipline (META RULE!)
|
|
14
14
|
|
|
15
|
-
**
|
|
15
|
+
**NEVER run commands you know will fail.** Act on reasoning BEFORE execution.
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**Common patterns:**
|
|
18
|
+
- Running code before compilation → `npm run rebuild` FIRST
|
|
19
|
+
- Database queries before migrations/setup
|
|
20
|
+
- File ops before directory creation
|
|
18
21
|
|
|
19
22
|
```typescript
|
|
20
|
-
// ❌ WRONG: Attempt →
|
|
21
|
-
node -e "require('./dist/file.js')" //
|
|
22
|
-
npm run rebuild
|
|
23
|
+
// ❌ WRONG: Attempt → Fail → Fix
|
|
24
|
+
node -e "require('./dist/file.js')" // You knew this would fail!
|
|
25
|
+
npm run rebuild
|
|
23
26
|
|
|
24
|
-
// ✅ CORRECT:
|
|
25
|
-
npm run rebuild
|
|
26
|
-
node -e "require('./dist/file.js')"
|
|
27
|
+
// ✅ CORRECT: Fix → Attempt
|
|
28
|
+
npm run rebuild
|
|
29
|
+
node -e "require('./dist/file.js')"
|
|
27
30
|
```
|
|
28
31
|
|
|
29
|
-
**Why**: Wastes time, creates confusion, makes execution harder to follow.
|
|
30
|
-
|
|
31
|
-
**How to avoid**:
|
|
32
|
-
1. **Read your own thinking process** - What dependencies did you identify?
|
|
33
|
-
2. **Order operations logically** - Prerequisites BEFORE dependent operations
|
|
34
|
-
3. **Catch predictable failures** - If you know it will fail, don't run it yet
|
|
35
|
-
|
|
36
|
-
**Example patterns to watch for**:
|
|
37
|
-
- Running code before compilation (`tsc`, `npm run build`)
|
|
38
|
-
- Database queries before migrations/setup
|
|
39
|
-
- API calls before authentication
|
|
40
|
-
- File operations before directory creation
|
|
41
|
-
|
|
42
32
|
---
|
|
43
33
|
|
|
44
34
|
### 1. Local Development Setup
|
|
45
35
|
|
|
46
|
-
**
|
|
47
|
-
|
|
48
|
-
#### Quick Start (Recommended - All Platforms)
|
|
36
|
+
**Standard Workflow** (Cross-platform):
|
|
49
37
|
|
|
50
38
|
```bash
|
|
51
|
-
#
|
|
39
|
+
# Setup
|
|
52
40
|
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
53
|
-
cd specweave
|
|
54
|
-
npm install
|
|
55
|
-
|
|
56
|
-
# 2. Build TypeScript
|
|
57
|
-
npm run rebuild
|
|
58
|
-
|
|
59
|
-
# 3. That's it! Claude Code auto-installs from GitHub marketplace
|
|
60
|
-
# Hooks execute from: ~/.claude/plugins/marketplaces/specweave/
|
|
61
|
-
```
|
|
41
|
+
cd specweave && npm install && npm run rebuild
|
|
62
42
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
**How it works**: Claude Code automatically pulls your latest code from GitHub every 5-10 seconds.
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
# 1. Make changes in local repo
|
|
43
|
+
# Development Cycle
|
|
69
44
|
vim src/core/task-parser.ts
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
npm run rebuild
|
|
73
|
-
|
|
74
|
-
# 3. Test locally
|
|
75
|
-
npm test
|
|
76
|
-
|
|
77
|
-
# 4. Commit and push to your branch
|
|
78
|
-
git add . && git commit -m "feat: new feature"
|
|
45
|
+
npm run rebuild && npm test
|
|
46
|
+
git add . && git commit -m "feat: feature"
|
|
79
47
|
git push origin develop
|
|
80
|
-
|
|
81
|
-
# 5. Wait 5-10 seconds → Claude Code auto-updates marketplace
|
|
82
|
-
|
|
83
|
-
# 6. Test in Claude Code
|
|
84
|
-
/specweave:increment "test feature"
|
|
85
|
-
# Your latest hooks now execute automatically!
|
|
48
|
+
# Wait 5-10s → Claude Code auto-updates marketplace
|
|
86
49
|
```
|
|
87
50
|
|
|
88
|
-
**
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
git push origin develop
|
|
93
|
-
# Wait 5-10 seconds → hooks updated!
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**Key Benefits**:
|
|
97
|
-
- ✅ **Cross-platform** (works on Windows, no admin privileges needed)
|
|
98
|
-
- ✅ **Simple** (standard git workflow, no scripts)
|
|
99
|
-
- ✅ **Reliable** (Claude Code manages updates, no symlink race conditions)
|
|
100
|
-
- ✅ **Team-friendly** (everyone gets updates automatically)
|
|
101
|
-
|
|
102
|
-
#### Testing Unpushed Changes (Advanced)
|
|
103
|
-
|
|
104
|
-
**Option 1: Temporary Branch** (Recommended)
|
|
105
|
-
```bash
|
|
106
|
-
# Create throwaway test branch
|
|
107
|
-
git checkout -b temp-test-$(date +%s)
|
|
108
|
-
git add . && git commit -m "temp: testing unpushed changes"
|
|
109
|
-
git push origin temp-test-1234567890
|
|
110
|
-
|
|
111
|
-
# Claude Code pulls from your test branch (5-10 seconds)
|
|
112
|
-
# Test your changes...
|
|
51
|
+
**Testing Unpushed Changes:**
|
|
52
|
+
- **Option 1**: Temp branch → push → test → delete
|
|
53
|
+
- **Option 2**: Fork-based (`claude plugin marketplace add github:YOUR_USERNAME/specweave`)
|
|
54
|
+
- **Option 3**: Symlink (Unix-only, see `.specweave/docs/internal/advanced/symlink-dev-mode.md`)
|
|
113
55
|
|
|
114
|
-
|
|
115
|
-
git push origin --delete temp-test-1234567890
|
|
116
|
-
git checkout develop && git branch -D temp-test-1234567890
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Option 2: Fork-Based Development**
|
|
120
|
-
```bash
|
|
121
|
-
# One-time: Point Claude Code to your fork
|
|
122
|
-
claude plugin marketplace remove specweave
|
|
123
|
-
claude plugin marketplace add github:YOUR_USERNAME/specweave
|
|
124
|
-
|
|
125
|
-
# Now push to your fork's branch
|
|
126
|
-
git push origin develop
|
|
127
|
-
# Claude Code pulls from YOUR fork, not upstream
|
|
128
|
-
```
|
|
56
|
+
---
|
|
129
57
|
|
|
130
|
-
|
|
131
|
-
If you need **instant updates** without pushing (e.g., rapid hook iteration):
|
|
132
|
-
- See: `.specweave/docs/internal/advanced/symlink-dev-mode.md`
|
|
133
|
-
- ⚠️ **Warning**: Only works on macOS/Linux, not Windows
|
|
134
|
-
- ⚠️ Requires bash scripts, registry manipulation, ongoing maintenance
|
|
58
|
+
### 2. Increment Folder Structure
|
|
135
59
|
|
|
136
|
-
|
|
60
|
+
**ONLY 4 files in `.specweave/increments/####/` root**: `spec.md`, `plan.md`, `tasks.md`, `metadata.json`
|
|
137
61
|
|
|
138
|
-
|
|
62
|
+
**Everything else → subfolders**: `reports/`, `scripts/`, `logs/`
|
|
139
63
|
|
|
140
64
|
```bash
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
# 2. Test in fresh directory
|
|
145
|
-
cd /tmp && mkdir test-project && cd test-project
|
|
146
|
-
specweave init .
|
|
147
|
-
# ... test end-user workflows ...
|
|
148
|
-
|
|
149
|
-
# 3. Resume development
|
|
150
|
-
cd /path/to/specweave/repo
|
|
151
|
-
# Claude Code automatically switches back to marketplace mode
|
|
65
|
+
# ❌ WRONG: .specweave/increments/0046/analysis-report.md
|
|
66
|
+
# ✅ CORRECT: .specweave/increments/0046/reports/analysis-report.md
|
|
152
67
|
```
|
|
153
68
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
**ONLY 4 files allowed in `.specweave/increments/####/` root**:
|
|
157
|
-
- `spec.md`, `plan.md`, `tasks.md`, `metadata.json`
|
|
158
|
-
|
|
159
|
-
**Everything else → subfolders**:
|
|
160
|
-
- `reports/` - Analysis, completion reports, validation
|
|
161
|
-
- `scripts/` - Helper scripts, automation
|
|
162
|
-
- `logs/` - Execution logs, debug output
|
|
163
|
-
|
|
164
|
-
**Examples**:
|
|
165
|
-
```bash
|
|
166
|
-
# ❌ WRONG
|
|
167
|
-
.specweave/increments/0046/analysis-report.md
|
|
168
|
-
|
|
169
|
-
# ✅ CORRECT
|
|
170
|
-
.specweave/increments/0046/reports/analysis-report.md
|
|
171
|
-
|
|
172
|
-
# Fix before committing:
|
|
173
|
-
mkdir -p .specweave/increments/0046/reports
|
|
174
|
-
mv .specweave/increments/0046/*.md .specweave/increments/0046/reports/
|
|
175
|
-
git restore .specweave/increments/0046/{spec,plan,tasks}.md
|
|
176
|
-
```
|
|
69
|
+
---
|
|
177
70
|
|
|
178
|
-
### 3.
|
|
71
|
+
### 3. Protected Directories
|
|
179
72
|
|
|
180
|
-
**
|
|
73
|
+
**Never delete**: `.specweave/docs/`, `.specweave/increments/`
|
|
181
74
|
|
|
182
|
-
**Pre-commit hook blocks**:
|
|
183
|
-
- `rm -rf .specweave/docs` or `rm -rf .specweave/increments`
|
|
184
|
-
- Deletion of 50+ files at once in these directories
|
|
75
|
+
**Pre-commit hook blocks**: Deletion of 50+ files, `rm -rf` on protected dirs
|
|
185
76
|
|
|
186
|
-
**
|
|
187
|
-
```bash
|
|
188
|
-
git restore .specweave/
|
|
189
|
-
```
|
|
77
|
+
**Recovery**: `git restore .specweave/`
|
|
190
78
|
|
|
191
|
-
|
|
79
|
+
---
|
|
192
80
|
|
|
193
|
-
|
|
81
|
+
### 4. Test Cleanup Safety
|
|
194
82
|
|
|
195
|
-
**REQUIRED
|
|
83
|
+
**REQUIRED before `rm -rf`**:
|
|
196
84
|
1. Verify `pwd` (MUST be project root)
|
|
197
85
|
2. Dry-run with `-print` (NO deletion)
|
|
198
|
-
3. Count files
|
|
199
|
-
4. Manual confirmation
|
|
200
|
-
5. Execute
|
|
201
|
-
6. Verify results
|
|
202
|
-
7. Run tests
|
|
86
|
+
3. Count files to delete
|
|
87
|
+
4. Manual confirmation
|
|
88
|
+
5. Execute → Verify → Run tests
|
|
203
89
|
|
|
204
|
-
|
|
90
|
+
---
|
|
205
91
|
|
|
206
92
|
### 5. NEVER Use `specweave init . --force`
|
|
207
93
|
|
|
208
|
-
**Danger**: Deletes ALL increments
|
|
94
|
+
**Danger**: Deletes ALL increments/docs without backup
|
|
209
95
|
|
|
210
|
-
**
|
|
211
|
-
```bash
|
|
212
|
-
specweave init . # Interactive, never deletes without confirmation
|
|
213
|
-
```
|
|
96
|
+
**Use**: `specweave init .` (interactive, safe)
|
|
214
97
|
|
|
215
|
-
|
|
98
|
+
---
|
|
216
99
|
|
|
217
|
-
|
|
218
|
-
1. All acceptance criteria checked (`- [x] **AC-...`)
|
|
219
|
-
2. All tasks completed
|
|
220
|
-
3. All tests passing
|
|
221
|
-
4. Coverage target met
|
|
100
|
+
### 6. Increment Completion
|
|
222
101
|
|
|
223
|
-
**Always use**: `/specweave:done 0043` (validates
|
|
224
|
-
**Never**: Manual `metadata.json` edit (blocked by pre-commit hook)
|
|
102
|
+
**Always use**: `/specweave:done 0043` (validates ACs, tasks, tests, coverage)
|
|
225
103
|
|
|
226
|
-
|
|
104
|
+
**Never**: Manual `metadata.json` edit (blocked by pre-commit hook)
|
|
227
105
|
|
|
228
|
-
|
|
229
|
-
1. **tasks.md** - Task completion status (`[x]` checkboxes)
|
|
230
|
-
2. **spec.md** - Acceptance criteria status (`[x]` checkboxes)
|
|
106
|
+
---
|
|
231
107
|
|
|
232
|
-
|
|
108
|
+
### 7. Source of Truth: tasks.md + spec.md (CRITICAL!)
|
|
233
109
|
|
|
234
|
-
|
|
235
|
-
For EVERY task marked complete in internal TODO:
|
|
236
|
-
1. ✅ Mark task as completed in internal TODO
|
|
237
|
-
2. ⚠️ IMMEDIATELY update tasks.md checkbox: `[ ] pending` → `[x] completed`
|
|
238
|
-
3. ⚠️ IMMEDIATELY update spec.md AC checkbox: `[ ]` → `[x]`
|
|
239
|
-
4. ✅ Verify both files updated BEFORE moving to next task
|
|
240
|
-
```
|
|
110
|
+
**THE MOST CRITICAL RULE**: Internal TODO is ephemeral. **tasks.md + spec.md are SOURCE OF TRUTH.**
|
|
241
111
|
|
|
242
|
-
**
|
|
112
|
+
**MANDATORY workflow:**
|
|
243
113
|
```typescript
|
|
244
|
-
//
|
|
114
|
+
// 1. Complete work
|
|
245
115
|
await createIntegrationTest();
|
|
246
116
|
|
|
247
|
-
//
|
|
117
|
+
// 2. Update internal TODO
|
|
248
118
|
TodoWrite([{task: "T-013", status: "completed"}]);
|
|
249
119
|
|
|
250
|
-
//
|
|
120
|
+
// 3. IMMEDIATELY update tasks.md (NEVER skip!)
|
|
251
121
|
Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
|
|
252
122
|
|
|
253
|
-
//
|
|
123
|
+
// 4. IMMEDIATELY update spec.md ACs
|
|
254
124
|
Edit("spec.md", "- [ ] **AC-US1-01**", "- [x] **AC-US1-01**");
|
|
255
|
-
|
|
256
|
-
// Step 5: Move to next task
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
**❌ CRITICAL ERROR - Never Do This**:
|
|
260
|
-
```typescript
|
|
261
|
-
// ❌ WRONG: Marking TODO as complete WITHOUT updating source files
|
|
262
|
-
TodoWrite([
|
|
263
|
-
{task: "T-013", status: "completed"}, // ❌ Only internal tracking
|
|
264
|
-
{task: "T-014", status: "completed"}, // ❌ Only internal tracking
|
|
265
|
-
{task: "T-015", status: "completed"} // ❌ Only internal tracking
|
|
266
|
-
]);
|
|
267
|
-
// tasks.md still shows `[ ] pending` → DESYNC!
|
|
268
|
-
// This is a CRITICAL VIOLATION!
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**Pre-Closure Validation** (MANDATORY before `/specweave:done`):
|
|
272
|
-
```bash
|
|
273
|
-
# 1. Verify ALL tasks marked in tasks.md
|
|
274
|
-
grep "^\*\*Status\*\*:" tasks.md | grep -c "\[x\] completed"
|
|
275
|
-
# Output MUST equal total_tasks in frontmatter
|
|
276
|
-
|
|
277
|
-
# 2. Verify ALL ACs checked in spec.md
|
|
278
|
-
grep -c "^- \[x\] \*\*AC-" spec.md
|
|
279
|
-
# Output MUST equal total ACs
|
|
280
|
-
|
|
281
|
-
# 3. Only then close increment
|
|
282
|
-
/specweave:done 0044
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
**Why This Matters**:
|
|
286
|
-
- Internal TODO is ephemeral (lost between sessions)
|
|
287
|
-
- tasks.md is permanent source of truth
|
|
288
|
-
- spec.md is contract with stakeholders
|
|
289
|
-
- Desync = broken promises to users/team
|
|
290
|
-
|
|
291
|
-
**Incident Reference**: 2025-11-19 - Increment 0044 was incorrectly closed with tasks.md showing `[ ] pending` while internal TODO showed "completed". This violated SpecWeave's core principle. See `.specweave/increments/0044-integration-testing-status-hooks/reports/INCIDENT-SOURCE-OF-TRUTH-VIOLATION.md` for full post-mortem.
|
|
292
|
-
|
|
293
|
-
### 7a. Status Line Synchronization (AUTOMATIC & ENFORCED!)
|
|
294
|
-
|
|
295
|
-
**CRITICAL**: Status line MUST ALWAYS reflect current task completion status.
|
|
296
|
-
|
|
297
|
-
**How It Works** (Automatic):
|
|
298
|
-
1. Every TodoWrite call → `post-task-completion.sh` hook fires
|
|
299
|
-
2. Hook calls `update-status-line.sh` → cache updates
|
|
300
|
-
3. Status line displays updated progress immediately
|
|
301
|
-
|
|
302
|
-
**The ONLY Way to Complete Tasks**:
|
|
303
|
-
```
|
|
304
|
-
ALWAYS use TodoWrite when working on increment tasks!
|
|
305
|
-
- TodoWrite triggers hooks automatically
|
|
306
|
-
- Hooks update status line cache
|
|
307
|
-
- Status line stays synchronized
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**❌ NEVER Complete Tasks Without TodoWrite**:
|
|
311
|
-
```typescript
|
|
312
|
-
// ❌ WRONG: Direct Edit without TodoWrite
|
|
313
|
-
Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
|
|
314
|
-
// Status line will NOT update! Hook never fires!
|
|
315
|
-
|
|
316
|
-
// ✅ CORRECT: TodoWrite triggers automatic update
|
|
317
|
-
TodoWrite([{task: "T-001", status: "in_progress"}]);
|
|
318
|
-
// ... do the work ...
|
|
319
|
-
TodoWrite([{task: "T-001", status: "completed"}]);
|
|
320
|
-
Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
|
|
321
|
-
// Hook fires → status line updates automatically!
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
**Validation Commands**:
|
|
325
|
-
```bash
|
|
326
|
-
# Check if status line is in sync
|
|
327
|
-
/specweave:validate-status
|
|
328
|
-
|
|
329
|
-
# Manual update (emergency only)
|
|
330
|
-
bash plugins/specweave/hooks/lib/update-status-line.sh
|
|
331
|
-
|
|
332
|
-
# Validate all increments
|
|
333
|
-
npx tsx src/core/status-line-validator.ts
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
**Detection & Recovery**:
|
|
337
|
-
- Pre-commit hook validates sync (blocks commit if desync detected)
|
|
338
|
-
- `/specweave:done` validates before closing (blocks if desync)
|
|
339
|
-
- Automatic tests verify hook fires correctly
|
|
340
|
-
|
|
341
|
-
**Why This Matters**:
|
|
342
|
-
- Status line is visible to user at ALL times
|
|
343
|
-
- Stale status = broken trust
|
|
344
|
-
- Hooks ensure atomic updates (task complete → status updates together)
|
|
345
|
-
|
|
346
|
-
**Incident Reference**: 2025-11-20 - Status line showed 21/52 tasks when actually 26/52 were complete (10% desync). Root cause: Tasks marked complete without using TodoWrite, so hooks never fired. Added validation layer and tests to prevent future occurrences.
|
|
347
|
-
|
|
348
|
-
### 7b. GitHub Duplicate Prevention (CRITICAL!)
|
|
349
|
-
|
|
350
|
-
**CRITICAL**: External tool items (GitHub issues, JIRA tickets, ADO work items) MUST NEVER be duplicated.
|
|
351
|
-
|
|
352
|
-
**Rule**: ALWAYS use DuplicateDetector for GitHub issue creation.
|
|
353
|
-
|
|
354
|
-
**Why This Matters**:
|
|
355
|
-
- GitHub search has eventual consistency (2-5 second lag)
|
|
356
|
-
- Race conditions can create duplicates if sync runs multiple times quickly
|
|
357
|
-
- Manual search with `--limit 1` hides duplicates
|
|
358
|
-
|
|
359
|
-
**The ONLY Way to Create GitHub Issues**:
|
|
360
|
-
```typescript
|
|
361
|
-
import { DuplicateDetector } from './duplicate-detector.js';
|
|
362
|
-
|
|
363
|
-
// ✅ CORRECT: Use DuplicateDetector.createWithProtection()
|
|
364
|
-
const titlePattern = `[${featureId}][${userStory.id}]`; // e.g., "[FS-047][US-001]"
|
|
365
|
-
const result = await DuplicateDetector.createWithProtection({
|
|
366
|
-
title: issueContent.title,
|
|
367
|
-
body: issueContent.body,
|
|
368
|
-
titlePattern,
|
|
369
|
-
labels: issueContent.labels,
|
|
370
|
-
milestone: milestoneTitle,
|
|
371
|
-
repo: `${owner}/${repo}`
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
// Provides automatic:
|
|
375
|
-
// ✅ Phase 1 (Detection): Search for existing before create
|
|
376
|
-
// ✅ Phase 2 (Verification): Count-check after creation
|
|
377
|
-
// ✅ Phase 3 (Reflection): Auto-close duplicates, keep oldest
|
|
378
|
-
|
|
379
|
-
// ❌ WRONG: Manual gh issue create (no duplicate protection!)
|
|
380
|
-
execSync('gh issue create --title "..." --body "..."');
|
|
381
125
|
```
|
|
382
126
|
|
|
383
|
-
**
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
127
|
+
**Status Line Sync (Automatic):**
|
|
128
|
+
- TodoWrite → `post-task-completion.sh` hook → status line cache updates
|
|
129
|
+
- **NEVER** edit tasks.md without TodoWrite (hook won't fire → desync)
|
|
130
|
+
- Validation: `/specweave:validate-status`
|
|
387
131
|
|
|
388
|
-
**
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
// ✅ CORRECT: --limit 50 detects duplicates
|
|
395
|
-
gh issue list --search "[FS-047][US-001] in:title" --limit 50
|
|
396
|
-
// Returns up to 50 results, enabling duplicate detection
|
|
397
|
-
```
|
|
132
|
+
**GitHub Duplicate Prevention:**
|
|
133
|
+
- **ALWAYS** use `DuplicateDetector.createWithProtection()` for GitHub issues
|
|
134
|
+
- 3-phase: Detection → Verification → Reflection (auto-close duplicates)
|
|
135
|
+
- **NEVER** use `--limit 1` in gh searches (hides duplicates, use `--limit 50`)
|
|
136
|
+
- Cleanup: `bash scripts/cleanup-duplicate-github-issues.sh --dry-run`
|
|
398
137
|
|
|
399
|
-
**
|
|
138
|
+
**Pre-closure validation:**
|
|
400
139
|
```bash
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
# Actually close duplicates (keeps oldest):
|
|
405
|
-
bash scripts/cleanup-duplicate-github-issues.sh
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
**Validation**:
|
|
409
|
-
```bash
|
|
410
|
-
# Check for duplicates:
|
|
411
|
-
gh issue list --json title,createdAt --limit 100 | \
|
|
412
|
-
jq -r '.[] | .title' | sort | uniq -d
|
|
413
|
-
|
|
414
|
-
# If output is empty → No duplicates! ✅
|
|
415
|
-
# If output shows titles → Duplicates exist, investigate!
|
|
140
|
+
grep "^\*\*Status\*\*:" tasks.md | grep -c "\[x\] completed" # Must equal total_tasks
|
|
141
|
+
grep -c "^- \[x\] \*\*AC-" spec.md # Must equal total ACs
|
|
142
|
+
/specweave:done 0044
|
|
416
143
|
```
|
|
417
144
|
|
|
418
|
-
**
|
|
419
|
-
-
|
|
420
|
-
-
|
|
421
|
-
-
|
|
422
|
-
- Root Cause #3: No post-create verification
|
|
423
|
-
- **Fix**: DuplicateDetector integration (github-feature-sync.ts:149-227)
|
|
145
|
+
**Incidents**:
|
|
146
|
+
- 2025-11-19 (0044): Internal TODO "completed" while tasks.md showed `[ ] pending`
|
|
147
|
+
- 2025-11-20: Status line 10% desync (tasks marked without TodoWrite)
|
|
148
|
+
- 2025-11-20: 10+ duplicate GitHub issues (race conditions, --limit 1 bug)
|
|
424
149
|
|
|
425
|
-
|
|
426
|
-
- `plugins/specweave-github/lib/github-feature-sync.ts` - Uses DuplicateDetector
|
|
427
|
-
- `plugins/specweave-github/lib/duplicate-detector.ts` - 3-phase protection
|
|
428
|
-
- `plugins/specweave-github/lib/github-client-v2.ts` - Fixed --limit 50
|
|
429
|
-
|
|
430
|
-
**Incident Reference**: 2025-11-20 - Duplicate GitHub issues for User Stories ([SP-US-006], [SP-US-007], etc.). Root cause: Race conditions + --limit 1 bug + missing DuplicateDetector integration. Fixed by implementing 3-phase protection. See `.specweave/increments/0047-us-task-linkage/reports/DUPLICATE-GITHUB-ISSUES-ROOT-CAUSE.md`.
|
|
431
|
-
|
|
432
|
-
### 8. NEVER Use `console.*` in Production Code
|
|
150
|
+
---
|
|
433
151
|
|
|
434
|
-
|
|
152
|
+
### 8. Logger Abstraction (NEVER `console.*`)
|
|
435
153
|
|
|
436
|
-
**
|
|
154
|
+
**Rule**: ALL `src/` code uses logger injection, NEVER `console.log/error/warn`
|
|
437
155
|
|
|
438
|
-
**Use logger injection**:
|
|
439
156
|
```typescript
|
|
440
157
|
import { Logger, consoleLogger } from '../../utils/logger.js';
|
|
441
158
|
|
|
442
159
|
export class MyClass {
|
|
443
|
-
private logger: Logger;
|
|
444
|
-
|
|
445
160
|
constructor(options: { logger?: Logger } = {}) {
|
|
446
161
|
this.logger = options.logger ?? consoleLogger;
|
|
447
162
|
}
|
|
448
|
-
|
|
449
|
-
doSomething() {
|
|
450
|
-
this.logger.log('Info message');
|
|
451
|
-
this.logger.error('Error message', error);
|
|
452
|
-
}
|
|
453
163
|
}
|
|
164
|
+
// In tests: new MyClass({ logger: silentLogger });
|
|
454
165
|
```
|
|
455
166
|
|
|
456
|
-
**
|
|
167
|
+
**Exception - CLI Commands**: `src/cli/commands/*.ts` may use `console.*` with comment:
|
|
457
168
|
```typescript
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const instance = new MyClass({ logger: silentLogger });
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
**Protection**: Code review + search before commit:
|
|
464
|
-
```bash
|
|
465
|
-
# Check for console.* in src/ before committing:
|
|
466
|
-
git diff --cached --name-only | grep '^src/.*\.ts$' | xargs grep -n 'console\.' 2>/dev/null
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
**Exception: CLI Commands (User-Facing Output)**:
|
|
470
|
-
|
|
471
|
-
CLI commands in `src/cli/commands/*.ts` are 99% user-facing output (colored messages, progress indicators, confirmations). These files may keep `console.*` calls with proper documentation:
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
export async function myCommand(options: CommandOptions = {}) {
|
|
475
|
-
// Initialize logger (injectable for testing)
|
|
476
|
-
const logger = options.logger ?? consoleLogger;
|
|
477
|
-
|
|
478
|
-
// NOTE: This CLI command is primarily user-facing output (console.log/console.error).
|
|
479
|
-
// All console.* calls in this file are legitimate user-facing exceptions
|
|
480
|
-
// as defined in CONTRIBUTING.md (colored messages, confirmations, formatted output).
|
|
481
|
-
// Logger infrastructure available for future internal debug logs if needed.
|
|
482
|
-
|
|
483
|
-
// User-facing output (keeps console.log)
|
|
484
|
-
console.log(chalk.green('✅ Operation successful!'));
|
|
485
|
-
|
|
486
|
-
// Internal debug logs (use logger)
|
|
487
|
-
logger.log('Internal state updated');
|
|
488
|
-
}
|
|
169
|
+
// NOTE: This CLI command is primarily user-facing output (console.log/console.error).
|
|
170
|
+
// All console.* calls are legitimate user-facing exceptions as defined in CONTRIBUTING.md.
|
|
489
171
|
```
|
|
490
172
|
|
|
491
|
-
|
|
492
|
-
- Files with comment `"user-facing output"` or `"legitimate user-facing exceptions"` bypass console.* check
|
|
493
|
-
- Pre-commit hook: `scripts/pre-commit-console-check.sh`
|
|
494
|
-
- See: `.specweave/increments/0046-console-elimination/` for migration pattern
|
|
495
|
-
|
|
496
|
-
### 8a. NEVER Use `fs-extra` (Native fs Migration)
|
|
497
|
-
|
|
498
|
-
**Rule**: ALL code MUST use native Node.js `fs` module, NEVER `fs-extra`.
|
|
499
|
-
|
|
500
|
-
**Why**: `fs-extra` causes hook failures when not installed. Native fs is faster, smaller, and always available.
|
|
501
|
-
|
|
502
|
-
**Migration completed**: 2025-11-20 - All hooks converted to native fs
|
|
173
|
+
---
|
|
503
174
|
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
// ✅ CORRECT - Native fs (sync operations)
|
|
507
|
-
import { existsSync, readFileSync, statSync } from 'fs';
|
|
175
|
+
### 8a. Native fs (NEVER `fs-extra`)
|
|
508
176
|
|
|
509
|
-
|
|
510
|
-
const content = readFileSync(configPath, 'utf-8');
|
|
511
|
-
const stats = statSync(configPath);
|
|
512
|
-
}
|
|
513
|
-
```
|
|
177
|
+
**Rule**: Use native Node.js `fs`, NEVER `fs-extra`
|
|
514
178
|
|
|
515
179
|
```typescript
|
|
516
|
-
// ✅ CORRECT - Native fs
|
|
180
|
+
// ✅ CORRECT - Native fs
|
|
181
|
+
import { existsSync, readFileSync } from 'fs';
|
|
517
182
|
import { promises as fs } from 'fs';
|
|
183
|
+
import { mkdirpSync, writeJsonSync } from '../utils/fs-native.js';
|
|
518
184
|
|
|
519
|
-
|
|
520
|
-
await fs.mkdir(dir, { recursive: true });
|
|
521
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
185
|
+
// ❌ WRONG: import fs from 'fs-extra';
|
|
522
186
|
```
|
|
523
187
|
|
|
524
|
-
|
|
525
|
-
// ✅ CORRECT - Custom utilities (from utils/fs-native.js)
|
|
526
|
-
import { mkdirpSync, writeJsonSync, readJsonSync } from '../utils/fs-native.js';
|
|
527
|
-
|
|
528
|
-
mkdirpSync(dir); // Create directory recursively
|
|
529
|
-
writeJsonSync(path, data); // Write JSON file
|
|
530
|
-
const config = readJsonSync(configPath); // Read JSON file
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
**Migration guide (fs-extra → native fs)**:
|
|
534
|
-
```typescript
|
|
535
|
-
// ❌ WRONG (fs-extra)
|
|
536
|
-
import fs from 'fs-extra';
|
|
537
|
-
|
|
538
|
-
fs.existsSync(path); → existsSync(path)
|
|
539
|
-
fs.readFileSync(path, 'utf-8'); → readFileSync(path, 'utf-8')
|
|
540
|
-
fs.statSync(path); → statSync(path)
|
|
541
|
-
await fs.readFile(path, 'utf-8'); → await fs.readFile(path, 'utf-8')
|
|
542
|
-
await fs.ensureDir(dir); → await fs.mkdir(dir, { recursive: true })
|
|
543
|
-
OR mkdirpSync(dir) for sync
|
|
544
|
-
await fs.writeFile(path, content); → await fs.writeFile(path, content, 'utf-8')
|
|
545
|
-
fs.removeSync(path); → removeSync(path) from fs-native.js
|
|
546
|
-
await fs.copy(src, dest); → await fs.cp(src, dest, { recursive: true })
|
|
547
|
-
```
|
|
188
|
+
**Migration**: `fs.existsSync → existsSync`, `fs.ensureDir → fs.mkdir(dir, {recursive: true})`, `fs.removeSync → removeSync`
|
|
548
189
|
|
|
549
|
-
**Prevention**:
|
|
550
|
-
1. **Pre-commit hook**: `scripts/pre-commit-fs-extra-check.sh` blocks fs-extra imports
|
|
551
|
-
2. **Installation**: Hook installed automatically via `bash scripts/install-git-hooks.sh`
|
|
552
|
-
3. **Legacy marker**: Add `// legacy fs-extra` comment to bypass check (temporary only)
|
|
190
|
+
**Prevention**: Pre-commit hook blocks fs-extra imports (bypass: `// legacy fs-extra`)
|
|
553
191
|
|
|
554
|
-
|
|
555
|
-
```bash
|
|
556
|
-
# Verify no fs-extra in hooks
|
|
557
|
-
grep -r "from 'fs-extra'" plugins/*/lib/hooks/*.js
|
|
558
|
-
|
|
559
|
-
# Should return nothing (empty output)
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
**Incident Reference**: 2025-11-20 - Hook failures due to fs-extra dependency. All hooks converted to native fs. Pre-commit hook added to prevent regression.
|
|
192
|
+
---
|
|
563
193
|
|
|
564
194
|
### 9. Coding Standards
|
|
565
195
|
|
|
566
|
-
**
|
|
567
|
-
|
|
196
|
+
**Critical rules (enforced)**:
|
|
197
|
+
1. ✅ NEVER `console.*` (use logger)
|
|
198
|
+
2. ✅ ALWAYS `.js` extensions in imports
|
|
199
|
+
3. ✅ Test files: `.test.ts` (NEVER `.spec.ts`)
|
|
200
|
+
4. Avoid `any` type
|
|
201
|
+
5. Functions < 100 lines
|
|
202
|
+
6. Custom error types
|
|
203
|
+
7. Comment "why" not "what"
|
|
204
|
+
8. No hardcoded secrets
|
|
205
|
+
9. No N+1 queries
|
|
206
|
+
10. Naming: camelCase (vars), PascalCase (classes), UPPER_SNAKE_CASE (constants)
|
|
568
207
|
|
|
569
|
-
**
|
|
208
|
+
**Auto-discovery**: `/specweave:analyze-standards`
|
|
570
209
|
|
|
571
|
-
|
|
572
|
-
2. ✅ **ALWAYS import with `.js` extensions** - Required for ESM (already enforced in Build section)
|
|
573
|
-
3. ✅ **Test files MUST use `.test.ts`** suffix, never `.spec.ts` (already enforced in Testing section)
|
|
574
|
-
4. **Avoid `any` type** - Use specific types or generics
|
|
575
|
-
5. **Functions < 50 lines** (ideal), < 100 lines (max)
|
|
576
|
-
6. **Use custom error types**, not generic Error
|
|
577
|
-
7. **Comment "why" not "what"**
|
|
578
|
-
8. **No hardcoded secrets** - Use environment variables
|
|
579
|
-
9. **No N+1 queries** - Batch database operations
|
|
580
|
-
10. **Naming**: camelCase (vars), PascalCase (classes), UPPER_SNAKE_CASE (constants)
|
|
581
|
-
|
|
582
|
-
**Auto-discovery features**:
|
|
583
|
-
- **Brownfield projects**: Standards auto-detected during project analysis
|
|
584
|
-
- **Manual analysis**: `/specweave:analyze-standards` - Generate comprehensive standards report
|
|
585
|
-
- **Drift detection**: `/specweave:analyze-standards --drift` - Check compliance with declared standards
|
|
586
|
-
- **Update standards**: `/specweave:analyze-standards --update` - Update official standards from analysis
|
|
587
|
-
|
|
588
|
-
**How it works**:
|
|
589
|
-
1. Scans codebase (src/**/*.ts) for naming patterns, import styles, function characteristics
|
|
590
|
-
2. Parses ESLint, Prettier, TypeScript configs for enforced rules
|
|
591
|
-
3. Analyzes existing CLAUDE.md, CONTRIBUTING.md for declared standards
|
|
592
|
-
4. Generates evidence-based standards with confidence levels (90%+ = HIGH confidence)
|
|
593
|
-
5. Detects anti-patterns: hardcoded secrets, large files (>500 lines), missing error handling
|
|
594
|
-
6. Outputs to `.specweave/docs/internal/governance/coding-standards-analysis.md`
|
|
595
|
-
|
|
596
|
-
**Note**: Most standards are enforced by ESLint/Prettier. This list focuses on SpecWeave-specific rules and patterns that can't be auto-fixed by linters.
|
|
210
|
+
---
|
|
597
211
|
|
|
598
|
-
### 10. GitHub Issue Format
|
|
212
|
+
### 10. GitHub Issue Format (v0.24.0+)
|
|
599
213
|
|
|
600
|
-
**CRITICAL**:
|
|
214
|
+
**CRITICAL**: GitHub issues are ONLY created for User Stories, NEVER for Features!
|
|
601
215
|
|
|
602
|
-
**ONLY Correct Format**:
|
|
603
|
-
```
|
|
604
|
-
[FS-XXX][US-YYY] User Story Title
|
|
605
|
-
```
|
|
216
|
+
**ONLY Correct Format**: `[FS-XXX][US-YYY] User Story Title`
|
|
606
217
|
|
|
607
218
|
**Examples**:
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
- ❌ `[SP-FS-047-specweave]` (SP prefix, project name)
|
|
615
|
-
- ❌ `[INC-0047]` (Increment-only)
|
|
616
|
-
|
|
617
|
-
**How to Create Issues**:
|
|
618
|
-
```bash
|
|
619
|
-
# CORRECT way (creates [FS-XXX][US-YYY] issues)
|
|
620
|
-
node -e "
|
|
621
|
-
const { GitHubFeatureSync } = require('./dist/plugins/specweave-github/lib/github-feature-sync.js');
|
|
622
|
-
const { GitHubClientV2 } = require('./dist/plugins/specweave-github/lib/github-client-v2.js');
|
|
623
|
-
|
|
624
|
-
const client = GitHubClientV2.fromRepo('anton-abyzov', 'specweave');
|
|
625
|
-
const sync = new GitHubFeatureSync(client, '.specweave/docs/internal/specs', process.cwd());
|
|
626
|
-
sync.syncFeatureToGitHub('FS-047').then(console.log).catch(console.error);
|
|
627
|
-
"
|
|
628
|
-
|
|
629
|
-
# WRONG way (deprecated, creates [FS-XXX] issues)
|
|
630
|
-
/specweave:increment "feature" # ← This no longer creates GitHub issues
|
|
219
|
+
```
|
|
220
|
+
✅ [FS-048][US-001] Smart Pagination During Init
|
|
221
|
+
✅ [FS-048][US-002] CLI-First Defaults
|
|
222
|
+
❌ [FS-048] (Feature-only - USE MILESTONE!)
|
|
223
|
+
❌ [SP-FS-048-specweave] (SP prefix - DEPRECATED!)
|
|
224
|
+
❌ [FS-048-specweave] (Project suffix - README.md ONLY, NOT GitHub!)
|
|
631
225
|
```
|
|
632
226
|
|
|
633
|
-
**
|
|
634
|
-
- **Features** are tracked via GitHub **Milestones** (not Issues)
|
|
635
|
-
- **User Stories** are tracked via GitHub **Issues**
|
|
636
|
-
- **Tasks** are tracked as **checkboxes** in User Story issue body
|
|
637
|
-
|
|
638
|
-
**Architecture**:
|
|
227
|
+
**Architecture** (ADR-0032 Universal Hierarchy Mapping):
|
|
639
228
|
```
|
|
640
|
-
Feature
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
└─ User Story (US-003) → GitHub Issue #640: [FS-047][US-003] Title
|
|
229
|
+
Feature FS-048 → GitHub Milestone "FS-048: Feature Title"
|
|
230
|
+
├─ User Story US-001 → Issue #XXX: [FS-048][US-001] US Title
|
|
231
|
+
├─ User Story US-002 → Issue #YYY: [FS-048][US-002] US Title
|
|
232
|
+
└─ User Story US-003 → Issue #ZZZ: [FS-048][US-003] US Title
|
|
645
233
|
```
|
|
646
234
|
|
|
647
|
-
**
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
-
|
|
235
|
+
**Create issues**:
|
|
236
|
+
```bash
|
|
237
|
+
# ✅ CORRECT: Creates User Story issues
|
|
238
|
+
/specweave-github:sync FS-048
|
|
651
239
|
|
|
652
|
-
|
|
240
|
+
# ❌ WRONG: /specweave:increment does NOT create GitHub issues
|
|
241
|
+
```
|
|
653
242
|
|
|
654
|
-
**
|
|
655
|
-
|
|
656
|
-
|
|
243
|
+
**If you see Feature-level issues** (`[FS-XXX]` without `[US-YYY]`):
|
|
244
|
+
1. Close them immediately with comment explaining the violation
|
|
245
|
+
2. Delete any duplicate Feature folders (e.g., FS-050 when FS-048 exists)
|
|
246
|
+
3. Use `/specweave-github:sync FS-XXX` to create correct User Story issues
|
|
247
|
+
4. **REPORT THE BUG** - this should never happen!
|
|
657
248
|
|
|
658
|
-
**See
|
|
659
|
-
- `.specweave/increments/0047-us-task-linkage/reports/GITHUB-
|
|
660
|
-
-
|
|
249
|
+
**See**:
|
|
250
|
+
- `.specweave/increments/0047-us-task-linkage/reports/FEATURE-LEVEL-GITHUB-SYNC-REMOVAL-PLAN.md`
|
|
251
|
+
- `.specweave/increments/0050-*/reports/GITHUB-ISSUE-BUG-ANALYSIS-2025-11-22.md`
|
|
661
252
|
|
|
662
|
-
|
|
253
|
+
---
|
|
663
254
|
|
|
664
|
-
|
|
255
|
+
### 11. Task Format with US Linkage (v0.23.0+)
|
|
665
256
|
|
|
666
|
-
**
|
|
257
|
+
**Required fields**:
|
|
667
258
|
```markdown
|
|
668
259
|
### T-001: Task Title
|
|
669
|
-
|
|
670
|
-
**
|
|
671
|
-
**Satisfies ACs**: AC-US1-01, AC-US1-02 ← MANDATORY: AC coverage mapping
|
|
260
|
+
**User Story**: US-001 ← MANDATORY
|
|
261
|
+
**Satisfies ACs**: AC-US1-01, AC-US1-02 ← MANDATORY
|
|
672
262
|
**Status**: [x] completed
|
|
673
|
-
**Priority**: P0 (Critical)
|
|
674
|
-
**Estimated Effort**: 6 hours
|
|
675
|
-
|
|
676
|
-
**Description**: Detailed task description...
|
|
677
|
-
|
|
678
|
-
**Implementation Steps**:
|
|
679
|
-
1. Step one
|
|
680
|
-
2. Step two
|
|
681
|
-
|
|
682
|
-
**Test Plan**:
|
|
683
|
-
- **File**: `tests/unit/component.test.ts`
|
|
684
|
-
- **Tests**: TC-001, TC-002
|
|
685
|
-
|
|
686
|
-
**Files Affected**:
|
|
687
|
-
- `src/path/to/file.ts`
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
**Why This Matters**:
|
|
691
|
-
- **Traceability**: Navigate Task ↔ User Story ↔ Acceptance Criteria ↔ Feature
|
|
692
|
-
- **Living Docs Sync**: Automatic task list updates in living docs US files
|
|
693
|
-
- **AC Coverage**: Validation ensures all acceptance criteria have implementing tasks
|
|
694
|
-
- **Progress Tracking**: Show per-US completion (e.g., "US-001: 8/11 tasks, 73%")
|
|
695
|
-
|
|
696
|
-
**Hierarchical Structure**:
|
|
697
|
-
```markdown
|
|
698
|
-
## User Story: US-001 - User Authentication
|
|
699
|
-
|
|
700
|
-
**Linked ACs**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
701
|
-
**Tasks**: 11 total, 8 completed
|
|
702
|
-
|
|
703
|
-
### T-001: Implement login API
|
|
704
|
-
**User Story**: US-001
|
|
705
|
-
**Satisfies ACs**: AC-US1-01, AC-US1-02
|
|
706
|
-
...
|
|
707
|
-
|
|
708
|
-
### T-002: Add JWT token generation
|
|
709
|
-
**User Story**: US-001
|
|
710
|
-
**Satisfies ACs**: AC-US1-02, AC-US1-03
|
|
711
|
-
...
|
|
712
263
|
```
|
|
713
264
|
|
|
714
|
-
**
|
|
715
|
-
1. `userStory` field MUST reference valid US-ID from spec.md (format: `US-XXX`)
|
|
716
|
-
2. `satisfiesACs` field MUST list valid AC-IDs from spec.md (format: `AC-USXX-YY`)
|
|
717
|
-
3. AC-IDs MUST belong to correct User Story (AC-US1-XX belongs to US-001)
|
|
718
|
-
4. Tasks without US linkage trigger warnings during `/specweave:validate`
|
|
719
|
-
5. `/specweave:done` blocks closure if orphan tasks exist (no AC coverage)
|
|
265
|
+
**Why**: Traceability (Task ↔ User Story ↔ AC ↔ Feature), Living docs auto-sync, AC coverage validation
|
|
720
266
|
|
|
721
|
-
**
|
|
722
|
-
When task marked completed in tasks.md:
|
|
723
|
-
1. Hook detects change via `post-task-completion.sh`
|
|
724
|
-
2. `sync-living-docs.js` parses tasks with `parseTasksWithUSLinks()`
|
|
725
|
-
3. Updates living docs US file:
|
|
726
|
-
- Task list: `- [x] [T-001](link): Task title`
|
|
727
|
-
- AC checkboxes: `- [x] **AC-US1-01**` (if all tasks complete)
|
|
267
|
+
**Validation**: Tasks without linkage → warnings, orphan tasks → `/specweave:done` blocks closure
|
|
728
268
|
|
|
729
|
-
|
|
730
|
-
- Old increments (0001-0046) work without US linkage
|
|
731
|
-
- Parser supports both formats (graceful degradation)
|
|
732
|
-
- Migration tool available: `npx tsx scripts/migrate-task-linkage.ts <increment-id>`
|
|
269
|
+
---
|
|
733
270
|
|
|
734
|
-
|
|
735
|
-
- Implementation: `.specweave/increments/0047-us-task-linkage/`
|
|
736
|
-
- Proposal: `.specweave/increments/0046-console-elimination/reports/US-TASK-LINKAGE-PROPOSAL.md`
|
|
737
|
-
- Living Docs: `.specweave/docs/public/guides/bidirectional-linking.md`
|
|
271
|
+
### 12. ADR Naming Convention
|
|
738
272
|
|
|
739
|
-
|
|
273
|
+
**Correct format**: `XXXX-decision-title.md` (4-digit, kebab-case, NO `adr-` prefix)
|
|
740
274
|
|
|
741
|
-
**
|
|
275
|
+
**Header**: `# ADR-XXXX: Decision Title`
|
|
742
276
|
|
|
743
|
-
**
|
|
744
|
-
- **Filename**: `XXXX-decision-title.md` (4-digit number, kebab-case, NO `adr-` prefix)
|
|
745
|
-
- **Header**: `# ADR-XXXX: Decision Title` (includes `ADR-` prefix for document clarity)
|
|
746
|
-
- **Location**: `.specweave/docs/internal/architecture/adr/`
|
|
277
|
+
**Location**: `.specweave/docs/internal/architecture/adr/`
|
|
747
278
|
|
|
748
|
-
**Examples**:
|
|
749
279
|
```
|
|
750
|
-
✅
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
✅ CORRECT:
|
|
755
|
-
Filename: 0032-universal-hierarchy-mapping.md
|
|
756
|
-
Header: # ADR-0032: Universal Hierarchy Mapping
|
|
757
|
-
|
|
758
|
-
❌ WRONG:
|
|
759
|
-
Filename: adr-0007-github-first-task-sync.md (NO adr- prefix!)
|
|
760
|
-
Reason: Redundant (already in /adr/ directory)
|
|
761
|
-
|
|
762
|
-
❌ WRONG:
|
|
763
|
-
Filename: ADR-0007-github-first-task-sync.md (uppercase)
|
|
764
|
-
Reason: Filenames must be lowercase
|
|
765
|
-
|
|
766
|
-
❌ WRONG:
|
|
767
|
-
Filename: 007-github-first-task-sync.md (3-digit)
|
|
768
|
-
Reason: MUST be 4-digit (0001-9999)
|
|
280
|
+
✅ Filename: 0007-github-first-task-sync.md, Header: # ADR-0007: ...
|
|
281
|
+
❌ adr-0007-github-first-task-sync.md (redundant adr- prefix)
|
|
282
|
+
❌ 007-github-first-task-sync.md (3-digit)
|
|
769
283
|
```
|
|
770
284
|
|
|
771
|
-
**
|
|
772
|
-
- **Consistency**: All ADRs follow same pattern (sortable, predictable)
|
|
773
|
-
- **Clarity**: File location indicates type (in `/adr/` directory)
|
|
774
|
-
- **Tooling**: Scripts expect 4-digit format for auto-numbering
|
|
775
|
-
- **Cross-references**: Links use `adr/XXXX-name.md` format
|
|
776
|
-
|
|
777
|
-
**Enforcement**:
|
|
778
|
-
- Architect agent validates format before creating ADRs
|
|
779
|
-
- Pre-commit hook checks for `adr-XXXX-*.md` pattern and rejects
|
|
780
|
-
- `/specweave:validate` command verifies ADR naming
|
|
781
|
-
|
|
782
|
-
**Common Mistakes**:
|
|
783
|
-
1. Adding `adr-` prefix to filename (copying from header)
|
|
784
|
-
2. Using 3-digit numbers instead of 4-digit (001 vs 0001)
|
|
785
|
-
3. Uppercase filenames (ADR-0007 vs 0007)
|
|
786
|
-
4. Missing kebab-case (spaces or underscores instead of hyphens)
|
|
787
|
-
|
|
788
|
-
**Auto-Numbering**:
|
|
789
|
-
To find next available ADR number (handles duplicates correctly):
|
|
285
|
+
**Auto-numbering**:
|
|
790
286
|
```bash
|
|
791
|
-
ls .specweave/docs/internal/architecture/adr/*.md | \
|
|
792
|
-
|
|
793
|
-
sed 's/.*\/\([0-9][0-9][0-9][0-9]\)-.*/\1/' | \
|
|
794
|
-
sort -u | \
|
|
795
|
-
tail -1 | \
|
|
287
|
+
ls .specweave/docs/internal/architecture/adr/*.md | grep -E '/[0-9]{4}-' | \
|
|
288
|
+
sed 's/.*\/\([0-9][0-9][0-9][0-9]\)-.*/\1/' | sort -u | tail -1 | \
|
|
796
289
|
awk '{printf "Next ADR: %04d\n", $1 + 1}'
|
|
797
|
-
# Output: Next ADR: 0049
|
|
798
|
-
# (Extracts unique numbers only, finds max, adds 1)
|
|
799
290
|
```
|
|
800
291
|
|
|
801
|
-
|
|
292
|
+
---
|
|
802
293
|
|
|
803
|
-
|
|
294
|
+
### 13. Structured Data Matching
|
|
804
295
|
|
|
805
|
-
|
|
296
|
+
**NEVER use string search for frontmatter/IDs**:
|
|
806
297
|
|
|
807
298
|
```typescript
|
|
808
|
-
// ❌ WRONG: Matches ANYWHERE
|
|
809
|
-
|
|
810
|
-
if (content.includes('FS-039')) {
|
|
811
|
-
// This matches:
|
|
812
|
-
// - feature_id: FS-039 ✓ (correct)
|
|
813
|
-
// - "See FS-039 for details" ✗ (FALSE POSITIVE!)
|
|
814
|
-
// - [Related](FS-039) ✗ (FALSE POSITIVE!)
|
|
815
|
-
}
|
|
299
|
+
// ❌ WRONG: Matches ANYWHERE (false positives!)
|
|
300
|
+
content.includes('FS-039') // Matches "See FS-039" in docs!
|
|
816
301
|
|
|
817
302
|
// ✅ CORRECT: Parse frontmatter explicitly
|
|
818
|
-
const
|
|
819
|
-
if (
|
|
820
|
-
// Only matches actual frontmatter field
|
|
821
|
-
}
|
|
822
|
-
```
|
|
303
|
+
const match = content.match(/^feature_id:\s*["']?([^"'\n]+)["']?$/m);
|
|
304
|
+
if (match && match[1].trim() === 'FS-039') { /* ... */ }
|
|
823
305
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
```typescript
|
|
827
|
-
// ❌ WRONG: Substring matching (false positives!)
|
|
828
|
-
const isArchived = archivedList.some(item => item.includes(searchId));
|
|
829
|
-
// "0039-ultra-smart-v2".includes("0039-ultra-smart") → TRUE (WRONG!)
|
|
306
|
+
// ❌ WRONG: Substring matching
|
|
307
|
+
archivedList.some(item => item.includes(searchId))
|
|
830
308
|
|
|
831
309
|
// ✅ CORRECT: Exact equality
|
|
832
|
-
|
|
310
|
+
archivedList.some(item => item === searchId)
|
|
833
311
|
```
|
|
834
312
|
|
|
835
|
-
**
|
|
836
|
-
- **Incident 2025-11-20**: String search caused 11 features to be incorrectly archived
|
|
837
|
-
- Features that merely REFERENCED another feature appeared to BELONG to it
|
|
838
|
-
- Substring matching confused similar IDs as identical
|
|
839
|
-
|
|
840
|
-
**Prevention**:
|
|
841
|
-
1. Always parse structured data (YAML frontmatter, JSON) explicitly
|
|
842
|
-
2. Use exact equality (`===`) for ID matching, never `.includes()`
|
|
843
|
-
3. Add comprehensive logging to show matching decisions
|
|
844
|
-
4. Test with edge cases: references, links, partial matches
|
|
845
|
-
|
|
846
|
-
**See Also**: `.specweave/increments/0047-us-task-linkage/reports/CRITICAL-ARCHIVING-BUGS-FIX.md`
|
|
847
|
-
|
|
848
|
-
### 14. Marketplace Plugin Completeness (CRITICAL!)
|
|
849
|
-
|
|
850
|
-
**NEVER add incomplete plugins to `.claude-plugin/marketplace.json`**
|
|
851
|
-
|
|
852
|
-
**Rule**: ONLY plugins with complete implementation (agents/, commands/, or lib/) may be listed in marketplace.json.
|
|
853
|
-
|
|
854
|
-
**Why This Matters**:
|
|
855
|
-
When users install `npm i -g specweave`, Claude Code loads ALL plugins listed in marketplace.json. Incomplete plugins (skeleton-only with just skills/) cause loading errors that confuse users and damage the framework's reputation.
|
|
856
|
-
|
|
857
|
-
**Incomplete Plugin Definition**:
|
|
858
|
-
A plugin is considered INCOMPLETE if it ONLY has:
|
|
859
|
-
- `.claude-plugin/` directory
|
|
860
|
-
- `skills/` directory
|
|
861
|
-
|
|
862
|
-
A plugin is COMPLETE if it has ANY of:
|
|
863
|
-
- `agents/` directory (specialized Claude Code agents)
|
|
864
|
-
- `commands/` directory (slash commands)
|
|
865
|
-
- `lib/` directory (shared utilities, TypeScript implementations)
|
|
866
|
-
|
|
867
|
-
**Validation Process** (MANDATORY before ANY marketplace.json changes):
|
|
868
|
-
|
|
869
|
-
```bash
|
|
870
|
-
# 1. Run validation script
|
|
871
|
-
bash scripts/validate-marketplace-plugins.sh
|
|
872
|
-
|
|
873
|
-
# Expected output: "✅ VALIDATION PASSED!"
|
|
874
|
-
# If FAILED: Remove incomplete plugins from marketplace.json
|
|
875
|
-
```
|
|
876
|
-
|
|
877
|
-
**Examples**:
|
|
878
|
-
|
|
879
|
-
```bash
|
|
880
|
-
# ✅ COMPLETE plugins (may be listed in marketplace.json):
|
|
881
|
-
plugins/specweave-github/
|
|
882
|
-
├── .claude-plugin/
|
|
883
|
-
├── agents/ ← Has agents
|
|
884
|
-
├── commands/ ← Has commands
|
|
885
|
-
├── lib/ ← Has lib
|
|
886
|
-
└── skills/
|
|
887
|
-
|
|
888
|
-
plugins/specweave-kafka/
|
|
889
|
-
├── .claude-plugin/
|
|
890
|
-
├── agents/ ← Has agents
|
|
891
|
-
├── lib/ ← Has lib
|
|
892
|
-
└── skills/
|
|
893
|
-
|
|
894
|
-
# ✗ INCOMPLETE plugins (MUST NOT be listed in marketplace.json):
|
|
895
|
-
plugins/specweave-cost-optimizer/
|
|
896
|
-
├── .claude-plugin/
|
|
897
|
-
└── skills/ ← ONLY skills!
|
|
898
|
-
|
|
899
|
-
plugins/specweave-figma/
|
|
900
|
-
├── .claude-plugin/
|
|
901
|
-
└── skills/ ← ONLY skills!
|
|
902
|
-
```
|
|
313
|
+
**Incident**: 2025-11-20 - 11 features incorrectly archived (string search false positives)
|
|
903
314
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
```bash
|
|
907
|
-
# 1. Create plugin with COMPLETE structure
|
|
908
|
-
mkdir -p plugins/specweave-newplugin/{.claude-plugin,agents,skills}
|
|
909
|
-
|
|
910
|
-
# 2. Implement at least ONE of: agents/, commands/, or lib/
|
|
911
|
-
# (Don't just create empty directories!)
|
|
912
|
-
|
|
913
|
-
# 3. Add to marketplace.json
|
|
914
|
-
vim .claude-plugin/marketplace.json
|
|
315
|
+
---
|
|
915
316
|
|
|
916
|
-
|
|
917
|
-
bash scripts/validate-marketplace-plugins.sh
|
|
317
|
+
### 14. Marketplace Plugin Completeness
|
|
918
318
|
|
|
919
|
-
|
|
920
|
-
vim bin/fix-marketplace-errors.sh
|
|
921
|
-
# Add "specweave-newplugin" to plugins=(...) array
|
|
319
|
+
**NEVER add incomplete plugins to marketplace.json**
|
|
922
320
|
|
|
923
|
-
|
|
924
|
-
git add .claude-plugin/marketplace.json bin/fix-marketplace-errors.sh
|
|
925
|
-
git commit -m "feat: add specweave-newplugin to marketplace"
|
|
926
|
-
```
|
|
321
|
+
**Complete plugin requires**: `agents/`, `commands/`, OR `lib/` (not just `.claude-plugin/` + `skills/`)
|
|
927
322
|
|
|
928
|
-
**
|
|
323
|
+
**MANDATORY validation**:
|
|
929
324
|
```bash
|
|
930
|
-
|
|
931
|
-
bash scripts/validate-marketplace-plugins.sh
|
|
932
|
-
# Block commit if validation fails
|
|
325
|
+
bash scripts/validate-marketplace-plugins.sh # Must see "✅ VALIDATION PASSED!"
|
|
933
326
|
```
|
|
934
327
|
|
|
935
|
-
**
|
|
936
|
-
|
|
328
|
+
**Adding new plugin**:
|
|
329
|
+
1. Create with agents/commands/lib (NOT empty dirs!)
|
|
330
|
+
2. Add to marketplace.json
|
|
331
|
+
3. **VALIDATE** (critical!)
|
|
332
|
+
4. Update `bin/fix-marketplace-errors.sh`
|
|
333
|
+
5. Test: `npm pack && npm i -g ./specweave-*.tgz`
|
|
937
334
|
|
|
938
|
-
**
|
|
939
|
-
1. Run `bash scripts/validate-marketplace-plugins.sh` before EVERY marketplace.json change
|
|
940
|
-
2. NEVER add plugins to marketplace.json until they have agents/, commands/, or lib/
|
|
941
|
-
3. Update bin/fix-marketplace-errors.sh whenever marketplace.json changes
|
|
942
|
-
4. Test global npm install (`npm pack && npm i -g ./specweave-*.tgz`) before releases
|
|
335
|
+
**Incident**: 2025-11-20 - 8 incomplete plugins failed loading on global install
|
|
943
336
|
|
|
944
|
-
|
|
945
|
-
- Validation script: `scripts/validate-marketplace-plugins.sh`
|
|
946
|
-
- Fix script: `bin/fix-marketplace-errors.sh`
|
|
947
|
-
|
|
948
|
-
### 15. Skills vs Agents: Understanding the Distinction (CRITICAL!)
|
|
949
|
-
|
|
950
|
-
**NEVER confuse skills with agents** - They are different components with different invocation methods.
|
|
337
|
+
---
|
|
951
338
|
|
|
952
|
-
|
|
953
|
-
Empty agent directories cause "Agent type not found" errors when someone tries to invoke them. This happened with `specweave:increment-quality-judge-v2` which existed as a skill but had an empty agent directory.
|
|
339
|
+
### 15. Skills vs Agents
|
|
954
340
|
|
|
955
341
|
**Key Differences**:
|
|
956
342
|
|
|
957
343
|
| Aspect | Skills | Agents |
|
|
958
344
|
|--------|--------|--------|
|
|
959
345
|
| **Location** | `plugins/*/skills/name/SKILL.md` | `plugins/*/agents/name/AGENT.md` |
|
|
960
|
-
| **Invocation** | Skill
|
|
961
|
-
| **Activation** | Automatic (
|
|
962
|
-
| **
|
|
963
|
-
| **Purpose** | Expand context with knowledge | Execute multi-step tasks |
|
|
346
|
+
| **Invocation** | `Skill()` or `/command` | `Task()` with `subagent_type` |
|
|
347
|
+
| **Activation** | Automatic (keywords) | Explicit call |
|
|
348
|
+
| **File** | `SKILL.md` (YAML frontmatter) | `AGENT.md` |
|
|
964
349
|
|
|
965
|
-
**
|
|
350
|
+
**Agent naming**: `{plugin}:{directory}:{yaml-name}`
|
|
966
351
|
|
|
967
352
|
```typescript
|
|
968
|
-
// ✅ CORRECT:
|
|
969
|
-
Skill({ skill: "increment-quality-judge-v2" });
|
|
970
|
-
// OR use slash command:
|
|
971
|
-
/specweave:qa 0047
|
|
972
|
-
|
|
973
|
-
// ✅ CORRECT: Invoking an agent
|
|
974
|
-
Task({
|
|
975
|
-
subagent_type: "specweave:qa-lead:qa-lead",
|
|
976
|
-
prompt: "Create test plan for increment 0047"
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
// ❌ WRONG: Trying to invoke skill as agent
|
|
980
|
-
Task({
|
|
981
|
-
subagent_type: "specweave:increment-quality-judge-v2", // ERROR!
|
|
982
|
-
prompt: "Quality assessment"
|
|
983
|
-
});
|
|
984
|
-
```
|
|
985
|
-
|
|
986
|
-
**Agent Naming Convention** (CRITICAL!):
|
|
353
|
+
// ✅ CORRECT: Skill
|
|
354
|
+
Skill({ skill: "increment-quality-judge-v2" }); // or /specweave:qa
|
|
987
355
|
|
|
988
|
-
|
|
356
|
+
// ✅ CORRECT: Agent
|
|
357
|
+
Task({ subagent_type: "specweave:qa-lead:qa-lead", prompt: "..." });
|
|
989
358
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
Examples:
|
|
993
|
-
- Agent at `plugins/specweave/agents/qa-lead/AGENT.md` with `name: qa-lead`
|
|
994
|
-
→ Invoke as: `specweave:qa-lead:qa-lead`
|
|
995
|
-
- Agent at `plugins/specweave/agents/pm/AGENT.md` with `name: pm`
|
|
996
|
-
→ Invoke as: `specweave:pm:pm`
|
|
997
|
-
- Agent at `plugins/specweave/agents/architect/AGENT.md` with `name: architect`
|
|
998
|
-
→ Invoke as: `specweave:architect:architect`
|
|
999
|
-
|
|
1000
|
-
**Why the "duplication"?**
|
|
1001
|
-
The pattern is `{plugin}:{directory}:{yaml-name}`. When the directory name matches the YAML `name` field (best practice), it creates the appearance of duplication: `qa-lead:qa-lead`.
|
|
1002
|
-
|
|
1003
|
-
**File-based agents** (legacy pattern):
|
|
1004
|
-
- Agent at `plugins/specweave/agents/code-reviewer.md`
|
|
1005
|
-
→ Invoke as: `specweave:code-reviewer` (no duplication)
|
|
1006
|
-
|
|
1007
|
-
**How to find the correct agent type**:
|
|
1008
|
-
```bash
|
|
1009
|
-
# List all available agents
|
|
1010
|
-
ls -la plugins/specweave/agents/
|
|
1011
|
-
|
|
1012
|
-
# Check YAML name field
|
|
1013
|
-
head -5 plugins/specweave/agents/qa-lead/AGENT.md
|
|
1014
|
-
# Output: name: qa-lead
|
|
1015
|
-
|
|
1016
|
-
# Construct agent type: specweave:qa-lead:qa-lead
|
|
359
|
+
// ❌ WRONG: Skill as agent
|
|
360
|
+
Task({ subagent_type: "specweave:increment-quality-judge-v2" }); // ERROR!
|
|
1017
361
|
```
|
|
1018
362
|
|
|
1019
|
-
**
|
|
1020
|
-
```typescript
|
|
1021
|
-
// ❌ WRONG: Missing the directory/name duplication
|
|
1022
|
-
Task({ subagent_type: "specweave:qa-lead", ... });
|
|
1023
|
-
// Error: Agent type 'specweave:qa-lead' not found
|
|
363
|
+
**Validation**: `bash scripts/validate-plugin-directories.sh --fix`
|
|
1024
364
|
|
|
1025
|
-
|
|
1026
|
-
Task({ subagent_type: "specweave:qa-lead:qa-lead", ... });
|
|
1027
|
-
```
|
|
365
|
+
**Incident**: 2025-11-20 - Empty agent directory caused "Agent not found" error
|
|
1028
366
|
|
|
1029
|
-
**Directory Structure Requirements**:
|
|
1030
|
-
|
|
1031
|
-
```bash
|
|
1032
|
-
# ✅ CORRECT: Skill with SKILL.md
|
|
1033
|
-
plugins/specweave/skills/increment-quality-judge-v2/
|
|
1034
|
-
└── SKILL.md (with YAML frontmatter)
|
|
1035
|
-
|
|
1036
|
-
# ✅ CORRECT: Agent with AGENT.md
|
|
1037
|
-
plugins/specweave/agents/qa-lead/
|
|
1038
|
-
└── AGENT.md
|
|
1039
|
-
|
|
1040
|
-
# ❌ WRONG: Empty agent directory
|
|
1041
|
-
plugins/specweave/agents/increment-quality-judge-v2/
|
|
1042
|
-
(empty - no AGENT.md!)
|
|
1043
|
-
|
|
1044
|
-
# ❌ WRONG: Skill missing SKILL.md
|
|
1045
|
-
plugins/specweave/skills/my-skill/
|
|
1046
|
-
└── some-file.txt (not SKILL.md!)
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
**SKILL.md Format** (MANDATORY):
|
|
1050
|
-
```yaml
|
|
1051
|
-
---
|
|
1052
|
-
name: skill-name
|
|
1053
|
-
description: What it does AND trigger keywords. Include all variations.
|
|
1054
|
-
---
|
|
1055
|
-
|
|
1056
|
-
# Skill Content
|
|
1057
|
-
|
|
1058
|
-
Your skill documentation here...
|
|
1059
|
-
```
|
|
1060
|
-
|
|
1061
|
-
**Validation** (MANDATORY before commits):
|
|
1062
|
-
|
|
1063
|
-
```bash
|
|
1064
|
-
# Check for empty/invalid directories
|
|
1065
|
-
bash scripts/validate-plugin-directories.sh
|
|
1066
|
-
|
|
1067
|
-
# Auto-fix empty directories
|
|
1068
|
-
bash scripts/validate-plugin-directories.sh --fix
|
|
1069
|
-
|
|
1070
|
-
# This catches:
|
|
1071
|
-
# - Empty agent/skill directories
|
|
1072
|
-
# - Missing SKILL.md files
|
|
1073
|
-
# - Missing YAML frontmatter
|
|
1074
|
-
# - Invalid plugin structures
|
|
1075
|
-
```
|
|
1076
|
-
|
|
1077
|
-
**Common Mistakes**:
|
|
1078
|
-
|
|
1079
|
-
1. **Creating empty agent directories during scaffolding**
|
|
1080
|
-
```bash
|
|
1081
|
-
# ❌ WRONG
|
|
1082
|
-
mkdir -p plugins/specweave/agents/new-agent
|
|
1083
|
-
git add . && git commit # Empty directory!
|
|
1084
|
-
|
|
1085
|
-
# ✅ CORRECT
|
|
1086
|
-
mkdir -p plugins/specweave/agents/new-agent
|
|
1087
|
-
echo "---" > plugins/specweave/agents/new-agent/AGENT.md
|
|
1088
|
-
# ... add agent content ...
|
|
1089
|
-
git add . && git commit
|
|
1090
|
-
```
|
|
1091
|
-
|
|
1092
|
-
2. **Copying skill as agent without changing structure**
|
|
1093
|
-
- Skills need `SKILL.md` with YAML
|
|
1094
|
-
- Agents need `AGENT.md` or config
|
|
1095
|
-
- Don't copy-paste between them!
|
|
1096
|
-
|
|
1097
|
-
3. **Using wrong invocation method**
|
|
1098
|
-
- Check available skills: Skills list in context
|
|
1099
|
-
- Check available agents: Error message shows all agents
|
|
1100
|
-
- Skills → Skill tool or slash commands
|
|
1101
|
-
- Agents → Task tool
|
|
1102
|
-
|
|
1103
|
-
**When to Use Skills vs Agents**:
|
|
1104
|
-
|
|
1105
|
-
**Use Skills when**:
|
|
1106
|
-
- Providing domain knowledge (e.g., Kafka best practices)
|
|
1107
|
-
- Expanding Claude's context with project-specific info
|
|
1108
|
-
- Explaining concepts, patterns, frameworks
|
|
1109
|
-
- Want automatic activation based on keywords
|
|
1110
|
-
|
|
1111
|
-
**Use Agents when**:
|
|
1112
|
-
- Need multi-step task execution (e.g., generate docs)
|
|
1113
|
-
- Require specialized sub-agent capabilities
|
|
1114
|
-
- Building complex workflows with tools
|
|
1115
|
-
- Want explicit control over when they run
|
|
1116
|
-
|
|
1117
|
-
**Incident History**:
|
|
1118
|
-
- **2025-11-20**: `specweave:increment-quality-judge-v2` agent invocation failed because only skill existed. Empty agent directory caused "Agent type not found" error. Fixed by removing empty directory and documenting distinction.
|
|
1119
|
-
|
|
1120
|
-
**Prevention**:
|
|
1121
|
-
1. Run `bash scripts/validate-plugin-directories.sh` before commits
|
|
1122
|
-
2. Never create empty agent/skill directories
|
|
1123
|
-
3. Always include required files (SKILL.md, AGENT.md)
|
|
1124
|
-
4. Test invocation method matches component type
|
|
1125
|
-
5. Use pre-commit hook (blocks invalid structures)
|
|
1126
|
-
|
|
1127
|
-
**See Also**:
|
|
1128
|
-
- Validation script: `scripts/validate-plugin-directories.sh`
|
|
1129
|
-
- Skills index: `plugins/specweave/skills/SKILLS-INDEX.md`
|
|
1130
|
-
- Claude Code Skills docs: `~/CLAUDE.md` (Personal skills reference)
|
|
1131
|
-
|
|
1132
|
-
### 16. YAML Frontmatter Validation (CRITICAL!)
|
|
1133
|
-
|
|
1134
|
-
**Rule**: ALL spec.md files MUST have valid YAML frontmatter with required fields.
|
|
1135
|
-
|
|
1136
|
-
**Required Format**:
|
|
1137
|
-
```yaml
|
|
1138
|
-
---
|
|
1139
|
-
increment: 0001-feature-name # REQUIRED: 4-digit number + kebab-case
|
|
1140
|
-
title: Feature Title # OPTIONAL: Human-readable title
|
|
1141
|
-
feature_id: FS-001 # OPTIONAL: Living docs feature ID
|
|
1142
367
|
---
|
|
1143
|
-
```
|
|
1144
368
|
|
|
1145
|
-
|
|
369
|
+
### 16. YAML Frontmatter Validation
|
|
1146
370
|
|
|
371
|
+
**Required format**:
|
|
1147
372
|
```yaml
|
|
1148
|
-
# ❌ WRONG: Unclosed bracket
|
|
1149
|
-
---
|
|
1150
|
-
increment: 0001-test
|
|
1151
|
-
data: [unclosed
|
|
1152
373
|
---
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
increment: 0001-test
|
|
1157
|
-
title: "unclosed string
|
|
1158
|
-
---
|
|
1159
|
-
|
|
1160
|
-
# ❌ WRONG: Invalid YAML object
|
|
1161
|
-
---
|
|
1162
|
-
increment: 0001-test
|
|
1163
|
-
config: {key: value, broken
|
|
1164
|
-
---
|
|
1165
|
-
|
|
1166
|
-
# ❌ WRONG: Invalid increment ID format
|
|
1167
|
-
---
|
|
1168
|
-
increment: 1-test # Missing leading zeros
|
|
1169
|
-
---
|
|
1170
|
-
|
|
1171
|
-
# ❌ WRONG: Invalid increment ID format (uppercase)
|
|
1172
|
-
---
|
|
1173
|
-
increment: 0001-Test-Feature # Uppercase letters not allowed
|
|
1174
|
-
---
|
|
1175
|
-
|
|
1176
|
-
# ❌ WRONG: Missing required field
|
|
1177
|
-
---
|
|
1178
|
-
title: Feature Title # Missing increment field!
|
|
1179
|
-
---
|
|
1180
|
-
|
|
1181
|
-
# ✅ CORRECT: Minimal valid frontmatter
|
|
1182
|
-
---
|
|
1183
|
-
increment: 0001-feature-name
|
|
1184
|
-
---
|
|
1185
|
-
|
|
1186
|
-
# ✅ CORRECT: Full frontmatter
|
|
1187
|
-
---
|
|
1188
|
-
increment: 0042-bug-fix
|
|
1189
|
-
title: Critical Bug Fix
|
|
1190
|
-
feature_id: FS-013
|
|
374
|
+
increment: 0001-feature-name # REQUIRED: 4-digit + kebab-case
|
|
375
|
+
title: Feature Title # OPTIONAL
|
|
376
|
+
feature_id: FS-001 # OPTIONAL
|
|
1191
377
|
---
|
|
1192
378
|
```
|
|
1193
379
|
|
|
1194
|
-
**
|
|
1195
|
-
|
|
1196
|
-
1. **Pre-commit hook** - Validates YAML before commits (blocks malformed frontmatter)
|
|
1197
|
-
```bash
|
|
1198
|
-
# Runs automatically on git commit
|
|
1199
|
-
scripts/pre-commit-yaml-validation.sh
|
|
1200
|
-
```
|
|
1201
|
-
|
|
1202
|
-
2. **Spec parser** - Uses `js-yaml` library (detects errors at runtime)
|
|
1203
|
-
- Provides descriptive error messages
|
|
1204
|
-
- Shows line numbers for YAML errors
|
|
1205
|
-
- Suggests common fixes
|
|
380
|
+
**Common mistakes**: Unclosed brackets/quotes, invalid objects, missing `increment`, uppercase in ID
|
|
1206
381
|
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
**Manual YAML Testing**:
|
|
382
|
+
**Validation layers**:
|
|
383
|
+
1. Pre-commit hook: `scripts/pre-commit-yaml-validation.sh`
|
|
384
|
+
2. Spec parser (uses `js-yaml`, provides line numbers)
|
|
385
|
+
3. `/specweave:validate 0001`
|
|
1213
386
|
|
|
387
|
+
**Manual test**:
|
|
1214
388
|
```bash
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1219
|
-
const content = fs.readFileSync('.specweave/increments/0001-test/spec.md', 'utf-8');
|
|
1220
|
-
const frontmatter = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1221
|
-
if (!frontmatter) throw new Error('No frontmatter found');
|
|
1222
|
-
const parsed = yaml.load(frontmatter[1]);
|
|
1223
|
-
console.log('✅ Valid YAML:', JSON.stringify(parsed, null, 2));
|
|
1224
|
-
"
|
|
1225
|
-
```
|
|
1226
|
-
|
|
1227
|
-
**Error Messages**:
|
|
1228
|
-
|
|
1229
|
-
When YAML validation fails, you'll see descriptive errors:
|
|
1230
|
-
|
|
1231
|
-
```
|
|
1232
|
-
ERROR: Malformed YAML syntax in frontmatter
|
|
1233
|
-
DETAILS: Unexpected end of stream
|
|
1234
|
-
LOCATION: Lines 2-5
|
|
1235
|
-
HINT: Common mistakes:
|
|
1236
|
-
- Unclosed brackets: [unclosed
|
|
1237
|
-
- Unclosed quotes: "unclosed
|
|
1238
|
-
- Invalid YAML object: {key: value, broken
|
|
389
|
+
node -e "const yaml = require('js-yaml'); const fs = require('fs'); \
|
|
390
|
+
const content = fs.readFileSync('.specweave/increments/0001-test/spec.md', 'utf-8'); \
|
|
391
|
+
const fm = content.match(/^---\n([\s\S]*?)\n---/); \
|
|
392
|
+
console.log('✅ Valid:', JSON.stringify(yaml.load(fm[1]), null, 2));"
|
|
1239
393
|
```
|
|
1240
394
|
|
|
1241
|
-
**Why This Matters**:
|
|
1242
|
-
- **Silent failures**: Malformed YAML can cause missing/incorrect metadata
|
|
1243
|
-
- **Sync issues**: Invalid increment IDs break living docs sync
|
|
1244
|
-
- **GitHub sync**: Broken frontmatter prevents issue creation
|
|
1245
|
-
- **Validation failures**: Tasks/ACs can't be parsed without valid metadata
|
|
1246
|
-
|
|
1247
|
-
**Incident History**:
|
|
1248
|
-
- **Test case**: `tests/integration/commands/plan-command.integration.test.ts:626` tests malformed YAML handling
|
|
1249
|
-
- **Root cause**: Regex-based parsing was tolerant but unreliable
|
|
1250
|
-
- **Solution**: Multi-layered YAML validation with `js-yaml` library
|
|
1251
|
-
|
|
1252
|
-
**See Also**:
|
|
1253
|
-
- Pre-commit hook: `scripts/pre-commit-yaml-validation.sh`
|
|
1254
|
-
- Spec parser: `src/generators/spec/spec-parser.ts` (uses js-yaml)
|
|
1255
|
-
- Test suite: `tests/integration/commands/plan-command.integration.test.ts`
|
|
1256
|
-
|
|
1257
395
|
---
|
|
1258
396
|
|
|
1259
397
|
## Project Structure
|
|
1260
398
|
|
|
1261
399
|
```
|
|
1262
|
-
src/ # TypeScript
|
|
1263
|
-
plugins/ #
|
|
400
|
+
src/ # TypeScript (compiled to dist/)
|
|
401
|
+
plugins/ # Skills, agents, commands, hooks
|
|
1264
402
|
├── specweave/ # Core plugin
|
|
1265
|
-
└── specweave-*/ # Optional plugins
|
|
1266
|
-
.specweave/ #
|
|
403
|
+
└── specweave-*/ # Optional plugins
|
|
404
|
+
.specweave/ # Increments, docs, logs
|
|
1267
405
|
```
|
|
1268
406
|
|
|
1269
|
-
**Rules**:
|
|
1270
|
-
- `src/` = TypeScript ONLY
|
|
1271
|
-
- ALL skills/agents/commands/hooks = `plugins/`
|
|
1272
|
-
- Marketplace = GLOBAL via CLI
|
|
1273
|
-
- NEVER mix `*.ts` and `SKILL.md` in same directory
|
|
1274
|
-
- NEVER create files in project root
|
|
407
|
+
**Rules**: `src/` = TS only, ALL components = `plugins/`, NEVER mix `.ts` + `SKILL.md`, NEVER root files
|
|
1275
408
|
|
|
1276
409
|
---
|
|
1277
410
|
|
|
1278
|
-
## Plugin Hook Registration
|
|
1279
|
-
|
|
1280
|
-
**When**: Adding or modifying hooks that respond to Claude Code tool events
|
|
1281
|
-
|
|
1282
|
-
**Hook Schema Rules** (v0.22.14+):
|
|
1283
|
-
1. ✅ **ONLY use valid Claude Code hook events** (e.g., PostToolUse, PreToolUse, SessionStart)
|
|
1284
|
-
2. ❌ **NEVER use custom hook names** (e.g., "TodoWrite") as hook events
|
|
1285
|
-
3. ✅ **Use matchers** to filter which tool calls trigger the hook
|
|
411
|
+
## Plugin Hook Registration
|
|
1286
412
|
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
Claude Code supports **only these 10 hook events**:
|
|
1290
|
-
- `PostToolUse` - After a tool completes (use this for TodoWrite, Write, Edit, etc.)
|
|
1291
|
-
- `PreToolUse` - Before a tool executes
|
|
1292
|
-
- `PermissionRequest` - When permission dialogs appear
|
|
1293
|
-
- `Notification` - When notifications are sent
|
|
1294
|
-
- `UserPromptSubmit` - When users submit prompts
|
|
1295
|
-
- `Stop` - When the main agent finishes
|
|
1296
|
-
- `SubagentStop` - When subagents finish
|
|
1297
|
-
- `PreCompact` - Before compaction operations
|
|
1298
|
-
- `SessionStart` - At session initialization
|
|
1299
|
-
- `SessionEnd` - When sessions terminate
|
|
1300
|
-
|
|
1301
|
-
### Correct Hook Registration Format
|
|
1302
|
-
|
|
1303
|
-
**File**: `plugins/*/. claude-plugin/plugin.json`
|
|
413
|
+
**Valid hook events** (10 total): `PostToolUse`, `PreToolUse`, `PermissionRequest`, `Notification`, `UserPromptSubmit`, `Stop`, `SubagentStop`, `PreCompact`, `SessionStart`, `SessionEnd`
|
|
1304
414
|
|
|
415
|
+
**Format** (`plugins/*/.claude-plugin/plugin.json`):
|
|
1305
416
|
```json
|
|
1306
417
|
{
|
|
1307
|
-
"name": "specweave",
|
|
1308
|
-
"version": "0.22.14",
|
|
1309
418
|
"hooks": {
|
|
1310
419
|
"PostToolUse": [
|
|
1311
420
|
{
|
|
1312
421
|
"matcher": "TodoWrite",
|
|
1313
|
-
"hooks": [
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
}
|
|
1319
|
-
]
|
|
422
|
+
"hooks": [{
|
|
423
|
+
"type": "command",
|
|
424
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-task-completion.sh",
|
|
425
|
+
"timeout": 10
|
|
426
|
+
}]
|
|
1320
427
|
}
|
|
1321
428
|
]
|
|
1322
429
|
}
|
|
1323
430
|
}
|
|
1324
431
|
```
|
|
1325
432
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|-------|------|---------|
|
|
1329
|
-
| `PostToolUse` | array | Hook event (one of 10 valid events above) |
|
|
1330
|
-
| `matcher` | string | Tool name pattern (e.g., "TodoWrite", "Write\|Edit") |
|
|
1331
|
-
| `type` | string | Always "command" for shell scripts |
|
|
1332
|
-
| `command` | string | Script path (use `${CLAUDE_PLUGIN_ROOT}` for plugin directory) |
|
|
1333
|
-
| `timeout` | number | Seconds before timeout (default: 30) |
|
|
433
|
+
**❌ WRONG**: `"TodoWrite": {...}` (invalid event)
|
|
434
|
+
**✅ CORRECT**: `"PostToolUse"` with `"matcher": "TodoWrite"`
|
|
1334
435
|
|
|
1335
|
-
|
|
436
|
+
---
|
|
1336
437
|
|
|
1337
|
-
|
|
1338
|
-
```json
|
|
1339
|
-
{
|
|
1340
|
-
"hooks": {
|
|
1341
|
-
"TodoWrite": {
|
|
1342
|
-
"post": "./hooks/post-task-completion.sh"
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
```
|
|
1347
|
-
**Error**: `"TodoWrite"` is not a valid Claude Code hook event
|
|
438
|
+
## 9a. Hook Performance & Safety (CRITICAL - v0.24.3)
|
|
1348
439
|
|
|
1349
|
-
|
|
1350
|
-
```json
|
|
1351
|
-
{
|
|
1352
|
-
"hooks": {
|
|
1353
|
-
"PostToolUse": [
|
|
1354
|
-
{
|
|
1355
|
-
"matcher": "TodoWrite",
|
|
1356
|
-
"hooks": [{"type": "command", "command": "..."}]
|
|
1357
|
-
}
|
|
1358
|
-
]
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
```
|
|
440
|
+
**Critical incidents**: 2025-11-22 - Multiple Claude Code crashes due to hook overhead
|
|
1362
441
|
|
|
1363
|
-
|
|
442
|
+
**Root cause**: Process exhaustion from spawning 6+ Node.js processes per task completion
|
|
1364
443
|
|
|
1365
|
-
|
|
1366
|
-
# 1. Update plugin.json with correct schema
|
|
1367
|
-
vim plugins/specweave/.claude-plugin/plugin.json
|
|
444
|
+
**Emergency fixes implemented (v0.24.3)**:
|
|
1368
445
|
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
446
|
+
### 1. Emergency Kill Switch
|
|
447
|
+
```bash
|
|
448
|
+
# INSTANT disable of ALL hooks
|
|
449
|
+
export SPECWEAVE_DISABLE_HOOKS=1
|
|
450
|
+
```
|
|
1373
451
|
|
|
1374
|
-
|
|
452
|
+
### 2. Circuit Breaker (Auto-Protection)
|
|
453
|
+
- **Threshold**: 3 consecutive failures → auto-disable hooks
|
|
454
|
+
- **File**: `.specweave/state/.hook-circuit-breaker`
|
|
455
|
+
- **Recovery**: `rm .specweave/state/.hook-circuit-breaker`
|
|
1375
456
|
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
457
|
+
### 3. File Locking (Prevents Concurrent Execution)
|
|
458
|
+
- **Max instances**: 1 per hook type
|
|
459
|
+
- **Timeout**: 5-10 seconds with stale lock cleanup
|
|
460
|
+
- **Mechanism**: Directory-based mutex
|
|
1380
461
|
|
|
1381
|
-
|
|
462
|
+
### 4. Aggressive Debouncing
|
|
463
|
+
- **Window**: 5 seconds (increased from 1s)
|
|
464
|
+
- **Effect**: Batches rapid operations
|
|
465
|
+
- **Trade-off**: 5s staleness acceptable for UX
|
|
1382
466
|
|
|
1383
|
-
|
|
1384
|
-
|
|
467
|
+
### 5. Complete Error Isolation
|
|
468
|
+
```bash
|
|
469
|
+
set +e # NEVER use set -e in hooks
|
|
470
|
+
exit 0 # ALWAYS exit 0, never block workflow
|
|
1385
471
|
```
|
|
1386
472
|
|
|
1387
|
-
###
|
|
473
|
+
### 6. Consolidated Background Work
|
|
474
|
+
- **Before**: 6+ Node.js spawns per task (exhaustion!)
|
|
475
|
+
- **After**: 1 consolidated background job
|
|
476
|
+
- **Reduction**: 85% fewer processes
|
|
1388
477
|
|
|
1389
|
-
|
|
1390
|
-
- **Hooks Reference**: https://code.claude.com/docs/en/hooks-reference.md
|
|
1391
|
-
- **Fix History**: See CHANGELOG.md v0.22.14 for the hook schema bug fix
|
|
478
|
+
### Hook Safety Checklist (MANDATORY)
|
|
1392
479
|
|
|
1393
|
-
|
|
480
|
+
**✅ EVERY hook MUST have**:
|
|
481
|
+
1. Kill switch check (`SPECWEAVE_DISABLE_HOOKS`)
|
|
482
|
+
2. Circuit breaker check (3 failure threshold)
|
|
483
|
+
3. File locking (prevent concurrent runs)
|
|
484
|
+
4. Debouncing (5s minimum)
|
|
485
|
+
5. Error isolation (`set +e`, `exit 0`)
|
|
486
|
+
6. Background work wrapped in subshell
|
|
487
|
+
7. Circuit breaker updates on success/failure
|
|
1394
488
|
|
|
1395
|
-
|
|
489
|
+
**❌ NEVER in hooks**:
|
|
490
|
+
- `set -e` (causes crashes)
|
|
491
|
+
- Synchronous Node.js spawns
|
|
492
|
+
- Multiple separate background jobs
|
|
493
|
+
- Error propagation to Claude Code
|
|
494
|
+
- Missing `exit 0` at end
|
|
1396
495
|
|
|
1397
|
-
###
|
|
496
|
+
### Performance Targets
|
|
1398
497
|
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
/specweave:done # Close (validates ACs, tasks, tests)
|
|
1405
|
-
|
|
1406
|
-
# State management
|
|
1407
|
-
/specweave:pause 0002 --reason="..."
|
|
1408
|
-
/specweave:resume 0002
|
|
1409
|
-
/specweave:abandon 0002
|
|
1410
|
-
|
|
1411
|
-
# Quality
|
|
1412
|
-
/specweave:validate 0001
|
|
1413
|
-
/specweave:qa 0001
|
|
1414
|
-
|
|
1415
|
-
# Documentation
|
|
1416
|
-
/specweave:sync-docs update
|
|
1417
|
-
/specweave:sync-tasks
|
|
1418
|
-
```
|
|
498
|
+
| Metric | Target | Warning | Critical |
|
|
499
|
+
|--------|--------|---------|----------|
|
|
500
|
+
| Hook execution | <100ms | 100-500ms | >500ms |
|
|
501
|
+
| Background processes | 0-2 | 3-5 | 6+ |
|
|
502
|
+
| Circuit breaker count | 0 | 1-2 | 3 (open) |
|
|
1419
503
|
|
|
1420
|
-
###
|
|
504
|
+
### Emergency Recovery
|
|
1421
505
|
|
|
506
|
+
**If Claude Code crashes**:
|
|
1422
507
|
```bash
|
|
1423
|
-
# 1.
|
|
1424
|
-
|
|
1425
|
-
cd specweave
|
|
1426
|
-
npm install
|
|
508
|
+
# 1. Immediate kill switch
|
|
509
|
+
export SPECWEAVE_DISABLE_HOOKS=1
|
|
1427
510
|
|
|
1428
|
-
# 2.
|
|
1429
|
-
|
|
1430
|
-
rm -rf ~/.claude/plugins/marketplaces/specweave
|
|
1431
|
-
ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
|
|
511
|
+
# 2. Reset circuit breaker
|
|
512
|
+
rm -f .specweave/state/.hook-circuit-breaker
|
|
1432
513
|
|
|
1433
|
-
# 3.
|
|
1434
|
-
|
|
514
|
+
# 3. Clear locks
|
|
515
|
+
rm -rf .specweave/state/.hook-*.lock
|
|
1435
516
|
|
|
1436
|
-
# 4.
|
|
1437
|
-
|
|
517
|
+
# 4. Rebuild
|
|
518
|
+
npm run rebuild
|
|
1438
519
|
```
|
|
1439
520
|
|
|
1440
|
-
**
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
```
|
|
521
|
+
**See**:
|
|
522
|
+
- `.specweave/docs/internal/emergency-procedures/HOOK-CRASH-RECOVERY.md` (Complete recovery guide)
|
|
523
|
+
- ADR-0060 (Three-tier optimization architecture)
|
|
524
|
+
- `.specweave/increments/0050-*/reports/hook-crash-analysis.md` (Incident analysis)
|
|
1445
525
|
|
|
1446
526
|
---
|
|
1447
527
|
|
|
1448
|
-
##
|
|
1449
|
-
|
|
1450
|
-
### Build
|
|
528
|
+
## Development Workflow
|
|
1451
529
|
|
|
530
|
+
**Core commands**:
|
|
1452
531
|
```bash
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
532
|
+
/specweave:increment "feature" # Plan
|
|
533
|
+
/specweave:do # Execute
|
|
534
|
+
/specweave:progress # Status
|
|
535
|
+
/specweave:done 0002 # Close (validates)
|
|
536
|
+
/specweave:validate 0001 # Validate
|
|
537
|
+
/specweave:qa 0001 # Quality check
|
|
538
|
+
/specweave:pause/resume/abandon # State management
|
|
1456
539
|
```
|
|
1457
540
|
|
|
1458
|
-
**
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
541
|
+
**Local setup**:
|
|
542
|
+
```bash
|
|
543
|
+
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
544
|
+
cd specweave && npm install
|
|
545
|
+
mkdir -p ~/.claude/plugins/marketplaces
|
|
546
|
+
ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
|
|
547
|
+
bash scripts/install-git-hooks.sh
|
|
548
|
+
```
|
|
1463
549
|
|
|
1464
|
-
|
|
1465
|
-
- Problem: Hooks imported from `../../../../dist/src/...` (failed in marketplace)
|
|
1466
|
-
- Solution: Copy compiled files to `plugins/*/lib/vendor/`
|
|
1467
|
-
- Hooks now import from `../vendor/...` (self-contained)
|
|
1468
|
-
- Script: `scripts/copy-hook-dependencies.js`
|
|
1469
|
-
- Auto-detect deps: `scripts/find-hook-dependencies.js`
|
|
550
|
+
---
|
|
1470
551
|
|
|
1471
|
-
|
|
1472
|
-
```typescript
|
|
1473
|
-
// ✅ CORRECT
|
|
1474
|
-
import { foo } from './bar.js';
|
|
552
|
+
## Build & Test
|
|
1475
553
|
|
|
1476
|
-
|
|
1477
|
-
|
|
554
|
+
**Build**:
|
|
555
|
+
```bash
|
|
556
|
+
npm run rebuild # Clean + build (development)
|
|
557
|
+
npm run build # Compile TS + copy deps
|
|
1478
558
|
```
|
|
1479
559
|
|
|
1480
|
-
**
|
|
1481
|
-
|
|
1482
|
-
### Testing
|
|
560
|
+
**Architecture**: `tsc` → `dist/src/`, esbuild → plugin hooks, copy deps → `plugins/*/lib/vendor/`
|
|
1483
561
|
|
|
1484
|
-
**
|
|
562
|
+
**CRITICAL**: Always `.js` extensions (`import { foo } from './bar.js'`)
|
|
1485
563
|
|
|
564
|
+
**Test**:
|
|
1486
565
|
```bash
|
|
1487
|
-
npm test # Smoke
|
|
1488
|
-
npm run test:unit # Unit
|
|
1489
|
-
npm run test:integration # Integration
|
|
1490
|
-
npm run test:
|
|
1491
|
-
npm run test:
|
|
1492
|
-
npm run test:coverage # Coverage report
|
|
566
|
+
npm test # Smoke
|
|
567
|
+
npm run test:unit # Unit
|
|
568
|
+
npm run test:integration # Integration
|
|
569
|
+
npm run test:all # All
|
|
570
|
+
npm run test:coverage # Coverage (80%+ required)
|
|
1493
571
|
```
|
|
1494
572
|
|
|
1495
|
-
**Test
|
|
1496
|
-
- `
|
|
1497
|
-
-
|
|
1498
|
-
-
|
|
573
|
+
**Test rules**:
|
|
574
|
+
- Use `vi.fn()` (NOT `jest.fn()`)
|
|
575
|
+
- Use `os.tmpdir()` (NOT `process.cwd()`)
|
|
576
|
+
- ALL tests = `.test.ts` (NEVER `.spec.ts`)
|
|
577
|
+
- Use `createIsolatedTestDir()` helper
|
|
578
|
+
|
|
579
|
+
---
|
|
1499
580
|
|
|
1500
|
-
|
|
581
|
+
## Configuration Management (v0.24.0+)
|
|
1501
582
|
|
|
1502
|
-
|
|
583
|
+
**Secrets** (.env, gitignored) vs **Config** (.specweave/config.json, committed)
|
|
1503
584
|
|
|
1504
585
|
```typescript
|
|
1505
|
-
|
|
1506
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
1507
|
-
import fs from 'fs-extra';
|
|
586
|
+
import { getConfigManager } from '../core/config/index.js';
|
|
1508
587
|
|
|
1509
|
-
|
|
588
|
+
const configManager = getConfigManager(projectRoot);
|
|
589
|
+
const config = await configManager.read();
|
|
590
|
+
await configManager.update({ issueTracker: { provider: 'jira', domain: 'example.atlassian.net' }});
|
|
591
|
+
```
|
|
1510
592
|
|
|
1511
|
-
|
|
593
|
+
**What goes where**:
|
|
1512
594
|
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
```
|
|
595
|
+
| Type | Location | Example | Committed? |
|
|
596
|
+
|------|----------|---------|------------|
|
|
597
|
+
| Tokens/Emails | `.env` | `JIRA_API_TOKEN=xyz` | ❌ |
|
|
598
|
+
| Domains/Strategies | `config.json` | `"domain": "example.atlassian.net"` | ✅ |
|
|
1518
599
|
|
|
1519
|
-
**
|
|
1520
|
-
```typescript
|
|
1521
|
-
// ❌ NEVER use jest APIs
|
|
1522
|
-
jest.fn() // Use: vi.fn()
|
|
1523
|
-
jest.mock() // Use: vi.mock()
|
|
600
|
+
**Migration**: `node -e "require('./dist/src/cli/commands/migrate-config.js').migrateConfig({ dryRun: true })"`
|
|
1524
601
|
|
|
1525
|
-
|
|
1526
|
-
const testRoot = path.join(process.cwd(), '.test-something');
|
|
602
|
+
**See**: ADR-0050, `src/core/config/config-manager.ts`
|
|
1527
603
|
|
|
1528
|
-
|
|
1529
|
-
const testRoot = path.join(os.tmpdir(), 'test-' + Date.now());
|
|
1530
|
-
```
|
|
604
|
+
---
|
|
1531
605
|
|
|
1532
|
-
|
|
1533
|
-
```typescript
|
|
1534
|
-
import { createIsolatedTestDir } from '../test-utils/isolated-test-dir';
|
|
606
|
+
## Cache Management (v0.24.0+)
|
|
1535
607
|
|
|
1536
|
-
|
|
1537
|
-
try {
|
|
1538
|
-
// Test code here
|
|
1539
|
-
} finally {
|
|
1540
|
-
await cleanup(); // ALWAYS cleanup
|
|
1541
|
-
}
|
|
1542
|
-
```
|
|
608
|
+
**Smart Caching with 24-Hour TTL**: Reduces API calls by 90% during init and sync operations.
|
|
1543
609
|
|
|
1544
|
-
###
|
|
610
|
+
### Cache Architecture
|
|
1545
611
|
|
|
1546
|
-
**
|
|
1547
|
-
|
|
1548
|
-
|
|
612
|
+
**Location**: `.specweave/cache/`
|
|
613
|
+
**TTL**: 24 hours (configurable)
|
|
614
|
+
**Format**: JSON with timestamps
|
|
1549
615
|
|
|
1550
|
-
|
|
1551
|
-
```typescript
|
|
1552
|
-
#!/usr/bin/env node
|
|
1553
|
-
import { ACStatusManager } from '../../../../dist/src/core/...'; // Use dist/
|
|
1554
|
-
```
|
|
616
|
+
### Cached Data
|
|
1555
617
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
618
|
+
| Cache Key | Data | Use Case |
|
|
619
|
+
|-----------|------|----------|
|
|
620
|
+
| `jira-projects-{domain}` | Project list | JIRA init (auto-discovery) |
|
|
621
|
+
| `ado-config` | Org/project/teams | ADO init (manual entry) |
|
|
622
|
+
| `jira-{PROJECT}-deps` | Boards, components, versions | On-demand dependency loading |
|
|
623
|
+
| `ado-{PROJECT}-deps` | Area paths, teams | ADO dependency loading |
|
|
1561
624
|
|
|
1562
|
-
|
|
1563
|
-
```bash
|
|
1564
|
-
npx tsx .specweave/increments/####/scripts/script-name.ts
|
|
1565
|
-
```
|
|
625
|
+
### Cache Operations
|
|
1566
626
|
|
|
1567
|
-
|
|
627
|
+
**Automatic caching** (during init):
|
|
628
|
+
- JIRA: `promptJiraCredentials()` caches selected projects
|
|
629
|
+
- ADO: `promptAzureDevOpsCredentials()` caches org/project config
|
|
1568
630
|
|
|
1569
|
-
|
|
1570
|
-
|
|
631
|
+
**Manual cache management**:
|
|
632
|
+
```bash
|
|
633
|
+
# Refresh cache (bypass TTL)
|
|
634
|
+
/specweave-jira:refresh-cache --all
|
|
635
|
+
/specweave-ado:refresh-cache --all
|
|
1571
636
|
|
|
1572
|
-
|
|
637
|
+
# Clean old caches
|
|
638
|
+
/specweave:cleanup-cache --older-than 7d
|
|
1573
639
|
|
|
1574
|
-
|
|
640
|
+
# View cache statistics
|
|
641
|
+
/specweave:cache-stats
|
|
642
|
+
```
|
|
1575
643
|
|
|
1576
|
-
###
|
|
644
|
+
### Cache Security
|
|
1577
645
|
|
|
1578
|
-
|
|
1579
|
-
-
|
|
1580
|
-
|
|
1581
|
-
-
|
|
646
|
+
**Never cached**: API tokens, PATs, passwords (secrets stay in `.env`)
|
|
647
|
+
**Always cached**: Non-sensitive config (domains, project keys, org names)
|
|
648
|
+
**Atomic writes**: Temp file → rename pattern prevents corruption
|
|
649
|
+
**Auto-recovery**: Corrupted cache auto-deleted, fallback to API
|
|
1582
650
|
|
|
1583
|
-
|
|
651
|
+
### Integration
|
|
1584
652
|
|
|
1585
|
-
|
|
653
|
+
**CLI Helpers**:
|
|
654
|
+
- `src/cli/helpers/issue-tracker/jira.ts`: JIRA project caching
|
|
655
|
+
- `src/cli/helpers/issue-tracker/ado.ts`: ADO config caching
|
|
1586
656
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
vim .specweave/docs/internal/architecture/hld-system.md
|
|
657
|
+
**Core Module**:
|
|
658
|
+
- `src/core/cache/cache-manager.ts`: TTL validation, atomic writes, corruption handling
|
|
1590
659
|
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
660
|
+
**Tests**:
|
|
661
|
+
- `tests/integration/cli/helpers/cache-integration.test.ts`: 85%+ coverage
|
|
662
|
+
|
|
663
|
+
**See**: ADR-0051 (Smart Caching with TTL), `src/core/cache/rate-limit-checker.ts`
|
|
1594
664
|
|
|
1595
665
|
---
|
|
1596
666
|
|
|
1597
667
|
## Troubleshooting
|
|
1598
668
|
|
|
1599
|
-
**Skills not activating**: Check YAML frontmatter, restart Claude Code
|
|
1600
|
-
**Commands not working**: Verify plugin installed, restart
|
|
1601
|
-
**Tests failing**:
|
|
1602
|
-
**Root
|
|
1603
|
-
**Hooks failing**:
|
|
669
|
+
- **Skills not activating**: Check YAML frontmatter, restart Claude Code
|
|
670
|
+
- **Commands not working**: Verify plugin installed, restart
|
|
671
|
+
- **Tests failing**: `npm run rebuild`
|
|
672
|
+
- **Root polluted**: Move to `.specweave/increments/####/reports/`
|
|
673
|
+
- **Hooks failing**: Push to GitHub (auto-updates 5-10s)
|
|
1604
674
|
|
|
1605
675
|
---
|
|
1606
676
|
|
|
1607
677
|
## Quick Reference
|
|
1608
678
|
|
|
1609
|
-
**Commands**:
|
|
1610
|
-
- `/specweave:increment "feature"` - Plan
|
|
1611
|
-
- `/specweave:do` - Execute
|
|
1612
|
-
- `/specweave:done 0002` - Close (validates)
|
|
1613
|
-
- `/specweave:status` - Show status
|
|
1614
|
-
- `/specweave:progress` - Check progress
|
|
1615
|
-
- `/specweave:validate 0002` - Validate
|
|
1616
|
-
- `/specweave:qa 0002` - Quality check
|
|
1617
|
-
- `/specweave:pause/resume/abandon` - State management
|
|
1618
|
-
- `/specweave:archive/restore` - Archiving (manual only)
|
|
1619
|
-
- `/specweave:sync-docs update` - Sync living docs
|
|
679
|
+
**Commands**: `/specweave:increment`, `/specweave:do`, `/specweave:done`, `/specweave:progress`, `/specweave:validate`, `/specweave:qa`
|
|
1620
680
|
|
|
1621
|
-
**Build**:
|
|
1622
|
-
- `npm run rebuild` - Clean + build
|
|
1623
|
-
- `npm test` - Smoke tests
|
|
1624
|
-
- `npm run test:all` - All tests
|
|
1625
|
-
- `npm run test:coverage` - Coverage
|
|
681
|
+
**Build**: `npm run rebuild`, `npm test`, `npm run test:all`
|
|
1626
682
|
|
|
1627
|
-
**
|
|
1628
|
-
- Source: `src/` (TypeScript), `plugins/` (skills/agents/commands/hooks)
|
|
1629
|
-
- Increments: `.specweave/increments/`
|
|
1630
|
-
- Docs: `.specweave/docs/internal/`, `.specweave/docs/public/`
|
|
1631
|
-
- Tests: `tests/` (unit, integration, E2E)
|
|
683
|
+
**Structure**: `src/` (TS), `plugins/` (components), `.specweave/` (data), `tests/` (tests)
|
|
1632
684
|
|
|
1633
685
|
**Remember**:
|
|
1634
|
-
1. Push
|
|
1635
|
-
2. Keep root clean
|
|
1636
|
-
3. Test before
|
|
1637
|
-
4.
|
|
1638
|
-
5. Use `/specweave:done` (
|
|
686
|
+
1. Push → GitHub → Claude Code auto-updates (5-10s)
|
|
687
|
+
2. Keep root clean
|
|
688
|
+
3. Test before commit
|
|
689
|
+
4. NEVER delete `.specweave/`
|
|
690
|
+
5. Use `/specweave:done` (not manual edits)
|
|
691
|
+
|
|
692
|
+
**See**: `.github/CONTRIBUTING.md`, https://spec-weave.com
|
|
1639
693
|
|
|
1640
|
-
**See also**: `.github/CONTRIBUTING.md`, https://spec-weave.com
|