-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp-development-steps.json
More file actions
466 lines (466 loc) · 25.5 KB
/
Copy pathapp-development-steps.json
File metadata and controls
466 lines (466 loc) · 25.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"version": "1.0.0",
"title": "App Development Process",
"description": "Nine-phase, twenty-six-step playbook to develop a new application end-to-end with Claude Code. Generic across product domains.",
"fields": {
"id": "Phase.Step identifier (e.g. 1.1).",
"title": "Short human label for the step.",
"inputs": "Files the step expects to find before running.",
"question": "Exact prompt the agent should ask the user before doing anything.",
"process": {
"user-answer": "What to do with the user's response.",
"local-files": "What to read or write in the local working tree.",
"internet": "What, if anything, to fetch from the web."
},
"outputs": "Files the step is expected to produce or modify.",
"completion": "The binary gate that proves the step is done."
},
"phases": [
{
"id": "phase-1",
"name": "Specification",
"steps": [
{
"id": "1.1",
"title": "Capture the project requirements",
"inputs": [],
"question": "Describe the project. Paste the build spec, or describe the product in 1–3 paragraphs covering: goal, primary user, key capabilities, explicit non-goals, and any locked-in tech choices.",
"process": {
"user-answer": "Record the user's description verbatim into the spec doc.",
"local-files": "None yet — this is the entry point.",
"internet": "If the user references external standards (OpenAPI, OAuth2, SARIF, etc.), fetch the canonical definition once to lock vocabulary."
},
"outputs": ["docs/<spec-name>.md"],
"completion": "The spec file exists, lists acceptance criteria, and the user confirms 'yes, that is the product.'"
},
{
"id": "1.2",
"title": "Produce a 10-keypoint brochure",
"inputs": ["docs/<spec-name>.md"],
"question": "Should the brochure be exactly 10 single-line capabilities? Tone: engineer-facing or marketing?",
"process": {
"user-answer": "Capture tone + any must-include capability.",
"local-files": "Read the spec; extract the 10 most product-defining capabilities.",
"internet": "Not required."
},
"outputs": ["docs/<product>-keypoints.md"],
"completion": "File contains exactly 10 lines under the keypoints block; the user confirms it matches their pitch."
},
{
"id": "1.3",
"title": "Expand the brochure when scope grows",
"inputs": ["docs/<product>-keypoints.md"],
"question": "What additional capabilities are in scope? (e.g. declarative tests, LLM verification, CI/CD reports, scheduled monitors)",
"process": {
"user-answer": "Take the new themes — usually 10 of them.",
"local-files": "Preserve the original 10 keypoints unchanged.",
"internet": "Look up the dominant tool in each new theme's ecosystem (Newman, JUnit, SARIF, ajv, Anthropic SDK) to phrase capabilities idiomatically."
},
"outputs": ["docs/<product>-keypoints.md"],
"completion": "20 keypoints exist in two labelled sections; the original 10 are intact; the new section leads with the highest-leverage capability."
}
]
},
{
"id": "phase-2",
"name": "Architecture",
"steps": [
{
"id": "2.1",
"title": "Define the architectural contract",
"inputs": ["docs/<spec-name>.md", "docs/<product>-keypoints.md"],
"question": "How many top-level isolated folders should the app have, what does each own, and what is the inter-folder communication channel? (HTTP, JSON files in a shared state/ dir, message bus, etc.)",
"process": {
"user-answer": "Folder count + names + communication channel.",
"local-files": "Cross-check every keypoint against the chosen channel — every capability must be expressible through it.",
"internet": "Optional: research monorepo isolation patterns (npm workspaces, nx, turbo)."
},
"outputs": ["docs/development-plan.md"],
"completion": "Every keypoint can be satisfied without violating the contract; the user signs off on the isolation rule."
},
{
"id": "2.2",
"title": "Design the shared utils/ surface",
"inputs": ["docs/<spec-name>.md", "docs/development-plan.md"],
"question": "What cross-cutting concerns do you already know about? (LLM judge, schema validation, curl serialization, file I/O, HTTP execution, etc.)",
"process": {
"user-answer": "Hints about reusable modules.",
"local-files": "Scan the spec for verbs/nouns appearing in ≥ 2 folders → they become utils modules.",
"internet": "Look up the authoritative library per module (undici, ajv, JSONPath-plus, @anthropic-ai/sdk); record version pins."
},
"outputs": ["docs/development-plan.md"],
"completion": "Every folder in the tree has its expected files listed; every utils module has documented signatures; the tree compiles against an include glob in tsconfig."
},
{
"id": "2.3",
"title": "Draw the frontend block diagram",
"inputs": ["docs/<spec-name>.md", "docs/development-plan.md"],
"question": "Persistent left sidebar with flat top-level routes? Or a different navigation model? Group the routes into intents (Build / Verify / Setup / etc.).",
"process": {
"user-answer": "Sidebar groups + route list + per-page priorities.",
"local-files": "Enumerate every page implied by the keypoints.",
"internet": "Optional: research current SPA layout conventions for dashboards."
},
"outputs": ["docs/development-plan.md"],
"completion": "Every keypoint maps to a route or shared component; the sidebar exposes every page; no nested router is required."
}
]
},
{
"id": "phase-3",
"name": "Agent organisation",
"steps": [
{
"id": "3.1",
"title": "Author the agent roster + skills",
"inputs": ["docs/development-plan.md", "docs/<product>-keypoints.md"],
"question": "Confirm the TDD role structure. Default: test-designer → implementer → verifier triad per module. Any extra specialty roles? (security, e2e, release coordinator, contract-drift)",
"process": {
"user-answer": "Triad shape + extra specialty roles.",
"local-files": "Every utils module, every workspace module, and every page becomes one triad.",
"internet": "Not yet."
},
"outputs": ["docs/agents-plan.md"],
"completion": "Every file/module in the dev plan has a triad assigned; skills are concrete tools (Vitest, undici, claude-api, etc.), not vague labels."
},
{
"id": "3.2",
"title": "Map agents to external reference repos",
"inputs": ["docs/agents-plan.md"],
"question": "Cite public Claude Code subagent repos as reference material? You won't reuse them as-is — only read for prompt structure and skill conventions.",
"process": {
"user-answer": "Confirmation + preferred repos.",
"local-files": "Take each agent role-family from the roster.",
"internet": "Web-search popular community repos (VoltAgent, wshobson, contains-studio, anthropics/skills, lst97, 0xfurai, rshah515, supatest-ai, neonwatty/qa-skills, yusuftayman/playwright-cli-agents, hesreallyhim/awesome-claude-code, travisvn/awesome-claude-skills). Verify each cited .md file exists."
},
"outputs": ["docs/agents-plan.md"],
"completion": "Every agent role-family has ≥ 1 verified reference URL; no broken links."
},
{
"id": "3.3",
"title": "Choose the .claude/ folder structure",
"inputs": ["docs/agents-plan.md", "docs/development-plan.md"],
"question": "I'll propose two .claude/ folder layouts (centralised at root vs per-workspace) with pros and cons against your project's specific invariants. Which fits?",
"process": {
"user-answer": "Pick A or B (and any custom constraints).",
"local-files": "Re-check the isolation contract — does the tooling layer need to enforce it?",
"internet": "Web-search current best practices (CLAUDE.md ≤ 200 lines, skill description 15k char budget, recursive agent discovery, monorepo nested-skills walk-up)."
},
"outputs": [
"CLAUDE.md",
".claude/agents/",
".claude/skills/",
"<workspace>/CLAUDE.md (if per-workspace)",
"<workspace>/.claude/ (if per-workspace)",
"<rejected-layout>/",
".claudeignore"
],
"completion": "Both layouts exist on disk; only one is loaded into context; the rejected one is ignored; the chosen layout enforces the architectural invariant in tooling, not only in documentation."
}
]
},
{
"id": "phase-4",
"name": "Workflow plan",
"steps": [
{
"id": "4.1",
"title": "Author the agents development plan",
"inputs": ["docs/agents-plan.md", "docs/development-plan.md"],
"question": "Confirm the TDD lifecycle (red → green → verify), the dependency order (utils first, then app workspaces in parallel, then cross-cutting), and any extra phases (e2e, security, release).",
"process": {
"user-answer": "Confirmation + phase additions.",
"local-files": "Extract the dependency graph from the file tree.",
"internet": "Optional: review TDD literature for coverage thresholds."
},
"outputs": ["docs/agents-dev-plan.md"],
"completion": "Every workflow rule is binary; coverage thresholds are set per layer; the document tells a triad exactly when it is allowed to ship."
},
{
"id": "4.2",
"title": "Declare the hard rules",
"inputs": ["docs/agents-dev-plan.md"],
"question": "Confirm the merge-gating rules: tests first, verifier sign-off, no cross-folder imports, no orphan utils functions, no prompt change without fixture re-record, triad ships as one PR. Add/remove any?",
"process": {
"user-answer": "Confirmation or amendments.",
"local-files": "Codify each rule as one bullet under a 'Workflow rules (must-follow)' section.",
"internet": "Not required."
},
"outputs": ["docs/agents-dev-plan.md"],
"completion": "Every rule is binary (yes/no), referenced by tooling that can enforce it (hook, CI test, PR-template check)."
}
]
},
{
"id": "phase-5",
"name": "Repo & infra bootstrap",
"steps": [
{
"id": "5.1",
"title": "Create the git repo",
"inputs": ["docs/"],
"question": "Which GitHub org, and what visibility? (private recommended unless this is open-source from day one) Should the initial commit include the local files as-is?",
"process": {
"user-answer": "Org + visibility + initial-commit policy.",
"local-files": "Stage docs/*.md and a minimal .gitignore.",
"internet": "`gh org list` to confirm membership; `gh repo create <org>/<name> --<visibility> --source=. --push`."
},
"outputs": ["Remote git repo on the chosen org", "Initial commit on main"],
"completion": "`gh repo view` returns the new repo; `git log` shows one commit; `git remote -v` shows the correct origin."
},
{
"id": "5.2",
"title": "Stand up the workspace skeleton",
"inputs": ["docs/development-plan.md", "docs/agents-dev-plan.md"],
"question": "Confirm Node version, package manager (npm/yarn/pnpm), build tool (Vite/Webpack/none), and any opinionated stack choices (Tailwind, shadcn-ui, Zustand, undici).",
"process": {
"user-answer": "Versions + tool picks.",
"local-files": "Materialise empty source dirs from the file tree.",
"internet": "Look up latest stable versions for each pinned dep."
},
"outputs": [
"package.json",
"tsconfig.base.json",
"tsconfig.json",
"vitest.config.ts",
"<workspace>/package.json",
"<workspace>/tsconfig.json",
".env.example",
".gitignore",
"CLAUDE.md"
],
"completion": "`npm install` succeeds; `npx tsc --noEmit` passes on empty source; `npx vitest run` runs with 0 tests and exits 0."
},
{
"id": "5.3",
"title": "Add the boundary-check hook",
"inputs": ["docs/development-plan.md"],
"question": "Which folder names are mutually isolated? (Usually answered by the architectural contract — confirm only.)",
"process": {
"user-answer": "The isolated folder list.",
"local-files": "Walk the source tree, regex-match `from '…'` import statements, classify by workspace, fail on any cross-folder relative path.",
"internet": "Not required."
},
"outputs": [".claude/hooks/boundary-check.mjs", ".claude/settings.json"],
"completion": "Running the script on the empty repo exits 0; an intentionally inserted cross-folder import makes it exit 1 with file:line printed."
}
]
},
{
"id": "phase-6",
"name": "Test-first implementation",
"steps": [
{
"id": "6.1",
"title": "Implement utils/ test-first",
"inputs": ["docs/development-plan.md"],
"question": "Confirm the build order. The dependency graph suggests: types → result → id → time → log → io → template → curl → http → jsonpath → schema → assertions → openapi → llm → report → schemas. Skip anything for v1?",
"process": {
"user-answer": "Ordering + skips.",
"local-files": "Signatures from dev plan; fixtures in __fixtures__/.",
"internet": "Read library docs for each pinned dep."
},
"outputs": [
"utils/src/<mod>/index.ts",
"utils/src/<mod>/<mod>.test.ts",
"utils/src/<mod>/__fixtures__/* (optional)",
"utils/src/index.ts (barrel)"
],
"completion": "`vitest run` shows the module's tests passing; ≥ 90% line coverage; no top-level `node:*` import that would break browser consumers — use lazy `await import` for Node-only APIs, or split sync helpers into a <mod>/sync.ts sub-path that the main barrel does NOT re-export."
},
{
"id": "6.2",
"title": "Implement the first app workspace",
"inputs": ["utils/ (built)", "docs/development-plan.md", "JSON schema for state/<file>.json"],
"question": "For this workspace, what input sources are in scope? (file path / URL / pasted JSON / stdin / etc.)",
"process": {
"user-answer": "Accepted source types.",
"local-files": "Utils barrel for parser/IO; fixtures.",
"internet": "Not required if utils already covers the heavy lifting."
},
"outputs": ["<workspace>/src/*.ts", "<workspace>/src/*.test.ts", "<workspace>/src/index.ts (CLI entry)"],
"completion": "`npx tsx <workspace>/src/index.ts <fixture>` writes the expected state/*.json and that JSON validates against the schema; vitest green for the workspace."
},
{
"id": "6.3",
"title": "Implement the second app workspace",
"inputs": ["utils/", "state schemas", "LLM fixtures (if used)"],
"question": "Confirm assertion types (status, jsonpath, schema, latency, …) and whether LLM verification is in v1.",
"process": {
"user-answer": "Assertion list + LLM scope.",
"local-files": "Utils modules for assertions, http, llm, report, io, template.",
"internet": "msw docs for mocking; recorded fixtures for LLM if applicable."
},
"outputs": [
"<workspace>/src/*.ts",
"<workspace>/src/*.test.ts",
"<workspace>/src/index.ts",
"<workspace>/src/__fixtures__/*.json"
],
"completion": "CLI runs end-to-end against a real HTTP target (e.g. httpbin); LLM tests pass without network; opt-in `--live` flag invokes the real client."
},
{
"id": "6.4",
"title": "Implement the backend (when separate from runner)",
"inputs": ["utils/", "persistence schema"],
"question": "Persistence choice — embedded (PGlite/SQLite) or external? Need a CORS proxy?",
"process": {
"user-answer": "Persistence + proxy decision.",
"local-files": "Utils/io for path handling; utils/http for proxy executor.",
"internet": "Framework docs (Express/Hono/Fastify); persistence-library docs."
},
"outputs": [
"backend/src/index.ts",
"backend/src/config.ts",
"backend/src/db/pool.ts",
"backend/src/db/migrate.ts",
"backend/src/db/migrations/*.sql",
"backend/src/routes/*.ts"
],
"completion": "`curl /api/v1/health` → `{\"status\":\"ok\"}`; CRUD round-trips for every resource pass; proxy executor returns full timing."
},
{
"id": "6.5",
"title": "Implement the UI",
"inputs": ["utils/", "backend API contract", "frontend block diagram", "design tokens"],
"question": "Confirm the UI stack (Vite + React + Tailwind + shadcn-ui or alternative) and state library (Zustand or alternative).",
"process": {
"user-answer": "Stack confirmation.",
"local-files": "Utils browser-safe exports; frontend block diagram for layout.",
"internet": "Component-library and router docs for the chosen stack."
},
"outputs": [
"ui/src/main.tsx",
"ui/src/App.tsx",
"ui/src/index.css",
"ui/src/layout/{Layout,Sidebar,TopBar}.tsx",
"ui/src/pages/*Page.tsx",
"ui/src/components/{input,output}/*",
"ui/src/state/store.ts",
"ui/src/lib/api.ts",
"ui/vite.config.ts"
],
"completion": "`npm run dev --workspace=ui` serves at the chosen port; every route renders without errors; bidirectional views (e.g. Form ⇄ Curl) round-trip in the browser."
}
]
},
{
"id": "phase-7",
"name": "Iterative verification",
"steps": [
{
"id": "7.1",
"title": "Full test + boundary + CLI smoke",
"inputs": ["all source + tests", "boundary-check hook"],
"question": "(automated — no question)",
"process": {
"user-answer": "n/a",
"local-files": "Run `npx vitest run`, then `node .claude/hooks/boundary-check.mjs`, then a CLI smoke against a real HTTP target.",
"internet": "The smoke target (network call)."
},
"outputs": ["stdout test report", "implementation/REPORT-<module>.md per failing module (only if failures)"],
"completion": "vitest exits 0; boundary-check exits 0; CLI smoke prints `passed`."
},
{
"id": "7.2",
"title": "Browser smoke",
"inputs": ["built UI", "live backend"],
"question": "Are you on a workstation with a default browser, or running headless? If headless, I'll skip auto-open and rely on Chrome DevTools Protocol.",
"process": {
"user-answer": "Environment.",
"local-files": "Launch backend + UI via the work-in-progress start.sh.",
"internet": "Navigate the running app via the browser-automation tool; capture screenshots of every routed page."
},
"outputs": ["implementation/screenshots/*.png", "implementation/console-errors.log (if any)"],
"completion": "Every routed page renders the expected layout; no `process is not defined`, no `node:fs externalized`, no blank screen; React mounts at #root."
},
{
"id": "7.3",
"title": "Fix isomorphic regressions",
"inputs": ["failing modules from 7.2"],
"question": "For each offending module: make it isomorphic (lazy `await import`, globalThis-guarded `process`, Web Crypto in place of `node:crypto`), or split sync helpers into a separate sub-path?",
"process": {
"user-answer": "Per-module direction.",
"local-files": "Edit utils/src/<mod>/index.ts; add <mod>/sync.ts where needed; update utils/package.json exports map; update vite.config.ts optimizeDeps.",
"internet": "Web-search 'vite externalized for browser compatibility' if a fix pattern is unclear."
},
"outputs": ["refactored utils/src/<mod>/index.ts", "new utils/src/<mod>/sync.ts", "updated utils/package.json"],
"completion": "The same vitest suite from 7.1 still green; UI loads without runtime errors; Step 7.2 re-screenshots clean."
}
]
},
{
"id": "phase-8",
"name": "One-command launch",
"steps": [
{
"id": "8.1",
"title": "Author start.sh",
"inputs": ["all built workspaces", "JSON schemas", "one sample fixture"],
"question": "Confirm: backend port, frontend port, whether to auto-import a sample dataset on first run, and whether to open every routed page in the browser.",
"process": {
"user-answer": "Ports + seed policy + browser policy.",
"local-files": "Backend health URL; sample fixture path; best-effort first-record id via jq.",
"internet": "Detect OS-specific opener (open on macOS, xdg-open on Linux, wslview on WSL)."
},
"outputs": ["start.sh (executable)", "stop.sh"],
"completion": "start.sh frees stale ports, installs deps if missing, launches backend + frontend in the background with logs redirected, polls health endpoints until they answer (max 30s), auto-seeds when empty, prints every element URL with colour-coded status, opens every URL in the default browser, and traps SIGINT/SIGTERM for cleanup."
},
{
"id": "8.2",
"title": "Validate start.sh end-to-end",
"inputs": ["./start.sh"],
"question": "Run `./start.sh` now? It will open N browser tabs and write .backend.log / .frontend.log in the working directory.",
"process": {
"user-answer": "Go-ahead.",
"local-files": "Invoke; tail .backend.log and .frontend.log for errors.",
"internet": "Hit http://localhost:<backend>/api/v1/health and the frontend root; navigate every printed URL."
},
"outputs": ["live stack", "implementation/screenshots/*.png"],
"completion": "Every printed URL responds with the expected status; Step 7.2 browser smoke passes against the live stack."
}
]
},
{
"id": "phase-9",
"name": "Final verification matrix",
"steps": [
{
"id": "9.1",
"title": "Produce the verification matrix",
"inputs": ["docs/<product>-keypoints.md", "all source files", "all test reports", "live-stack smoke evidence"],
"question": "Confirm matrix columns: # · Keypoint · Status (✓/✗) · Evidence (source files + smoke proof). Add any column?",
"process": {
"user-answer": "Column shape.",
"local-files": "For each keypoint, locate the implementing files + smoke evidence.",
"internet": "Optional: re-run curl smoke for any keypoint needing live evidence captured this session."
},
"outputs": ["implementation/VERIFICATION.md"],
"completion": "Every keypoint has ≥ 1 source-file reference and ≥ 1 evidence line; the matrix has no ✗; docs/ is byte-identical to the Phase-5 commit."
},
{
"id": "9.2",
"title": "Confirm docs/ immutability + commit",
"inputs": ["full working tree"],
"question": "Ready to commit and push the implementation/ artefacts and the source workspaces?",
"process": {
"user-answer": "Go-ahead.",
"local-files": "`git status` to confirm docs/ is unchanged since the Phase 5 commit.",
"internet": "`git add` only intended paths; `git commit`; `git push`; `gh pr create` if on a branch."
},
"outputs": ["final commit on the active branch", "PR URL (when applicable)"],
"completion": "`git diff <phase-5-sha> -- docs/` is empty; every file under implementation/, .claude/, and the source workspaces is tracked; CI (if configured) is green."
}
]
}
],
"cross-cutting": [
"Before starting a step, mark it `in_progress` in the harness task tracker; mark `completed` immediately when done.",
"Issue independent tool calls in parallel (reads, writes, shell) — never serially.",
"Keep CLAUDE.md ≤ 200 lines; rely on `@docs/…` imports for the bulk.",
"Prefer hooks over advisory agents for binary rules (boundary-check is the canonical example).",
"When the prevailing directive says 'proceed autonomously,' skip user-facing asks and use the default answer.",
"All new markdown produced during Phases 5–9 goes under `implementation/` — never modify `docs/`."
]
}