specweave 0.23.10 → 0.23.14

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.
Files changed (135) hide show
  1. package/.claude-plugin/marketplace.json +7 -7
  2. package/CLAUDE.md +384 -1449
  3. package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
  4. package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
  5. package/dist/src/cli/commands/cleanup-cache.js +63 -0
  6. package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
  7. package/dist/src/cli/commands/init.js +40 -0
  8. package/dist/src/cli/commands/init.js.map +1 -1
  9. package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
  10. package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
  11. package/dist/src/cli/helpers/async-project-loader.js +351 -0
  12. package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
  13. package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
  14. package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
  15. package/dist/src/cli/helpers/cancelation-handler.js +187 -0
  16. package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
  17. package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
  18. package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
  19. package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
  20. package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
  21. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
  22. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  23. package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
  24. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  25. package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
  26. package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
  27. package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
  28. package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
  29. package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
  30. package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
  31. package/dist/src/cli/helpers/progress-tracker.js +202 -0
  32. package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
  33. package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
  34. package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
  35. package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
  36. package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
  37. package/dist/src/config/types.d.ts +14 -14
  38. package/dist/src/core/cache/cache-manager.d.ts +119 -0
  39. package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
  40. package/dist/src/core/cache/cache-manager.js +304 -0
  41. package/dist/src/core/cache/cache-manager.js.map +1 -0
  42. package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
  43. package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
  44. package/dist/src/core/cache/rate-limit-checker.js +160 -0
  45. package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
  46. package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
  47. package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
  48. package/dist/src/core/progress/cancelation-handler.js +111 -0
  49. package/dist/src/core/progress/cancelation-handler.js.map +1 -0
  50. package/dist/src/core/progress/error-logger.d.ts +58 -0
  51. package/dist/src/core/progress/error-logger.d.ts.map +1 -0
  52. package/dist/src/core/progress/error-logger.js +99 -0
  53. package/dist/src/core/progress/error-logger.js.map +1 -0
  54. package/dist/src/core/progress/import-state.d.ts +71 -0
  55. package/dist/src/core/progress/import-state.d.ts.map +1 -0
  56. package/dist/src/core/progress/import-state.js +96 -0
  57. package/dist/src/core/progress/import-state.js.map +1 -0
  58. package/dist/src/core/progress/progress-tracker.d.ts +139 -0
  59. package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
  60. package/dist/src/core/progress/progress-tracker.js +223 -0
  61. package/dist/src/core/progress/progress-tracker.js.map +1 -0
  62. package/dist/src/init/architecture/types.d.ts +6 -6
  63. package/dist/src/integrations/ado/ado-client.d.ts +25 -0
  64. package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
  65. package/dist/src/integrations/ado/ado-client.js +67 -0
  66. package/dist/src/integrations/ado/ado-client.js.map +1 -1
  67. package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
  68. package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
  69. package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
  70. package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
  71. package/dist/src/integrations/jira/jira-client.d.ts +32 -0
  72. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  73. package/dist/src/integrations/jira/jira-client.js +81 -0
  74. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  75. package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
  76. package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
  77. package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
  78. package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
  79. package/package.json +1 -1
  80. package/plugins/specweave/.claude-plugin/plugin.json +20 -0
  81. package/plugins/specweave/agents/architect/AGENT.md +100 -602
  82. package/plugins/specweave/agents/pm/AGENT.md +96 -597
  83. package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
  84. package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
  85. package/plugins/specweave/commands/check-hooks.md +257 -0
  86. package/plugins/specweave/hooks/docs-changed.sh +9 -1
  87. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  88. package/plugins/specweave/hooks/human-input-required.sh +9 -1
  89. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  90. package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
  91. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  92. package/plugins/specweave/hooks/post-increment-change.sh +6 -1
  93. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  94. package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
  95. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  96. package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
  97. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  98. package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
  99. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  100. package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
  101. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  102. package/plugins/specweave/hooks/post-task-completion.sh +225 -228
  103. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  104. package/plugins/specweave/hooks/post-write-spec.sh +207 -31
  105. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  106. package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
  107. package/plugins/specweave/hooks/pre-implementation.sh +9 -1
  108. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  109. package/plugins/specweave/hooks/pre-task-completion.sh +14 -8
  110. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  111. package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
  112. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  113. package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
  114. package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
  115. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  116. package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
  117. package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
  118. package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
  119. package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
  120. package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
  121. package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
  122. package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
  123. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  124. package/plugins/specweave-ado/hooks/post-task-completion.sh +10 -2
  125. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  126. package/plugins/specweave-github/hooks/post-task-completion.sh +10 -2
  127. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  128. package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
  129. package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
  130. package/plugins/specweave-jira/hooks/post-task-completion.sh +10 -2
  131. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  132. package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
  133. package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
  134. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +252 -6465
  135. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
package/CLAUDE.md CHANGED
@@ -10,1749 +10,684 @@ For **contributors to SpecWeave itself** (not users).
10
10
 
11
11
  ## 🚨 CRITICAL SAFETY RULES
12
12
 
13
- ### 0. Thinking-Before-Acting Discipline (META RULE!)
13
+ ### 0. Think-Then-Act Discipline (META RULE!)
14
14
 
15
- **ALWAYS act on your reasoning BEFORE attempting operations that will fail.**
15
+ **NEVER run commands you know will fail.** Act on reasoning BEFORE execution.
16
16
 
