safeword 0.2.4 → 0.2.6

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 (235) hide show
  1. package/dist/check-3NGQ4NR5.js +129 -0
  2. package/dist/check-3NGQ4NR5.js.map +1 -0
  3. package/dist/chunk-2XWIUEQK.js +190 -0
  4. package/dist/chunk-2XWIUEQK.js.map +1 -0
  5. package/dist/chunk-GZRQL3SX.js +146 -0
  6. package/dist/chunk-GZRQL3SX.js.map +1 -0
  7. package/dist/chunk-ORQHKDT2.js +10 -0
  8. package/dist/chunk-ORQHKDT2.js.map +1 -0
  9. package/dist/chunk-W66Z3C5H.js +21 -0
  10. package/dist/chunk-W66Z3C5H.js.map +1 -0
  11. package/dist/cli.d.ts +1 -0
  12. package/dist/cli.js +34 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/diff-Y6QTAW4O.js +166 -0
  15. package/dist/diff-Y6QTAW4O.js.map +1 -0
  16. package/dist/index.d.ts +11 -0
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/reset-3ACTIYYE.js +143 -0
  20. package/dist/reset-3ACTIYYE.js.map +1 -0
  21. package/dist/setup-AIL5RL45.js +276 -0
  22. package/dist/setup-AIL5RL45.js.map +1 -0
  23. package/dist/upgrade-6AR3DHUV.js +134 -0
  24. package/dist/upgrade-6AR3DHUV.js.map +1 -0
  25. package/package.json +44 -19
  26. package/{.safeword → templates}/hooks/agents-md-check.sh +0 -0
  27. package/{.safeword → templates}/hooks/post-tool.sh +0 -0
  28. package/{.safeword → templates}/hooks/pre-commit.sh +0 -0
  29. package/.claude/commands/arch-review.md +0 -32
  30. package/.claude/commands/lint.md +0 -6
  31. package/.claude/commands/quality-review.md +0 -13
  32. package/.claude/commands/setup-linting.md +0 -6
  33. package/.claude/hooks/auto-lint.sh +0 -6
  34. package/.claude/hooks/auto-quality-review.sh +0 -170
  35. package/.claude/hooks/check-linting-sync.sh +0 -17
  36. package/.claude/hooks/inject-timestamp.sh +0 -6
  37. package/.claude/hooks/question-protocol.sh +0 -12
  38. package/.claude/hooks/run-linters.sh +0 -8
  39. package/.claude/hooks/run-quality-review.sh +0 -76
  40. package/.claude/hooks/version-check.sh +0 -10
  41. package/.claude/mcp/README.md +0 -96
  42. package/.claude/mcp/arcade.sample.json +0 -9
  43. package/.claude/mcp/context7.sample.json +0 -7
  44. package/.claude/mcp/playwright.sample.json +0 -7
  45. package/.claude/settings.json +0 -62
  46. package/.claude/skills/quality-reviewer/SKILL.md +0 -190
  47. package/.claude/skills/safeword-quality-reviewer/SKILL.md +0 -13
  48. package/.env.arcade.example +0 -4
  49. package/.env.example +0 -11
  50. package/.gitmodules +0 -4
  51. package/.safeword/SAFEWORD.md +0 -33
  52. package/.safeword/eslint/eslint-base.mjs +0 -101
  53. package/.safeword/guides/architecture-guide.md +0 -404
  54. package/.safeword/guides/code-philosophy.md +0 -174
  55. package/.safeword/guides/context-files-guide.md +0 -405
  56. package/.safeword/guides/data-architecture-guide.md +0 -183
  57. package/.safeword/guides/design-doc-guide.md +0 -165
  58. package/.safeword/guides/learning-extraction.md +0 -515
  59. package/.safeword/guides/llm-instruction-design.md +0 -239
  60. package/.safeword/guides/llm-prompting.md +0 -95
  61. package/.safeword/guides/tdd-best-practices.md +0 -570
  62. package/.safeword/guides/test-definitions-guide.md +0 -243
  63. package/.safeword/guides/testing-methodology.md +0 -573
  64. package/.safeword/guides/user-story-guide.md +0 -237
  65. package/.safeword/guides/zombie-process-cleanup.md +0 -214
  66. package/.safeword/planning/002-user-story-quality-evaluation.md +0 -1840
  67. package/.safeword/planning/003-langsmith-eval-setup-prompt.md +0 -363
  68. package/.safeword/planning/004-llm-eval-test-cases.md +0 -3226
  69. package/.safeword/planning/005-architecture-enforcement-system.md +0 -169
  70. package/.safeword/planning/006-reactive-fix-prevention-research.md +0 -135
  71. package/.safeword/planning/011-cli-ux-vision.md +0 -330
  72. package/.safeword/planning/012-project-structure-cleanup.md +0 -154
  73. package/.safeword/planning/README.md +0 -39
  74. package/.safeword/planning/automation-plan-v2.md +0 -1225
  75. package/.safeword/planning/automation-plan-v3.md +0 -1291
  76. package/.safeword/planning/automation-plan.md +0 -3058
  77. package/.safeword/planning/design/005-cli-implementation.md +0 -343
  78. package/.safeword/planning/design/013-cli-self-contained-templates.md +0 -596
  79. package/.safeword/planning/design/013a-eslint-plugin-suite.md +0 -256
  80. package/.safeword/planning/design/013b-implementation-snippets.md +0 -385
  81. package/.safeword/planning/design/013c-config-isolation-strategy.md +0 -242
  82. package/.safeword/planning/design/code-philosophy-improvements.md +0 -60
  83. package/.safeword/planning/mcp-analysis.md +0 -545
  84. package/.safeword/planning/phase2-subagents-vs-skills-analysis.md +0 -451
  85. package/.safeword/planning/settings-improvements.md +0 -970
  86. package/.safeword/planning/test-definitions/005-cli-implementation.md +0 -1301
  87. package/.safeword/planning/test-definitions/cli-self-contained-templates.md +0 -205
  88. package/.safeword/planning/user-stories/001-guides-review-user-stories.md +0 -1381
  89. package/.safeword/planning/user-stories/003-reactive-fix-prevention.md +0 -132
  90. package/.safeword/planning/user-stories/004-technical-constraints.md +0 -86
  91. package/.safeword/planning/user-stories/005-cli-implementation.md +0 -311
  92. package/.safeword/planning/user-stories/cli-self-contained-templates.md +0 -172
  93. package/.safeword/planning/versioned-distribution.md +0 -740
  94. package/.safeword/prompts/arch-review.md +0 -43
  95. package/.safeword/prompts/quality-review.md +0 -11
  96. package/.safeword/scripts/arch-review.sh +0 -235
  97. package/.safeword/scripts/check-linting-sync.sh +0 -58
  98. package/.safeword/scripts/setup-linting.sh +0 -559
  99. package/.safeword/templates/architecture-template.md +0 -136
  100. package/.safeword/templates/ci/architecture-check.yml +0 -79
  101. package/.safeword/templates/design-doc-template.md +0 -127
  102. package/.safeword/templates/test-definitions-feature.md +0 -100
  103. package/.safeword/templates/ticket-template.md +0 -74
  104. package/.safeword/templates/user-stories-template.md +0 -82
  105. package/.safeword/tickets/001-guides-review-user-stories.md +0 -83
  106. package/.safeword/tickets/002-architecture-enforcement.md +0 -211
  107. package/.safeword/tickets/003-reactive-fix-prevention.md +0 -57
  108. package/.safeword/tickets/004-technical-constraints-in-user-stories.md +0 -39
  109. package/.safeword/tickets/005-cli-implementation.md +0 -248
  110. package/.safeword/tickets/006-flesh-out-skills.md +0 -43
  111. package/.safeword/tickets/007-flesh-out-questioning.md +0 -44
  112. package/.safeword/tickets/008-upgrade-questioning.md +0 -58
  113. package/.safeword/tickets/009-naming-conventions.md +0 -41
  114. package/.safeword/tickets/010-safeword-md-cleanup.md +0 -34
  115. package/.safeword/tickets/011-cursor-setup.md +0 -86
  116. package/.safeword/tickets/README.md +0 -73
  117. package/.safeword/version +0 -1
  118. package/AGENTS.md +0 -59
  119. package/CLAUDE.md +0 -12
  120. package/README.md +0 -347
  121. package/docs/001-cli-implementation-plan.md +0 -856
  122. package/docs/elite-dx-implementation-plan.md +0 -1034
  123. package/framework/README.md +0 -131
  124. package/framework/mcp/README.md +0 -96
  125. package/framework/mcp/arcade.sample.json +0 -8
  126. package/framework/mcp/context7.sample.json +0 -6
  127. package/framework/mcp/playwright.sample.json +0 -6
  128. package/framework/scripts/arch-review.sh +0 -235
  129. package/framework/scripts/check-linting-sync.sh +0 -58
  130. package/framework/scripts/load-env.sh +0 -49
  131. package/framework/scripts/setup-claude.sh +0 -223
  132. package/framework/scripts/setup-linting.sh +0 -559
  133. package/framework/scripts/setup-quality.sh +0 -477
  134. package/framework/scripts/setup-safeword.sh +0 -550
  135. package/framework/templates/ci/architecture-check.yml +0 -78
  136. package/learnings/ai-sdk-v5-breaking-changes.md +0 -178
  137. package/learnings/e2e-test-zombie-processes.md +0 -231
  138. package/learnings/milkdown-crepe-editor-property.md +0 -96
  139. package/learnings/prosemirror-fragment-traversal.md +0 -119
  140. package/packages/cli/AGENTS.md +0 -1
  141. package/packages/cli/ARCHITECTURE.md +0 -279
  142. package/packages/cli/package.json +0 -51
  143. package/packages/cli/src/cli.ts +0 -63
  144. package/packages/cli/src/commands/check.ts +0 -166
  145. package/packages/cli/src/commands/diff.ts +0 -209
  146. package/packages/cli/src/commands/reset.ts +0 -190
  147. package/packages/cli/src/commands/setup.ts +0 -325
  148. package/packages/cli/src/commands/upgrade.ts +0 -163
  149. package/packages/cli/src/index.ts +0 -3
  150. package/packages/cli/src/templates/config.ts +0 -58
  151. package/packages/cli/src/templates/content.ts +0 -18
  152. package/packages/cli/src/templates/index.ts +0 -12
  153. package/packages/cli/src/utils/agents-md.ts +0 -66
  154. package/packages/cli/src/utils/fs.ts +0 -179
  155. package/packages/cli/src/utils/git.ts +0 -124
  156. package/packages/cli/src/utils/hooks.ts +0 -29
  157. package/packages/cli/src/utils/output.ts +0 -60
  158. package/packages/cli/src/utils/project-detector.test.ts +0 -185
  159. package/packages/cli/src/utils/project-detector.ts +0 -44
  160. package/packages/cli/src/utils/version.ts +0 -28
  161. package/packages/cli/src/version.ts +0 -6
  162. package/packages/cli/templates/SAFEWORD.md +0 -776
  163. package/packages/cli/templates/doc-templates/architecture-template.md +0 -136
  164. package/packages/cli/templates/doc-templates/design-doc-template.md +0 -134
  165. package/packages/cli/templates/doc-templates/test-definitions-feature.md +0 -131
  166. package/packages/cli/templates/doc-templates/ticket-template.md +0 -82
  167. package/packages/cli/templates/doc-templates/user-stories-template.md +0 -92
  168. package/packages/cli/templates/guides/architecture-guide.md +0 -423
  169. package/packages/cli/templates/guides/code-philosophy.md +0 -195
  170. package/packages/cli/templates/guides/context-files-guide.md +0 -457
  171. package/packages/cli/templates/guides/data-architecture-guide.md +0 -200
  172. package/packages/cli/templates/guides/design-doc-guide.md +0 -171
  173. package/packages/cli/templates/guides/learning-extraction.md +0 -552
  174. package/packages/cli/templates/guides/llm-instruction-design.md +0 -248
  175. package/packages/cli/templates/guides/llm-prompting.md +0 -102
  176. package/packages/cli/templates/guides/tdd-best-practices.md +0 -615
  177. package/packages/cli/templates/guides/test-definitions-guide.md +0 -334
  178. package/packages/cli/templates/guides/testing-methodology.md +0 -618
  179. package/packages/cli/templates/guides/user-story-guide.md +0 -256
  180. package/packages/cli/templates/guides/zombie-process-cleanup.md +0 -219
  181. package/packages/cli/templates/hooks/agents-md-check.sh +0 -27
  182. package/packages/cli/templates/hooks/post-tool.sh +0 -4
  183. package/packages/cli/templates/hooks/pre-commit.sh +0 -10
  184. package/packages/cli/templates/prompts/arch-review.md +0 -43
  185. package/packages/cli/templates/prompts/quality-review.md +0 -10
  186. package/packages/cli/templates/skills/safeword-quality-reviewer/SKILL.md +0 -207
  187. package/packages/cli/tests/commands/check.test.ts +0 -129
  188. package/packages/cli/tests/commands/cli.test.ts +0 -89
  189. package/packages/cli/tests/commands/diff.test.ts +0 -115
  190. package/packages/cli/tests/commands/reset.test.ts +0 -310
  191. package/packages/cli/tests/commands/self-healing.test.ts +0 -170
  192. package/packages/cli/tests/commands/setup-blocking.test.ts +0 -71
  193. package/packages/cli/tests/commands/setup-core.test.ts +0 -135
  194. package/packages/cli/tests/commands/setup-git.test.ts +0 -139
  195. package/packages/cli/tests/commands/setup-hooks.test.ts +0 -334
  196. package/packages/cli/tests/commands/setup-linting.test.ts +0 -189
  197. package/packages/cli/tests/commands/setup-noninteractive.test.ts +0 -80
  198. package/packages/cli/tests/commands/setup-templates.test.ts +0 -181
  199. package/packages/cli/tests/commands/upgrade.test.ts +0 -215
  200. package/packages/cli/tests/helpers.ts +0 -243
  201. package/packages/cli/tests/npm-package.test.ts +0 -83
  202. package/packages/cli/tests/technical-constraints.test.ts +0 -96
  203. package/packages/cli/tsconfig.json +0 -25
  204. package/packages/cli/tsup.config.ts +0 -11
  205. package/packages/cli/vitest.config.ts +0 -23
  206. package/promptfoo.yaml +0 -3270
  207. /package/{framework → templates}/SAFEWORD.md +0 -0
  208. /package/{packages/cli/templates → templates}/commands/arch-review.md +0 -0
  209. /package/{packages/cli/templates → templates}/commands/lint.md +0 -0
  210. /package/{packages/cli/templates → templates}/commands/quality-review.md +0 -0
  211. /package/{framework/templates → templates/doc-templates}/architecture-template.md +0 -0
  212. /package/{framework/templates → templates/doc-templates}/design-doc-template.md +0 -0
  213. /package/{framework/templates → templates/doc-templates}/test-definitions-feature.md +0 -0
  214. /package/{framework/templates → templates/doc-templates}/ticket-template.md +0 -0
  215. /package/{framework/templates → templates/doc-templates}/user-stories-template.md +0 -0
  216. /package/{framework → templates}/guides/architecture-guide.md +0 -0
  217. /package/{framework → templates}/guides/code-philosophy.md +0 -0
  218. /package/{framework → templates}/guides/context-files-guide.md +0 -0
  219. /package/{framework → templates}/guides/data-architecture-guide.md +0 -0
  220. /package/{framework → templates}/guides/design-doc-guide.md +0 -0
  221. /package/{framework → templates}/guides/learning-extraction.md +0 -0
  222. /package/{framework → templates}/guides/llm-instruction-design.md +0 -0
  223. /package/{framework → templates}/guides/llm-prompting.md +0 -0
  224. /package/{framework → templates}/guides/tdd-best-practices.md +0 -0
  225. /package/{framework → templates}/guides/test-definitions-guide.md +0 -0
  226. /package/{framework → templates}/guides/testing-methodology.md +0 -0
  227. /package/{framework → templates}/guides/user-story-guide.md +0 -0
  228. /package/{framework → templates}/guides/zombie-process-cleanup.md +0 -0
  229. /package/{packages/cli/templates → templates}/hooks/inject-timestamp.sh +0 -0
  230. /package/{packages/cli/templates → templates}/lib/common.sh +0 -0
  231. /package/{packages/cli/templates → templates}/lib/jq-fallback.sh +0 -0
  232. /package/{packages/cli/templates → templates}/markdownlint.jsonc +0 -0
  233. /package/{framework → templates}/prompts/arch-review.md +0 -0
  234. /package/{framework → templates}/prompts/quality-review.md +0 -0
  235. /package/{framework/skills/quality-reviewer → templates/skills/safeword-quality-reviewer}/SKILL.md +0 -0
