@skyf0xx/hedgehog 2.0.13 → 3.0.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 (35) hide show
  1. package/README.md +9 -3
  2. package/bin/cli.mjs +463 -19
  3. package/package.json +3 -2
  4. package/src/agents/backend-eng.md +56 -45
  5. package/src/agents/bootstrap.md +67 -73
  6. package/src/agents/front-end-eng.md +31 -18
  7. package/src/agents/planner.md +163 -84
  8. package/src/agents/reviewer.md +4 -4
  9. package/src/agents/tweaker.md +138 -106
  10. package/src/db/core.mjs +141 -0
  11. package/src/db/friction.mjs +25 -0
  12. package/src/db/init.mjs +35 -0
  13. package/src/db/intent.mjs +101 -0
  14. package/src/db/next.mjs +179 -0
  15. package/src/db/plan.mjs +222 -0
  16. package/src/db/schema.mjs +95 -0
  17. package/src/db/status.mjs +113 -0
  18. package/src/db/verify.mjs +286 -0
  19. package/src/db/why.mjs +97 -0
  20. package/src/golden-cores/full-stack-app/core.yaml +41 -0
  21. package/src/golden-cores/landing-page/core.yaml +41 -0
  22. package/src/skills/conventional-commits/SKILL.md +1 -1
  23. package/src/skills/hedgehog-bootstrap/SKILL.md +38 -41
  24. package/src/skills/hedgehog-bootstrap-full-stack-app-core/SKILL.md +8 -12
  25. package/src/skills/hedgehog-bootstrap-landing-page-core/SKILL.md +7 -9
  26. package/src/skills/hedgehog-core-design/SKILL.md +239 -0
  27. package/src/skills/hedgehog-landing-loop/SKILL.md +91 -57
  28. package/src/skills/hedgehog-loop/SKILL.md +109 -77
  29. package/src/skills/hedgehog-planning-intake/SKILL.md +72 -97
  30. package/src/templates/CLAUDE.core.full-stack-app.md +31 -24
  31. package/src/templates/CLAUDE.core.landing-page.md +11 -7
  32. package/src/templates/CLAUDE.md +46 -38
  33. package/src/templates/TODO.core.full-stack-app.md +0 -51
  34. package/src/templates/TODO.core.landing-page.md +0 -31
  35. package/src/templates/TODO.md +0 -12
@@ -1,27 +1,34 @@
1
1
  ---
2
2
  name: hedgehog-loop
3
- description: Use for every unit of work once a Hedgehog project is bootstrapped — building one Order step (schema, contract, repository, service, controller, hook, screen), gating it, committing it, and checking it off TODO.md. Triggers on "next step", "build this module", "what's next", or the start of any work session on a bootstrapped project. Also covers the Correction Protocol for fixing a wrong upstream step.
3
+ description: Use for every unit of work once a Hedgehog project is bootstrapped — building one layer (schema, contract, repository, service, controller, hook, screen) per module, gated by `hedgehog verify` and committed one layer at a time. Triggers on "next step", "build this module", "what's next", or the start of any work session on a bootstrapped project. Also covers the Correction Protocol for fixing a wrong upstream step.
4
4
  ---
5
5
 
6
6
  # Hedgehog Loop
7
7
 
8
- The operating loop for a bootstrapped Hedgehog project: pick the next step,
9
- build it, gate it, commit it, check it off. `TODO.md` at repo root is the
10
- live list — read it before starting. It's thin: a context blurb plus a
11
- checklist mirroring the phase/step structure below. Checked/unchecked is
12
- its only state.
8
+ The operating loop for a bootstrapped Hedgehog project: `hedgehog next`
9
+ emits the packet for one ready layer, build it, `hedgehog verify` gates
10
+ and commits it. The build graph (`.hedgehog/hedgehog.db`) is the live
11
+ list — query it via `hedgehog status`/`hedgehog next`, never re-derive
12
+ state from prose. The step tables below mirror
13
+ `src/golden-cores/full-stack-app/core.yaml`, already the source of truth
14
+ for layer order, scope, and verify command per layer — read the tables
15
+ for the human-readable shape, trust the YAML (and the packet `hedgehog
16
+ next` emits from it) as the authoritative one if they ever seem to
17
+ disagree.
13
18
 
14
19
  ## Determine phase
15
20
 
16
21
  Before touching code, know which phase applies to the module in scope:
17
22
 
18
23
  - **Phase A** — building/extending the backend. Every module in scope
19
- needs schema → contract → repository → service → controller (→ queue)
20
- before Phase B starts for any of them.
24
+ needs schema → contract → repository → service → controller before
25
+ Phase B starts for any of them.
21
26
  - **Phase B** — Phase A is closed for the module. Build hooks and screens.
22
27
 
23
- Check `TODO.md`, or the commit log for `feat(<module>): api` commits. No
24
- such commit means the module is in Phase A.
28
+ Check `hedgehog status` (or `hedgehog why <path>` for a specific file),
29
+ or the commit log for `feat(<module>): api` commits. No such commit (and
30
+ no `controller` task `complete` for that module) means the module is in
31
+ Phase A.
25
32
 