17
- **Anti-pattern**: Running commands you know will fail, then fixing the issue.
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 → Predictable failure → Fix
21
- node -e "require('./dist/file.js')" // Fails (you saw this coming!)
22
- npm run rebuild // Then fix
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: Recognize dependency → Fix → Attempt
25
- npm run rebuild // Fix first
26
- node -e "require('./dist/file.js')" // Then succeed
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
- **SpecWeave uses Claude Code's GitHub marketplace** for plugin management. This is the **cross-platform, simple approach** that works on macOS, Linux, and Windows.
47
-
48
- #### Quick Start (Recommended - All Platforms)
36
+ **Standard Workflow** (Cross-platform):
49
37
 
50
38
  ```bash
51
- # 1. Clone and install
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
- ```
62
-
63
- #### Development Workflow
41
+ cd specweave && npm install && npm run rebuild
64
42
 
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
- # 2. Build TypeScript changes
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"
79
- 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!
86
- ```
87
-
88
- **For hook-only changes** (no TypeScript build needed):
89
- ```bash
90
- vim plugins/specweave/hooks/post-task-completion.sh
91
- git add . && git commit -m "fix: improve hook logic"
45
+ npm run rebuild && npm test
46
+ git add . && git commit -m "feat: feature"
92
47
  git push origin develop
93
- # Wait 5-10 seconds hooks updated!
48
+ # Wait 5-10sClaude Code auto-updates marketplace
94
49
  ```
95
50
 
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)
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`)
101
55
 
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...
113
-
114
- # Clean up when done
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
- **Option 3: Symlink Mode** (Advanced, Unix-Only)
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
- #### NPM Testing Mode (End-User Experience)
60
+ **ONLY 4 files in `.specweave/increments/####/` root**: `spec.md`, `plan.md`, `tasks.md`, `metadata.json`
137
61
 
138
- To test the published npm package as end-users experience it:
62
+ **Everything else subfolders**: `reports/`, `scripts/`, `logs/`
139
63
 
140
64
  ```bash
141
- # 1. Install global npm package
142
- npm install -g specweave
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
- ### 2. NEVER Pollute Increment Folders
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. NEVER Delete .specweave/ Directories
71
+ ### 3. Protected Directories
179
72
 
180
- **Protected**: `.specweave/docs/`, `.specweave/increments/`
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
- **If accidental deletion**:
187
- ```bash
188
- git restore .specweave/
189
- ```
77
+ **Recovery**: `git restore .specweave/`
190
78
 
191
- ### 4. Test Cleanup Safety (MANDATORY)
79
+ ---
192
80
 
193
- **Danger**: `rm -rf` with wrong `pwd` = delete entire test suite.
81
+ ### 4. Test Cleanup Safety
194
82
 
195
- **REQUIRED steps before any `rm -rf`**:
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/directories to delete
199
- 4. Manual confirmation (type "DELETE")
200
- 5. Execute deletion
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
- **Never** use `rm -rf` without ALL safety checks above.
90
+ ---
205
91
 
206
92
  ### 5. NEVER Use `specweave init . --force`
207
93
 
208
- **Danger**: Deletes ALL increments and docs without backup (unless you bypass warnings).
94
+ **Danger**: Deletes ALL increments/docs without backup
209
95
 
210
- **Safe alternative**:
211
- ```bash
212
- specweave init . # Interactive, never deletes without confirmation
213
- ```
96
+ **Use**: `specweave init .` (interactive, safe)
214
97
 
215
- ### 6. Increment Completion Validation
98
+ ---
216
99
 
217
- **NEVER** mark increment "completed" without:
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 before closing)
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
- ### 7. Source of Truth: tasks.md and spec.md (CRITICAL!)
104
+ **Never**: Manual `metadata.json` edit (blocked by pre-commit hook)
227
105
 
228
- **THE MOST CRITICAL RULE**: Internal TODO lists are ONLY for tracking work during execution. The SOURCE OF TRUTH is ALWAYS:
229
- 1. **tasks.md** - Task completion status (`[x]` checkboxes)
230
- 2. **spec.md** - Acceptance criteria status (`[x]` checkboxes)
106
+ ---
231
107
 
232
- **MANDATORY Workflow When Using TodoWrite Tool**:
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
- **Example of CORRECT workflow**:
112
+ **MANDATORY workflow:**
243
113
  ```typescript
244
- // Step 1: Complete the work
114
+ // 1. Complete work
245
115
  await createIntegrationTest();
246
116
 
247
- // Step 2: Update internal TODO
117
+ // 2. Update internal TODO
248
118
  TodoWrite([{task: "T-013", status: "completed"}]);
249
119
 
250
- // Step 3: IMMEDIATELY update tasks.md (NEVER skip this!)
120
+ // 3. IMMEDIATELY update tasks.md (NEVER skip!)
251
121
  Edit("tasks.md", "**Status**: [ ] pending", "**Status**: [x] completed");
252
122
 