@@ -1,570 +0,0 @@
1
- # TDD Best Practices
2
-
3
- Patterns and examples for user stories and test definitions following TDD best practices.
4
-
5
- **LLM Instruction Design:** These templates create documentation that LLMs read and follow. For comprehensive framework on writing clear, actionable LLM-consumable documentation, see `@.safeword/guides/llm-instruction-design.md`.
6
-
7
- ---
8
-
9
- ## Fillable Template Files (When to Use Each)
10
-
11
- ### Quick Reference
12
-
13
- | Need | Template | Location |
14
- |------|----------|----------|
15
- | Feature/issue user stories | `user-stories-template.md` | `.safeword/planning/user-stories/` |
16
- | Feature test suites | `test-definitions-feature.md` | `.safeword/planning/test-definitions/` |
17
- | Feature implementation design | `design-doc-template.md` | `.safeword/planning/design/` |
18
- | Project-wide architecture | No template | `ARCHITECTURE.md` at root |
19
-
20
- **Decision rule:** If unclear, ask: "Does this affect the whole project or just one feature?" Project-wide → architecture doc. Single feature → design doc.
21
-
22
- ### Template Details
23
-
24
- **User Stories** (`@.safeword/templates/user-stories-template.md`) - **For features/issues**
25
- - Multiple related stories in one file
26
- - Status tracking (✅/❌ per story and AC)
27
- - Test file references and implementation notes
28
- - Completion % and phase tracking
29
- - Use for GitHub issues with multiple user stories
30
- - Guidance: `@.safeword/guides/user-story-guide.md`
31
-
32
- **Test Definitions** (`@.safeword/templates/test-definitions-feature.md`) - **For feature test suites**
33
- - Organized by test suites and individual tests
34
- - Status tracking (✅ Passing / ⏭️ Skipped / ❌ Not Implemented / 🔴 Failing)
35
- - Detailed steps and expected outcomes
36
- - Coverage summary with percentages
37
- - Test execution commands
38
- - Guidance: `@.safeword/guides/test-definitions-guide.md`
39
-
40
- **Design Doc** (`@.safeword/templates/design-doc-template.md`) - **For feature/system implementation**
41
- - Implementation-focused (architecture, components, data model, user flow, component interaction)
42
- - Key technical decisions with rationale (includes "why")
43
- - Full [N] and [N+1] examples (matches user stories/test definitions pattern)
44
- - ~121 lines, optimized for LLM filling and consumption
45
- - No duplication (references user stories, test definitions)
46
- - Guidance: `@.safeword/guides/architecture-guide.md`
47
-
48
- **Architecture Document** (no template) - **For project/package-wide architecture decisions**
49
- - One `ARCHITECTURE.md` per project or package (in monorepos)
50
- - Document principles, data model, component design, decision rationale
51
- - Living document (updated as architecture evolves)
52
- - Include version, status, table of contents
53
- - All architectural decisions in one place (not separate ADRs)
54
- - Guidance: `@.safeword/guides/architecture-guide.md`
55
-
56
- **Example prompts:**
57
- - "Create user stories for issue #N" → Uses user stories template
58
- - "Create test definitions for issue #N" → Uses test definitions template
59
- - "Create a design doc for [feature]" → Uses design doc template (2-3 pages)
60
- - "Update the project architecture doc" → Adds to existing ARCHITECTURE.md
61
-
62
- **TDD Workflow:** See `@.safeword/guides/testing-methodology.md` for comprehensive RED → GREEN → REFACTOR workflow with latest best practices
63
-
64
- ---
65
-
66
- ## User Story Templates
67
-
68
- ### When to Use Each Format
69
-
70
- | Format | Best For | Example Trigger |
71
- |--------|----------|-----------------|
72
- | Standard (As a/I want/So that) | User-facing features, UI flows | "User can do X" |
73
- | Given-When-Then | API behavior, state transitions, edge cases | "When X happens, then Y" |
74
- | Job Story | Problem-solving, user motivation unclear | "User needs to accomplish X" |
75
-
76
- **Decision rule:** Default to Standard. Use Given-When-Then for APIs or complex state. Use Job Story when focusing on the problem, not the solution.
77
-
78
- ### Standard Format (Recommended)
79
-
80
- ```
81
- As a [role/persona]
82
- I want [capability/feature]
83
- So that [business value/benefit]
84
-
85
- Acceptance Criteria:
86
- - [Specific, testable condition 1]
87
- - [Specific, testable condition 2]
88
- - [Specific, testable condition 3]
89
-
90
- Out of Scope:
91
- - [What this story explicitly does NOT include]
92
- ```
93
-
94
- ### Given-When-Then Format (Behavior-Focused)
95
-
96
- ```
97
- Given [initial context/state]
98
- When [action/event occurs]
99
- Then [expected outcome]
100
-
101
- And [additional context/outcome]
102
- But [exception/edge case]
103
- ```
104
-
105
- **Filled example:**
106
- ```
107
- Given I am an authenticated API user
108
- When I POST to /api/campaigns with valid JSON
109
- Then I receive a 201 Created response with campaign ID
110
- And the campaign appears in my GET /api/campaigns list
111
- But invalid JSON returns 400 with descriptive error messages
112
- ```
113
-
114
- ### Job Story Format (Outcome-Focused)
115
-
116
- ```
117
- When [situation/context]
118
- I want to [motivation/job-to-be-done]
119
- So I can [expected outcome]
120
- ```
121
-
122
- **Filled example:**
123
- ```
124
- When I'm debugging a failing test
125
- I want to see the exact LLM prompt and response
126
- So I can identify whether the issue is prompt engineering or code logic
127
- ```
128
-
129
- ---
130
-
131
- ## User Story Best Practices
132
-
133
- ### ✅ GOOD Examples
134
-
135
- **Web App Feature:**
136
- ```
137
- As a user with multiple campaigns
138
- I want to switch between campaigns without reloading the page
139
- So that I can quickly compare game states
140
-
141
- Acceptance Criteria:
142
- - Campaign list shows all saved campaigns with last-played timestamp
143
- - Clicking a campaign loads its state within 200ms
144
- - Current campaign is visually highlighted
145
- - Switching preserves unsaved input in the current campaign
146
-
147
- Out of Scope:
148
- - Campaign merging/deletion (separate story)
149
- - Multi-campaign view (future epic)
150
- ```
151
-
152
- **API Feature:**
153
- ```
154
- Given I am an authenticated API user
155
- When I POST to /api/campaigns with valid JSON
156
- Then I receive a 201 Created response with campaign ID
157
- And the campaign appears in my GET /api/campaigns list
158
- But invalid JSON returns 400 with descriptive error messages
159
- ```
160
-
161
- **CLI Feature:**
162
- ```
163
- When I'm debugging a failing test
164
- I want to see the exact LLM prompt and response
165
- So I can identify whether the issue is prompt engineering or code logic
166
-
167
- Acceptance Criteria:
168
- - `--verbose` flag prints full prompt to stderr
169
- - Response JSON is pretty-printed with syntax highlighting
170
- - Token count and cost are displayed
171
- - Works with all agent types (rules, narrative, character)
172
- ```
173
-
174
- **With Technical Constraints:**
175
- ```
176
- As a user with multiple campaigns
177
- I want to switch between campaigns without reloading the page
178
- So that I can quickly compare game states
179
-
180
- Acceptance Criteria:
181
- - Campaign list shows all saved campaigns with last-played timestamp
182
- - Clicking a campaign loads its state within 200ms
183
- - Current campaign is visually highlighted
184
-
185
- Technical Constraints:
186
- Performance:
187
- - [ ] Campaign switch completes in < 200ms at P95
188
- - [ ] Works with up to 50 campaigns without UI lag
189
-
190
- Compatibility:
191
- - [ ] Chrome 100+, Safari 16+, Firefox 115+
192
-
193
- Data:
194
- - [ ] Campaign data persists across browser sessions
195
- ```
196
-
197
- ### ❌ BAD Examples (Anti-Patterns)
198
-
199
- **Too Vague:**
200
- ```
201
- As a user
202
- I want the app to work better
203
- So that I'm happy
204
- ```
205
- - ❌ No specific role
206
- - ❌ "Work better" is not measurable
207
- - ❌ No acceptance criteria
208
-
209
- **Too Technical (Implementation Details):**
210
- ```
211
- As a developer
212
- I want to refactor the CharacterStore to use Immer
213
- So that state mutations are prevented
214
- ```
215
- - ❌ This is a technical task, not a user story
216
- - ❌ Users don't care about Immer
217
- - ✅ Better as: Spike ticket or refactoring task
218
-
219
- **Missing "So That" (No Value):**
220
- ```
221
- As a GM
222
- I want to roll dice
223
- ```
224
- - ❌ No business value stated
225
- - ❌ Why does the GM need this?
226
-
227
- **Multiple Features in One Story:**
228
- ```
229
- As a player
230
- I want to create characters, manage inventory, and track relationships
231
- So that I can play the game
232
- ```
233
- - ❌ 3+ separate features bundled together
234
- - ❌ Cannot be completed in one sprint
235
- - ✅ Split into 3 stories
236
-
237
- ---
238
-
239
- ## Test Definition Templates
240
-
241
- ### Unit Test Template
242
-
243
- ```typescript
244
- describe('[Unit/Module Name]', () => {
245
- describe('[function/method name]', () => {
246
- it('should [expected behavior] when [condition]', () => {
247
- // Arrange: Set up test data and dependencies
248
- const input = { /* test data */ };
249
- const expected = { /* expected output */ };
250
-
251
- // Act: Execute the function under test
252
- const result = functionUnderTest(input);
253
-
254
- // Assert: Verify the outcome
255
- expect(result).toEqual(expected);
256
- });
257
-
258
- it('should throw [error type] when [invalid condition]', () => {
259
- const invalidInput = { /* bad data */ };
260
-
261
- expect(() => functionUnderTest(invalidInput))
262
- .toThrow('Expected error message');
263
- });
264
-
265
- it('should handle edge case: [specific edge case]', () => {
266
- // Edge cases: empty arrays, null, undefined, boundary values
267
- });
268
- });
269
- });
270
- ```
271
-
272
- ### Integration Test Template
273
-
274
- ```typescript
275
- describe('[Feature Name] Integration', () => {
276
- beforeEach(async () => {
277
- // Setup: Initialize database, mock external APIs
278
- await setupTestDatabase();
279
- });
280
-
281
- afterEach(async () => {
282
- // Teardown: Clean up resources
283
- await cleanupTestDatabase();
284
- });
285
-
286
- it('should [complete user flow] successfully', async () => {
287
- // Arrange: Create test user and prerequisites
288
- const user = await createTestUser();
289
-
290
- // Act: Execute the full workflow
291
- const campaign = await createCampaign(user.id);
292
- const character = await createCharacter(campaign.id);
293
- const result = await performAction(character.id, 'Skirmish');
294
-
295
- // Assert: Verify end-to-end behavior
296
- expect(result.position).toBe('risky');
297
- expect(result.effect).toBe('standard');
298
- expect(campaign.history).toHaveLength(1);
299
- });
300
-
301
- it('should rollback transaction when [failure occurs]', async () => {
302
- // Test error handling and data consistency
303
- });
304
-
305
- // Filled example: rollback on failure
306
- it('should rollback order when payment fails', async () => {
307
- const user = await createTestUser();
308
- const order = await createOrder(user.id, { items: ['sword'] });
309
-
310
- // Simulate payment failure
311
- mockPaymentGateway.mockRejectedValue(new Error('Card declined'));
312
-
313
- await expect(processOrder(order.id)).rejects.toThrow('Card declined');
314
-
315
- // Verify rollback - order cancelled, inventory restored
316
- const updatedOrder = await getOrder(order.id);
317
- expect(updatedOrder.status).toBe('cancelled');
318
- expect(await getInventory('sword')).toBe(1); // Not decremented
319
- });
320
- });
321
- ```
322
-
323
- ### E2E Test Template (Playwright/Cypress)
324
-
325
- ```typescript
326
- test.describe('[User Journey Name]', () => {
327
- test('should [complete full user flow]', async ({ page }) => {
328
- // Arrange: Navigate to starting point
329
- await page.goto('/campaigns');
330
-
331
- // Act: Simulate user interactions
332
- await page.click('button:has-text("New Campaign")');
333
- await page.fill('[name="campaignName"]', 'The Bloodletters');
334
- await page.click('button:has-text("Create")');
335
-
336
- // Assert: Verify UI state matches expectations
337
- await expect(page.locator('h1')).toContainText('The Bloodletters');
338
- await expect(page.locator('.campaign-list')).toContainText('The Bloodletters');
339
-
340
- // Act: Continue the flow
341
- await page.click('button:has-text("Create Character")');
342
-
343
- // Assert: Verify next state
344
- await expect(page).toHaveURL(/\/characters\/create/);
345
- });
346
- });
347
- ```
348
-
349
- ---
350
-
351
- ## Test Best Practices
352
-
353
- ### Test Naming Conventions
354
-
355
- **✅ GOOD - Descriptive and Specific:**
356
- ```typescript
357
- it('should return risky position when outnumbered 3-to-1')
358
- it('should cache LLM responses for 5 minutes to reduce costs')
359
- it('should preserve armor state after reducing harm from L2 to L1')
360
- it('should throw ValidationError when dice pool is negative')
361
- ```
362
-
363
- **❌ BAD - Vague or Implementation-Focused:**
364
- ```typescript
365
- it('works correctly') // What does "correctly" mean?
366
- it('tests the function') // Obvious, not descriptive
367
- it('should call setState') // Implementation detail
368
- it('scenario 1') // No context
369
- ```
370
-
371
- **How to rename:**
372
- 1. Identify the behavior being tested
373
- 2. Identify the condition/input
374
- 3. Use pattern: `'should [behavior] when [condition]'`
375
-
376
- Example: `'works correctly'` → `'should return 200 when user is authenticated'`
377
-
378
- ### Arrange-Act-Assert (AAA) Pattern
379
-
380
- **Always use AAA structure for clarity:**
381
-
382
- ```typescript
383
- it('should calculate critical success on 6', () => {
384
- // Arrange: Setup test data
385
- const diceResults = [6, 6, 4];
386
-
387
- // Act: Execute the logic
388
- const outcome = evaluateDiceRoll(diceResults);
389
-
390
- // Assert: Verify expectations
391
- expect(outcome).toBe('critical');
392
- expect(outcome.highestDie).toBe(6);
393
- });
394
- ```
395
-
396
- ### Test Independence
397
-
398
- **✅ GOOD - Isolated Tests:**
399
- ```typescript
400
- beforeEach(() => {
401
- // Each test gets fresh state
402
- gameState = createFreshGameState();
403
- });
404
-
405
- it('test A', () => { /* uses gameState */ });
406
- it('test B', () => { /* uses separate gameState */ });
407
- ```
408
-
409
- **❌ BAD - Shared State:**
410
- ```typescript
411
- let sharedState = {}; // Tests modify this
412
- it('test A', () => { sharedState.foo = 'bar'; });
413
- it('test B', () => { expect(sharedState.foo).toBe('bar'); }); // Depends on test A!
414
- ```
415
-
416
- ### What to Test
417
-
418
- **✅ Test These:**
419
- - Public API behavior (functions, methods, components)
420
- - User-facing features (can the user do X?)
421
- - Edge cases (empty, null, boundary values)
422
- - Error handling (does it fail gracefully?)
423
- - Integration points (API calls, database queries)
424
-
425
- **❌ Don't Test These:**
426
- - Private implementation details (internal helper functions)
427
- - Third-party library internals (assume React works)
428
- - Generated code (unless it's business logic)
429
- - Trivial getters/setters with no logic
430
-
431
- **Boundary example:**
432
- ```typescript
433
- // ❌ DON'T test this private helper
434
- function _formatDateInternal(date) { /* internal logic */ }
435
-
436
- // ✅ DO test the public function that uses it
437
- export function getFormattedTimestamp(event) {
438
- return _formatDateInternal(event.createdAt);
439
- }
440
- // Test getFormattedTimestamp, not _formatDateInternal
441
- ```
442
-
443
- ### Test Data Builders
444
-
445
- **Use builders for complex test data:**
446
-
447
- ```typescript
448
- // ✅ GOOD - Reusable test data builder
449
- function buildCharacter(overrides = {}) {
450
- return {
451
- id: 'test-char-1',
452
- name: 'Cutter',
453
- playbook: 'Cutter',
454
- stress: 0,
455
- harm: [],
456
- armor: true,
457
- ...overrides // Easy to customize per test
458
- };
459
- }
460
-
461
- it('should increase stress when resisting', () => {
462
- const character = buildCharacter({ stress: 3 });
463
- // Test uses character with stress=3
464
- });
465
- ```
466
-
467
- ---
468
-
469
- ## LLM Testing Patterns
470
-
471
- ### Promptfoo LLM-as-Judge Template
472
-
473
- ```yaml
474
- # Tests for AI outputs (narrative quality, reasoning)
475
- prompts:
476
- - file://prompts/gm-narrative.txt
477
-
478
- providers:
479
- - id: anthropic:messages:claude-sonnet-4
480
- config:
481
- temperature: 1.0
482
-
483
- tests:
484
- - description: "GM should telegraph position/effect before roll"
485
- vars:
486
- action: "I Skirmish with the gang enforcers"
487
- character: { /* character JSON */ }
488
- assert:
489
- - type: llm-rubric
490
- value: |
491
- The GM response must:
492
- - State position (controlled/risky/desperate) explicitly
493
- - State effect (limited/standard/great) explicitly
494
- - Explain WHY these were chosen based on fiction
495
-
496
- Grade as:
497
- EXCELLENT: All three present and clear
498
- ACCEPTABLE: Position and effect stated, reasoning weak
499
- POOR: Missing position or effect
500
-
501
- - type: llm-rubric
502
- value: |
503
- Does the GM show collaborative tone (asking questions, inviting detail)?
504
-
505
- EXCELLENT: Asks open-ended questions, invites player creativity
506
- ACCEPTABLE: Acknowledges player action, minimal collaboration
507
- POOR: Dictates outcomes without player input
508
- ```
509
-
510
- ### Integration Test with Real LLM
511
-
512
- ```typescript
513
- describe('Rules Agent Integration', () => {
514
- it('should infer correct position for desperate situation', async () => {
515
- // Arrange
516
- const scenario = {
517
- action: 'I Skirmish against 5 armed guards while wounded',
518
- character: buildCharacter({ harm: [{ level: 2, description: 'Broken Arm' }] })
519
- };
520
-
521
- // Act: Real LLM call (costs ~$0.01)
522
- const response = await rulesAgent.processAction(scenario);
523
-
524
- // Assert: Structured output (not narrative quality)
525
- expect(response.position).toBe('desperate');
526
- expect(response.effect).toBe('limited');
527
- expect(response.dicePool).toBeLessThan(3); // Harm reduces dice
528
- expect(response.consequences).toContain('severe harm');
529
- });
530
- });
531
- ```
532
-
533
- ---
534
-
535
- ## INVEST Checklist (Apply to Every User Story)
536
-
537
- Before writing a story, verify it passes all six criteria:
538
-
539
- - [ ] **Independent** - Can be completed without depending on other stories
540
- - [ ] **Negotiable** - Details emerge through conversation, not a fixed contract
541
- - [ ] **Valuable** - Delivers clear value to user or business
542
- - [ ] **Estimable** - Team can estimate effort (not too vague, not too detailed)
543
- - [ ] **Small** - Completable in one sprint/iteration (typically 1-5 days)
544
- - [ ] **Testable** - Clear acceptance criteria define when it's done
545
-
546
- **If a story fails any criteria, it's not ready - refine or split it.**
547
-
548
- ---
549
-
550
- ## Quick Reference
551
-
552
- **User Story Red Flags (INVEST Violations):**
553
- - No acceptance criteria → Too vague
554
- - >3 acceptance criteria → Split into multiple stories
555
- - Technical implementation details → Wrong audience
556
- - Missing "So that" → No clear value
557
-
558
- **Test Red Flags:**
559
- - Test name doesn't describe behavior → Rename
560
- - Test depends on another test's state → Isolate
561
- - Test is >50 lines → Break into smaller tests
562
- - Test tests implementation details → Test behavior instead
563
- - Test never fails → Remove (not testing anything)
564
-
565
- **When to Write E2E vs Integration vs Unit:**
566
- - **E2E:** User can complete full workflow (slow, expensive, high confidence)
567
- - **Integration:** Multiple modules work together (moderate speed, good ROI)
568
- - **Unit:** Single function/module logic (fast, cheap, low-level confidence)
569
-
570
- **Ratio guidance:** 70% unit, 20% integration, 10% E2E (adjust based on project)