create-rigel 0.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.
Files changed (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/cli.js +122 -0
  4. package/package.json +47 -0
  5. package/templates/express/.claude/CLAUDE.md +114 -0
  6. package/templates/express/.claude/agents/arch-validator.md +85 -0
  7. package/templates/express/.claude/agents/db-optimizer.md +72 -0
  8. package/templates/express/.claude/agents/doc-gardener.md +67 -0
  9. package/templates/express/.claude/agents/garbage-collector.md +94 -0
  10. package/templates/express/.claude/agents/gate-checker.md +176 -0
  11. package/templates/express/.claude/agents/reviewer.md +84 -0
  12. package/templates/express/.claude/agents/security-auditor.md +82 -0
  13. package/templates/express/.claude/hooks/post-write.sh +93 -0
  14. package/templates/express/.claude/rules/api.md +149 -0
  15. package/templates/express/.claude/rules/architecture.md +78 -0
  16. package/templates/express/.claude/rules/database.md +104 -0
  17. package/templates/express/.claude/rules/jobs.md +81 -0
  18. package/templates/express/.claude/rules/security.md +92 -0
  19. package/templates/express/.claude/rules/testing.md +97 -0
  20. package/templates/express/.claude/settings.json +35 -0
  21. package/templates/express/.claude/skills/00-infra-setup/SKILL.md +479 -0
  22. package/templates/express/.claude/skills/01-write-roadmap/SKILL.md +72 -0
  23. package/templates/express/.claude/skills/02-write-spec/SKILL.md +119 -0
  24. package/templates/express/.claude/skills/03-write-plan/SKILL.md +124 -0
  25. package/templates/express/.claude/skills/04-build-layer/SKILL.md +216 -0
  26. package/templates/express/.claude/skills/05-validate-layer/SKILL.md +43 -0
  27. package/templates/express/.claude/skills/06-push-layer/SKILL.md +59 -0
  28. package/templates/express/.claude/skills/07-layer-check/SKILL.md +62 -0
  29. package/templates/express/.claude/skills/08-garbage-collect/SKILL.md +86 -0
  30. package/templates/express/.claude/skills/09-doc-garden/SKILL.md +64 -0
  31. package/templates/express/.claude/skills/10-db-optimize/SKILL.md +96 -0
  32. package/templates/express/.claude/skills/11-load-test/SKILL.md +77 -0
  33. package/templates/express/.dockerignore +43 -0
  34. package/templates/express/.env.example +42 -0
  35. package/templates/express/.github/CODEOWNERS +22 -0
  36. package/templates/express/.github/dependabot.yml +48 -0
  37. package/templates/express/.github/pull_request_template.md +58 -0
  38. package/templates/express/.github/workflows/ci.yml +278 -0
  39. package/templates/express/.github/workflows/load-test.yml +41 -0
  40. package/templates/express/.gitleaks.toml +18 -0
  41. package/templates/express/.lintstagedrc.json +3 -0
  42. package/templates/express/.nvmrc +1 -0
  43. package/templates/express/.prettierrc +8 -0
  44. package/templates/express/.sequelizerc +8 -0
  45. package/templates/express/AGENTS.md +94 -0
  46. package/templates/express/ARCHITECTURE.md +161 -0
  47. package/templates/express/Dockerfile +40 -0
  48. package/templates/express/Makefile +79 -0
  49. package/templates/express/QUICKSTART.md +131 -0
  50. package/templates/express/docker-compose.yml +114 -0
  51. package/templates/express/docs/PLANS.md +111 -0
  52. package/templates/express/docs/QUALITY_SCORE.md +66 -0
  53. package/templates/express/docs/design-docs/core-beliefs.md +89 -0
  54. package/templates/express/docs/design-docs/decisions/ADR-000-infrastructure.md +70 -0
  55. package/templates/express/docs/design-docs/decisions/ADR-001-observability.md +82 -0
  56. package/templates/express/docs/design-docs/decisions/index.md +23 -0
  57. package/templates/express/docs/design-docs/index.md +11 -0
  58. package/templates/express/docs/design-docs/observability.md +194 -0
  59. package/templates/express/docs/design-docs/team-workflow.md +64 -0
  60. package/templates/express/docs/exec-plans/active/.gitkeep +0 -0
  61. package/templates/express/docs/exec-plans/completed/.gitkeep +0 -0
  62. package/templates/express/docs/exec-plans/tech-debt-tracker.md +31 -0
  63. package/templates/express/docs/generated/.gitkeep +0 -0
  64. package/templates/express/docs/product-specs/ROADMAP.md +49 -0
  65. package/templates/express/docs/product-specs/draft/.gitkeep +0 -0
  66. package/templates/express/docs/product-specs/index.md +21 -0
  67. package/templates/express/docs/product-specs/ready/.gitkeep +0 -0
  68. package/templates/express/eslint.config.mjs +94 -0
  69. package/templates/express/gitignore +36 -0
  70. package/templates/express/infra/monitoring/alloy/config.alloy +59 -0
  71. package/templates/express/jest.config.ts +61 -0
  72. package/templates/express/package.json +45 -0
  73. package/templates/express/scripts/openapi.export.ts +77 -0
  74. package/templates/express/tests/architecture/isolation.test.ts +51 -0
  75. package/templates/express/tests/architecture/layers.test.ts +83 -0
  76. package/templates/express/tests/integration/health.test.ts +40 -0
  77. package/templates/express/tests/integration/isolation.test.template.ts +88 -0
  78. package/templates/express/tests/load/smoke.js +46 -0
  79. package/templates/express/tests/load/soak.js +45 -0
  80. package/templates/express/tests/load/stress.js +44 -0
  81. package/templates/express/tests/unit/utils/response.util.test.ts +53 -0
  82. package/templates/express/tsconfig.build.json +8 -0
  83. package/templates/express/tsconfig.json +20 -0
  84. package/templates/fastapi/.claude/CLAUDE.md +122 -0
  85. package/templates/fastapi/.claude/agents/arch-validator.md +64 -0
  86. package/templates/fastapi/.claude/agents/db-optimizer.md +59 -0
  87. package/templates/fastapi/.claude/agents/doc-gardener.md +55 -0
  88. package/templates/fastapi/.claude/agents/garbage-collector.md +74 -0
  89. package/templates/fastapi/.claude/agents/gate-checker.md +133 -0
  90. package/templates/fastapi/.claude/agents/reviewer.md +74 -0
  91. package/templates/fastapi/.claude/agents/security-auditor.md +69 -0
  92. package/templates/fastapi/.claude/hooks/post-write.sh +65 -0
  93. package/templates/fastapi/.claude/rules/api.md +119 -0
  94. package/templates/fastapi/.claude/rules/architecture.md +84 -0
  95. package/templates/fastapi/.claude/rules/database.md +153 -0
  96. package/templates/fastapi/.claude/rules/jobs.md +85 -0
  97. package/templates/fastapi/.claude/rules/security.md +102 -0
  98. package/templates/fastapi/.claude/rules/testing.md +207 -0
  99. package/templates/fastapi/.claude/settings.json +50 -0
  100. package/templates/fastapi/.claude/skills/00-infra-setup/SKILL.md +311 -0
  101. package/templates/fastapi/.claude/skills/01-write-roadmap/SKILL.md +61 -0
  102. package/templates/fastapi/.claude/skills/02-write-spec/SKILL.md +82 -0
  103. package/templates/fastapi/.claude/skills/03-write-plan/SKILL.md +83 -0
  104. package/templates/fastapi/.claude/skills/04-build-layer/SKILL.md +170 -0
  105. package/templates/fastapi/.claude/skills/05-validate-layer/SKILL.md +20 -0
  106. package/templates/fastapi/.claude/skills/06-push-layer/SKILL.md +31 -0
  107. package/templates/fastapi/.claude/skills/07-layer-check/SKILL.md +51 -0
  108. package/templates/fastapi/.claude/skills/08-garbage-collect/SKILL.md +47 -0
  109. package/templates/fastapi/.claude/skills/09-doc-garden/SKILL.md +9 -0
  110. package/templates/fastapi/.claude/skills/10-db-optimize/SKILL.md +53 -0
  111. package/templates/fastapi/.claude/skills/11-load-test/SKILL.md +81 -0
  112. package/templates/fastapi/.dockerignore +30 -0
  113. package/templates/fastapi/.github/dependabot.yml +24 -0
  114. package/templates/fastapi/AGENTS.md +87 -0
  115. package/templates/fastapi/ARCHITECTURE.md +141 -0
  116. package/templates/fastapi/Makefile +42 -0
  117. package/templates/fastapi/README.md +179 -0
  118. package/templates/fastapi/docs/PLANS.md +26 -0
  119. package/templates/fastapi/docs/QUALITY_SCORE.md +26 -0
  120. package/templates/fastapi/docs/design-docs/core-beliefs.md +46 -0
  121. package/templates/fastapi/docs/design-docs/decisions/ADR-000-infrastructure.md +79 -0
  122. package/templates/fastapi/docs/design-docs/decisions/index.md +7 -0
  123. package/templates/fastapi/docs/design-docs/index.md +9 -0
  124. package/templates/fastapi/docs/exec-plans/active/.gitkeep +0 -0
  125. package/templates/fastapi/docs/exec-plans/completed/.gitkeep +0 -0
  126. package/templates/fastapi/docs/exec-plans/tech-debt-tracker.md +19 -0
  127. package/templates/fastapi/docs/generated/.gitkeep +0 -0
  128. package/templates/fastapi/docs/product-specs/ROADMAP.md +49 -0
  129. package/templates/fastapi/docs/product-specs/draft/.gitkeep +0 -0
  130. package/templates/fastapi/docs/product-specs/index.md +18 -0
  131. package/templates/fastapi/docs/product-specs/ready/.gitkeep +0 -0
  132. package/templates/fastapi/gitignore +46 -0
  133. package/templates/fastapi/scripts/gate.sh +68 -0
  134. package/templates/nestjs/.claude/CLAUDE.md +121 -0
  135. package/templates/nestjs/.claude/agents/db-optimizer.md +51 -0
  136. package/templates/nestjs/.claude/agents/doc-gardener.md +45 -0
  137. package/templates/nestjs/.claude/agents/garbage-collector.md +50 -0
  138. package/templates/nestjs/.claude/agents/gate-checker.md +127 -0
  139. package/templates/nestjs/.claude/agents/reviewer.md +68 -0
  140. package/templates/nestjs/.claude/agents/security-auditor.md +72 -0
  141. package/templates/nestjs/.claude/hooks/post-write.sh +91 -0
  142. package/templates/nestjs/.claude/rules/api.md +87 -0
  143. package/templates/nestjs/.claude/rules/architecture.md +104 -0
  144. package/templates/nestjs/.claude/rules/database.md +111 -0
  145. package/templates/nestjs/.claude/rules/security.md +110 -0
  146. package/templates/nestjs/.claude/rules/testing.md +145 -0
  147. package/templates/nestjs/.claude/settings.json +33 -0
  148. package/templates/nestjs/.claude/skills/00-infra-setup/SKILL.md +222 -0
  149. package/templates/nestjs/.claude/skills/01-write-spec/SKILL.md +25 -0
  150. package/templates/nestjs/.claude/skills/02-write-plan/SKILL.md +18 -0
  151. package/templates/nestjs/.claude/skills/03-build-layer/SKILL.md +242 -0
  152. package/templates/nestjs/.claude/skills/04-validate-layer/SKILL.md +4 -0
  153. package/templates/nestjs/.claude/skills/05-push-layer/SKILL.md +6 -0
  154. package/templates/nestjs/.claude/skills/06-layer-check/SKILL.md +12 -0
  155. package/templates/nestjs/.claude/skills/07-garbage-collect/SKILL.md +2 -0
  156. package/templates/nestjs/.claude/skills/08-doc-garden/SKILL.md +4 -0
  157. package/templates/nestjs/.claude/skills/09-api-sync/SKILL.md +36 -0
  158. package/templates/nestjs/.claude/skills/10-load-test/SKILL.md +29 -0
  159. package/templates/nestjs/.env.example +11 -0
  160. package/templates/nestjs/AGENTS.md +88 -0
  161. package/templates/nestjs/ARCHITECTURE.md +192 -0
  162. package/templates/nestjs/docs/PLANS.md +22 -0
  163. package/templates/nestjs/docs/QUALITY_SCORE.md +27 -0
  164. package/templates/nestjs/docs/design-docs/core-beliefs.md +18 -0
  165. package/templates/nestjs/docs/design-docs/decisions/ADR-000-infrastructure.md +58 -0
  166. package/templates/nestjs/docs/design-docs/decisions/index.md +7 -0
  167. package/templates/nestjs/docs/design-docs/index.md +7 -0
  168. package/templates/nestjs/docs/exec-plans/active/.gitkeep +0 -0
  169. package/templates/nestjs/docs/exec-plans/completed/.gitkeep +0 -0
  170. package/templates/nestjs/docs/exec-plans/tech-debt-tracker.md +16 -0
  171. package/templates/nestjs/docs/generated/.gitkeep +0 -0
  172. package/templates/nestjs/docs/product-specs/draft/.gitkeep +0 -0
  173. package/templates/nestjs/docs/product-specs/index.md +7 -0
  174. package/templates/nestjs/docs/product-specs/ready/.gitkeep +0 -0
  175. package/templates/nestjs/gitignore +8 -0
  176. package/templates/nextjs/.claude/CLAUDE.md +139 -0
  177. package/templates/nextjs/.claude/agents/arch-validator.md +66 -0
  178. package/templates/nextjs/.claude/agents/contract-checker.md +78 -0
  179. package/templates/nextjs/.claude/agents/doc-gardener.md +52 -0
  180. package/templates/nextjs/.claude/agents/garbage-collector.md +61 -0
  181. package/templates/nextjs/.claude/agents/gate-checker.md +129 -0
  182. package/templates/nextjs/.claude/agents/perf-auditor.md +109 -0
  183. package/templates/nextjs/.claude/agents/reviewer.md +79 -0
  184. package/templates/nextjs/.claude/agents/security-auditor.md +50 -0
  185. package/templates/nextjs/.claude/hooks/post-write.sh +121 -0
  186. package/templates/nextjs/.claude/rules/api-contract.md +166 -0
  187. package/templates/nextjs/.claude/rules/architecture.md +99 -0
  188. package/templates/nextjs/.claude/rules/components.md +122 -0
  189. package/templates/nextjs/.claude/rules/security.md +122 -0
  190. package/templates/nextjs/.claude/rules/testing.md +187 -0
  191. package/templates/nextjs/.claude/scripts/infra-setup.sh +550 -0
  192. package/templates/nextjs/.claude/settings.json +33 -0
  193. package/templates/nextjs/.claude/skills/00-infra-setup/SKILL.md +471 -0
  194. package/templates/nextjs/.claude/skills/01-write-roadmap/SKILL.md +77 -0
  195. package/templates/nextjs/.claude/skills/02-write-spec/SKILL.md +78 -0
  196. package/templates/nextjs/.claude/skills/03-write-plan/SKILL.md +91 -0
  197. package/templates/nextjs/.claude/skills/04-build-layer/SKILL.md +141 -0
  198. package/templates/nextjs/.claude/skills/05-validate-layer/SKILL.md +13 -0
  199. package/templates/nextjs/.claude/skills/06-push-layer/SKILL.md +20 -0
  200. package/templates/nextjs/.claude/skills/07-layer-check/SKILL.md +28 -0
  201. package/templates/nextjs/.claude/skills/08-garbage-collect/SKILL.md +14 -0
  202. package/templates/nextjs/.claude/skills/09-doc-garden/SKILL.md +12 -0
  203. package/templates/nextjs/.claude/skills/10-api-sync/SKILL.md +50 -0
  204. package/templates/nextjs/.claude/skills/11-perf-budget/SKILL.md +51 -0
  205. package/templates/nextjs/.dockerignore +25 -0
  206. package/templates/nextjs/.gitattributes +10 -0
  207. package/templates/nextjs/.github/CODEOWNERS +24 -0
  208. package/templates/nextjs/.github/dependabot.yml +31 -0
  209. package/templates/nextjs/.github/pull_request_template.md +59 -0
  210. package/templates/nextjs/.github/workflows/ci.yml +143 -0
  211. package/templates/nextjs/.github/workflows/lighthouse.yml +54 -0
  212. package/templates/nextjs/.github/workflows/load-test.yml +54 -0
  213. package/templates/nextjs/.husky/pre-commit +1 -0
  214. package/templates/nextjs/.lintstagedrc.json +4 -0
  215. package/templates/nextjs/.mcp.json +8 -0
  216. package/templates/nextjs/.prettierignore +13 -0
  217. package/templates/nextjs/.prettierrc +9 -0
  218. package/templates/nextjs/AGENTS.md +88 -0
  219. package/templates/nextjs/ARCHITECTURE.md +165 -0
  220. package/templates/nextjs/Dockerfile +38 -0
  221. package/templates/nextjs/Makefile +50 -0
  222. package/templates/nextjs/QUICKSTART.md +128 -0
  223. package/templates/nextjs/docs/PLANS.md +23 -0
  224. package/templates/nextjs/docs/QUALITY_SCORE.md +27 -0
  225. package/templates/nextjs/docs/design-docs/core-beliefs.md +43 -0
  226. package/templates/nextjs/docs/design-docs/decisions/ADR-000-infrastructure.md +72 -0
  227. package/templates/nextjs/docs/design-docs/decisions/index.md +7 -0
  228. package/templates/nextjs/docs/design-docs/index.md +7 -0
  229. package/templates/nextjs/docs/design-docs/team-workflow.md +66 -0
  230. package/templates/nextjs/docs/exec-plans/active/.gitkeep +0 -0
  231. package/templates/nextjs/docs/exec-plans/completed/.gitkeep +0 -0
  232. package/templates/nextjs/docs/exec-plans/tech-debt-tracker.md +19 -0
  233. package/templates/nextjs/docs/generated/.gitkeep +0 -0
  234. package/templates/nextjs/docs/product-specs/ROADMAP.md +59 -0
  235. package/templates/nextjs/docs/product-specs/draft/.gitkeep +0 -0
  236. package/templates/nextjs/docs/product-specs/index.md +18 -0
  237. package/templates/nextjs/docs/product-specs/ready/.gitkeep +0 -0
  238. package/templates/nextjs/eslint.config.mjs +150 -0
  239. package/templates/nextjs/gitignore +35 -0
  240. package/templates/nextjs/lighthouserc.js +37 -0
@@ -0,0 +1,128 @@
1
+ # QUICKSTART — Your First 30 Minutes
2
+
3
+ This is an **agent-first** Next.js template. You don't scaffold or wire it by hand — you
4
+ drive [Claude Code](https://claude.com/claude-code) through a fixed set of slash commands,
5
+ and a gate enforces the architecture on every step. This page gets you from clone to a
6
+ running, contract-typed app.
7
+
8
+ > New here? Read in order: this file → `AGENTS.md` (navigation map) → `ARCHITECTURE.md`
9
+ > (layer rules) → `.claude/CLAUDE.md` (the agent's standing instructions).
10
+
11
+ ---
12
+
13
+ ## 0. Prerequisites
14
+
15
+ - **Node.js** (latest LTS) and **npm**
16
+ - **Claude Code** installed — CLI (`npm i -g @anthropic-ai/claude-code`), the desktop/web
17
+ app, or the VS Code / JetBrains extension
18
+ - **bash** available on PATH (Git Bash on Windows) — the hooks and the infra script run in bash
19
+ - A backend that exposes an **`openapi.json`** spec (needed before you build features)
20
+
21
+ This template ships **only** the harness (`.claude/`, `docs/`, root docs). There is no
22
+ `package.json` yet — that's deliberate. `/infra-setup` generates the app.
23
+
24
+ ---
25
+
26
+ ## 1. Open the project in Claude Code
27
+
28
+ ```bash
29
+ cd harness-nextjs
30
+ claude # or open the folder in the IDE extension
31
+ ```
32
+
33
+ Claude reads `.claude/CLAUDE.md` automatically and follows the Session Start Checklist.
34
+ The model is pinned to **Opus 4.8** in `.claude/settings.json`.
35
+
36
+ ---
37
+
38
+ ## 2. Run Phase 0 — infrastructure (once)
39
+
40
+ ```
41
+ /infra-setup
42
+ ```
43
+
44
+ This runs the deterministic scaffold (`bash .claude/scripts/infra-setup.sh`) —
45
+ `create-next-app@latest`, all deps at latest LTS (no version pins), `shadcn/ui`, the
46
+ directory tree, and `package.json` scripts — then Claude hand-authors the harness glue
47
+ (`src/lib/env.ts`, `src/lib/api-client.ts`, utils, store, providers, configs, and the
48
+ `tests/architecture/layers.test.ts` gate). Ends with a passing gate + ADR-000 committed.
49
+
50
+ You now have a runnable app:
51
+
52
+ ```bash
53
+ npm run dev # http://localhost:3000
54
+ npm run typecheck
55
+ npm test
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 3. Plan the whole product (once, before the feature loop)
61
+
62
+ For a real multi-screen product, decompose it into an ordered set of specs first — don't
63
+ free-style screen-by-screen. With the product brief and the backend's `openapi.json` in the repo:
64
+
65
+ ```
66
+ /api-sync → generate src/types/api.generated.ts from the backend openapi.json
67
+ /write-roadmap → brief + contract → docs/product-specs/ROADMAP.md
68
+ (feature areas + personas, dependency order, a walking-skeleton first slice,
69
+ and an `Implements (backend SPEC)` column so each row is gated on the
70
+ backend capability being shipped)
71
+ ```
72
+
73
+ This is the altitude above specs. It's a LIVING doc — re-run `/write-roadmap` when the backend
74
+ contract grows. (Small one-off feature? Skip it and go straight to `/write-spec`.)
75
+
76
+ ---
77
+
78
+ ## 4. The feature loop (every feature, forever)
79
+
80
+ ```
81
+ /write-spec → describe the feature (roadmap-guided); output lands in docs/product-specs/draft/
82
+ (you review the spec and move it to docs/product-specs/ready/)
83
+ /write-plan → turns the READY spec into a layered execution plan
84
+ /api-sync → regenerate src/types/api.generated.ts from the backend openapi.json
85
+ /build-layer → builds the next unchecked layer, then the gate-checker runs (PASS/FAIL)
86
+ (repeat /build-layer until every layer is checked)
87
+ /garbage-collect → end-of-feature cleanup; plan moves to docs/exec-plans/completed/
88
+ ```
89
+
90
+ `/build-layer` builds **one layer at a time** (types → lib → hooks → features → app →
91
+ tests) and will not let you commit until the gate is green.
92
+
93
+ ---
94
+
95
+ ## 5. The rules the harness enforces for you
96
+
97
+ You don't have to memorise these — the post-write hook and `gate-checker` catch them —
98
+ but knowing them explains the guardrails (full list in `AGENTS.md`):
99
+
100
+ - No `fetch()` in components/pages — all API calls go through `src/hooks/`
101
+ - `src/types/api.generated.ts` is **READ ONLY** — regenerated by `/api-sync`
102
+ - `process.env` only inside `src/lib/env.ts`
103
+ - Access tokens live in memory (React context), never `localStorage`
104
+ - No file > 400 lines; no `console.log` in `src/`
105
+ - Every `'use client'` needs a `// Client: <reason>` comment
106
+
107
+ ---
108
+
109
+ ## 6. Useful agents (invoke by asking Claude)
110
+
111
+ | Agent | When |
112
+ |---|---|
113
+ | `reviewer` | "Use the reviewer agent to review current changes" — before a PR |
114
+ | `security-auditor` | before any auth / token / data-exposure change |
115
+ | `perf-auditor` | before adding new routes/components (Core Web Vitals + bundle) |
116
+ | `contract-checker` | after the OpenAPI spec changes |
117
+
118
+ ---
119
+
120
+ ## Troubleshooting
121
+
122
+ - **`/infra-setup` says package.json exists** — infra runs once; it's already set up.
123
+ - **Hook prints nothing** — it only warns on `.ts`/`.tsx` under `src/`/`app/`; that's normal.
124
+ - **Gate fails on architecture tests** — `tests/architecture/layers.test.ts` enforces layer
125
+ imports; the failure message names the offending `file → import`. Fix the import direction.
126
+ - **A skill looks out of date** — check its `Verified:` header; if stale, Claude refreshes
127
+ the relevant library docs via `ctx7` before following it (see the Skill Freshness Rule in
128
+ `.claude/CLAUDE.md`).
@@ -0,0 +1,23 @@
1
+ # PLANS.md — Execution Plan Format
2
+
3
+ ## Roadmap → Specs (the altitude above plans)
4
+ /write-roadmap creates → docs/product-specs/ROADMAP.md (brief + backend openapi.json →
5
+ feature-area- and persona-ordered frontend specs, each gated on the backend spec it `Implements`).
6
+ The roadmap plans the SET of specs; /write-spec then authors each one. A large feature area may
7
+ span MULTIPLE plans — its spec's `**Plan:**` field then lists them all (e.g. PLAN-003, PLAN-007).
8
+
9
+ ## Lifecycle
10
+ /write-plan creates → docs/exec-plans/active/PLAN-XXX.md [IN_PROGRESS]
11
+ → layers built one by one, checkboxes ticked
12
+ → /garbage-collect closes → docs/exec-plans/completed/ [COMPLETE]
13
+
14
+ Plans are NEVER deleted. They are the project memory.
15
+
16
+ ## Pre-Build Requirement
17
+ Always run /api-sync before the first /build-layer to ensure the contract is current.
18
+
19
+ ## Escalation Rule
20
+ Escalate to human only when judgment is required:
21
+ - Ambiguous acceptance criteria
22
+ - API contract has breaking changes requiring design decisions
23
+ - Performance budget impossible without architecture change
@@ -0,0 +1,27 @@
1
+ # QUALITY_SCORE.md — Domain Health Grades
2
+
3
+ Updated by /garbage-collect after every feature.
4
+
5
+ ## Grading Rubric
6
+ | Grade | Meaning |
7
+ |---|---|
8
+ | A | All invariants met, coverage above threshold, zero known debt |
9
+ | B | Minor issues, coverage at threshold, low-priority debt logged |
10
+ | C | Layer violation OR coverage below threshold OR unresolved debt |
11
+ | D | Multiple violations, significant coverage gaps |
12
+
13
+ ## Architecture Health
14
+ | Check | Status |
15
+ |---|---|
16
+ | No cross-layer imports | — |
17
+ | No files > 400 lines | — |
18
+ | No process.env outside env.ts | — |
19
+ | No console.log in src/ | — |
20
+ | No direct fetch() in components | — |
21
+ | api.generated.ts not manually edited | — |
22
+ | Utils: 100% test coverage | — |
23
+
24
+ ## Domain Grades
25
+ | Domain | Grade | Coverage | Last Updated | Notes |
26
+ |---|---|---|---|---|
27
+ | *(no domains yet)* | — | — | — | — |
@@ -0,0 +1,43 @@
1
+ # Core Beliefs — The Engineering Constitution
2
+
3
+ Rules without reasons get bent under pressure.
4
+
5
+ ## 1. The Repo Is Reality
6
+ If it isn't in this repository, it doesn't exist.
7
+ **Consequence:** Every decision → ADR. Every product → ROADMAP.md. Every intent → spec. Every plan → PLAN-XXX.md.
8
+
9
+ ## 2. The API Contract Is the Source of Truth
10
+ api.generated.ts is generated from the backend OpenAPI spec. Never hand-write types that duplicate it.
11
+ **Consequence:** /api-sync runs before every feature. TypeScript errors after sync = contract drift to fix.
12
+
13
+ ## 3. Hooks Are the Only API Gateway
14
+ No component or page calls fetch() directly. All API calls go through TanStack Query hooks in src/hooks/.
15
+ **Consequence:** One place to add auth headers, one place to handle errors, one place to add retries.
16
+
17
+ ## 4. Enforce Mechanically, Not Aspirationally
18
+ ESLint rules, hooks, and structural tests enforce the architecture. Docs alone do not.
19
+ **Consequence:** Every constraint is a linter rule, a hook warning, or a failing test.
20
+
21
+ ## 5. Server Components Are the Default
22
+ Every component is a Server Component unless it explicitly needs browser APIs or React hooks.
23
+ **Consequence:** Every 'use client' directive requires a comment explaining why.
24
+
25
+ ## 6. Layers Protect Concerns
26
+ Features don't call fetch(). Pages don't contain business logic. Utils don't import domain code.
27
+ **Consequence:** ESLint import rules + structural tests enforce this mechanically.
28
+
29
+ ## 7. Tokens Live in Memory
30
+ Access tokens are stored in React context only. Never localStorage, never sessionStorage.
31
+ **Consequence:** Post-hook catches this. Tokens are wiped on page refresh by design (refresh token in httpOnly cookie handles re-auth).
32
+
33
+ ## 8. All Three States, Every Time
34
+ Every component that fetches data must handle: loading, error, and empty. Silence is not acceptable.
35
+ **Consequence:** Gate-checker scans for isPending/isError patterns on data-fetching components.
36
+
37
+ ## 9. Gate Before Commit — Always
38
+ TypeScript must compile. ESLint must pass. Architecture tests must pass. Before every commit.
39
+ **Consequence:** /push-layer runs typecheck + lint before committing. No exceptions.
40
+
41
+ ## 10. Technical Debt Is a High-Interest Loan
42
+ Log debt immediately. Pay it in small daily amounts. Garbage collect after every feature.
43
+ **Consequence:** tech-debt-tracker.md updated after every feature.
@@ -0,0 +1,72 @@
1
+ # ADR-000 — Infrastructure & Stack Choices
2
+
3
+ **Status:** ACCEPTED
4
+ **Date:** *(fill when /infra-setup is run)*
5
+ **Plan:** Phase 0
6
+
7
+ ---
8
+
9
+ ## Context
10
+ Starting a new Next.js frontend project. Stack choices made here are expensive to change.
11
+
12
+ ---
13
+
14
+ ## Decisions
15
+
16
+ ### Framework: Next.js 16.2 + React 19.2
17
+ - Next.js 16 is the current stable with React Compiler stable
18
+ - App Router (not Pages Router) — RSC, streaming, better performance
19
+ - React Compiler enabled — automatic memoisation, zero manual useMemo/useCallback
20
+ - Turbopack as bundler — significantly faster dev server than Webpack
21
+ - Alternatives rejected: Remix (less ecosystem), Vite SPA (no SSR/RSC benefits)
22
+
23
+ ### API Contract: openapi-typescript + openapi-fetch
24
+ - openapi-typescript generates types from backend OpenAPI spec — zero runtime overhead
25
+ - openapi-fetch: type-safe fetch client, 6kb, infers types from generated schema
26
+ - Together: full end-to-end type safety from backend response to component props
27
+ - Alternatives rejected: axios (no OpenAPI integration), React Query with manual types (error-prone)
28
+
29
+ ### Server State: TanStack Query 5
30
+ - Industry standard for async server state management
31
+ - Built-in caching, background refetch, optimistic updates, devtools
32
+ - Version 5: simplified API (one object argument), smaller bundle
33
+ - Alternatives rejected: SWR (less features), Redux RTK Query (more boilerplate)
34
+
35
+ ### Client State: Zustand 5
36
+ - Minimal (~1kb), TypeScript-native, no boilerplate
37
+ - Used ONLY for UI state that genuinely belongs on the client (sidebar, modals)
38
+ - NOT for server data — that's in TanStack Query
39
+ - Alternatives rejected: Redux (overkill), Jotai (less ecosystem), Context (re-render issues)
40
+
41
+ ### Components: shadcn/ui
42
+ - Copy-owned model — components are in your repo, you control them
43
+ - Built on Radix UI primitives (accessibility built-in)
44
+ - Tailwind CSS 4 styling — no runtime CSS-in-JS
45
+ - No upgrade hell — you own the code
46
+ - Alternatives rejected: MUI (heavy, hard to customise), Chakra (JSX props model)
47
+
48
+ ### Forms: React Hook Form 7 + Zod 3
49
+ - React Hook Form: uncontrolled, minimal re-renders, best performance
50
+ - Zod: same validation library as backend — consistent error messages
51
+ - @hookform/resolvers bridges them
52
+ - Alternatives rejected: Formik (slow, too many re-renders), Yup (less TypeScript support)
53
+
54
+ ### Testing: Vitest 4 + Playwright + MSW 2
55
+ - Vitest 4: 3.8x faster than Jest, native TypeScript, same Jest API
56
+ - Playwright: E2E + visual regression in one tool, 80%+ new project adoption
57
+ - MSW 2: intercept at network level, works in both browser and node
58
+ - Alternatives rejected: Jest (slower), Cypress (less capable than Playwright)
59
+
60
+ ### Auth Token Strategy
61
+ - Access token in React context (memory) — wiped on refresh
62
+ - Refresh token in httpOnly cookie (set by backend) — never accessible to JS
63
+ - On 401: call /api/auth/refresh → backend reads cookie → issues new access token
64
+ - No localStorage/sessionStorage — XSS attack surface reduction
65
+
66
+ ---
67
+
68
+ ## Consequences
69
+ - openapi-typescript: api.generated.ts is READ ONLY — must regenerate on backend changes
70
+ - React Compiler: no manual useMemo/useCallback needed (but don't remove existing ones without testing)
71
+ - Server Components: most pages are async by default — data fetching happens at render time on server
72
+ - Zustand for UI only: if it lives in TanStack Query cache, don't duplicate in Zustand
@@ -0,0 +1,7 @@
1
+ # ADR Index
2
+
3
+ | ID | Title | Status | Date | Plan |
4
+ |---|---|---|---|---|
5
+ | ADR-000 | Infrastructure & Stack Choices | ACCEPTED | *(fill on /infra-setup)* | — |
6
+
7
+ Add a row after every new ADR.
@@ -0,0 +1,7 @@
1
+ # Design Docs Index
2
+
3
+ | Document | Purpose |
4
+ |---|---|
5
+ | core-beliefs.md | Engineering constitution — WHY every rule exists |
6
+ | decisions/index.md | ADR registry |
7
+ | decisions/ADR-000-infrastructure.md | Stack choices and rationale |
@@ -0,0 +1,66 @@
1
+ # Team Workflow — Branch Protection & Review Policy
2
+
3
+ Referenced by `.github/CODEOWNERS`. This documents how the harness is operated by a
4
+ team: branch protection, who reviews what, and the merge rules. Adjust to your org.
5
+
6
+ ---
7
+
8
+ ## Branch model
9
+
10
+ - `main` is protected and always deployable. No direct pushes.
11
+ - All work lands via pull request from a short-lived branch:
12
+ `feat/<scope>`, `fix/<scope>`, `chore/<scope>`.
13
+ - One execution plan → one (or a few) PRs; one layer per commit where practical.
14
+
15
+ ## Branch protection rules (GitHub → Settings → Branches → `main`)
16
+
17
+ Enable:
18
+
19
+ - [ ] **Require a pull request before merging**
20
+ - [ ] **Require approvals** — at least **1** (2 for security-sensitive paths)
21
+ - [ ] **Require review from Code Owners** — activates `.github/CODEOWNERS`
22
+ - [ ] **Require status checks to pass** → select the **CI / verify** check
23
+ (typecheck · lint · format · test · build) and **Lighthouse CI** for UI PRs
24
+ - [ ] **Require branches to be up to date before merging**
25
+ - [ ] **Require conversation resolution before merging**
26
+ - [ ] **Do not allow bypassing the above** (applies to admins too)
27
+
28
+ ## Who reviews what (CODEOWNERS)
29
+
30
+ | Path | Owner | Why |
31
+ |---|---|---|
32
+ | `*` (default) | `@your-team/engineers` | Any engineer can review ordinary changes |
33
+ | `.claude/hooks/`, `src/lib/env.ts`, `src/lib/api-client.ts`, `src/features/auth/`, `app/api/`, `next.config.ts` | `@your-team/leads` | Security-sensitive: auth, token handling, env, headers |
34
+ | `src/types/api.generated.ts` | `@your-team/leads` | Contract drift / accidental hand-edit (file is generated) |
35
+ | `.github/workflows/`, `Dockerfile` | `@your-team/platform` | CI/CD and container surface |
36
+
37
+ > Replace the placeholder team slugs in `CODEOWNERS` with real GitHub teams/usernames,
38
+ > then tick "Require review from Code Owners" above. Until then they are inert.
39
+
40
+ ## Approve vs merge
41
+
42
+ - **Approve**: any code owner for the touched paths.
43
+ - **Merge**: the PR author after all required approvals + green checks, using
44
+ **Squash and merge**. The squash title must follow conventional commits
45
+ (`feat(scope): …`) — enforced locally by the commit-msg hook and reviewed against
46
+ the PR template.
47
+
48
+ ## Local quality gates (run before you push)
49
+
50
+ The harness enforces these automatically; this is what runs and when:
51
+
52
+ | When | What | How |
53
+ |---|---|---|
54
+ | On save (optional) | format + eslint | editor / `npm run format` |
55
+ | On `git commit` | eslint --fix + prettier on staged files | Husky `pre-commit` → `lint-staged` |
56
+ | On `/build-layer` | full layer gate (PASS/FAIL) | `gate-checker` agent |
57
+ | On PR | typecheck, lint, format check, tests+coverage, build | `.github/workflows/ci.yml` |
58
+ | On UI PR | Core Web Vitals budget | `.github/workflows/lighthouse.yml` |
59
+
60
+ ## Definition of done for a PR
61
+
62
+ - Gate is green (`/validate-layer` passes locally).
63
+ - CI is green.
64
+ - PR template fully checked, including the **cross-user isolation test** for any new
65
+ user-owned resource.
66
+ - An ADR exists for any non-obvious decision (`docs/design-docs/decisions/`).
@@ -0,0 +1,19 @@
1
+ # Technical Debt Tracker
2
+
3
+ ## Severity
4
+ | Level | Fix by |
5
+ |---|---|
6
+ | P0 | Immediately — security/XSS/token exposure |
7
+ | P1 | Within 2 sprints — blocks features or causes bugs |
8
+ | P2 | Within quarter — degrades quality or DX |
9
+ | P3 | When in area — code smell |
10
+
11
+ ## Open Debt
12
+ | ID | Severity | Area | Description | Created By | Date |
13
+ |---|---|---|---|---|---|
14
+ | *(none yet)* | — | — | — | — | — |
15
+
16
+ ## Resolved Debt
17
+ | ID | Description | Resolved By | Date |
18
+ |---|---|---|---|
19
+ | *(none yet)* | — | — | — |
File without changes
@@ -0,0 +1,59 @@
1
+ # Product Roadmap (Frontend)
2
+
3
+ **Product:** *(name)* · **Brief:** *(one-line, or link to the brief)* · **Last updated:** *(YYYY-MM-DD)*
4
+ **Walking skeleton:** *(SPEC-001 — login + app shell + one auth-gated route that fetches via the generated client; build first)*
5
+
6
+ > LIVING document — the altitude ABOVE specs. `/write-roadmap` writes it from the product brief
7
+ > + the backend `openapi.json`. `/write-spec` reads it to pick the next spec (one whose
8
+ > `Implements` backend spec is SHIPPED) and flips a row's **Spec ID** + **Status** as specs are
9
+ > created. Update in place; never delete history.
10
+ >
11
+ > This is NOT a mirror of the backend roadmap — it re-decomposes the product along **frontend
12
+ > axes** (screens, flows, personas, real-time). The OpenAPI is the *contract*, not the roadmap:
13
+ > one screen composes many endpoints, and many endpoints have no UI.
14
+
15
+ ---
16
+
17
+ ## Feature Areas & Personas
18
+
19
+ | Feature Area | Persona(s) | What the user does here |
20
+ |---|---|---|
21
+ | *(none yet)* | — | — |
22
+
23
+ > Personas (e.g. agent / supervisor / admin) are often different surfaces over the same API.
24
+
25
+ ---
26
+
27
+ ## Spec Roadmap (dependency-ordered)
28
+
29
+ | Order | Spec ID | Name | Feature Area | Implements (backend SPEC/domain) | Depends On | Skeleton | Status |
30
+ |---|---|---|---|---|---|---|---|
31
+ | *(none yet)* | — | — | — | — | — | — | — |
32
+
33
+ > `Spec ID` is `—` until `/write-spec` creates the file and assigns the real number.
34
+ > `Implements` = the backend spec/domain this UI consumes; a row is only **buildable** once that
35
+ > backend spec is SHIPPED. `Depends On` references other *frontend* rows. Exactly one row is the
36
+ > `✅ yes` skeleton, and it depends on nothing.
37
+
38
+ ---
39
+
40
+ ## Build Sequence Rationale
41
+
42
+ 1. *(walking skeleton — why first: proves auth + app shell + generated client + TanStack Query, and the WS client for a real-time product)*
43
+ 2. *(shared design-system / layout / real-time client — what it unblocks)*
44
+ 3. *(first persona surface, gated on its backend specs being shipped)*
45
+
46
+ ---
47
+
48
+ ## Roadmap Statuses
49
+
50
+ | Status | Meaning |
51
+ |---|---|
52
+ | NOT_STARTED | On the roadmap, no spec file yet |
53
+ | BLOCKED | Backend spec it `Implements` is not SHIPPED yet |
54
+ | DRAFT | `/write-spec` wrote a SPEC-XXX (in `draft/`) |
55
+ | READY | Spec approved — plannable |
56
+ | PLANNED | `/write-plan` created a plan |
57
+ | IN_PROGRESS | Being built |
58
+ | SHIPPED | Complete and live |
59
+ | CANCELLED | Removed from the roadmap |
@@ -0,0 +1,18 @@
1
+ # Product Specs Index
2
+
3
+ > Whole-product decomposition (feature areas → dependency-ordered specs, each gated on the backend
4
+ > spec it implements) lives in [`ROADMAP.md`](ROADMAP.md). `/write-spec` fills this index per spec.
5
+
6
+ | ID | Name | Status | Plan | Created |
7
+ |---|---|---|---|---|
8
+ | *(no specs yet)* | — | — | — | — |
9
+
10
+ ## Statuses
11
+ | Status | Meaning |
12
+ |---|---|
13
+ | DRAFT | Written, not reviewed |
14
+ | READY | Approved — plannable |
15
+ | PLANNED | Plan created |
16
+ | IN_PROGRESS | Being built |
17
+ | SHIPPED | Complete and live |
18
+ | CANCELLED | Not being built |
@@ -0,0 +1,150 @@
1
+ // eslint.config.mjs — committed by the harness; OVERRIDES the create-next-app default
2
+ // (the park-and-restore in /infra-setup restores this on top of the generated one).
3
+ // This is what makes the layer-import matrix and the "no direct fetch / no process.env"
4
+ // rules MECHANICAL — `npm run lint` (= `eslint .`) fails CI on a violation, instead of
5
+ // the rules only living in prose. Mirrors .claude/rules/architecture.md.
6
+ //
7
+ // Uses the Next 16+ native flat-config imports (eslint-config-next/core-web-vitals),
8
+ // NOT the legacy FlatCompat bridge — that bridge crashes against eslint-config-next 16.
9
+ import { defineConfig, globalIgnores } from 'eslint/config'
10
+ import nextVitals from 'eslint-config-next/core-web-vitals'
11
+ import nextTs from 'eslint-config-next/typescript'
12
+ import eslintConfigPrettier from 'eslint-config-prettier'
13
+
14
+ // Direct fetch() is forbidden outside the hooks layer (call the API through a hook).
15
+ const noFetch = {
16
+ selector: "CallExpression[callee.name='fetch']",
17
+ message: 'Direct fetch() is forbidden here — call the API through a hook in src/hooks/.',
18
+ }
19
+ // process.env is forbidden outside src/lib/ (env.ts is the single validated boundary).
20
+ const noProcessEnv = {
21
+ selector: "MemberExpression[object.name='process'][property.name='env']",
22
+ message: 'process.env is only allowed in src/lib/ — read validated env from src/lib/env.ts.',
23
+ }
24
+
25
+ const eslintConfig = defineConfig([
26
+ ...nextVitals,
27
+ ...nextTs,
28
+
29
+ globalIgnores([
30
+ '.next/**',
31
+ 'node_modules/**',
32
+ 'coverage/**',
33
+ 'playwright-report/**',
34
+ 'next-env.d.ts',
35
+ 'src/types/api.generated.ts',
36
+ 'src/components/ui/**',
37
+ 'tests/load/**', // k6 scripts run in the k6 runtime, not linted as app code
38
+ ]),
39
+
40
+ // Harness-wide rules
41
+ {
42
+ rules: {
43
+ 'no-console': ['warn', { allow: ['warn', 'error'] }],
44
+ },
45
+ },
46
+
47
+ // The structured logger IS the sanctioned console boundary — allow all console here.
48
+ {
49
+ files: ['src/lib/logger.ts'],
50
+ rules: { 'no-console': 'off' },
51
+ },
52
+
53
+ // ── Layer import boundaries (the matrix in .claude/rules/architecture.md) ──
54
+ // Each block's `files` glob is a distinct directory, so no file matches two
55
+ // no-restricted-imports blocks (flat config REPLACES rules across blocks).
56
+ {
57
+ files: ['src/types/**/*.{ts,tsx}'],
58
+ rules: {
59
+ 'no-restricted-imports': [
60
+ 'error',
61
+ { patterns: ['@/lib/*', '@/hooks/*', '@/features/*', '@/store/*', '@/components/*', '@/utils/*'] },
62
+ ],
63
+ },
64
+ },
65
+ {
66
+ files: ['src/utils/**/*.{ts,tsx}'],
67
+ rules: {
68
+ 'no-restricted-imports': [
69
+ 'error',
70
+ { patterns: ['@/lib/*', '@/hooks/*', '@/features/*', '@/store/*', '@/components/*'] },
71
+ ],
72
+ },
73
+ },
74
+ {
75
+ files: ['src/lib/**/*.{ts,tsx}'],
76
+ rules: {
77
+ 'no-restricted-imports': [
78
+ 'error',
79
+ { patterns: ['@/hooks/*', '@/features/*', '@/store/*', '@/components/*'] },
80
+ ],
81
+ },
82
+ },
83
+ {
84
+ files: ['src/store/**/*.{ts,tsx}'],
85
+ rules: {
86
+ 'no-restricted-imports': [
87
+ 'error',
88
+ { patterns: ['@/lib/*', '@/hooks/*', '@/features/*', '@/components/*'] },
89
+ ],
90
+ },
91
+ },
92
+ {
93
+ files: ['src/hooks/**/*.{ts,tsx}'],
94
+ rules: {
95
+ 'no-restricted-imports': ['error', { patterns: ['@/features/*', '@/components/*'] }],
96
+ },
97
+ },
98
+ {
99
+ files: ['src/components/**/*.{ts,tsx}'],
100
+ rules: {
101
+ 'no-restricted-imports': [
102
+ 'error',
103
+ { patterns: ['@/lib/*', '@/hooks/*', '@/features/*', '@/store/*'] },
104
+ ],
105
+ },
106
+ },
107
+
108
+ // ── App router pages/layouts: render features, never call data hooks directly ──
109
+ {
110
+ files: ['src/app/**/page.tsx', 'src/app/**/layout.tsx', 'app/**/page.tsx', 'app/**/layout.tsx'],
111
+ rules: { 'no-restricted-imports': ['error', { patterns: ['@/hooks/*', '@/store/*'] }] },
112
+ },
113
+
114
+ // ── no-restricted-syntax: fetch + process.env ──
115
+ // NOTE: ESLint flat config REPLACES (does not merge) a rule's value across matching
116
+ // config objects — last match wins. So every file that needs `no-restricted-syntax`
117
+ // must get ALL its selectors in a SINGLE block, or earlier selectors are lost.
118
+ //
119
+ // Render layers (features/components/app): forbid BOTH direct fetch() AND process.env.
120
+ {
121
+ files: [
122
+ 'src/features/**/*.{ts,tsx}',
123
+ 'src/components/**/*.{ts,tsx}',
124
+ 'src/app/**/*.{ts,tsx}',
125
+ 'app/**/*.{ts,tsx}',
126
+ ],
127
+ rules: { 'no-restricted-syntax': ['error', noFetch, noProcessEnv] },
128
+ },
129
+ // Non-render src layers (hooks/store/utils): forbid process.env only.
130
+ // (fetch isn't restricted in hooks — that's where the typed api-client lives.)
131
+ {
132
+ files: ['src/hooks/**/*.{ts,tsx}', 'src/store/**/*.{ts,tsx}', 'src/utils/**/*.{ts,tsx}'],
133
+ rules: { 'no-restricted-syntax': ['error', noProcessEnv] },
134
+ },
135
+
136
+ // ── Tests cross layers by design — relax the boundary + console rules there ──
137
+ {
138
+ files: ['tests/**/*.{ts,tsx}', 'src/**/*.test.{ts,tsx}'],
139
+ rules: {
140
+ 'no-restricted-imports': 'off',
141
+ 'no-restricted-syntax': 'off',
142
+ 'no-console': 'off',
143
+ },
144
+ },
145
+
146
+ // Prettier LAST — disable formatting rules that fight Prettier.
147
+ eslintConfigPrettier,
148
+ ])
149
+
150
+ export default eslintConfig