253
- // Step 4: IMMEDIATELY update spec.md ACs
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
- **3-Phase Protection**:
384
- 1. **Detection** - Search GitHub for existing issues BEFORE creating
385
- 2. **Verification** - Count-check AFTER creation (handles eventual consistency)
386
- 3. **Reflection** - Auto-close duplicates if detected, keep oldest
387
-
388
- **Search Limits** (CRITICAL!):
389
- ```typescript
390
- // ❌ WRONG: --limit 1 hides duplicates!
391
- gh issue list --search "[FS-047][US-001] in:title" --limit 1
392
- // Returns ONLY 1 result even if 10 duplicates exist!
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`
393
131
 
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
- **Cleanup Existing Duplicates**:
138
+ **Pre-closure validation:**
400
139
  ```bash
401
- # Preview what will be cleaned up:
402
- bash scripts/cleanup-duplicate-github-issues.sh --dry-run
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
- **Why This Matters**:
419
- - Incident 2025-11-20: 10+ duplicate User Story issues created
420
- - Root Cause #1: Race condition (GitHub search eventual consistency lag)
421
- - Root Cause #2: `--limit 1` bug (hid duplicates in search results)
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
- **Protected Files**:
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
- **Rule**: ALL `src/` code MUST use logger abstraction, NEVER `console.log/error/warn`.
152
+ ### 8. Logger Abstraction (NEVER `console.*`)
435
153
 
436
- **Why**: `console.*` pollutes test output even when errors are expected and properly handled.
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
- **In tests, use `silentLogger`**:
167
+ **Exception - CLI Commands**: `src/cli/commands/*.ts` may use `console.*` with comment:
457
168
  ```typescript
458
- import { silentLogger } from '../../src/utils/logger.js';
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
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.
467
171
  ```
468
172
 
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
- }
489
- ```
490
-
491
- **Pre-commit hook allows files with documentation marker**:
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
- **Correct usage**:
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
- if (existsSync(configPath)) {
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 (async operations)
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
- const content = await fs.readFile(configPath, 'utf-8');
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
- ```typescript
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
- **Testing**:
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
- **Full standards**: `.specweave/docs/internal/governance/coding-standards.md`
567
- **Auto-discovery**: Runs during brownfield analysis or `/specweave:analyze-standards`
568
-
569
- **Critical rules (enforced during code generation)**:
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)
570
207
 
571
- 1. ✅ **NEVER use `console.*`** - Use logger abstraction (already enforced above)
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)
208
+ **Auto-discovery**: `/specweave:analyze-standards`
581
209
 
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 Policy (v0.24.0+)
212
+ ### 10. GitHub Issue Format (v0.24.0+)
599
213
 
600
- **CRITICAL**: ALL GitHub issues MUST use User Story-level format.
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
- - ✅ `[FS-043][US-001] Status Line Shows Correct Active Increment`
609
- - `[FS-047][US-002] AC-Task Mapping`
610
-
611
- **Incorrect Formats** (NEVER use):
612
- - `[FS-047]` (Feature-only, missing US-ID)
613
- - `[SP-US-006]` (SP prefix, missing Feature ID)
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
- **Why This Matters**:
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 (FS-047)
641
- GitHub Milestone #13
642
- ├─ User Story (US-001)GitHub Issue #638: [FS-047][US-001] Title
643
- ├─ User Story (US-002)GitHub Issue #639: [FS-047][US-002] Title
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
- **Deprecated Mechanisms**:
648
- - ❌ `post-increment-planning.sh` hook (disabled by default)
649
- - `update-epic-github-issue.sh` script (deprecated)
650
- - ❌ `generate-epic-issue-body.ts` script (deprecated)
235
+ **Create issues**:
236
+ ```bash
237
+ # CORRECT: Creates User Story issues
238
+ /specweave-github:sync FS-048
651
239
 
652
- These created Feature-only issues with format `[FS-XXX]` which is INCORRECT.
240
+ # WRONG: /specweave:increment does NOT create GitHub issues
241
+ ```
653
242
 
654
- **Hooks Disabled**:
655
- - Increment-level GitHub sync in `post-increment-planning.sh` (disabled unless `SPECWEAVE_ENABLE_INCREMENT_GITHUB_SYNC=true`)
656
- - Epic sync in `post-task-completion.sh` (disabled unless `SPECWEAVE_ENABLE_EPIC_SYNC=true`)
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 Also**:
659
- - `.specweave/increments/0047-us-task-linkage/reports/GITHUB-TITLE-FORMAT-FIX-PLAN.md`
660
- - `plugins/specweave-github/lib/user-story-issue-builder.ts:94`
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
- ### 11. Task Format with US-Task Linkage (v0.23.0+)
253
+ ---
663
254
 
664
- **CRITICAL**: ALL tasks MUST include User Story linkage fields for proper traceability.
255
+ ### 11. Task Format with US Linkage (v0.23.0+)
665
256
 
666
- **New Task Format** (increment 0047+):
257
+ **Required fields**:
667
258
  ```markdown
668
259
  ### T-001: Task Title
669
-
670
- **User Story**: US-001 ← MANDATORY: Link to parent User Story
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
- **Validation Rules**:
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
- **Living Docs Auto-Sync**:
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
- **Backward Compatibility**:
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
- **See Also**:
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
- ### 12. ADR Naming Convention (CRITICAL!)
273
+ **Correct format**: `XXXX-decision-title.md` (4-digit, kebab-case, NO `adr-` prefix)
740
274
 
741
- **Architecture Decision Records (ADRs) MUST follow strict naming convention**:
275
+ **Header**: `# ADR-XXXX: Decision Title`
742
276
 
743
- **Correct Format**:
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
- CORRECT:
751
- Filename: 0007-github-first-task-sync.md
752
- Header: # ADR-0007: GitHub-First Task-Level Synchronization
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
- **Why This Matters**:
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
- grep -E '/[0-9]{4}-' | \
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
- ### 13. Archiving Logic Anti-Patterns (CRITICAL!)
292
+ ---
802
293
 
803
- **NEVER use string search or substring matching for structured data matching**
294
+ ### 13. Structured Data Matching
804
295
 
805
- #### Anti-Pattern #1: String Search for Frontmatter Fields
296
+ **NEVER use string search for frontmatter/IDs**:
806
297
 
807
298
  ```typescript
808
- // ❌ WRONG: Matches ANYWHERE in file (false positives!)
809
- const content = await fs.readFile('spec.md', 'utf-8');
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 featureIdMatch = content.match(/^feature_id:\s*["']?([^"'\n]+)["']?$/m);
819
- if (featureIdMatch && featureIdMatch[1].trim() === 'FS-039') {
820
- // Only matches actual frontmatter field
821
- }
822
- ```
823
-
824
- #### Anti-Pattern #2: Substring Matching for IDs
303
+ const match = content.match(/^feature_id:\s*["']?([^"'\n]+)["']?$/m);
304
+ if (match && match[1].trim() === 'FS-039') { /* ... */ }
825
305
 
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
- const isArchived = archivedList.some(item => item === searchId);
310
+ archivedList.some(item => item === searchId)
833
311
  ```
834
312
 
835
- **Why This Matters**:
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
313
+ **Incident**: 2025-11-20 - 11 features incorrectly archived (string search false positives)
872
314
 
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
- ```
903
-
904
- **Adding New Plugins**:
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
- # 4. VALIDATE (this is CRITICAL!)
917
- bash scripts/validate-marketplace-plugins.sh
317
+ ### 14. Marketplace Plugin Completeness
918
318
 
