cfsa-antigravity 2.19.0 → 2.19.2

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 (200) hide show
  1. package/package.json +1 -1
  2. package/template/.agent/kit-sync.md +3 -3
  3. package/template/.claude/commands/audit-ambiguity-execute.md +6 -0
  4. package/template/.claude/commands/audit-ambiguity-rubrics.md +6 -0
  5. package/template/.claude/commands/audit-ambiguity.md +6 -0
  6. package/template/.claude/commands/bootstrap-agents-fill.md +6 -0
  7. package/template/.claude/commands/bootstrap-agents-provision.md +6 -0
  8. package/template/.claude/commands/bootstrap-agents.md +6 -0
  9. package/template/.claude/commands/create-prd-architecture.md +6 -0
  10. package/template/.claude/commands/create-prd-compile.md +6 -0
  11. package/template/.claude/commands/create-prd-design-system.md +6 -0
  12. package/template/.claude/commands/create-prd-security.md +6 -0
  13. package/template/.claude/commands/create-prd-stack.md +6 -0
  14. package/template/.claude/commands/decompose-architecture-structure.md +6 -0
  15. package/template/.claude/commands/decompose-architecture-validate.md +6 -0
  16. package/template/.claude/commands/evolve-contract.md +6 -0
  17. package/template/.claude/commands/evolve-feature-cascade.md +6 -0
  18. package/template/.claude/commands/evolve-feature-classify.md +6 -0
  19. package/template/.claude/commands/evolve-feature.md +6 -0
  20. package/template/.claude/commands/ideate-discover.md +6 -0
  21. package/template/.claude/commands/ideate-extract.md +6 -0
  22. package/template/.claude/commands/ideate-validate.md +6 -0
  23. package/template/.claude/commands/implement-slice-setup.md +6 -0
  24. package/template/.claude/commands/implement-slice-tdd.md +6 -0
  25. package/template/.claude/commands/plan-phase-preflight.md +6 -0
  26. package/template/.claude/commands/plan-phase-write.md +6 -0
  27. package/template/.claude/commands/propagate-decision-apply.md +6 -0
  28. package/template/.claude/commands/propagate-decision-scan.md +6 -0
  29. package/template/.claude/commands/propagate-decision.md +6 -0
  30. package/template/.claude/commands/remediate-pipeline-assess.md +6 -0
  31. package/template/.claude/commands/remediate-pipeline-execute.md +6 -0
  32. package/template/.claude/commands/remediate-pipeline.md +6 -0
  33. package/template/.claude/commands/remediate-shard-split.md +6 -0
  34. package/template/.claude/commands/resolve-ambiguity.md +6 -0
  35. package/template/.claude/commands/setup-workspace-cicd.md +6 -0
  36. package/template/.claude/commands/setup-workspace-data.md +6 -0
  37. package/template/.claude/commands/setup-workspace-hosting.md +6 -0
  38. package/template/.claude/commands/setup-workspace-scaffold.md +6 -0
  39. package/template/.claude/commands/sync-kit.md +6 -0
  40. package/template/.claude/commands/update-architecture-map.md +6 -0
  41. package/template/.claude/commands/validate-phase-quality.md +6 -0
  42. package/template/.claude/commands/validate-phase-readiness.md +6 -0
  43. package/template/.claude/commands/verify-infrastructure.md +6 -0
  44. package/template/.claude/commands/write-architecture-spec-deepen.md +6 -0
  45. package/template/.claude/commands/write-architecture-spec-design.md +6 -0
  46. package/template/.claude/commands/write-be-spec-classify.md +6 -0
  47. package/template/.claude/commands/write-be-spec-write.md +6 -0
  48. package/template/.claude/commands/write-fe-spec-classify.md +6 -0
  49. package/template/.claude/commands/write-fe-spec-write.md +6 -0
  50. package/template/.claude/skills/accessibility/SKILL.md +522 -0
  51. package/template/.claude/skills/accessibility/references/WCAG.md +162 -0
  52. package/template/.claude/skills/accessibility/references/ia-spec-checklist.md +35 -0
  53. package/template/.claude/skills/adversarial-review/SKILL.md +90 -0
  54. package/template/.claude/skills/antigravity-workflows/SKILL.md +81 -0
  55. package/template/.claude/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
  56. package/template/.claude/skills/api-design-principles/SKILL.md +169 -0
  57. package/template/.claude/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  58. package/template/.claude/skills/api-design-principles/assets/rest-api-template.py +182 -0
  59. package/template/.claude/skills/api-design-principles/references/graphql-schema-design.md +583 -0
  60. package/template/.claude/skills/api-design-principles/references/rest-best-practices.md +408 -0
  61. package/template/.claude/skills/api-design-principles/resources/implementation-playbook.md +513 -0
  62. package/template/.claude/skills/api-versioning/SKILL.md +166 -0
  63. package/template/.claude/skills/api-versioning/references/typescript.md +157 -0
  64. package/template/.claude/skills/architecture-mapping/SKILL.md +219 -0
  65. package/template/.claude/skills/bootstrap-agents/SKILL.md +258 -0
  66. package/template/.claude/skills/brainstorming/SKILL.md +177 -0
  67. package/template/.claude/skills/brand-guidelines/SKILL.md +44 -0
  68. package/template/.claude/skills/clean-code/SKILL.md +196 -0
  69. package/template/.claude/skills/clean-code/references/typescript.md +126 -0
  70. package/template/.claude/skills/code-review-pro/SKILL.md +152 -0
  71. package/template/.claude/skills/concise-planning/SKILL.md +107 -0
  72. package/template/.claude/skills/cross-layer-consistency/SKILL.md +117 -0
  73. package/template/.claude/skills/database-schema-design/SKILL.md +205 -0
  74. package/template/.claude/skills/database-schema-design/references/relational.md +228 -0
  75. package/template/.claude/skills/deployment-procedures/SKILL.md +241 -0
  76. package/template/.claude/skills/design-anti-cliche/SKILL.md +159 -0
  77. package/template/.claude/skills/design-direction/SKILL.md +45 -0
  78. package/template/.claude/skills/error-handling-patterns/SKILL.md +226 -0
  79. package/template/.claude/skills/error-handling-patterns/references/go.md +162 -0
  80. package/template/.claude/skills/error-handling-patterns/references/python.md +262 -0
  81. package/template/.claude/skills/error-handling-patterns/references/rust.md +112 -0
  82. package/template/.claude/skills/error-handling-patterns/references/typescript.md +178 -0
  83. package/template/.claude/skills/find-skills/SKILL.md +145 -0
  84. package/template/.claude/skills/git-advanced/SKILL.md +972 -0
  85. package/template/.claude/skills/git-workflow/SKILL.md +420 -0
  86. package/template/.claude/skills/idea-extraction/SKILL.md +644 -0
  87. package/template/.claude/skills/logging-best-practices/SKILL.md +192 -0
  88. package/template/.claude/skills/logging-best-practices/references/go.md +49 -0
  89. package/template/.claude/skills/logging-best-practices/references/python.md +52 -0
  90. package/template/.claude/skills/logging-best-practices/references/typescript.md +215 -0
  91. package/template/.claude/skills/migration-management/SKILL.md +200 -0
  92. package/template/.claude/skills/migration-management/references/relational.md +214 -0
  93. package/template/.claude/skills/minimalist-surgical-development/SKILL.md +135 -0
  94. package/template/.claude/skills/parallel-agents/SKILL.md +165 -0
  95. package/template/.claude/skills/parallel-debugging/SKILL.md +135 -0
  96. package/template/.claude/skills/parallel-feature-development/SKILL.md +157 -0
  97. package/template/.claude/skills/performance-budgeting/SKILL.md +144 -0
  98. package/template/.claude/skills/pipeline-rubrics/SKILL.md +51 -0
  99. package/template/.claude/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
  100. package/template/.claude/skills/pipeline-rubrics/references/be-rubric.md +21 -0
  101. package/template/.claude/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
  102. package/template/.claude/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
  103. package/template/.claude/skills/pipeline-rubrics/references/scoring.md +32 -0
  104. package/template/.claude/skills/pipeline-rubrics/references/vision-rubric.md +12 -0
  105. package/template/.claude/skills/prd-templates/SKILL.md +107 -0
  106. package/template/.claude/skills/prd-templates/references/architecture-completeness-checklist.md +28 -0
  107. package/template/.claude/skills/prd-templates/references/architecture-design-template.md +88 -0
  108. package/template/.claude/skills/prd-templates/references/be-spec-classification.md +41 -0
  109. package/template/.claude/skills/prd-templates/references/be-spec-template.md +107 -0
  110. package/template/.claude/skills/prd-templates/references/bootstrap-verification-protocol.md +50 -0
  111. package/template/.claude/skills/prd-templates/references/constraint-exploration.md +41 -0
  112. package/template/.claude/skills/prd-templates/references/data-placement-template.md +74 -0
  113. package/template/.claude/skills/prd-templates/references/decision-confirmation-protocol.md +68 -0
  114. package/template/.claude/skills/prd-templates/references/decision-propagation.md +121 -0
  115. package/template/.claude/skills/prd-templates/references/decomposition-templates.md +226 -0
  116. package/template/.claude/skills/prd-templates/references/deep-ideation-loading-protocol.md +114 -0
  117. package/template/.claude/skills/prd-templates/references/design-system-decisions.md +198 -0
  118. package/template/.claude/skills/prd-templates/references/design-system-prerequisite-check.md +18 -0
  119. package/template/.claude/skills/prd-templates/references/domain-exhaustion-criteria.md +37 -0
  120. package/template/.claude/skills/prd-templates/references/engagement-tier-protocol.md +58 -0
  121. package/template/.claude/skills/prd-templates/references/engineering-standards-template.md +126 -0
  122. package/template/.claude/skills/prd-templates/references/evolution-layer-guidance.md +91 -0
  123. package/template/.claude/skills/prd-templates/references/expansion-modes.md +27 -0
  124. package/template/.claude/skills/prd-templates/references/fe-classification-procedures.md +47 -0
  125. package/template/.claude/skills/prd-templates/references/fe-spec-template.md +90 -0
  126. package/template/.claude/skills/prd-templates/references/feature-ledger-protocol.md +149 -0
  127. package/template/.claude/skills/prd-templates/references/folder-seeding-protocol.md +77 -0
  128. package/template/.claude/skills/prd-templates/references/fractal-cx-template.md +58 -0
  129. package/template/.claude/skills/prd-templates/references/fractal-feature-template.md +93 -0
  130. package/template/.claude/skills/prd-templates/references/fractal-node-index-template.md +55 -0
  131. package/template/.claude/skills/prd-templates/references/gate-applicability.md +92 -0
  132. package/template/.claude/skills/prd-templates/references/ideation-crosscut-template.md +36 -0
  133. package/template/.claude/skills/prd-templates/references/ideation-index-template.md +111 -0
  134. package/template/.claude/skills/prd-templates/references/ideation-meta-template.md +126 -0
  135. package/template/.claude/skills/prd-templates/references/infrastructure-report-template.md +71 -0
  136. package/template/.claude/skills/prd-templates/references/input-classification.md +23 -0
  137. package/template/.claude/skills/prd-templates/references/map-guard-protocol.md +65 -0
  138. package/template/.claude/skills/prd-templates/references/operational-templates.md +116 -0
  139. package/template/.claude/skills/prd-templates/references/persona-completeness-gate.md +20 -0
  140. package/template/.claude/skills/prd-templates/references/placeholder-guard-template.md +21 -0
  141. package/template/.claude/skills/prd-templates/references/placeholder-workflow-mapping.md +50 -0
  142. package/template/.claude/skills/prd-templates/references/shard-boundary-analysis.md +103 -0
  143. package/template/.claude/skills/prd-templates/references/shard-split-remediation.md +157 -0
  144. package/template/.claude/skills/prd-templates/references/skill-loading-protocol.md +36 -0
  145. package/template/.claude/skills/prd-templates/references/slice-completion-gates.md +29 -0
  146. package/template/.claude/skills/prd-templates/references/spec-coverage-sweep.md +44 -0
  147. package/template/.claude/skills/prd-templates/references/surface-model.md +61 -0
  148. package/template/.claude/skills/prd-templates/references/tdd-testing-policy.md +39 -0
  149. package/template/.claude/skills/prd-templates/references/vision-template.md +57 -0
  150. package/template/.claude/skills/prd-templates/references/workflow-checkpoint-protocol.md +112 -0
  151. package/template/.claude/skills/prd-templates/references/write-verification-protocol.md +57 -0
  152. package/template/.claude/skills/prompt-engineer/SKILL.md +203 -0
  153. package/template/.claude/skills/regex-patterns/SKILL.md +333 -0
  154. package/template/.claude/skills/regex-patterns/references/go.md +44 -0
  155. package/template/.claude/skills/regex-patterns/references/javascript.md +63 -0
  156. package/template/.claude/skills/regex-patterns/references/python.md +77 -0
  157. package/template/.claude/skills/regex-patterns/references/rust.md +43 -0
  158. package/template/.claude/skills/resolve-ambiguity/SKILL.md +278 -0
  159. package/template/.claude/skills/security-scanning-security-hardening/SKILL.md +231 -0
  160. package/template/.claude/skills/session-continuity/SKILL.md +732 -0
  161. package/template/.claude/skills/session-continuity/protocols/01-session-resumption.md +38 -0
  162. package/template/.claude/skills/session-continuity/protocols/02-progress-generation.md +85 -0
  163. package/template/.claude/skills/session-continuity/protocols/03-progress-update.md +70 -0
  164. package/template/.claude/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
  165. package/template/.claude/skills/session-continuity/protocols/05-session-close.md +37 -0
  166. package/template/.claude/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
  167. package/template/.claude/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
  168. package/template/.claude/skills/session-continuity/protocols/08-spec-pipeline-update.md +55 -0
  169. package/template/.claude/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
  170. package/template/.claude/skills/session-continuity/protocols/10-placeholder-verification-gate.md +83 -0
  171. package/template/.claude/skills/session-continuity/protocols/11-parallel-synthesis.md +21 -0
  172. package/template/.claude/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
  173. package/template/.claude/skills/skill-creator/SKILL.md +203 -0
  174. package/template/.claude/skills/skill-creator/references/.gitkeep +0 -0
  175. package/template/.claude/skills/skill-creator/scripts/.gitkeep +0 -0
  176. package/template/.claude/skills/spec-writing/SKILL.md +110 -0
  177. package/template/.claude/skills/systematic-debugging/CREATION-LOG.md +119 -0
  178. package/template/.claude/skills/systematic-debugging/SKILL.md +297 -0
  179. package/template/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  180. package/template/.claude/skills/systematic-debugging/condition-based-waiting.md +115 -0
  181. package/template/.claude/skills/systematic-debugging/defense-in-depth.md +122 -0
  182. package/template/.claude/skills/systematic-debugging/find-polluter.sh +63 -0
  183. package/template/.claude/skills/systematic-debugging/root-cause-tracing.md +169 -0
  184. package/template/.claude/skills/systematic-debugging/test-academic.md +14 -0
  185. package/template/.claude/skills/systematic-debugging/test-pressure-1.md +58 -0
  186. package/template/.claude/skills/systematic-debugging/test-pressure-2.md +68 -0
  187. package/template/.claude/skills/systematic-debugging/test-pressure-3.md +69 -0
  188. package/template/.claude/skills/tdd-workflow/SKILL.md +186 -0
  189. package/template/.claude/skills/tdd-workflow/references/typescript.md +231 -0
  190. package/template/.claude/skills/tech-stack-catalog/SKILL.md +49 -0
  191. package/template/.claude/skills/tech-stack-catalog/references/constraint-questions.md +237 -0
  192. package/template/.claude/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
  193. package/template/.claude/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
  194. package/template/.claude/skills/technical-writer/SKILL.md +242 -0
  195. package/template/.claude/skills/testing-strategist/SKILL.md +319 -0
  196. package/template/.claude/skills/testing-strategist/references/typescript.md +328 -0
  197. package/template/.claude/skills/verification-before-completion/SKILL.md +97 -0
  198. package/template/.claude/skills/workflow-automation/SKILL.md +166 -0
  199. package/template/.claude/skills/workflow-automation/references/inngest.md +88 -0
  200. package/template/.claude/skills/workflow-automation/references/temporal.md +64 -0
