@complexthings/superpowers-agent 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/docs/SUPERPOWERS.md +108 -0
- package/.agents/prompts/001-copilot-tool-mapping-do/001-copilot-tool-mapping-do.md +116 -0
- package/.agents/prompts/001-copilot-tool-mapping-do/SUMMARY.md +72 -0
- package/.agents/prompts/001-copilot-tool-mapping-do/copilot-tool-mapping-do-output.md +83 -0
- package/.agents/prompts/001-release-management-do/001-release-management-do.md +161 -0
- package/.agents/prompts/001-release-management-do/SUMMARY.md +19 -0
- package/.agents/prompts/001-release-management-do/completed/001-release-management-do.md +161 -0
- package/.agents/prompts/002-pull-command-do/SUMMARY.md +28 -0
- package/.agents/prompts/002-pull-command-do/completed/002-pull-command-do.md +122 -0
- package/.agents/prompts/002-pull-command-do/pull-command-do-output.md +174 -0
- package/.agents/prompts/command_updates_prompt.md +69 -0
- package/.agents/prompts/current_prompt.md +8 -0
- package/.agents/prompts/refactor.prompt.md +57 -0
- package/.agents/skills/.gitkeep +0 -0
- package/.agents/superpowers-agent +355 -0
- package/.agents/superpowers-bootstrap.md +42 -0
- package/.agents/templates/AGENTS.md.template +40 -0
- package/.agents/templates/SUPERPOWERS.md.template +108 -0
- package/.agents/templates/TOOLS.md.template +15 -0
- package/.github/workflows/main.yaml +32 -0
- package/AGENTS.md +60 -0
- package/LICENSE +21 -0
- package/README.md +724 -0
- package/hooks/hooks.json +15 -0
- package/hooks/session-start.sh +27 -0
- package/package.json +51 -0
- package/skills/architecture/ABOUT.md +20 -0
- package/skills/architecture/preserving-productive-tensions/SKILL.md +146 -0
- package/skills/architecture/preserving-productive-tensions/skill.json +9 -0
- package/skills/collaboration/brainstorming/SKILL.md +166 -0
- package/skills/collaboration/brainstorming/skill.json +9 -0
- package/skills/collaboration/brainstorming/spec-document-reviewer-prompt.md +50 -0
- package/skills/collaboration/brainstorming/visual-companion.md +277 -0
- package/skills/collaboration/dispatching-parallel-agents/SKILL.md +174 -0
- package/skills/collaboration/dispatching-parallel-agents/skill.json +9 -0
- package/skills/collaboration/executing-plans/SKILL.md +130 -0
- package/skills/collaboration/executing-plans/skill.json +9 -0
- package/skills/collaboration/finishing-a-development-branch/SKILL.md +261 -0
- package/skills/collaboration/finishing-a-development-branch/skill.json +9 -0
- package/skills/collaboration/leveraging-cli-tools/SKILL.md +132 -0
- package/skills/collaboration/leveraging-cli-tools/skill.json +9 -0
- package/skills/collaboration/receiving-code-review/SKILL.md +233 -0
- package/skills/collaboration/receiving-code-review/skill.json +9 -0
- package/skills/collaboration/requesting-code-review/SKILL.md +110 -0
- package/skills/collaboration/requesting-code-review/code-reviewer.md +146 -0
- package/skills/collaboration/requesting-code-review/skill.json +12 -0
- package/skills/collaboration/subagent-driven-development/SKILL.md +255 -0
- package/skills/collaboration/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/collaboration/subagent-driven-development/implementer-prompt.md +113 -0
- package/skills/collaboration/subagent-driven-development/skill.json +15 -0
- package/skills/collaboration/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/collaboration/using-git-worktrees/SKILL.md +366 -0
- package/skills/collaboration/using-git-worktrees/skill.json +9 -0
- package/skills/collaboration/writing-plans/SKILL.md +121 -0
- package/skills/collaboration/writing-plans/plan-document-reviewer-prompt.md +52 -0
- package/skills/collaboration/writing-plans/skill.json +9 -0
- package/skills/debugging/defense-in-depth/SKILL.md +380 -0
- package/skills/debugging/defense-in-depth/skill.json +9 -0
- package/skills/debugging/root-cause-tracing/SKILL.md +361 -0
- package/skills/debugging/root-cause-tracing/find-polluter.sh +63 -0
- package/skills/debugging/root-cause-tracing/skill.json +12 -0
- package/skills/debugging/systematic-debugging/SKILL.md +299 -0
- package/skills/debugging/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/skills/debugging/systematic-debugging/condition-based-waiting.md +115 -0
- package/skills/debugging/systematic-debugging/defense-in-depth.md +122 -0
- package/skills/debugging/systematic-debugging/find-polluter.sh +63 -0
- package/skills/debugging/systematic-debugging/root-cause-tracing.md +169 -0
- package/skills/debugging/systematic-debugging/skill.json +9 -0
- package/skills/debugging/systematic-debugging/test-academic.md +14 -0
- package/skills/debugging/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/debugging/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/debugging/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/debugging/verification-before-completion/SKILL.md +143 -0
- package/skills/debugging/verification-before-completion/skill.json +9 -0
- package/skills/finding-skills/SKILL.md +101 -0
- package/skills/finding-skills/skill.json +8 -0
- package/skills/meta/create-skill-json/SKILL.md +370 -0
- package/skills/meta/create-skill-json/skill.json +9 -0
- package/skills/meta/create-skill-json/test-scenarios.md +29 -0
- package/skills/meta/creating-prompts/SKILL.md +349 -0
- package/skills/meta/creating-prompts/examples/do-example.md +65 -0
- package/skills/meta/creating-prompts/examples/plan-example.md +75 -0
- package/skills/meta/creating-prompts/examples/refine-example.md +65 -0
- package/skills/meta/creating-prompts/examples/research-example.md +63 -0
- package/skills/meta/creating-prompts/scripts/get-next-number.sh +27 -0
- package/skills/meta/creating-prompts/skill.json +20 -0
- package/skills/meta/creating-prompts/templates/do-template.md +59 -0
- package/skills/meta/creating-prompts/templates/plan-template.md +58 -0
- package/skills/meta/creating-prompts/templates/refine-template.md +54 -0
- package/skills/meta/creating-prompts/templates/research-template.md +56 -0
- package/skills/meta/using-superpowers/SKILL.md +122 -0
- package/skills/meta/using-superpowers/skill.json +5 -0
- package/skills/meta/writing-prompts/SKILL.md +345 -0
- package/skills/meta/writing-prompts/skill.json +9 -0
- package/skills/problem-solving/ABOUT.md +40 -0
- package/skills/problem-solving/collision-zone-thinking/SKILL.md +188 -0
- package/skills/problem-solving/collision-zone-thinking/references/historical-examples.md +393 -0
- package/skills/problem-solving/collision-zone-thinking/skill.json +9 -0
- package/skills/problem-solving/inversion-exercise/SKILL.md +174 -0
- package/skills/problem-solving/inversion-exercise/skill.json +9 -0
- package/skills/problem-solving/meta-pattern-recognition/SKILL.md +116 -0
- package/skills/problem-solving/meta-pattern-recognition/skill.json +9 -0
- package/skills/problem-solving/scale-game/SKILL.md +222 -0
- package/skills/problem-solving/scale-game/skill.json +9 -0
- package/skills/problem-solving/simplification-cascades/SKILL.md +113 -0
- package/skills/problem-solving/simplification-cascades/skill.json +9 -0
- package/skills/problem-solving/when-stuck/SKILL.md +69 -0
- package/skills/problem-solving/when-stuck/skill.json +9 -0
- package/skills/research/ABOUT.md +20 -0
- package/skills/research/tracing-knowledge-lineages/SKILL.md +241 -0
- package/skills/research/tracing-knowledge-lineages/skill.json +9 -0
- package/skills/setup-skills/SKILL.md +47 -0
- package/skills/testing/condition-based-waiting/SKILL.md +359 -0
- package/skills/testing/condition-based-waiting/example.ts +158 -0
- package/skills/testing/condition-based-waiting/skill.json +12 -0
- package/skills/testing/test-driven-development/SKILL.md +434 -0
- package/skills/testing/test-driven-development/skill.json +9 -0
- package/skills/testing/testing-anti-patterns/SKILL.md +298 -0
- package/skills/testing/testing-anti-patterns/skill.json +9 -0
- package/skills/testing/verification-before-completion/SKILL.md +246 -0
- package/skills/testing/verification-before-completion/skill.json +10 -0
- package/skills/using-a-skill/SKILL.md +101 -0
- package/skills/using-a-skill/skill.json +8 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing-anti-patterns
|
|
3
|
+
description: Identifies and corrects dangerous testing anti-patterns including testing mock behavior instead of real behavior, adding test-only methods to production classes, mocking without understanding dependencies, writing brittle implementation-coupled tests, and sharing mutable state across tests. Use when writing or changing tests, adding mocks, designing test fixtures, debugging flaky tests, or tempted to add test-only methods to production code.
|
|
4
|
+
metadata:
|
|
5
|
+
version: 1.2.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Testing Anti-Patterns
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Tests must verify real behavior, not mock behavior. Mocks isolate; they are not the thing being tested.
|
|
13
|
+
|
|
14
|
+
**Core principle:** Test what the code *does*, not how it *does it* or what the mocks *do*.
|
|
15
|
+
|
|
16
|
+
**Following strict TDD prevents most of these anti-patterns.**
|
|
17
|
+
|
|
18
|
+
## The Iron Laws
|
|
19
|
+
|
|
20
|
+
1. NEVER test mock behavior
|
|
21
|
+
2. NEVER add test-only methods to production classes
|
|
22
|
+
3. NEVER mock without understanding dependencies
|
|
23
|
+
4. NEVER couple tests to implementation details — test contracts, not internals
|
|
24
|
+
|
|
25
|
+
## Anti-Pattern 1: Testing Mock Behavior
|
|
26
|
+
|
|
27
|
+
**The violation:**
|
|
28
|
+
```typescript
|
|
29
|
+
// ❌ BAD: Testing that the mock exists, not real behavior
|
|
30
|
+
test('renders sidebar', () => {
|
|
31
|
+
render(<Page />);
|
|
32
|
+
expect(screen.getByTestId('sidebar-mock')).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Why this is wrong:**
|
|
37
|
+
- Verifies the mock is present, not that the component works
|
|
38
|
+
- Passes when mock exists, fails when mock changes — irrelevant to behavior
|
|
39
|
+
- `getByTestId` is an implementation artifact; prefer semantic queries
|
|
40
|
+
|
|
41
|
+
**The fix:**
|
|
42
|
+
```typescript
|
|
43
|
+
// ✅ GOOD: Test real behavior; query by role, not by test ID
|
|
44
|
+
test('renders sidebar', () => {
|
|
45
|
+
render(<Page />); // Don't mock sidebar if avoidable
|
|
46
|
+
expect(screen.getByRole('navigation')).toBeInTheDocument();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// If sidebar must be mocked for isolation:
|
|
50
|
+
// Assert Page's behavior, not the mock's presence
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**When you see an assertion on a `*-mock` testId:** Ask "Am I testing real component behavior or just mock existence?" If the latter, delete the assertion.
|
|
54
|
+
|
|
55
|
+
## Anti-Pattern 2: Test-Only Methods in Production
|
|
56
|
+
|
|
57
|
+
**The violation:**
|
|
58
|
+
```typescript
|
|
59
|
+
// ❌ BAD: destroy() only called from tests
|
|
60
|
+
class Session {
|
|
61
|
+
async destroy() { // Looks like a production API!
|
|
62
|
+
await this._workspaceManager?.destroyWorkspace(this.id);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
afterEach(() => session.destroy());
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Why this is wrong:**
|
|
69
|
+
- Pollutes production API with test concerns
|
|
70
|
+
- Dangerous if called accidentally in production
|
|
71
|
+
- Violates YAGNI and separation of concerns
|
|
72
|
+
|
|
73
|
+
**The fix:**
|
|
74
|
+
```typescript
|
|
75
|
+
// ✅ GOOD: Cleanup lives in test utilities
|
|
76
|
+
// Session has no destroy() in production
|
|
77
|
+
|
|
78
|
+
// In test-utils/session-helpers.ts
|
|
79
|
+
export async function cleanupSession(session: Session) {
|
|
80
|
+
const workspace = session.getWorkspaceInfo();
|
|
81
|
+
if (workspace) {
|
|
82
|
+
await workspaceManager.destroyWorkspace(workspace.id);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
afterEach(() => cleanupSession(session));
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Before adding any method to a production class:** Ask "Is this only used by tests?" If yes, put it in test utilities.
|
|
89
|
+
|
|
90
|
+
## Anti-Pattern 3: Mocking Without Understanding
|
|
91
|
+
|
|
92
|
+
**The violation:**
|
|
93
|
+
```typescript
|
|
94
|
+
// ❌ BAD: Mock kills the side effect this test actually depends on
|
|
95
|
+
test('detects duplicate server', () => {
|
|
96
|
+
vi.mock('ToolCatalog', () => ({
|
|
97
|
+
discoverAndCacheTools: vi.fn().mockResolvedValue(undefined)
|
|
98
|
+
}));
|
|
99
|
+
await addServer(config);
|
|
100
|
+
await addServer(config); // Should throw — but won't, mock prevented config write
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Why this is wrong:**
|
|
105
|
+
- Mocked method had a side effect the test depended on
|
|
106
|
+
- Over-mocking "to be safe" hides the real behavior
|
|
107
|
+
- Test passes for the wrong reason or fails mysteriously
|
|
108
|
+
|
|
109
|
+
**The fix:**
|
|
110
|
+
```typescript
|
|
111
|
+
// ✅ GOOD: Mock at the correct level — the slow/external part only
|
|
112
|
+
test('detects duplicate server', () => {
|
|
113
|
+
vi.mock('MCPServerManager'); // Mock slow startup, not config logic
|
|
114
|
+
await addServer(config); // Config written ✓
|
|
115
|
+
await addServer(config); // Duplicate detected ✓
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Before mocking any method:**
|
|
120
|
+
1. Ask "What side effects does the real method have?"
|
|
121
|
+
2. Ask "Does this test depend on any of those side effects?"
|
|
122
|
+
3. Run the test with the real implementation first; observe what it needs
|
|
123
|
+
4. THEN add minimal mocking at the lowest appropriate level
|
|
124
|
+
|
|
125
|
+
**Red flags:** "I'll mock this to be safe" · "This might be slow, better mock it" · Mocking a high-level method without reading its source
|
|
126
|
+
|
|
127
|
+
## Anti-Pattern 4: Incomplete Mocks
|
|
128
|
+
|
|
129
|
+
**The violation:**
|
|
130
|
+
```typescript
|
|
131
|
+
// ❌ BAD: Only mock the fields you think you need
|
|
132
|
+
const mockResponse = {
|
|
133
|
+
status: 'success',
|
|
134
|
+
data: { userId: '123', name: 'Alice' }
|
|
135
|
+
// Missing: metadata.requestId that downstream code reads
|
|
136
|
+
};
|
|
137
|
+
// Breaks silently when code accesses response.metadata.requestId
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Why this is wrong:**
|
|
141
|
+
- Partial mocks hide structural assumptions
|
|
142
|
+
- Silent failures when downstream code accesses unmocked fields
|
|
143
|
+
- Tests pass in isolation; integration fails against the real API
|
|
144
|
+
|
|
145
|
+
**The fix:**
|
|
146
|
+
```typescript
|
|
147
|
+
// ✅ GOOD: Mirror the complete real API structure
|
|
148
|
+
const mockResponse = {
|
|
149
|
+
status: 'success',
|
|
150
|
+
data: { userId: '123', name: 'Alice' },
|
|
151
|
+
metadata: { requestId: 'req-789', timestamp: 1234567890 }
|
|
152
|
+
// All fields the real API returns
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Before creating a mock response:** Examine the actual API docs or real response. Include ALL fields downstream code might access. If uncertain, include all documented fields.
|
|
157
|
+
|
|
158
|
+
## Anti-Pattern 5: Brittle Implementation-Coupled Tests
|
|
159
|
+
|
|
160
|
+
**The violation:**
|
|
161
|
+
```typescript
|
|
162
|
+
// ❌ BAD: Tests internal method call order, not the outcome
|
|
163
|
+
test('calculates total', () => {
|
|
164
|
+
const spy = vi.spyOn(calculator, '_applyDiscount');
|
|
165
|
+
calculator.total(items);
|
|
166
|
+
expect(spy).toHaveBeenCalledWith(items, 0.1); // Tests HOW, not WHAT
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Why this is wrong:**
|
|
171
|
+
- Tests lock in implementation details, not behavioral contracts
|
|
172
|
+
- A valid refactor (same output, different internals) breaks the test
|
|
173
|
+
- *"Coupling to the implementation also interferes with refactoring"* — Fowler
|
|
174
|
+
- Discourages clean code evolution
|
|
175
|
+
|
|
176
|
+
**The fix:**
|
|
177
|
+
```typescript
|
|
178
|
+
// ✅ GOOD: Test the observable outcome/state
|
|
179
|
+
test('applies 10% discount to qualifying items', () => {
|
|
180
|
+
const result = calculator.total(qualifyingItems);
|
|
181
|
+
expect(result).toBe(expectedDiscountedTotal);
|
|
182
|
+
// Don't care HOW the discount was applied
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Rule of thumb:** A test should survive any refactor that preserves the public contract. If renaming a private method breaks a test, the test is wrong.
|
|
187
|
+
|
|
188
|
+
## Anti-Pattern 6: Shared Mutable State Between Tests
|
|
189
|
+
|
|
190
|
+
**The violation:**
|
|
191
|
+
```typescript
|
|
192
|
+
// ❌ BAD: State leaks between tests; order-dependent results
|
|
193
|
+
let store: AppStore;
|
|
194
|
+
beforeAll(() => {
|
|
195
|
+
store = createStore(); // Shared across all tests
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('adds item', () => {
|
|
199
|
+
store.add({ id: 1 });
|
|
200
|
+
expect(store.count()).toBe(1);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('removes item', () => {
|
|
204
|
+
store.remove(1); // Assumes 'adds item' ran first — flaky!
|
|
205
|
+
expect(store.count()).toBe(0);
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Why this is wrong:**
|
|
210
|
+
- Tests become order-dependent — pass in one order, fail in another
|
|
211
|
+
- Debugging requires running the full suite to reproduce
|
|
212
|
+
- Violates test isolation; each test should be a self-contained unit
|
|
213
|
+
|
|
214
|
+
**The fix:**
|
|
215
|
+
```typescript
|
|
216
|
+
// ✅ GOOD: Fresh state for each test
|
|
217
|
+
let store: AppStore;
|
|
218
|
+
beforeEach(() => {
|
|
219
|
+
store = createStore(); // Reset before each test
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('adds item', () => {
|
|
223
|
+
store.add({ id: 1 });
|
|
224
|
+
expect(store.count()).toBe(1);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('removes item', () => {
|
|
228
|
+
store.add({ id: 1 }); // Set up own preconditions
|
|
229
|
+
store.remove(1);
|
|
230
|
+
expect(store.count()).toBe(0);
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Red flags:** `beforeAll` modifying state that tests mutate · Tests that only pass when run in a specific order · Cleanup logic in `afterAll` that tests depend on
|
|
235
|
+
|
|
236
|
+
## Anti-Pattern 7: Tests as Afterthought
|
|
237
|
+
|
|
238
|
+
**The violation:**
|
|
239
|
+
```
|
|
240
|
+
✅ Implementation complete
|
|
241
|
+
❌ No tests written
|
|
242
|
+
"Ready for testing"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Testing is part of implementation, not optional follow-up. Claiming "complete" without tests is incomplete.
|
|
246
|
+
|
|
247
|
+
**The fix:** TDD cycle — write failing test → implement to pass → refactor → then claim complete.
|
|
248
|
+
|
|
249
|
+
## When Mocks Become Too Complex
|
|
250
|
+
|
|
251
|
+
**Warning signs:**
|
|
252
|
+
- Mock setup is longer than test logic
|
|
253
|
+
- Mocking everything just to make the test compile
|
|
254
|
+
- Mocks missing methods that real components have
|
|
255
|
+
- Test breaks when mock internals change, not when behavior changes
|
|
256
|
+
|
|
257
|
+
**Consider:** Integration tests with real components are often simpler than maintaining complex mocks.
|
|
258
|
+
|
|
259
|
+
## TDD Prevents These Anti-Patterns
|
|
260
|
+
|
|
261
|
+
1. **Write test first** → Forces clarity on what you're actually testing
|
|
262
|
+
2. **Watch it fail** → Confirms the test verifies real behavior, not mock presence
|
|
263
|
+
3. **Minimal implementation** → No test-only methods added speculatively
|
|
264
|
+
4. **Real dependencies visible** → You see what the test needs before mocking anything
|
|
265
|
+
|
|
266
|
+
**If you're testing mock behavior, you violated TDD** — mocks were added without watching the test fail against real code first.
|
|
267
|
+
|
|
268
|
+
## Quick Reference
|
|
269
|
+
|
|
270
|
+
| Anti-Pattern | Harm | Fix |
|
|
271
|
+
|---|---|---|
|
|
272
|
+
| Assert on mock elements | Tests mock, not behavior | Test real component or unmock it |
|
|
273
|
+
| Test-only methods in production | Pollutes production API | Move to test utilities |
|
|
274
|
+
| Mock without understanding | Hides bugs, wrong behavior | Understand first, mock minimally |
|
|
275
|
+
| Incomplete mocks | Silent failures downstream | Mirror full real API structure |
|
|
276
|
+
| Implementation-coupled tests | Break on valid refactors | Test contracts, not internals |
|
|
277
|
+
| Shared mutable state | Flaky, order-dependent | Fresh state per test (`beforeEach`) |
|
|
278
|
+
| Tests as afterthought | False completeness | TDD — tests first |
|
|
279
|
+
|
|
280
|
+
## Red Flags Checklist
|
|
281
|
+
|
|
282
|
+
- [ ] Assertion checks for `*-mock` testIds
|
|
283
|
+
- [ ] Methods only called in test files exist on production classes
|
|
284
|
+
- [ ] Mock setup is >50% of the test
|
|
285
|
+
- [ ] Test fails when you remove the mock (but not the real behavior)
|
|
286
|
+
- [ ] Can't explain why a mock is needed
|
|
287
|
+
- [ ] Mocking "just to be safe"
|
|
288
|
+
- [ ] Test breaks when implementation changes but output is the same
|
|
289
|
+
- [ ] Tests only pass when run in a specific order
|
|
290
|
+
- [ ] `beforeAll` modifies state that individual tests mutate
|
|
291
|
+
|
|
292
|
+
## The Bottom Line
|
|
293
|
+
|
|
294
|
+
**Mocks isolate; they are not the thing being tested.**
|
|
295
|
+
|
|
296
|
+
Test the *contract* (observable outputs and state), not the *mechanism* (how it's implemented internally).
|
|
297
|
+
|
|
298
|
+
If TDD reveals you're testing mock behavior or internal details, you've gone wrong. Fix: test real behavior or question whether you need the mock at all.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verification-before-completion
|
|
3
|
+
description: Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
|
|
4
|
+
metadata:
|
|
5
|
+
version: 2.0.0
|
|
6
|
+
when_to_use: before any completion claim, commit, PR, or task handoff
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Verification Before Completion
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Claiming work is complete without running verification is not efficiency — it is dishonesty.
|
|
14
|
+
|
|
15
|
+
**Core principle:** Evidence before claims, always.
|
|
16
|
+
|
|
17
|
+
The rule applies to the spirit, not just the letter. Any phrasing that implies success without verification evidence violates it.
|
|
18
|
+
|
|
19
|
+
## The Iron Law
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If you haven't run the verification command in this message, you cannot claim it passes.
|
|
26
|
+
|
|
27
|
+
## The Gate Function
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
flowchart LR
|
|
31
|
+
CLAIM[About to claim success?] --> ID[1. Identify: what command proves this?]
|
|
32
|
+
ID --> RUN[2. Run: execute the FULL command, fresh]
|
|
33
|
+
RUN --> READ[3. Read: full output, check exit code]
|
|
34
|
+
READ --> MATCH{4. Output confirms claim?}
|
|
35
|
+
MATCH -->|No| STATE[State actual status with evidence]
|
|
36
|
+
MATCH -->|Yes| MAKE[5. Make claim WITH evidence]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Step-by-step:**
|
|
40
|
+
|
|
41
|
+
1. **IDENTIFY**: What exact command proves this claim? (see table below)
|
|
42
|
+
2. **RUN**: Execute the full command fresh — not a cached result, not a partial run
|
|
43
|
+
3. **READ**: Read the complete output and check the exit code
|
|
44
|
+
4. **VERIFY**: Does the output confirm the claim?
|
|
45
|
+
- If NO → State actual status with evidence
|
|
46
|
+
- If YES → State claim WITH that evidence
|
|
47
|
+
5. **ONLY THEN**: Make the claim
|
|
48
|
+
|
|
49
|
+
Skip any step = asserting without evidence.
|
|
50
|
+
|
|
51
|
+
## What to Run for Each Claim
|
|
52
|
+
|
|
53
|
+
| Claim | Required command output | Not sufficient |
|
|
54
|
+
|-------|------------------------|----------------|
|
|
55
|
+
| Tests pass | Test runner: 0 failures | Previous run, "should pass" |
|
|
56
|
+
| Linter clean | Linter: 0 errors/warnings | Partial check, extrapolation |
|
|
57
|
+
| Build succeeds | Build command: exit 0 | Linter passing, logs "look OK" |
|
|
58
|
+
| Bug fixed | Original symptom: test passes | Code changed, assumed fixed |
|
|
59
|
+
| Regression test works | Full red→green cycle verified | Test passes once |
|
|
60
|
+
| Agent task completed | VCS diff shows expected changes | Agent reports "success" |
|
|
61
|
+
| Requirements met | Line-by-line checklist verified | Tests passing |
|
|
62
|
+
| Types valid | Type checker: 0 errors | Code compiles |
|
|
63
|
+
| No regressions | Full test suite: 0 new failures | Feature tests pass |
|
|
64
|
+
|
|
65
|
+
## Finding the Right Verification Command
|
|
66
|
+
|
|
67
|
+
Not sure what command to run? Start here:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Common test runners
|
|
71
|
+
npm test # Node.js (Jest, Vitest, Mocha)
|
|
72
|
+
python -m pytest # Python
|
|
73
|
+
cargo test # Rust
|
|
74
|
+
go test ./... # Go
|
|
75
|
+
bundle exec rspec # Ruby
|
|
76
|
+
|
|
77
|
+
# Common linters/type checkers
|
|
78
|
+
npm run lint # JS/TS (ESLint)
|
|
79
|
+
npx tsc --noEmit # TypeScript types
|
|
80
|
+
mypy . # Python types
|
|
81
|
+
cargo clippy # Rust
|
|
82
|
+
golangci-lint run # Go
|
|
83
|
+
|
|
84
|
+
# Common build commands
|
|
85
|
+
npm run build # JS/TS
|
|
86
|
+
cargo build # Rust
|
|
87
|
+
go build ./... # Go
|
|
88
|
+
|
|
89
|
+
# Check package.json/Makefile for project-specific commands
|
|
90
|
+
grep -A20 '"scripts"' package.json
|
|
91
|
+
grep "^[a-z]" Makefile
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
When uncertain, check the project README, `Makefile`, or `package.json` `scripts` section.
|
|
95
|
+
|
|
96
|
+
## Before a Commit or PR
|
|
97
|
+
|
|
98
|
+
Run all of these, in order, before committing or opening a PR:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
1. [ ] Tests pass (full suite, not just changed files)
|
|
102
|
+
2. [ ] No lint errors
|
|
103
|
+
3. [ ] No type errors
|
|
104
|
+
4. [ ] Build succeeds
|
|
105
|
+
5. [ ] Original bug/requirement is demonstrably addressed
|
|
106
|
+
6. [ ] No unintended side effects in related tests
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Every box must be checked with actual command output, not assumption.
|
|
110
|
+
|
|
111
|
+
## Key Patterns
|
|
112
|
+
|
|
113
|
+
**Tests:**
|
|
114
|
+
|
|
115
|
+
<Good>
|
|
116
|
+
```bash
|
|
117
|
+
$ npm test
|
|
118
|
+
PASS: 34 tests, 0 failures
|
|
119
|
+
|
|
120
|
+
# Now you can say: "All 34 tests pass"
|
|
121
|
+
```
|
|
122
|
+
</Good>
|
|
123
|
+
|
|
124
|
+
<Bad>
|
|
125
|
+
```
|
|
126
|
+
"Should pass now" / "Looks correct" / "I'm confident it works"
|
|
127
|
+
```
|
|
128
|
+
</Bad>
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
**TDD Regression Test (Red-Green Verification):**
|
|
133
|
+
|
|
134
|
+
<Good>
|
|
135
|
+
```bash
|
|
136
|
+
# 1. Write test, confirm it passes with fix in place
|
|
137
|
+
$ npm test feature.test.ts
|
|
138
|
+
PASS
|
|
139
|
+
|
|
140
|
+
# 2. Temporarily revert the fix
|
|
141
|
+
# 3. Confirm test now FAILS (proves test catches the bug)
|
|
142
|
+
$ npm test feature.test.ts
|
|
143
|
+
FAIL: expected X, got Y
|
|
144
|
+
|
|
145
|
+
# 4. Restore fix, confirm passes again
|
|
146
|
+
$ npm test feature.test.ts
|
|
147
|
+
PASS
|
|
148
|
+
```
|
|
149
|
+
</Good>
|
|
150
|
+
|
|
151
|
+
<Bad>
|
|
152
|
+
```
|
|
153
|
+
"I've written a regression test" (without verifying the red state)
|
|
154
|
+
```
|
|
155
|
+
</Bad>
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
**Requirements checklist:**
|
|
160
|
+
|
|
161
|
+
<Good>
|
|
162
|
+
```
|
|
163
|
+
1. Re-read the plan/requirements document
|
|
164
|
+
2. For each requirement item:
|
|
165
|
+
- Write down how you'll verify it
|
|
166
|
+
- Run that verification
|
|
167
|
+
- Check it off, or flag it as a gap
|
|
168
|
+
3. Report: "X of Y requirements verified, Z gaps found"
|
|
169
|
+
```
|
|
170
|
+
</Good>
|
|
171
|
+
|
|
172
|
+
<Bad>
|
|
173
|
+
```
|
|
174
|
+
"Tests pass, so the phase is complete"
|
|
175
|
+
```
|
|
176
|
+
</Bad>
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
**Agent delegation:**
|
|
181
|
+
|
|
182
|
+
<Good>
|
|
183
|
+
```bash
|
|
184
|
+
# Agent reports "done"
|
|
185
|
+
$ git diff HEAD~1 # What actually changed?
|
|
186
|
+
$ npm test # Does it still pass?
|
|
187
|
+
```
|
|
188
|
+
</Good>
|
|
189
|
+
|
|
190
|
+
<Bad>
|
|
191
|
+
```
|
|
192
|
+
Trust the agent's success report without independent verification
|
|
193
|
+
```
|
|
194
|
+
</Bad>
|
|
195
|
+
|
|
196
|
+
## When Verification Is Slow
|
|
197
|
+
|
|
198
|
+
If the full test suite takes a long time:
|
|
199
|
+
|
|
200
|
+
1. **Run the specific test file first** — fast feedback loop, catches most issues
|
|
201
|
+
2. **Run the full suite before commit** — required, not optional
|
|
202
|
+
3. **Never skip the full suite before a PR** — no exceptions
|
|
203
|
+
|
|
204
|
+
Partial verification is acceptable for iteration. It is never acceptable as the final gate before claiming completion.
|
|
205
|
+
|
|
206
|
+
## Red Flags — Stop
|
|
207
|
+
|
|
208
|
+
Encountering any of these means you haven't verified yet:
|
|
209
|
+
|
|
210
|
+
- Using "should", "probably", "seems to", "looks like"
|
|
211
|
+
- Expressing satisfaction before verification ("Great!", "Perfect!", "Done!")
|
|
212
|
+
- About to commit/push/PR without having run all checks
|
|
213
|
+
- Trusting agent success reports without independent verification
|
|
214
|
+
- Using a previous run's output as proof
|
|
215
|
+
- **ANY wording that implies success without evidence from this session**
|
|
216
|
+
|
|
217
|
+
## Rationalization Prevention
|
|
218
|
+
|
|
219
|
+
| Excuse | Reality |
|
|
220
|
+
|--------|---------|
|
|
221
|
+
| "Should work now" | Run the verification |
|
|
222
|
+
| "I'm confident" | Confidence ≠ evidence |
|
|
223
|
+
| "Just this once" | No exceptions |
|
|
224
|
+
| "Linter passed" | Linter ≠ compiler ≠ tests |
|
|
225
|
+
| "Agent said success" | Verify independently |
|
|
226
|
+
| "Partial check is enough" | Partial proves nothing for final gate |
|
|
227
|
+
| "Different words, rule doesn't apply" | Spirit over letter |
|
|
228
|
+
| "I already checked mentally" | Mental simulation ≠ execution |
|
|
229
|
+
| "The CI will catch it" | Your job is to catch it before CI |
|
|
230
|
+
|
|
231
|
+
## Why This Matters
|
|
232
|
+
|
|
233
|
+
Every shortcut here has a known failure mode:
|
|
234
|
+
|
|
235
|
+
- Undefined functions ship → crashes in production
|
|
236
|
+
- Missing requirements ship → incomplete features reach users
|
|
237
|
+
- False completion claims break trust between collaborators
|
|
238
|
+
- Time wasted on redirects and rework after false "done" reports
|
|
239
|
+
|
|
240
|
+
The verification step costs seconds. The rework from skipping it costs hours.
|
|
241
|
+
|
|
242
|
+
## The Bottom Line
|
|
243
|
+
|
|
244
|
+
Run the command. Read the output. THEN claim the result.
|
|
245
|
+
|
|
246
|
+
This is non-negotiable.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-a-skill
|
|
3
|
+
description: Use when you need to load and apply a specific skill from system, personal, or project locations - automatically handles priority resolution
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Using a Skill
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Load and apply a specific skill by name. The system automatically finds the skill across all locations and applies the highest-priority version.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
Use this skill when you:
|
|
15
|
+
- Need to apply a specific skill to your current task
|
|
16
|
+
- Want to reference a skill's detailed guidance
|
|
17
|
+
- Need to load supporting files or examples from a skill
|
|
18
|
+
- Are following another skill that references a sub-skill
|
|
19
|
+
|
|
20
|
+
## How to Use
|
|
21
|
+
|
|
22
|
+
**Basic usage:**
|
|
23
|
+
```bash
|
|
24
|
+
superpowers-agent use-skill <skill-name>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Examples:**
|
|
28
|
+
```bash
|
|
29
|
+
# Load a system skill
|
|
30
|
+
superpowers-agent use-skill superpowers:brainstorming
|
|
31
|
+
|
|
32
|
+
# Load a Claude skill
|
|
33
|
+
superpowers-agent use-skill claude:persistent-planning
|
|
34
|
+
|
|
35
|
+
# Load a project or personal skill (no prefix)
|
|
36
|
+
superpowers-agent use-skill my-custom-skill
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Skill Naming and Prefixes
|
|
40
|
+
|
|
41
|
+
**Prefixes indicate source:**
|
|
42
|
+
- `superpowers:skill-name` - System skill from `~/.agents/superpowers/skills/`
|
|
43
|
+
- `claude:skill-name` - Claude skill from `.claude/skills/`
|
|
44
|
+
- `skill-name` (no prefix) - Project or personal skill
|
|
45
|
+
|
|
46
|
+
**Priority resolution (when no prefix specified):**
|
|
47
|
+
1. Project skills (`.agents/skills/`) - highest priority
|
|
48
|
+
2. Claude skills (`.claude/skills/`)
|
|
49
|
+
3. Personal skills (`~/.agents/skills/`)
|
|
50
|
+
4. System skills (`~/.agents/superpowers/skills/`) - lowest priority
|
|
51
|
+
|
|
52
|
+
## What You Get
|
|
53
|
+
|
|
54
|
+
When you load a skill, you receive:
|
|
55
|
+
- The skill's main content (SKILL.md)
|
|
56
|
+
- Reference to supporting files directory
|
|
57
|
+
- Frontmatter metadata (name, description, when to use)
|
|
58
|
+
|
|
59
|
+
## Skill References
|
|
60
|
+
|
|
61
|
+
Skills often reference other skills using patterns like:
|
|
62
|
+
- `**REQUIRED SUB-SKILL:** Use superpowers:skill-name`
|
|
63
|
+
- `**REQUIRED BACKGROUND:** You MUST understand superpowers:skill-name`
|
|
64
|
+
|
|
65
|
+
When you see these, load the referenced skill before proceeding.
|
|
66
|
+
|
|
67
|
+
## Quick Reference
|
|
68
|
+
|
|
69
|
+
| Command | Purpose |
|
|
70
|
+
|---------|---------|
|
|
71
|
+
| `use-skill superpowers:<name>` | Load system skill |
|
|
72
|
+
| `use-skill claude:<name>` | Load Claude skill |
|
|
73
|
+
| `use-skill <name>` | Load with auto-priority |
|
|
74
|
+
| `find-skills` | See all available skills |
|
|
75
|
+
|
|
76
|
+
## Supporting Files
|
|
77
|
+
|
|
78
|
+
Skills may include supporting files in their directory:
|
|
79
|
+
- Example code (`.ts`, `.js`, `.py`, etc.)
|
|
80
|
+
- Reference documentation (`.md` files)
|
|
81
|
+
- Reusable tools (scripts, templates)
|
|
82
|
+
|
|
83
|
+
The skill header shows the directory path where these files are located.
|
|
84
|
+
|
|
85
|
+
## Common Mistakes
|
|
86
|
+
|
|
87
|
+
**Don't:**
|
|
88
|
+
- Force-load skills with `@` syntax (wastes context)
|
|
89
|
+
- Skip loading referenced skills (breaks workflows)
|
|
90
|
+
- Assume you remember skill content (skills evolve, reload them)
|
|
91
|
+
|
|
92
|
+
**Do:**
|
|
93
|
+
- Load skills on-demand when needed
|
|
94
|
+
- Follow cross-references to sub-skills
|
|
95
|
+
- Check `find-skills` if you can't find a skill
|
|
96
|
+
|
|
97
|
+
## Related Skills
|
|
98
|
+
|
|
99
|
+
- **finding-skills** - Discover available skills
|
|
100
|
+
- **using-superpowers** - Introduction to the skills system
|
|
101
|
+
- **writing-skills** - Create new skills
|