919
- # 5. Update bin/fix-marketplace-errors.sh
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
- # 6. Commit
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
- **Pre-Commit Hook** (TODO - add this):
323
+ **MANDATORY validation**:
929
324
  ```bash
930
- # .git/hooks/pre-commit should run:
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
- **Incident History**:
936
- - **2025-11-20**: Global npm install caused 8 incomplete plugins to fail loading, generating confusing errors for users. Root cause: marketplace.json listed skeleton plugins that weren't ready for distribution.
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
- **Prevention**:
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
- **See Also**:
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
- **The Problem**:
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 tool or slash commands | Task tool with `subagent_type` |
961
- | **Activation** | Automatic (based on keywords) | Explicit (you call them) |
962
- | **Required File** | `SKILL.md` with YAML frontmatter | `AGENT.md` or agent config |
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
- **Correct Invocation Examples**:
350
+ **Agent naming**: `{plugin}:{directory}:{yaml-name}`
966
351
 
967
352
  ```typescript
968
- // ✅ CORRECT: Invoking a skill
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!):
987
-
988
- Claude Code agents follow a strict naming pattern for `subagent_type`:
989
-
990
- **Directory-based agents**: `{plugin-name}:{directory-name}:{name-from-yaml}`
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/
353
+ // ✅ CORRECT: Skill
354
+ Skill({ skill: "increment-quality-judge-v2" }); // or /specweave:qa
1011
355
 
1012
- # Check YAML name field
1013
- head -5 plugins/specweave/agents/qa-lead/AGENT.md
1014
- # Output: name: qa-lead
356
+ // CORRECT: Agent
357
+ Task({ subagent_type: "specweave:qa-lead:qa-lead", prompt: "..." });
1015
358
 
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
- **Common Mistakes**:
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
1024
-
1025
- // ✅ CORRECT: Full pattern with duplication
1026
- Task({ subagent_type: "specweave:qa-lead:qa-lead", ... });
1027
- ```
1028
-
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)
363
+ **Validation**: `bash scripts/validate-plugin-directories.sh --fix`
1035
364
 
1036
- # CORRECT: Agent with AGENT.md
1037
- plugins/specweave/agents/qa-lead/
1038
- └── AGENT.md
365
+ **Incident**: 2025-11-20 - Empty agent directory caused "Agent not found" error
1039
366
 
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
367
  ---
1055
368
 
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
- ```
369
+ ### 16. YAML Frontmatter Validation
1076
370
 
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**:
371
+ **Required format**:
1137
372
  ```yaml
1138
373
  ---
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
374
+ increment: 0001-feature-name # REQUIRED: 4-digit + kebab-case
375
+ title: Feature Title # OPTIONAL
376
+ feature_id: FS-001 # OPTIONAL
1142
377
  ---
1143
378
  ```
1144
379
 
1145
- **Common Mistakes**:
380
+ **Common mistakes**: Unclosed brackets/quotes, invalid objects, missing `increment`, uppercase in ID
1146
381
 