@@ -0,0 +1,328 @@
1
+ # TypeScript Testing Patterns
2
+
3
+ Language-specific patterns for the `testing-strategist` skill. Read `SKILL.md` first for universal methodology.
4
+
5
+ ---
6
+
7
+ ## Framework Stack
8
+
9
+ | Level | Tool | Purpose |
10
+ |-------|------|---------|
11
+ | Unit | **Jest** or **Vitest** | Test runner, assertions, mocking |
12
+ | Component | **React Testing Library** | User-centric component testing |
13
+ | Integration | **Supertest** | HTTP API testing |
14
+ | E2E | **Playwright** | Browser automation |
15
+
16
+ ## Commands
17
+
18
+ ```bash
19
+ npm test # Run tests
20
+ npm test -- --watch # Watch mode
21
+ npm run test:coverage # Coverage report
22
+ npx playwright test # E2E tests
23
+ open coverage/lcov-report/index.html # View HTML report
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Unit Test: Business Logic
29
+
30
+ ```typescript
31
+ // src/lib/pricing.ts
32
+ export function calculateTotal(items: { price: number; quantity: number }[]) {
33
+ return items.reduce((sum, item) => sum + item.price * item.quantity, 0)
34
+ }
35
+
36
+ export function applyDiscount(total: number, discountPercent: number) {
37
+ if (discountPercent < 0 || discountPercent > 100) {
38
+ throw new Error('Invalid discount percentage')
39
+ }
40
+ return total * (1 - discountPercent / 100)
41
+ }
42
+
43
+ // src/lib/pricing.test.ts
44
+ import { calculateTotal, applyDiscount } from './pricing'
45
+
46
+ describe('calculateTotal', () => {
47
+ it('calculates total for single item', () => {
48
+ const items = [{ price: 10, quantity: 2 }]
49
+ expect(calculateTotal(items)).toBe(20)
50
+ })
51
+
52
+ it('calculates total for multiple items', () => {
53
+ const items = [
54
+ { price: 10, quantity: 2 },
55
+ { price: 5, quantity: 3 }
56
+ ]
57
+ expect(calculateTotal(items)).toBe(35)
58
+ })
59
+
60
+ it('returns 0 for empty array', () => {
61
+ expect(calculateTotal([])).toBe(0)
62
+ })
63
+ })
64
+
65
+ describe('applyDiscount', () => {
66
+ it('applies discount correctly', () => {
67
+ expect(applyDiscount(100, 20)).toBe(80)
68
+ })
69
+
70
+ it('throws error for invalid discount', () => {
71
+ expect(() => applyDiscount(100, -10)).toThrow('Invalid discount')
72
+ expect(() => applyDiscount(100, 150)).toThrow('Invalid discount')
73
+ })
74
+ })
75
+ ```
76
+
77
+ ## Unit Test: React Components
78
+
79
+ ```typescript
80
+ import { render, screen, fireEvent } from '@testing-library/react'
81
+ import { Button } from './Button'
82
+
83
+ describe('Button', () => {
84
+ it('renders with correct text', () => {
85
+ render(<Button>Click me</Button>)
86
+ expect(screen.getByText('Click me')).toBeInTheDocument()
87
+ })
88
+
89
+ it('applies primary variant by default', () => {
90
+ render(<Button>Click me</Button>)
91
+ expect(screen.getByRole('button')).toHaveClass('btn-primary')
92
+ })
93
+
94
+ it('calls onClick when clicked', () => {
95
+ const handleClick = jest.fn()
96
+ render(<Button onClick={handleClick}>Click me</Button>)
97
+
98
+ fireEvent.click(screen.getByRole('button'))
99
+ expect(handleClick).toHaveBeenCalledTimes(1)
100
+ })
101
+ })
102
+ ```
103
+
104
+ ## Unit Test: Custom Hooks
105
+
106
+ ```typescript
107
+ import { renderHook, act } from '@testing-library/react'
108
+ import { useCounter } from './useCounter'
109
+
110
+ describe('useCounter', () => {
111
+ it('initializes with default value', () => {
112
+ const { result } = renderHook(() => useCounter())
113
+ expect(result.current.count).toBe(0)
114
+ })
115
+
116
+ it('increments count', () => {
117
+ const { result } = renderHook(() => useCounter())
118
+ act(() => { result.current.increment() })
119
+ expect(result.current.count).toBe(1)
120
+ })
121
+
122
+ it('resets to initial value', () => {
123
+ const { result } = renderHook(() => useCounter(10))
124
+ act(() => {
125
+ result.current.increment()
126
+ result.current.reset()
127
+ })
128
+ expect(result.current.count).toBe(10)
129
+ })
130
+ })
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Integration Test: API Routes
136
+
137
+ ```typescript
138
+ import { testClient } from '@/lib/test-utils'
139
+
140
+ describe('POST /api/posts', () => {
141
+ beforeEach(async () => {
142
+ await db.post.deleteMany()
143
+ })
144
+
145
+ it('creates a new post', async () => {
146
+ const response = await testClient
147
+ .post('/api/posts')
148
+ .set('Authorization', `Bearer ${authToken}`)
149
+ .send({ title: 'Test Post', content: 'This is a test post' })
150
+
151
+ expect(response.status).toBe(201)
152
+ expect(response.body).toMatchObject({
153
+ title: 'Test Post',
154
+ content: 'This is a test post'
155
+ })
156
+
157
+ // Verify in database
158
+ const posts = await db.post.findMany()
159
+ expect(posts).toHaveLength(1)
160
+ expect(posts[0].title).toBe('Test Post')
161
+ })
162
+
163
+ it('returns 400 for invalid data', async () => {
164
+ const response = await testClient
165
+ .post('/api/posts')
166
+ .set('Authorization', `Bearer ${authToken}`)
167
+ .send({ title: '' })
168
+
169
+ expect(response.status).toBe(400)
170
+ expect(response.body.errors).toBeDefined()
171
+ })
172
+
173
+ it('returns 401 for unauthenticated request', async () => {
174
+ const response = await testClient.post('/api/posts')
175
+ .send({ title: 'Test', content: 'Test' })
176
+
177
+ expect(response.status).toBe(401)
178
+ })
179
+ })
180
+ ```
181
+
182
+ ## Integration Test: Database Operations
183
+
184
+ ```typescript
185
+ describe('userRepository', () => {
186
+ beforeEach(async () => { await db.user.deleteMany() })
187
+ afterAll(async () => { await db.$disconnect() })
188
+
189
+ describe('createUser', () => {
190
+ it('creates user with hashed password', async () => {
191
+ const user = await createUser({
192
+ email: 'test@example.com',
193
+ password: 'password123'
194
+ })
195
+
196
+ expect(user.email).toBe('test@example.com')
197
+ expect(user.password).not.toBe('password123')
198
+ expect(user.password).toMatch(/^\$2[aby]/) // bcrypt hash
199
+ })
200
+
201
+ it('throws error for duplicate email', async () => {
202
+ await createUser({ email: 'test@example.com', password: 'pass' })
203
+ await expect(createUser({ email: 'test@example.com', password: 'pass' }))
204
+ .rejects.toThrow()
205
+ })
206
+ })
207
+ })
208
+ ```
209
+
210
+ ---
211
+
212
+ ## E2E Test: Playwright
213
+
214
+ ```typescript
215
+ import { test, expect } from '@playwright/test'
216
+
217
+ test.describe('Authentication', () => {
218
+ test('user can sign up and log in', async ({ page }) => {
219
+ await page.goto('/signup')
220
+ await page.fill('input[name="email"]', 'test@example.com')
221
+ await page.fill('input[name="password"]', 'SecurePass123!')
222
+ await page.fill('input[name="confirmPassword"]', 'SecurePass123!')
223
+ await page.click('button[type="submit"]')
224
+
225
+ await expect(page).toHaveURL('/dashboard')
226
+ await expect(page.locator('h1')).toContainText('Welcome')
227
+ })
228
+
229
+ test('shows error for invalid credentials', async ({ page }) => {
230
+ await page.goto('/login')
231
+ await page.fill('input[name="email"]', 'wrong@example.com')
232
+ await page.fill('input[name="password"]', 'wrongpassword')
233
+ await page.click('button[type="submit"]')
234
+
235
+ await expect(page.locator('[role="alert"]')).toContainText('Invalid credentials')
236
+ await expect(page).toHaveURL('/login')
237
+ })
238
+ })
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Mocking
244
+
245
+ ```typescript
246
+ // Mock external API
247
+ import { fetchUserData } from '@/lib/api'
248
+
249
+ jest.mock('@/lib/api')
250
+ const mockFetchUserData = fetchUserData as jest.MockedFunction<typeof fetchUserData>
251
+
252
+ it('displays user data', async () => {
253
+ mockFetchUserData.mockResolvedValue({
254
+ id: '1', name: 'John Doe', email: 'john@example.com'
255
+ })
256
+
257
+ render(<UserProfile userId="1" />)
258
+
259
+ await waitFor(() => {
260
+ expect(screen.getByText('John Doe')).toBeInTheDocument()
261
+ })
262
+ })
263
+
264
+ // Mock Date
265
+ beforeAll(() => {
266
+ jest.useFakeTimers()
267
+ jest.setSystemTime(new Date('2024-01-01'))
268
+ })
269
+ afterAll(() => { jest.useRealTimers() })
270
+
271
+ // Mock Math.random
272
+ const mockRandom = jest.spyOn(Math, 'random')
273
+ mockRandom.mockReturnValue(0.5)
274
+ // ... assertions ...
275
+ mockRandom.mockRestore()
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Coverage Configuration
281
+
282
+ ```javascript
283
+ // jest.config.js
284
+ module.exports = {
285
+ collectCoverageFrom: [
286
+ 'src/**/*.{ts,tsx}',
287
+ '!src/**/*.d.ts',
288
+ '!src/**/*.stories.tsx',
289
+ '!src/types/**'
290
+ ],
291
+ coverageThresholds: {
292
+ global: {
293
+ branches: 70, functions: 70, lines: 70, statements: 70
294
+ },
295
+ './src/lib/auth/**': {
296
+ branches: 90, functions: 90, lines: 90
297
+ }
298
+ }
299
+ }
300
+ ```
301
+
302
+ ## CI/CD
303
+
304
+ ```yaml
305
+ - name: Run Tests
306
+ run: npm test -- --coverage
307
+ - name: Upload Coverage
308
+ uses: codecov/codecov-action@v3
309
+ ```
310
+
311
+ ## Assertion Examples
312
+
313
+ ### ❌ Shallow (BANNED)
314
+ ```typescript
315
+ expect(result).toBeDefined()
316
+ expect(result).toBeTruthy()
317
+ ```
318
+
319
+ ### ✅ Deep (REQUIRED)
320
+ ```typescript
321
+ expect(result).toEqual({
322
+ id: expect.any(String),
323
+ name: 'Test',
324
+ items: expect.arrayContaining([
325
+ expect.objectContaining({ amount: 100 })
326
+ ])
327
+ })
328
+ ```
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: verification-before-completion
3
+ description: "Use when about to claim work is complete, fixed, or passing — requires running verification commands and confirming output before making any success claims. Evidence before claims, always."
4
+ version: 2.0.0
5
+ source: self
6
+ date_added: "2026-02-27"
7
+ date_rewritten: "2026-03-14"
8
+ ---
9
+
10
+ # Verification Before Completion
11
+
12
+ ## The Iron Law
13
+
14
+ ```
15
+ NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE
16
+ ```
17
+
18
+ If you haven't run the verification command in this response, you cannot claim it passes. Period.
19
+
20
+ ## When to Apply
21
+
22
+ **Before ANY of these:**
23
+ - Claiming tests pass, build succeeds, or linter is clean
24
+ - Expressing satisfaction ("Great!", "Done!", "All good!")
25
+ - Committing, pushing, or creating a PR
26
+ - Moving to the next task or slice
27
+ - Reporting completion to the user
28
+
29
+ ## The Gate
30
+
31
+ ```
32
+ 1. IDENTIFY → What command proves this claim?
33
+ 2. RUN → Execute it. Fresh. Complete. Not a cached result.
34
+ 3. READ → Full output. Check exit code. Count failures.
35
+ 4. VERIFY → Does the output support the claim?
36
+ 5. CLAIM → Only now may you state the result.
37
+ ```
38
+
39
+ Skip any step = the claim is unverified.
40
+
41
+ ## Evidence Standards
42
+
43
+ | Claim | Required Evidence | Not Sufficient |
44
+ |-------|-------------------|----------------|
45
+ | "Tests pass" | Full test output showing 0 failures | Previous run, "should pass", partial suite |
46
+ | "Build succeeds" | Build command output, exit code 0 | Linter passing (linter ≠ compiler) |
47
+ | "Lint clean" | Linter output showing 0 errors/warnings | Build passing (build ≠ lint) |
48
+ | "Bug fixed" | Reproduce original symptom → now passes | "I changed the code" |
49
+ | "Regression test works" | Red-green cycle: fail → fix → pass | Test passes once without verifying it can fail |
50
+ | "Requirements met" | Line-by-line checklist against acceptance criteria | "Tests pass" (tests may not cover requirements) |
51
+ | "Migration works" | Run migration up AND down successfully | "Schema looks correct" |
52
+
53
+ ## Red-Green Verification (TDD)
54
+
55
+ When claiming a regression test is valid:
56
+
57
+ ```
58
+ 1. Write test
59
+ 2. Run test → MUST FAIL (Red)
60
+ 3. Implement fix
61
+ 4. Run test → MUST PASS (Green)
62
+ 5. Revert fix temporarily
63
+ 6. Run test → MUST FAIL AGAIN (proves test is meaningful)
64
+ 7. Restore fix
65
+ 8. Run test → Passes (final confirmation)
66
+ ```
67
+
68
+ If the test never fails, it proves nothing.
69
+
70
+ ## Red Flags — Stop and Verify
71
+
72
+ Catch yourself if you're about to say:
73
+
74
+ | Phrase | What to Do Instead |
75
+ |--------|-------------------|
76
+ | "Should work now" | Run the command |
77
+ | "I'm confident this is correct" | Confidence ≠ evidence |
78
+ | "Looks like it should pass" | Looks ≠ verified |
79
+ | "Just this once I'll skip" | No exceptions |
80
+ | "The linter passed so the build should too" | They check different things |
81
+ | "I changed the right file" | Run the test |
82
+ | "The agent said it succeeded" | Verify independently |
83
+
84
+ ## Integration with Pipeline
85
+
86
+ This skill reinforces the pipeline's `completion-checklist` rule:
87
+
88
+ 1. **Code** — implementation meets the contract ← verified by tests
89
+ 2. **Tests** — all pass ← verified by running them RIGHT NOW
90
+ 3. **Tracking** — progress files updated ← verified by reading them
91
+ 4. **Locks** — claims removed ← verified by checking
92
+
93
+ ## The Bottom Line
94
+
95
+ **Run the command. Read the output. Count the failures. THEN make the claim.**
96
+
97
+ This is non-negotiable. The cost of verification is 30 seconds. The cost of a false claim is broken trust, shipped bugs, and wasted debugging time downstream.
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: workflow-automation
3
+ description: "Architect durable, event-driven workflows using step functions, retry strategies, idempotency, fan-out patterns, and the critical differences between orchestration approaches."
4
+ version: 2.0.0
5
+ ---
6
+
7
+ # Workflow Automation
8
+
9
+ You are a workflow architect who understands the fundamental tradeoff: **simplicity vs. correctness**. Every workflow platform sits somewhere on that spectrum. Your job is to pick the right point for the user's situation and implement it correctly.
10
+
11
+ ## When to Use
12
+
13
+ - Background jobs that must complete even if the server restarts
14
+ - Multi-step processes where partial completion is worse than failure (payments, onboarding)
15
+ - Event-driven architectures where one event triggers multiple independent reactions
16
+ - Scheduled/recurring tasks that need observability and retry guarantees
17
+ - Any process where "it probably ran" is not acceptable
18
+
19
+ ## When NOT to Use
20
+
21
+ - Simple fire-and-forget tasks (use a queue or a delay)
22
+ - Synchronous request-response flows
23
+ - Tasks under 100ms that don't involve external services
24
+
25
+ ## Ecosystem-Specific References
26
+
27
+ After reading the methodology below, read the reference matching your orchestration platform:
28
+
29
+ | Platform | Reference | Best For |
30
+ |----------|-----------|----------|
31
+ | Inngest | `references/inngest.md` | Serverless, event-driven, fast shipping |
32
+ | Temporal | `references/temporal.md` | Complex orchestration, human-in-the-loop |
33
+ | BullMQ | `references/bullmq.md` | Simple job queues, rate limiting, Redis stack |
34
+
35
+ ---
36
+
37
+ ## Core Concept: Durable Execution
38
+
39
+ **Wrap each unit of work in a step, so the system can retry, resume, and checkpoint independently.**
40
+
41
+ ```
42
+ Without durable execution:
43
+ fetch data → process → save → send email
44
+ ↑ server crashes here
45
+ ↓ entire pipeline reruns from scratch
46
+ ↓ customer gets duplicate email
47
+
48
+ With durable execution:
49
+ step("fetch") ✓ saved
50
+ step("process") ✓ saved
51
+ step("save") ← server crashes here
52
+ step("save") ← retries ONLY this step
53
+ step("email") ✓ runs once
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Platform Decision Matrix
59
+
60
+ | Factor | Inngest | Temporal | BullMQ |
61
+ |--------|---------|----------|--------|
62
+ | **Complexity** | Low (serverless functions) | High (workers + server) | Medium (Redis-backed) |
63
+ | **Durability** | Steps checkpointed | Full workflow replay | Job-level retry |
64
+ | **Infrastructure** | Managed or self-hosted | Requires Temporal Server | Requires Redis |
65
+ | **Best for** | Serverless, event-driven | Complex orchestration | Simple job queues |
66
+ | **Learning curve** | 1-2 days | 1-2 weeks | 1-2 days |
67
+ | **Language support** | TS, Python, Go | TS, Go, Java, Python, .NET | TS/JS only |
68
+
69
+ ### Decision Rules
70
+
71
+ 1. **Serverless + event-driven?** → Inngest
72
+ 2. **Complex orchestration, human-in-the-loop, multi-day?** → Temporal
73
+ 3. **Simple job queue, Redis already in stack?** → BullMQ
74
+ 4. **Team of 1-3, shipping fast?** → Inngest
75
+ 5. **Enterprise, compliance-heavy, Java/.NET stack?** → Temporal
76
+
77
+ ---
78
+
79
+ ## Pattern 1: Sequential Steps
80
+
81
+ Each step depends on the previous result. Steps checkpoint independently.
82
+
83
+ ```
84
+ step("create-db-record") → returns user
85
+ step("create-stripe-customer") → uses user.email
86
+ step("send-welcome-email") → uses user.email
87
+ ```
88
+
89
+ If step 2 fails, only step 2 retries. Steps 1 and 3 are not re-executed.
90
+
91
+ ---
92
+
93
+ ## Pattern 2: Fan-Out (Parallel Execution)
94
+
95
+ One event triggers multiple independent workflows. Each runs and retries independently.
96
+
97
+ ```
98
+ Event: user/signup.completed
99
+ → Workflow A: send-welcome-email (independent)
100
+ → Workflow B: create-stripe-trial (independent)
101
+ → Workflow C: provision-workspace (independent)
102
+ ```
103
+
104
+ If Workflow B fails, Workflows A and C are unaffected.
105
+
106
+ ---
107
+
108
+ ## Pattern 3: Idempotency
109
+
110
+ Prevent duplicate execution when the same event fires twice.
111
+
112
+ **Rule:** Idempotency at the workflow level AND the external call level. Belt and suspenders.
113
+
114
+ - **Workflow level:** Deduplicate by event ID or business key (e.g., order ID)
115
+ - **External call level:** Use idempotency keys on payment APIs, email sends, etc.
116
+
117
+ ---
118
+
119
+ ## Pattern 4: Scheduled/Recurring
120
+
121
+ Cron-triggered workflows with observability:
122
+ - Scheduled trigger (e.g., daily at 9am)
123
+ - Steps checkpoint independently
124
+ - Failed runs are visible, retriable, and alertable
125
+
126
+ ---
127
+
128
+ ## Pattern 5: Human-in-the-Loop
129
+
130
+ Workflows that pause and wait for external input — approval flows, multi-day processes.
131
+
132
+ ```
133
+ workflow: purchaseWorkflow(amount)
134
+ if amount > threshold:
135
+ pause and wait for approval signal (up to 72h)
136
+ if no approval → deny
137
+ continue with purchase
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Sharp Edges
143
+
144
+ | Issue | Severity | Rule |
145
+ |-------|----------|------|
146
+ | No idempotency keys on external calls | Critical | ALWAYS use idempotency keys for payments, emails, mutations |
147
+ | Side effects in workflow code (Temporal) | Critical | Workflows must be deterministic — no I/O, no random, no clock |
148
+ | Giant payloads in step results | High | Steps serialize data — keep under 256KB |
149
+ | No timeouts on activities | High | ALWAYS set timeouts — default infinite hangs forever |
150
+ | Linear retry without backoff | Medium | ALWAYS use exponential backoff |
151
+ | Missing dead letter handling | High | Failed-after-all-retries jobs need a destination |
152
+ | Monolithic workflows | Medium | Break workflows >10 steps into child workflows |
153
+
154
+ ## Anti-Patterns
155
+
156
+ | Don't | Do |
157
+ |-------|-----|
158
+ | `setTimeout(fn, 3600000)` for delays | Platform sleep — survives restarts |
159
+ | Global variables for workflow state | Step results and explicit state passing |
160
+ | Retry loops in application code | Platform-level retry policies |
161
+ | Polling in a loop for completion | Event-driven triggers or workflow signals |
162
+ | One giant function with all logic | Decompose into steps/activities |
163
+
164
+ ## Related Skills
165
+
166
+ Works with: `error-handling-patterns`, `deployment-procedures`
@@ -0,0 +1,88 @@
1
+ # Inngest Workflow Patterns
2
+
3
+ Ecosystem-specific patterns for the `workflow-automation` skill. Read `SKILL.md` first for universal methodology.
4
+
5
+ ---
6
+
7
+ ## Sequential Steps
8
+
9
+ ```typescript
10
+ const syncUser = inngest.createFunction(
11
+ { id: "sync-user-data" },
12
+ { event: "user/signup.completed" },
13
+ async ({ event, step }) => {
14
+ const user = await step.run("create-db-record", async () => {
15
+ return db.users.create({ email: event.data.email });
16
+ });
17
+
18
+ const stripeCustomer = await step.run("create-stripe-customer", async () => {
19
+ return stripe.customers.create({ email: user.email });
20
+ });
21
+
22
+ await step.run("send-welcome-email", async () => {
23
+ return email.send({ to: user.email, template: "welcome" });
24
+ });
25
+ }
26
+ );
27
+ ```
28
+
29
+ ## Fan-Out
30
+
31
+ ```typescript
32
+ // Each function subscribes to the same event — runs independently
33
+ const sendWelcome = inngest.createFunction(
34
+ { id: "send-welcome-email" },
35
+ { event: "user/signup.completed" },
36
+ async ({ event, step }) => {
37
+ await step.run("send", async () => {
38
+ await email.send({ to: event.data.email, template: "welcome" });
39
+ });
40
+ }
41
+ );
42
+
43
+ const startTrial = inngest.createFunction(
44
+ { id: "start-stripe-trial" },
45
+ { event: "user/signup.completed" },
46
+ async ({ event, step }) => {
47
+ await step.run("create-trial", async () => {
48
+ await stripe.subscriptions.create({
49
+ customer: event.data.stripeId,
50
+ trial_period_days: 14,
51
+ });
52
+ });
53
+ }
54
+ );
55
+ ```
56
+
57
+ ## Idempotency
58
+
59
+ ```typescript
60
+ const processPayment = inngest.createFunction(
61
+ {
62
+ id: "process-payment",
63
+ idempotency: "event.data.orderId", // Dedup within 24h
64
+ },
65
+ { event: "order/payment.requested" },
66
+ async ({ event, step }) => {
67
+ await step.run("charge", async () => {
68
+ return stripe.charges.create({
69
+ amount: event.data.amount,
70
+ idempotencyKey: event.data.orderId, // Stripe-level too
71
+ });
72
+ });
73
+ }
74
+ );
75
+ ```
76
+
77
+ ## Scheduled/Recurring
78
+
79
+ ```typescript
80
+ const dailyReport = inngest.createFunction(
81
+ { id: "daily-metrics-report" },
82
+ { cron: "0 9 * * *" }, // 9am daily
83
+ async ({ step }) => {
84
+ const metrics = await step.run("fetch-metrics", fetchDailyMetrics);
85
+ await step.run("send-report", async () => sendSlackReport(metrics));
86
+ }
87
+ );
88
+ ```