26
33
  ## The Domain Module Pattern
27
34
 
@@ -56,13 +63,16 @@ hook (TanStack Query) — Phase B only
56
63
  ```
57
64
 
58
65
  Plus, when an operation needs async **and the Queue add-on is on for this
59
- project** (check `TODO.md`'s `## Add-ons` block): **queue = port +
66
+ project** (check `.hedgehog/addons.yaml`'s `queue.on`): **queue = port +
60
67
  BullMQ adapter**, same port/adapter shape as the repository. The service
61
- imports only ports. If the Queue add-on is off, there's no `apps/worker`
62
- and no queue step, full stop — an operation that seems to want async
63
- processing on a Queue-off project is a signal to revisit that add-on
64
- decision with `planner`, not to build a one-off queue outside the
65
- add-on's scaffolding.
68
+ imports only ports. Queue is one-time project infra, not a compiled
69
+ layer — `full-stack-app/core.yaml` has no `queue` layer, so this step has
70
+ no `hedgehog verify` gate of its own; build it as part of the
71
+ `controller` layer's packet, verified by that layer's own check. If the
72
+ Queue add-on is off, there's no `apps/worker` and no queue step, full
73
+ stop — an operation that seems to want async processing on a Queue-off
74
+ project is a signal to revisit that add-on decision with `planner`, not
75
+ to build a one-off queue outside the add-on's scaffolding.
66
76
 
67
77
  Standard Nx generators (`@nx/nest`, `@nx/next`, `@nx/expo`, `@nx/js`)
68
78
  scaffold the app/lib shell. Each step's actual content (schema, contract,
@@ -72,58 +82,76 @@ sequence.
72
82
  ## Domain Module — Backend Steps (Phase A, every module in scope)
73
83
 
74
84
  A horizontal pass across the whole backend — every module goes through
75
- these before any module gets a hook or screen. Delegate each module's
76
- Phase A steps to the `backend-eng` agent — it builds one step, gates it,
77
- commits it, and reports back.
85
+ these before any module gets a hook or screen. Each row is one compiled
86
+ layer in `full-stack-app/core.yaml`; delegate each module's Phase A
87
+ layers to the `backend-eng` agent, one `hedgehog next` packet at a time —
88
+ it builds the layer, `hedgehog verify` gates and commits it.
78
89
 
79
- | # | Step | Lives in | Commit |
90
+ | # | Layer | Lives in | Commit |
80
91
  |---|---|---|---|
81
- | 1 | Schema | `packages/db` (Drizzle) | `feat(<module>): schema` |
82
- | 2 | Contract | `packages/contracts` (Zod via `drizzle-zod` + ts-rest) | `feat(<module>): contract` |
83
- | 3 | Repository | `libs/<module>/repository` (port + Drizzle adapter) | `feat(<module>): repository` |
84
- | 4 | Service | `libs/<module>/service` (domain logic — imports only ports) | `feat(<module>): service` |
85
- | 5 | Controller | `apps/api` (thin HTTP, wires contract → service) | `feat(<module>): api` |
86
- | 5a | Queue *(if needed, and only if the Queue add-on is on)* | `apps/worker` (port + BullMQ adapter) | `feat(<module>): queue` |
92
+ | 1 | `schema` | `packages/db` (Drizzle) | `feat(<module>): schema` |
93
+ | 2 | `contract` | `packages/contracts` (Zod via `drizzle-zod` + ts-rest) | `feat(<module>): contract` |
94
+ | 3 | `repository` | `libs/<module>/repository` (port + Drizzle adapter) | `feat(<module>): repository` |
95
+ | 4 | `service` | `libs/<module>/service` (domain logic — imports only ports) | `feat(<module>): service` |
96
+ | 5 | `controller` | `apps/api` (thin HTTP, wires contract → service; bundles Queue infra, see above, if that add-on is on and this module needs it) | `feat(<module>): api` |
87
97
 
88
- Repeat 1–5(a) per module in scope. The API is complete, typed, and
89
- callable (Postman/curl/contract tests) before frontend work starts.
98
+ Repeat 1–5 per module in scope, via `hedgehog next`/`hedgehog verify`.
99
+ The API is complete, typed, and callable (Postman/curl/contract tests)
100
+ before frontend work starts.
90
101
 
91
102
  ## Domain Module — Frontend Steps (Phase B, after Phase A closes for the module)
92
103
 
93
- | # | Step | Lives in | Commit |
104
+ | # | Layer | Lives in | Commit |
94
105
  |---|---|---|---|
95
- | 6 | Hook | `packages/hooks` (TanStack Query) | `feat(<module>): hooks` |
96
- | 6a | UX rationale | `docs/design/<module>.md`, `ux-planner` agent | bundled into step 7's commit |
97
- | 7 | Screen | `apps/web` and/or `apps/mobile` | `feat(<module>): screen-web` / `feat(<module>): screen-mobile` |
106
+ | 6 | `hook` | `packages/hooks` (TanStack Query) | `feat(<module>): hooks` |
107
+ | 6a | UX rationale | `docs/design/<module>.md`, `ux-planner` agent | bundled into layer 7's commit |
108
+ | 7 | `screen` | `apps/web` and/or `apps/mobile` | `feat(<module>): screen-web` / `feat(<module>): screen-mobile` |
98
109
 
99
110
  Phase B starts once Phase A is done for the scope. The frontend is a pure
100
- consumer of an already-finished API. Delegate each module's Phase B steps
101
- to the `front-end-eng` agent, same reasoning as `backend-eng` for Phase A
102
- — one step at a time, in its own context. Step 6a is where "how it should
103
- feel" gets decided — once per module, after the hook exists and before
104
- `front-end-eng` starts the screen — via `ux-planner`, starting from whatever
105
- `planner` filed in `docs/design/<module>-notes.md` at planning intake. Its first run
106
- for a module also signals to the user that Phase B has started, and is the
107
- point a mockup, screenshot, or export (Google Stitch, Figma) can be handed
108
- over. It writes `docs/design/<module>.md`, not its own step commit;
109
- `TODO.md` tracks only hooks/screen-web/screen-mobile per module.
111
+ consumer of an already-finished API. Delegate each module's Phase B
112
+ layers to the `front-end-eng` agent, same reasoning as `backend-eng` for
113
+ Phase A — one `hedgehog next` packet at a time, in its own context. Step
114
+ 6a is where "how it should feel" gets decided — once per module, after
115
+ the `hook` layer's task is `complete` and before `front-end-eng` starts
116
+ the `screen` layer — via `ux-planner`, starting from whatever `planner`
117
+ filed in `docs/design/<module>-notes.md` at planning intake, or the raw
118
+ UX spec directly if that file is absent. Its first run for a module also
119
+ signals to the user that Phase B has started, and is the point a mockup,
120
+ screenshot, or export (Google Stitch, Figma) can be handed over. It
121
+ writes `docs/design/<module>.md`, not its own compiled layer — the
122
+ `screen` layer's `hedgehog verify` is what gates and commits it.
110
123
 
111
124
  ## The Loop (every unit of work)
112
125
 
113
- 1. **Pick the next step** per the tables above, from `TODO.md`. One step
114
- at a time, in order.
115
- 2. **Check the gate.** The prior step compiles and passes tests first.
116
- 3. **Delegate exactly one step** to `backend-eng` (Phase A) or
117
- `front-end-eng` (Phase B) — one schema, one contract, one repository.
118
- 4. The agent **runs the gate on its own work**: typecheck, lint, test
119
- (mirrors lefthook, wired at bootstrap).
120
- 5. The agent **commits** using the exact Conventional Commit format above.
121
- 6. **Check off the line in `TODO.md`** once the agent reports the commit
122
- landed.
123
- 7. **Repeat**, one delegated step at a time.
124
-
125
- Each commit batches exactly one step, built right for what's known now; a
126
- wrong step is fixed forward later via the Correction Protocol.
126
+ 1. **Run `hedgehog next`.** It emits the task packet for one ready layer
127
+ (STATUS/WHY NOW/BLOCKED DOWNSTREAM/ALLOWED SCOPE/VERIFICATION) —
128
+ trust it: `hedgehog next` never emits a layer whose dependencies
129
+ aren't `complete`, so there's no separate gate check to run by hand.
130
+ 2. **Delegate the full packet** (not a step name) to `backend-eng`
131
+ (Phase A) or `front-end-eng` (Phase B) — one schema, one contract, one
132
+ repository, matching the packet's ALLOWED SCOPE.
133
+ 3. The agent **runs typecheck/lint/test on its own work** (mirrors
134
+ lefthook, wired at bootstrap) as a sanity check before reporting
135
+ back — necessary, not sufficient. The agent reports the work as done;
136
+ it does not move the task and does not commit.
137
+ 4. **Run `hedgehog verify <task-id>`.** It checks the touched files
138
+ against the packet's ALLOWED SCOPE, runs the layer's VERIFICATION
139
+ command, and on a pass writes the commit (the exact Conventional
140
+ Commit message from the tables above, plus the updated build graph)
141
+ and unlocks the next layer. On a scope violation or a failing check,
142
+ the task stays `implemented`/`failed` and nothing downstream unlocks —
143
+ fix it and re-run `hedgehog verify <task-id>`, don't hand-commit
144
+ around it.
145
+
146
+ A stalled task is not pickable by `hedgehog next`, so both `hedgehog
147
+ next` and `hedgehog status` list it under NEEDS ATTENTION with the
148
+ task id to re-verify. If `hedgehog next` reports the graph blocked,
149
+ fix that task — don't treat it as "nothing left to do."
150
+ 5. **Repeat** — `hedgehog next` again for the following layer.
151
+
152
+ Each `hedgehog verify` call commits exactly one layer, built right for
153
+ what's known now; a wrong layer is fixed forward later via the
154
+ Correction Protocol.
127
155
 
128
156
  ## Intra-step conventions
129
157
 
@@ -165,12 +193,14 @@ had to correct the same kind of mistake more than once, or user
165
193
  feedback implied something was wrong even without a direct correction
166
194
  (a preference stated once that, read plainly, means an earlier step
167
195
  missed something) — is signal worth keeping past this session, separate
168
- from the Correction Protocol that fixes it in the moment. Append one
169
- entry to `.hedgehog/friction.md` (create it if it doesn't exist) when
170
- that happens: what was tried, what went wrong or was implied, why if
171
- visible, and the commit/message it traces to. This is a log, not a todo
172
- list — don't let it block or slow the Loop; append and keep moving.
173
- `tweaker` reads it once the build reaches its Stop Condition.
196
+ from the Correction Protocol that fixes it in the moment. Log one entry
197
+ via `hedgehog friction add "<note>" [--task <task-id>]` when that
198
+ happens: what was tried, what went wrong or was implied, why if visible,
199
+ and the commit/message it traces to, all in the note text; pass `--task`
200
+ with the layer's task id when the friction traces to one. This is a log,
201
+ not a todo list — don't let it block or slow the Loop; log and keep
202
+ moving. `tweaker` reads it (via `hedgehog friction list`) once the build
203
+ reaches its Stop Condition.
174
204
 
175
205
  ## Correction Protocol
176
206
 
@@ -195,7 +225,8 @@ working-tree pass and needs splitting back into per-step commits.
195
225
 
196
226
  Before starting Phase B for a module, confirm:
197
227
 
198
- - A `feat(<module>): api` commit exists for that module.
228
+ - `hedgehog status` shows that module's `controller` task `complete`
229
+ (equivalently, a `feat(<module>): api` commit exists).
199
230
  - The contract is callable and typed (contract tests pass).
200
231
 
201
232
  Use the `reviewer` agent for this — it checks what the mechanical gate
@@ -210,10 +241,10 @@ boundary from planning intake (`planner`). If not, stop and ask.
210
241
  working, tested API before any hook or screen starts.
211
242
  - **Sequential within a phase.** A step starts once the one before it
212
243
  compiles and passes tests.
213
- - **Step 5a is conditional twice over** — only if the Queue add-on is on
214
- for this project at all (per `TODO.md`'s `## Add-ons` block), and even
215
- then only when a given operation genuinely needs async (long-running,
216
- retries, fan-out); the normal case has no queue.
244
+ - **Queue infra is conditional twice over** — only if the Queue add-on is
245
+ on for this project at all (per `.hedgehog/addons.yaml`'s `queue.on`),
246
+ and even then only when a given operation genuinely needs async
247
+ (long-running, retries, fan-out); the normal case has no queue.
217
248
  - **A wrong step gets fixed at its source** — the Correction Protocol, not
218
249
  a downstream workaround.
219
250
  - **Tests gate every commit** in the sequence.
@@ -226,16 +257,17 @@ boundary from planning intake (`planner`). If not, stop and ask.
226
257
 
227
258
  ## Stop Condition
228
259
 
229
- A build session ends when every module in scope has completed both Phase
230
- A and Phase B, or when scope is ambiguous enough that continuing means
231
- guessing — ask one question and wait.
260
+ A build session ends when `hedgehog status` shows every task for every
261
+ module in scope `complete` (Phase A and Phase B both closed), or when
262
+ scope is ambiguous enough that continuing means guessing — ask one
263
+ question and wait.
232
264
 
233
265
  On the former (a real build completion, not an ambiguity stop), offer a
234
266
  fresh-context handoff before doing anything else: tell the user the
235
- build is complete, that clearing context now costs nothing (`TODO.md`
236
- and the commit log hold everything), and that a `tweaker` session is the
237
- right next step for any adjustments — it starts clean, reviews
238
- `.hedgehog/friction.md` once for a possible discipline-improvement
239
- suggestion, and takes tweak requests one at a time from there. Don't
240
- start making tweaks in the current, already-large context; that's what
241
- the fresh session is for.
267
+ build is complete, that clearing context now costs nothing (the build
268
+ graph and the commit log hold everything), and that a `tweaker` session
269
+ is the right next step for any adjustments — it starts clean, reviews
270
+ the friction log (`hedgehog friction list`) once for a possible
271
+ discipline-improvement suggestion, and takes tweak requests one at a
272
+ time from there. Don't start making tweaks in the current, already-large
273
+ context; that's what the fresh session is for.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hedgehog-planning-intake
3
- description: Use once per project, at the start, on either core — Phase 0 (running the vendored BMAD-METHOD planning shelf) is shared by full-stack-app and landing-page alike; Phase 1 (mining BMAD's output into scope boundary/domain modules/the Add-ons decision) is full-stack-app's own procedure, run again on a scoped pass when new domain scope enters play. Invoked by the `planner` agent after Phase 0 core selection; don't run standalone. landing-page runs this skill's Phase 0, then mines the same archive through `hedgehog-landing-loop`'s own planning-intake section, that core's counterpart to this skill's Phase 1.
3
+ description: Use once per project, at the start, on either core — Phase 0 (running the vendored BMAD-METHOD planning shelf) is shared by full-stack-app and landing-page alike; Phase 1 (mining `04-prd.md` into intent records plus the Add-ons decision) is full-stack-app's own procedure, run again on a scoped pass when new domain scope enters play. Invoked by the `planner` agent after Phase 0 core selection; don't run standalone. landing-page runs this skill's Phase 0, then mines the same archive through `hedgehog-landing-loop`'s own planning-intake section, that core's counterpart to this skill's Phase 1.
4
4
  ---
5
5
 
6
6
  # Hedgehog Planning Intake
@@ -8,13 +8,12 @@ description: Use once per project, at the start, on either core — Phase 0 (run
8
8
  Turns a person's description of a problem into planning material, by
9
9
  running the vendored BMAD-METHOD planning shelf (Phase 0, shared by both
10
10
  cores) and mining its output. On full-stack-app that mining is this
11
- skill's own Phase 1, into scope boundary/domain modules/Add-ons; on
12
- landing-page it's `hedgehog-landing-loop`'s planning-intake section, into
13
- a subject/audience/job statement. This is the mechanics `planner` calls
14
- once its Phase 0 core-selection check has picked a core — the
15
- interpretive judgment (scope boundary, module split, Add-ons decision on
16
- full-stack-app; subject statement on landing-page; Confirm & Lock either
17
- way) belongs to `planner`; this skill (Phase 0, and Phase 1 on
11
+ skill's own Phase 1, into intent records written via `hedgehog intent
12
+ add`; on landing-page it's `hedgehog-landing-loop`'s planning-intake
13
+ section, into a subject/audience/job statement. This is the mechanics
14
+ `planner` calls once its Phase 0 core-selection check has picked a core —
15
+ the interpretive judgment (which Feature becomes which intent, Confirm &
16
+ Lock either way) belongs to `planner`; this skill (Phase 0, and Phase 1 on
18
17
  full-stack-app) and `hedgehog-landing-loop` (landing-page's own mining)
19
18
  are the fixed procedures that judgment runs inside.
20
19
 
@@ -73,86 +72,63 @@ relationship the commit log has to a merged PR.
73
72
  landing-page's counterpart to this Phase 1 is
74
73
  `hedgehog-landing-loop`'s own planning-intake section, run once Phase 0
75
74
  above completes: it mines the same `.hedgehog/BMAD/` archive into a
76
- subject/audience/job statement, in place of the scope boundary/domain
77
- modules/Add-ons decision this Phase 1 produces.
78
-
79
- Read `.hedgehog/BMAD/` once and do the interpretive work BMAD's docs
80
- don't do for you — none of BMAD's outputs contain a ready-made
81
- Auth/Queue/Mobile toggle or a module-ownership/FK table; the PRD's
82
- Glossary is the closest thing, but it's vocabulary-shaped prose, not a
83
- decision table:
84
-
85
- 1. **Scope boundary** — derive from the brief's Scope section plus the
86
- PRD's Glossary/Features. In scope: what the elicited material actually
87
- called for. Out of scope: anything the brief or PRD flagged as
88
- deferred, painful-but-not-now, or explicitly excluded.
89
- 2. **Domain modules** — derive from the PRD's Glossary (entity,
90
- relationships, cardinality): one table = one module, same rule as
91
- Hedgehog has always used. A cluster with its own lifecycle, referenced
92
- by other things, is a candidate module; a thing mentioned only as a
93
- property of another isn't.
94
- 3. **Cross-module references** — from the Glossary's relationships/
95
- cardinality, identify which module's schema holds the FK, so build
96
- order between modules is clear before anyone writes a schema.
97
- 4. **Add-ons decision** (Auth, Queue, Mobile) — check BMAD's docs (brief,
98
- PRD, UX spec) for each trigger first:
99
- - **Auth** — on if the material describes accounts, logins, or
100
- per-user/per-account data.
101
- - **Queue** — on if at least one described operation is genuinely
102
- long-running, needs retries, or fans out.
103
- - **Mobile** — on if the material explicitly wants a mobile app
104
- alongside or instead of web.
105
-
106
- Infer first, gap-fill second — this is not a second full interview.
107
- For any add-on the text leaves genuinely unresolved (not mentioned
108
- either way), ask the user directly, the same direct-question posture
109
- as an ambiguous scope boundary: "does this need user accounts/login,
110
- or is it just for you?", "is anything here a background job, or is it
111
- all instant reads and writes?", "web only, or mobile too?" A "no" is a
112
- resolved answer, not a gap. Never default an add-on on or off without
113
- either a concrete trigger in BMAD's docs or a direct answer — an
114
- unasked add-on question is a guess.
115
- 5. **Run Confirm & Lock** (below) before writing anything.
116
- 6. **Write `TODO.md`** — the checklist mirroring Bootstrap, Phase A, and
117
- Phase B steps per module and add-on in scope, plus the `## Add-ons`
118
- block (see "The Add-ons block" below).
119
- 7. **File `docs/design/<module>-notes.md` per module** — sourced from
120
- `.hedgehog/BMAD/05-ux-spec/EXPERIENCE.md` (information architecture,
121
- states, flows) and `DESIGN.md` (visual identity): file each module's
122
- slice into its own notes file, same fixed filename pattern, same
123
- "every module gets one, even if empty" rule as always — a module with
124
- no UX-spec material yet still gets a `docs/design/<module>-notes.md`
125
- stating that plainly, not a missing file. `ux-planner` reads this file
126
- as raw screen/flow material at that module's Phase B.
127
- 8. **Fill root `CLAUDE.md`'s `{{PROJECT_NAME}}` and `{{PROJECT_SUMMARY}}`
75
+ subject/audience/job statement, in place of the intents this Phase 1
76
+ produces.
77
+
78
+ Read `.hedgehog/BMAD/04-prd.md` only — §3 Glossary and §4 Features.
79
+ Nothing else in `.hedgehog/BMAD/` is read again: brainstorming, brief,
80
+ PR-FAQ, and deep-recon existed to produce a good PRD, and the UX spec is
81
+ read later, once per module, by `ux-planner`, not by this mining pass.
82
+ Mining is mechanical, not interpretive — one graph row per PRD element,
83
+ per this table:
84
+
85
+ | PRD element | Graph row |
86
+ | --- | --- |
87
+ | §4 Feature | one `intents` row — the feature's description already reads as `goal` + `outcome` |
88
+ | FR "Consequences (testable)" item | `requirements` row, `kind='acceptance'` |
89
+ | Feature-specific NFR / cross-cutting rule | `requirements` row, `kind='rule'` |
90
+ | §3 Glossary relationship/cardinality | `intent_dependencies` row (the referencing feature's intent depends on the referenced feature's intent) |
91
+
92
+ Procedure:
93
+
94
+ 1. **Walk §4 Features top to bottom.** For each Feature, that's one
95
+ intent: `id` a short kebab-case slug of the Feature's name, `goal` and
96
+ `outcome` drawn directly from the Feature's description (split the
97
+ description across the two if it names both the capability and the
98
+ result; otherwise the same sentence can serve both).
99
+ 2. **Walk that Feature's FRs.** Each FR's "Consequences (testable)" list
100
+ items become that intent's `requirements` with `kind='acceptance'`,
101
+ one per item, verbatim or lightly tightened — no rephrasing that
102
+ changes what's being tested.
103
+ 3. **Collect any NFR or cross-cutting rule scoped to that Feature**
104
+ (not a project-wide NFR with no single owning Feature) as a
105
+ `requirements` row with `kind='rule'` on that intent.
106
+ 4. **Walk §3 Glossary relationships and cardinality.** Each relationship
107
+ between two entities that belong to different Features' intents
108
+ becomes one `intent_dependencies` row: the intent for the entity
109
+ holding the foreign key depends on the intent for the entity it
110
+ references. A relationship entirely inside one Feature's entities
111
+ produces no row — it's already the same intent.
112
+ 5. **Run the Add-ons decision** (`planner`'s own judgment call — see that
113
+ agent's "The Add-ons decision") for Auth, Queue, and Mobile.
114
+ 6. **Run Confirm & Lock** (below) before writing anything.
115
+ 7. **Write each intent via `hedgehog intent add`** — one invocation per
116
+ Feature: `--acceptance` per row from step 2, `--rule` per row from step
117
+ 3, `--depends-on` per row from step 4, or an equivalent `--file
118
+ <path.json>` batch matching the same shape (`{ id, goal, outcome,
119
+ rules, acceptance, depends_on, priority }`). This is Phase 1's only
120
+ write to the build graph.
121
+ 8. **Write `.hedgehog/addons.yaml`** with the Add-ons decision from step 5.
122
+ 9. **Fill root `CLAUDE.md`'s `{{PROJECT_NAME}}` and `{{PROJECT_SUMMARY}}`
128
123
  placeholders**, first run only, then delete the installer's HTML
129
124
  comment block at the top of that file. Leave every other line
130
125
  untouched.
131
126
 
132
- On a later run (new scope entering play), skip steps 4 and 8 unless new
133
- scope genuinely changes an add-on trigger (e.g. accounts get added where
134
- there were none) or the project's identity itself changed — append new
135
- module sections to `TODO.md` only, never touch an existing module's
136
- checked boxes or reorder modules already in progress.
137
-
138
- ## The Add-ons block
139
-
140
- `TODO.md` carries the Add-ons decision directly — no side-channel
141
- document. Write a short, fixed-format `## Add-ons` block into `TODO.md`:
142
-
143
- ```
144
- ## Add-ons
145
- - Auth: on — accounts/login in scope
146
- - Queue: off — no long-running ops
147
- - Mobile: off — not requested
148
- ```
149
-
150
- Each line: the add-on, on/off, a one-line reason it landed there. This is
151
- the single stable, machine-checkable field every downstream check reads
152
- — `hedgehog-bootstrap`, `bootstrap`, `hedgehog-loop`, and `reviewer` all
153
- check `TODO.md`'s `## Add-ons` block, not any other file. An absent
154
- `## Add-ons` block reads as "never decided," not "decided off" — those
155
- two are distinct and downstream checks treat them differently.
127
+ On a later run (new scope entering play), skip steps 8 and 9 unless new
128
+ scope genuinely changes an add-on trigger or the project's identity
129
+ itself changed — mine only the PRD's new or changed Features into
130
+ additional `hedgehog intent add` calls, never re-add or edit an intent
131
+ already in the graph.
156
132
 
157
133
  ## Confirm & Lock
158
134
 
@@ -162,25 +138,24 @@ stops being true, so it's a hard stop, not a recap in passing.
162
138
 
163
139
  🔒 **Confirm & Lock**. Show, in full, not condensed:
164
140
 
165
- - The scope boundary (in / out), sourced from the brief + PRD.
141
+ - Each intent about to be added: `id`, `goal`, `outcome`, its
142
+ `requirements` (rule/acceptance), and its `depends_on` list.
166
143
  - The Add-ons decision (Auth / Queue / Mobile, each explicitly on or
167
- off, with the one-line reason — from BMAD's docs or a direct answer).
168
- - The domain vocabulary / module list, in build order, with any
169
- cross-module FK dependencies flagged.
144
+ off, with the one-line reason).
170
145
  - Which BMAD skills ran and where their output lives
171
146
  (`.hedgehog/BMAD/`).
172
147
 
173
148
  Then state plainly what happens on confirmation, before it happens:
174
149
 
175
- > This locks in `TODO.md` (with the `## Add-ons` block) and
176
- > `docs/design/<module>-notes.md` per module, commits them in one pass
177
- > (`chore(planning): intake`), and hands off to the `bootstrap` agent to
178
- > scaffold the workspace and whichever add-ons are on. Phase A build
179
- > (schema first) starts on the first module once that closes. Anything
180
- > wrong or missing — say so now; it's a normal edit before this point,
181
- > and a Correction Protocol entry after. Confirm to proceed, or tell me
182
- > what to change.
150
+ > This writes each intent above via `hedgehog intent add` and the
151
+ > Add-ons decision to `.hedgehog/addons.yaml`, then shows the compiled
152
+ > graph with `hedgehog status`. Phase A build (schema first) starts on
153
+ > the first ready task once that closes. Anything wrong or missing — say
154
+ > so now; it's a normal edit before this point, and a Correction Protocol
155
+ > entry after. Confirm to proceed, or tell me what to change.
183
156
 
184
157
  Wait for an explicit go-ahead. A revision here is just another mining
185
158
  pass — update the draft, re-run this stage, don't write anything until
186
- the confirmation holds.
159
+ the confirmation holds. Once confirmed, after every `hedgehog intent add`
160
+ call lands, run `hedgehog status` and show it in full as the graph's
161
+ confirmation view.
@@ -4,18 +4,20 @@ Backend-first, schema → contract → repository → service → controller, th
4
4
  hook → UX rationale → screen, per domain module. See `.hedgehog/BMAD/` for
5
5
  the archival planning intake output — BMAD-METHOD's brainstorming, brief,
6
6
  PRD, and UX spec, written once by `planner` and never edited after.
7
- `TODO.md` also carries this core's `## Add-ons` block (Auth/Queue/Mobile,
8
- each on or off) — check it before assuming any add-on's infra exists.
7
+ `.hedgehog/addons.yaml` carries this core's Add-ons decision
8
+ (Auth/Queue/Mobile, each on or off) — check it before assuming any
9
+ add-on's infra exists.
9
10
 
10
11
  ### The skills — invoke these, don't improvise
11
12
 
12
13
  The discipline is packaged as skills. Use them; don't reconstruct their
13
14
  steps from memory:
14
15
 
15
- - **`hedgehog-loop`** — every unit of work once bootstrapped: pick the
16
- next step from `TODO.md`, build exactly one, gate it, commit it, check
17
- it off. Also holds the Correction Protocol for fixing a wrong upstream
18
- step. Invoke it at the start of any build session and for "what's next".
16
+ - **`hedgehog-loop`** — every unit of work once bootstrapped: `hedgehog
17
+ next` emits the packet for one ready layer, build exactly one, gate it
18
+ via `hedgehog verify`, which commits it on a pass. Also holds the
19
+ Correction Protocol for fixing a wrong upstream step. Invoke it at the
20
+ start of any build session and for "what's next".
19
21
  - **`hedgehog-bootstrap`** — run **once**, at project start, to scaffold
20
22
  the core stack, the enforcement config, and whichever add-ons (Auth,
21
23
  Queue, Mobile) planning intake turned on. Skip if `nx.json` already
@@ -28,22 +30,25 @@ steps from memory:
28
30
 
29
31
  - **`planner`** — planning intake (which core applies, then
30
32
  `hedgehog-planning-intake`'s BMAD-METHOD brainstorming/brief/PRD/UX-spec
31
- shelf, mined into scope boundary, the Add-ons decision, and domain
33
+ shelf, mined into intent records, the Add-ons decision, and domain
32
34
  vocabulary) at project start, and module scoping when new scope enters
33
- play. Writes `TODO.md` (including its `## Add-ons` block),
34
- `.hedgehog/BMAD/`, and `docs/design/<module>-notes.md`. On first run,
35
- hands off to the `bootstrap` agent once Confirm & Lock holds.
35
+ play. Writes intents via `hedgehog intent add`, `.hedgehog/addons.yaml`,
36
+ and `.hedgehog/BMAD/`. On first run, hands off to the `bootstrap` agent
37
+ once Confirm & Lock holds.
36
38
  - **`bootstrap`** — runs `hedgehog-bootstrap`'s core steps (always) plus
37
39
  whichever add-on steps planning intake turned on. Triggered
38
40
  automatically by `planner` after its first run; skip if `nx.json`
39
41
  already exists.
40
- - **`backend-eng`** — builds each module's Phase A steps (schema →
41
- contract → repository → service → controller → queue?), one step at a
42
- time, gated and committed in its own context.
42
+ - **`backend-eng`** — builds each module's Phase A layers (schema →
43
+ contract → repository → service → controller → queue?), one
44
+ `hedgehog next` packet at a time, gated by `hedgehog verify`.
43
45
  - **`ux-planner`** — once per module in Phase B, after the hook exists and
44
- before the screen: writes `docs/design/<module>.md`.
45
- - **`front-end-eng`** — builds each module's Phase B steps (hook, screen)
46
- from the ux-planner rationale, one step at a time, in its own context.
46
+ before the screen: writes `docs/design/<module>.md`, reading
47
+ `.hedgehog/BMAD/05-ux-spec/` directly (or
48
+ `docs/design/<module>-notes.md` if a prior run already filed one).
49
+ - **`front-end-eng`** — builds each module's Phase B layers (hook, screen)
50
+ from the ux-planner rationale, one `hedgehog next` packet at a time,
51
+ gated by `hedgehog verify`.
47
52
  - **`reviewer`** — phase-transition and Correction Protocol checks the
48
53
  mechanical gate can't make (port discipline, FK-by-ID discipline,
49
54
  contract shape).
@@ -61,8 +66,8 @@ Pino logging · Vitest + Playwright (tests) · Conventional Commits +
61
66
  commitlint + lefthook · Sentry.
62
67
 
63
68
  **Add-ons** — each on or off per project, decided at planning intake and
64
- recorded in `TODO.md`'s `## Add-ons` block; check that block for this
65
- project's actual picks rather than assuming any of these are present:
69
+ recorded in `.hedgehog/addons.yaml`; check that file for this project's
70
+ actual picks rather than assuming any of these are present:
66
71
 
67
72
  | Add-on | Adds |
68
73
  | --- | --- |
@@ -72,8 +77,8 @@ project's actual picks rather than assuming any of these are present:
72
77
 
73
78
  An add-on that's off means the corresponding piece of infra genuinely
74
79
  isn't in this codebase — don't write code assuming `packages/auth`,
75
- `apps/worker`, or `apps/mobile` exist without checking `TODO.md`'s
76
- `## Add-ons` block first.
80
+ `apps/worker`, or `apps/mobile` exist without checking
81
+ `.hedgehog/addons.yaml` first.
77
82
 
78
83
  Don't substitute libraries, in core or in whichever add-ons are on. If a
79
84
  package or generator name changed upstream, verify against current docs
@@ -99,13 +104,15 @@ packages/
99
104
  libs/
100
105
  <module>/port · <module>/repository · <module>/service (one triplet per table)
101
106
  .hedgehog/
102
- BMAD/ archival planning intake output (brief, PRD, UX spec, research) — write-once, from planner
107
+ hedgehog.db the build graph — intents, tasks, dependencies, verifications, committed to git
108
+ addons.yaml the Add-ons decision (Auth/Queue/Mobile), from planner
109
+ BMAD/ archival planning intake output (brief, PRD, UX spec, research) — write-once, from planner
103
110
  docs/
104
- design <module>-notes.md (planner, sourced from BMAD's UX spec) and <module>.md (ux-planner)
111
+ design <module>.md (ux-planner, reading .hedgehog/BMAD/05-ux-spec/ directly)
105
112
  ```
106
113
 
107
- Check `TODO.md`'s `## Add-ons` block before assuming any "only if" line
108
- above is actually present in this codebase.
114
+ Check `.hedgehog/addons.yaml` before assuming any "only if" line above is
115
+ actually present in this codebase.
109
116
 
110
117
  ### Core rules
111
118