1147
- ```yaml
1148
- # WRONG: Unclosed bracket
1149
- ---
1150
- increment: 0001-test
1151
- data: [unclosed
1152
- ---
1153
-
1154
- # ❌ WRONG: Unclosed quote
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
1191
- ---
1192
- ```
1193
-
1194
- **Prevention Layers**:
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
1206
-
1207
- 3. **Command validation** - `/specweave:validate` checks YAML syntax
1208
- ```bash
1209
- /specweave:validate 0001
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
- # Validate YAML in spec.md (manual check)
1216
- node -e "
1217
- const yaml = require('js-yaml');
1218
- const fs = require('fs');
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 code (compiled to dist/)
1263
- plugins/ # Claude Code components (skills, agents, commands, hooks)
400
+ src/ # TypeScript (compiled to dist/)
401
+ plugins/ # Skills, agents, commands, hooks
1264
402
  ├── specweave/ # Core plugin
1265
- └── specweave-*/ # Optional plugins (GitHub, JIRA, etc.)
1266
- .specweave/ # Framework data (increments, docs, logs)
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 (CRITICAL!)
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
1286
-
1287
- ### Valid Claude Code Hook Events
411
+ ## Plugin Hook Registration
1288
412
 
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
- "type": "command",
1316
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-task-completion.sh",
1317
- "timeout": 10
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
- **Schema Breakdown**:
1327
- | Field | Type | Purpose |
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) |
1334
-
1335
- ### Common Mistakes (v0.22.13 Bug)
1336
-
1337
- ❌ **WRONG** (Invalid hook event):
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
1348
-
1349
- ✅ **CORRECT** (Use PostToolUse with matcher):
1350
- ```json
1351
- {
1352
- "hooks": {
1353
- "PostToolUse": [
1354
- {
1355
- "matcher": "TodoWrite",
1356
- "hooks": [{"type": "command", "command": "..."}]
1357
- }
1358
- ]
1359
- }
1360
- }
1361
- ```
1362
-
1363
- ### Testing Hook Registration
1364
-
1365
- ```bash
1366
- # 1. Update plugin.json with correct schema
1367
- vim plugins/specweave/.claude-plugin/plugin.json
1368
-
1369
- # 2. Commit and push
1370
- git add plugins/specweave/.claude-plugin/plugin.json
1371
- git commit -m "fix: correct hook registration schema"
1372
- git push origin develop
1373
-
1374
- # 3. Wait 5-10 seconds for marketplace auto-update
1375
-
1376
- # 4. Force refresh marketplace (if needed)
1377
- cd ~/.claude/plugins/marketplaces
1378
- rm -rf specweave
1379
- git clone https://github.com/YOUR_USERNAME/specweave.git
1380
-
1381
- # 5. Restart Claude Code
1382
-
1383
- # 6. Verify no plugin loading errors
1384
- # Should NOT see: "hooks: Invalid input" error
1385
- ```
1386
-
1387
- ### Documentation References
1388
-
1389
- - **Claude Code Plugin Hooks**: https://code.claude.com/docs/en/hooks.md
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
433
+ **❌ WRONG**: `"TodoWrite": {...}` (invalid event)
434
+ **✅ CORRECT**: `"PostToolUse"` with `"matcher": "TodoWrite"`
1392
435
 
1393
436
  ---
1394
437
 
1395
- ## Development Workflow
1396
-
1397
- ### Core Commands
1398
-
1399
- ```bash
1400
- # Primary workflow
1401
- /specweave:increment "feature" # Plan new work
1402
- /specweave:do # Execute tasks
1403
- /specweave:progress # Check status
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
- ```
1419
-
1420
- ### Local Development Setup
1421
-
1422
- ```bash
1423
- # 1. Clone and install
1424
- git clone https://github.com/YOUR_USERNAME/specweave.git
1425
- cd specweave
1426
- npm install
438
+ ## 9a. Hook Performance & Safety (CRITICAL - v0.24.3)
1427
439
 
1428
- # 2. Create symlink (CRITICAL!)
1429
- mkdir -p ~/.claude/plugins/marketplaces
1430
- rm -rf ~/.claude/plugins/marketplaces/specweave
1431
- ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
440
+ **Critical incidents**: 2025-11-22 - Multiple Claude Code crashes due to hook overhead
1432
441
 
1433
- # 3. Verify setup
1434
- bash .specweave/increments/0043-spec-md-desync-fix/scripts/verify-dev-setup.sh
442
+ **Root cause**: Process exhaustion from spawning 6+ Node.js processes per task completion
1435
443
 
1436
- # 4. Install git hooks
1437
- bash scripts/install-git-hooks.sh
1438
- ```
444
+ **Emergency fixes implemented (v0.24.3)**:
1439
445
 
1440
- **If "Plugin not found" errors**:
446
+ ### 1. Emergency Kill Switch
1441
447
  ```bash
1442
- echo '{"version": 1, "plugins": {}}' > ~/.claude/plugins/installed_plugins.json
1443
- claude plugin marketplace update specweave
448
+ # INSTANT disable of ALL hooks
449
+ export SPECWEAVE_DISABLE_HOOKS=1
1444
450
  ```
1445
451
 
1446
- ---
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`
1447
456
 
1448
- ## Build & Test
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
1449
461
 
1450
- ### Build
462
+ ### 4. Aggressive Debouncing
463
+ - **Window**: 5 seconds (increased from 1s)
464
+ - **Effect**: Batches rapid operations
465
+ - **Trade-off**: 5s staleness acceptable for UX
1451
466
 
467
+ ### 5. Complete Error Isolation
1452
468
  ```bash
1453
- npm run rebuild # Clean + build (use this during development)
1454
- npm run build # Compile TypeScript + copy hook dependencies
1455
- npm run clean # Remove dist/
469
+ set +e # NEVER use set -e in hooks
470
+ exit 0 # ALWAYS exit 0, never block workflow
1456
471
  ```
1457
472
 
1458
- **Build Architecture**:
1459
- 1. `tsc` compiles `src/**/*.ts` → `dist/src/**/*.js`
1460
- 2. `copy:locales` copies translation files
1461
- 3. `copy:plugins` compiles plugin TypeScript with esbuild
1462
- 4. `copy:hook-deps` **NEW**: Copies hook dependencies to vendor/
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
1463
477
 
1464
- **Hook Dependencies** (NEW in v0.22.15):
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`
478
+ ### Hook Safety Checklist (MANDATORY)
1470
479
 
1471
- **Critical**: Always import with `.js` extensions:
1472
- ```typescript
1473
- // CORRECT
1474
- import { foo } from './bar.js';
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
1475
488
 
1476
- // WRONG
1477
- import { foo } from './bar';
1478
- ```
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
1479
495
 
1480
- **Fix missing extensions**: `node scripts/fix-js-extensions.js`
496
+ ### Performance Targets
1481
497
 
1482
- ### Testing
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) |
1483
503
 
1484
- **Framework**: Vitest (migrated from Jest 2025-11-17)
504
+ ### Emergency Recovery
1485
505
 
506
+ **If Claude Code crashes**:
1486
507
  ```bash
1487
- npm test # Smoke tests
1488
- npm run test:unit # Unit tests
1489
- npm run test:integration # Integration tests
1490
- npm run test:e2e # E2E tests (Playwright)
1491
- npm run test:all # All tests
1492
- npm run test:coverage # Coverage report
1493
- ```
1494
-
1495
- **Test structure**:
1496
- - `tests/unit/` - Pure logic (no I/O)
1497
- - `tests/integration/` - Organized by: `core/`, `external-tools/`, `generators/`, `features/`
1498
- - `tests/e2e/` - Full user scenarios
1499
-
1500
- **Naming**: ALL tests use `.test.ts` (NEVER `.spec.ts`)
1501
-
1502
- ### Writing Tests
1503
-
1504
- ```typescript
1505
- // ✅ CORRECT
1506
- import { describe, it, expect, beforeEach, vi } from 'vitest';
1507
- import fs from 'fs-extra';
1508
-
1509
- vi.mock('fs-extra');
1510
-
1511
- const mockReadFile = vi.mocked(fs.readFile);
508
+ # 1. Immediate kill switch
509
+ export SPECWEAVE_DISABLE_HOOKS=1
1512
510
 
1513
- beforeEach(() => {
1514
- vi.clearAllMocks();
1515
- mockReadFile.mockResolvedValue('content');
1516
- });
1517
- ```
1518
-
1519
- **Critical anti-patterns**:
1520
- ```typescript
1521
- // ❌ NEVER use jest APIs
1522
- jest.fn() // Use: vi.fn()
1523
- jest.mock() // Use: vi.mock()
1524
-
1525
- // ❌ NEVER use project root in tests
1526
- const testRoot = path.join(process.cwd(), '.test-something');
1527
-
1528
- // ✅ ALWAYS use temp directory
1529
- const testRoot = path.join(os.tmpdir(), 'test-' + Date.now());
1530
- ```
511
+ # 2. Reset circuit breaker
512
+ rm -f .specweave/state/.hook-circuit-breaker
1531
513
 
1532
- **Use test utilities**:
1533
- ```typescript
1534
- import { createIsolatedTestDir } from '../test-utils/isolated-test-dir';
514
+ # 3. Clear locks
515
+ rm -rf .specweave/state/.hook-*.lock
1535
516
 
1536
- const { testDir, cleanup } = await createIsolatedTestDir('my-test');
1537
- try {
1538
- // Test code here
1539
- } finally {
1540
- await cleanup(); // ALWAYS cleanup
1541
- }
517
+ # 4. Rebuild
518
+ npm run rebuild
1542
519
  ```
1543
520
 
1544
- ### Build Architecture
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)
1545
525
 
1546
- **Dual compilation**:
1547
- - `tsc`: `src/` → `dist/src/` (source files)
1548
- - `esbuild`: `plugins/**/lib/hooks/*.ts` → in-place `.js` (hooks only)
526
+ ---
1549
527
 
1550
- **Hook imports**:
1551
- ```typescript
1552
- #!/usr/bin/env node
1553
- import { ACStatusManager } from '../../../../dist/src/core/...'; // Use dist/
1554
- ```
528
+ ## Development Workflow
1555
529
 
1556
- **Increment script imports**:
1557
- ```typescript
1558
- #!/usr/bin/env tsx
1559
- import { ACStatusManager } from '../../../../src/core/...'; // Use src/
530
+ **Core commands**:
531
+ ```bash
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
1560
539
  ```
1561
540
 
1562
- **Running increment scripts**:
541
+ **Local setup**:
1563
542
  ```bash
1564
- npx tsx .specweave/increments/####/scripts/script-name.ts
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
1565
548
  ```
1566
549
 
1567
- ### Coverage
1568
-
1569
- - Critical paths: 90%+
1570
- - Overall: 80%+
1571
-
1572
550
  ---
1573
551
 
1574
- ## Common Tasks
1575
-
1576
- ### Adding Components
552
+ ## Build & Test
1577
553
 
1578
- All components go into `plugins/`:
1579
- - Core: `plugins/specweave/{skills|agents|commands|hooks}/`
1580
- - Plugins: `plugins/specweave-{name}/{skills|agents|commands}/`
1581
- - Tests: `tests/integration/` or `tests/unit/`
554
+ **Build**:
555
+ ```bash
556
+ npm run rebuild # Clean + build (development)
557
+ npm run build # Compile TS + copy deps
558
+ ```
1582
559
 
1583
- See `.github/CONTRIBUTING.md` for details.
560
+ **Architecture**: `tsc` `dist/src/`, esbuild → plugin hooks, copy deps → `plugins/*/lib/vendor/`
1584
561
 
1585
- ### Updating Documentation
562
+ **CRITICAL**: Always `.js` extensions (`import { foo } from './bar.js'`)
1586
563
 
564
+ **Test**:
1587
565
  ```bash
1588
- # Internal docs
1589
- vim .specweave/docs/internal/architecture/hld-system.md
1590
-
1591
- # Public docs
1592
- vim .specweave/docs/public/guides/user-guide.md
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)
1593
571
  ```
1594
572
 
1595
- ### Configuration Management
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
1596
578
 
1597
- **CRITICAL**: SpecWeave separates secrets from configuration (v0.24.0+)
1598
-
1599
- **Architecture**:
1600
- - **Secrets** (tokens, passwords) → `.env` (gitignored, NEVER commit)
1601
- - **Configuration** (domains, strategies, settings) → `.specweave/config.json` (committed to git)
579
+ ---
1602
580
 
1603
- **Why this matters**:
1604
- - ✅ Team shares configuration via git
1605
- - ✅ Secrets stay local (12-Factor App pattern)
1606
- - ✅ Onboarding: `cp .env.example .env` (fill in your tokens)
1607
- - ✅ Type-safe configuration with validation
581
+ ## Configuration Management (v0.24.0+)
1608
582
 
1609
- **Using ConfigManager**:
583
+ **Secrets** (.env, gitignored) vs **Config** (.specweave/config.json, committed)
1610
584
 
1611
585
  ```typescript
1612
586
  import { getConfigManager } from '../core/config/index.js';
1613
587
 
1614
- // Read configuration
1615
588
  const configManager = getConfigManager(projectRoot);
1616
589
  const config = await configManager.read();
590
+ await configManager.update({ issueTracker: { provider: 'jira', domain: 'example.atlassian.net' }});
591
+ ```
1617
592
 
1618
- // Get specific value
1619
- const domain = await configManager.get('issueTracker.domain');
1620
-
1621
- // Update configuration
1622
- await configManager.update({
1623
- issueTracker: {
1624
- provider: 'jira',
1625
- domain: 'example.atlassian.net',
1626
- strategy: 'project-per-team'
1627
- }
1628
- });
1629
-
1630
- // Write entire config (validates before writing)
1631
- await configManager.write(newConfig);
593
+ **What goes where**:
1632
594
 
1633
- // Set specific value
1634
- await configManager.set('sync.enabled', true);
1635
- ```
595
+ | Type | Location | Example | Committed? |
596
+ |------|----------|---------|------------|
597
+ | Tokens/Emails | `.env` | `JIRA_API_TOKEN=xyz` | ❌ |
598
+ | Domains/Strategies | `config.json` | `"domain": "example.atlassian.net"` | ✅ |
1636
599
 
1637
- **Init flow separation** (Jira example):
600
+ **Migration**: `node -e "require('./dist/src/cli/commands/migrate-config.js').migrateConfig({ dryRun: true })"`
1638
601
 
1639
- ```typescript
1640
- // Step 1: Save secrets to .env (gitignored)
1641
- const secretEnvVars = getJiraEnvVars(credentials); // ONLY tokens/emails
1642
- saveCredentialsToEnv(projectPath, 'jira', secretEnvVars);
602
+ **See**: ADR-0050, `src/core/config/config-manager.ts`
1643
603
 
1644
- // Step 2: Save config to .specweave/config.json (committed)
1645
- const configManager = getConfigManager(projectPath);
1646
- const jiraConfig = getJiraConfig(credentials); // domain, strategy, projects
1647
- await configManager.update(jiraConfig);
604
+ ---
1648
605
 
1649
- // Step 3: Generate .env.example for team onboarding
1650
- generateEnvExample(projectPath, 'jira');
1651
- ```
606
+ ## Cache Management (v0.24.0+)
1652
607
 
1653
- **What goes where**:
608
+ **Smart Caching with 24-Hour TTL**: Reduces API calls by 90% during init and sync operations.
1654
609
 
1655
- | Data Type | Location | Example | Committed? |
1656
- |-----------|----------|---------|------------|
1657
- | API Tokens | `.env` | `JIRA_API_TOKEN=xyz` | ❌ Never |
1658
- | Emails | `.env` | `JIRA_EMAIL=user@example.com` | ❌ Never |
1659
- | Domains | `config.json` | `"domain": "example.atlassian.net"` | ✅ Yes |
1660
- | Strategies | `config.json` | `"strategy": "project-per-team"` | ✅ Yes |
1661
- | Project Keys | `config.json` | `"projects": [{"key": "PROJ1"}]` | ✅ Yes |
1662
- | Sync Settings | `config.json` | `"includeStatus": true` | ✅ Yes |
610
+ ### Cache Architecture
1663
611
 
1664
- **Validation**:
612
+ **Location**: `.specweave/cache/`
613
+ **TTL**: 24 hours (configurable)
614
+ **Format**: JSON with timestamps
1665
615
 
1666
- ConfigManager validates configuration before writing:
616
+ ### Cached Data
1667
617
 
1668
- ```typescript
1669
- const result = configManager.validate(config);
1670
- if (!result.valid) {
1671
- console.error('Validation errors:', result.errors);
1672
- // Example error:
1673
- // {
1674
- // path: 'issueTracker.provider',
1675
- // message: 'Invalid provider. Must be one of: none, jira, github, ado',
1676
- // value: 'invalid-provider'
1677
- // }
1678
- }
1679
- ```
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 |
1680
624
 
1681
- **Migration Tool** (for existing projects):
625
+ ### Cache Operations
1682
626
 
1683
- If you have an existing project using the old .env-only format, use the migration tool:
627
+ **Automatic caching** (during init):
628
+ - JIRA: `promptJiraCredentials()` caches selected projects
629
+ - ADO: `promptAzureDevOpsCredentials()` caches org/project config
1684
630
 
631
+ **Manual cache management**:
1685
632
  ```bash
1686
- # Preview what will be migrated (dry run)
1687
- node -e "require('./dist/src/cli/commands/migrate-config.js').migrateConfig({ dryRun: true })"
633
+ # Refresh cache (bypass TTL)
634
+ /specweave-jira:refresh-cache --all
635
+ /specweave-ado:refresh-cache --all
1688
636
 
1689
- # Perform migration
1690
- node -e "require('./dist/src/cli/commands/migrate-config.js').migrateConfig()"
637
+ # Clean old caches
638
+ /specweave:cleanup-cache --older-than 7d
1691
639
 
1692
- # Force migration even if not needed
1693
- node -e "require('./dist/src/cli/commands/migrate-config.js').migrateConfig({ force: true })"
640
+ # View cache statistics
641
+ /specweave:cache-stats
1694
642
  ```
1695
643
 
1696
- **What the migration tool does**:
1697
- 1. ✅ Analyzes `.env` file and classifies variables
1698
- 2. ✅ Creates backup: `.env.backup.TIMESTAMP`
1699
- 3. ✅ Updates `.env` (keeps only secrets)
1700
- 4. ✅ Creates/updates `.specweave/config.json` (adds config)
1701
- 5. ✅ Generates `.env.example` for team onboarding
644
+ ### Cache Security
1702
645
 
1703
- **Classification logic**:
1704
- - **Secrets** (stay in .env): Variables containing `token`, `api_token`, `pat`, `secret`, `key`, `password`, `credential`, `auth`, or email addresses
1705
- - **Config** (move to config.json): Everything else (domains, strategies, project keys, etc.)
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
1706
650
 
1707
- **See also**:
1708
- - ADR-0050: Secrets vs Configuration Separation
1709
- - `src/core/config/config-manager.ts` - ConfigManager implementation
1710
- - `src/core/config/config-migrator.ts` - Migration tool implementation
1711
- - `tests/unit/core/config/config-migrator.test.ts` - Usage examples
651
+ ### Integration
652
+
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
656
+
657
+ **Core Module**:
658
+ - `src/core/cache/cache-manager.ts`: TTL validation, atomic writes, corruption handling
659
+
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`
1712
664
 
1713
665
  ---
1714
666
 
1715
667
  ## Troubleshooting
1716
668
 
1717
- **Skills not activating**: Check YAML frontmatter, restart Claude Code
1718
- **Commands not working**: Verify plugin installed, restart Claude Code
1719
- **Tests failing**: Run `npm run rebuild`, check test output
1720
- **Root folder polluted**: Move files to `.specweave/increments/####/reports/`
1721
- **Hooks failing**: Ensure changes are pushed to GitHub (Claude Code auto-updates marketplace every 5-10s). For symlink mode, see `.specweave/docs/internal/advanced/symlink-dev-mode.md`
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)
1722
674
 
1723
675
  ---
1724
676
 
1725
677
  ## Quick Reference
1726
678
 
1727
- **Commands**:
1728
- - `/specweave:increment "feature"` - Plan
1729
- - `/specweave:do` - Execute
1730
- - `/specweave:done 0002` - Close (validates)
1731
- - `/specweave:status` - Show status
1732
- - `/specweave:progress` - Check progress
1733
- - `/specweave:validate 0002` - Validate
1734
- - `/specweave:qa 0002` - Quality check
1735
- - `/specweave:pause/resume/abandon` - State management
1736
- - `/specweave:archive/restore` - Archiving (manual only)
1737
- - `/specweave:sync-docs update` - Sync living docs
679
+ **Commands**: `/specweave:increment`, `/specweave:do`, `/specweave:done`, `/specweave:progress`, `/specweave:validate`, `/specweave:qa`
1738
680
 
1739
- **Build**:
1740
- - `npm run rebuild` - Clean + build
1741
- - `npm test` - Smoke tests
1742
- - `npm run test:all` - All tests
1743
- - `npm run test:coverage` - Coverage
681
+ **Build**: `npm run rebuild`, `npm test`, `npm run test:all`
1744
682
 
1745
- **File Structure**:
1746
- - Source: `src/` (TypeScript), `plugins/` (skills/agents/commands/hooks)
1747
- - Increments: `.specweave/increments/`
1748
- - Docs: `.specweave/docs/internal/`, `.specweave/docs/public/`
1749
- - Tests: `tests/` (unit, integration, E2E)
683
+ **Structure**: `src/` (TS), `plugins/` (components), `.specweave/` (data), `tests/` (tests)
1750
684
 
1751
685
  **Remember**:
1752
- 1. Push changes to GitHub → Claude Code auto-updates marketplace (5-10s)
1753
- 2. Keep root clean (use increment folders)
1754
- 3. Test before committing
1755
- 4. Never delete .specweave/ directories
1756
- 5. Use `/specweave:done` (never manual metadata edits)
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
1757
693
 
1758
- **See also**: `.github/CONTRIBUTING.md`, https://spec-weave.com