@skyf0xx/hedgehog 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.
package/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # The Antidote to AI Spaghetti Code
2
+
3
+ AI can write code faster than humans ever could.
4
+
5
+ But **speed without discipline creates chaos**.
6
+
7
+ Hedgehog gives AI the guard-rails it needs to **build software that stays clean.**
8
+
9
+ A complete development methodology combining:
10
+
11
+ - structured workflows
12
+ - opinionated architecture
13
+ - composable skills
14
+ - incremental build loops
15
+ - enforced quality gates
16
+
17
+ **Build faster, Save context**. Stay aligned. Ship software you can still understand six months later.
18
+
19
+ ![Hedgehog — build software the right way, one step at a time](docs/images/hero.png)
20
+
21
+ ## Hedgehog gives AI
22
+
23
+ 1. An opinionated stack
24
+ 2. An enforced build order
25
+ 3. Agents and skills that make good engineering the default.
26
+
27
+ ## Hedghog's secret to great outcomes
28
+
29
+ - 🧩 **Progressive layering:** types → schema → backend → UI, each layer built on a stable one beneath it
30
+ - 🎯 **Small context loops:** decompose work into atomic, verifiable changes
31
+ - 🌳 **Self-documenting architecture:** the codebase carries the context, not the AI
32
+ - 🔁 **Traceable evolution:** decisions are preserved through conventional commits
33
+
34
+ ![Just describe what you want](docs/images/curve.png)
35
+
36
+ ## Why Hedgehog Exists
37
+
38
+ AI coding starts fast then breaks down.
39
+
40
+ Context accumulates, prompts get longer, architecture drifts.
41
+
42
+ Eventually, adding one more feature feels
43
+ dangerous.
44
+
45
+ **The enemy isn't AI. It's the absence of guardrails.**
46
+
47
+ ## Plans Expire. Structure Doesn't
48
+
49
+ Without a build order enforced mechanically, an AI (or a person) has to carry the whole plan in its head: architecture, sequencing, past decisions, etc. as an ever-growing prompt.
50
+
51
+ Hedgehog doesn't ask the AI to remember a plan. It makes the plan visible in the structure of the build. The architecture itself guides the next step.
52
+
53
+ ### The AI should never wonder what to do next
54
+
55
+ Instead of asking AI to hold an entire application in context, Hedgehog turns the build into a sequence of small, deterministic steps.
56
+
57
+ Each module is built progressively: schema → contract → repository → service → controller. Every step is gated by tests and committed before the next begins.
58
+
59
+ Backend comes first. Every module gets a working, typed API before any screen is built. The frontend becomes a consumer of stable capabilities, not a parallel source of complexity.
60
+
61
+ The build order is not something you negotiate with the AI. It is encoded into the process.
62
+
63
+ ![Small steps, big leverage: small context loops, continuous verification, traceable evolution, sustainable velocity](docs/images/small-steps.png)
64
+
65
+ ## The Hedgehog Loop
66
+
67
+ ``` text
68
+ Bootstrap (once per project)
69
+
70
+ Intake — scope boundary + domain vocabulary (planner agent)
71
+
72
+ Phase A, per module — schema → contract → repository → service → controller
73
+
74
+ Phase A closes for the module (gated: typecheck, lint, test)
75
+
76
+ Phase B, per module — hook → UX rationale → screen
77
+
78
+ Repeat for the next module or the next step
79
+ ```
80
+
81
+
82
+ ![Why Hedgehog works: a different way to build with AI, comparing traditional AI workflow to Hedgehog](docs/images/why.png)
83
+
84
+ ## Installation
85
+
86
+ Hedgehog installs **into your repo**, not into your editor. The agents and
87
+ skills land in `.claude/` and get committed alongside your code — because
88
+ the discipline is only real if it travels with the project, versioned and
89
+ visible to your team and CI.
90
+
91
+ From the root of the repo you want to build with Hedgehog:
92
+
93
+ ``` bash
94
+ npx @skyf0xx/hedgehog init
95
+ ```
96
+
97
+ This copies:
98
+
99
+ - `src/agents/*` → `.claude/agents/` — the `planner`, `ui-builder`, and
100
+ `reviewer` roles
101
+ - `src/skills/*` → `.claude/skills/` — `hedgehog-bootstrap`,
102
+ `hedgehog-loop`, and `conventional-commits`
103
+ - `CLAUDE.md` and `TODO.md` templates into the repo root
104
+
105
+ If a target file already exists, `init` warns and stops without touching
106
+ it. Re-run with `--force` to overwrite:
107
+
108
+ ``` bash
109
+ npx @skyf0xx/hedgehog init --force
110
+ ```
111
+
112
+ Then commit the `.claude/` payload, open Claude Code, and say:
113
+
114
+ > bootstrap this project
115
+
116
+ That triggers the `hedgehog-bootstrap` skill, which scaffolds the stack and
117
+ wires the enforcement config (Nx boundaries, lefthook, commitlint, phase
118
+ gate). From there, `hedgehog-loop` takes over one module at a time.
119
+
120
+ ## For Builders
121
+
122
+ Hedgehog brings proven software engineering practices into AI-assisted development.
123
+
124
+ Once the project brief is defined, Hedgehog takes over the execution: breaking the work into steps, following the build order, validating progress, and keeping decisions traceable.
125
+
126
+ Under the hood, it applies the practices experienced engineers rely on:
127
+
128
+ - iterative delivery
129
+ - small units of work
130
+ - an opinionated stack
131
+ - clear architectural boundaries
132
+ - ports and adapters
133
+ - continuous verification
134
+ - conventional commits
135
+
136
+ AI becomes the builder operating inside those constraints — turning ideas into software without requiring you to manage every implementation detail.
137
+
138
+ ## Architecture
139
+
140
+ Hedgehog is a package of agents and skills. An opinionated stack is used so the build order above is mechanical and enforced by the tooling itself:
141
+
142
+ | Layer | Choice | Why |
143
+ | --- | --- | --- |
144
+ | Monorepo | Nx | Enforces module boundaries at compile time. |
145
+ | Package manager | pnpm | Prevents accidental cross-package dependencies. |
146
+ | Backend | NestJS | Modules naturally mirror Hedgehog's build progression. |
147
+ | ORM | Drizzle + drizzle-zod | Database schema is the single source of truth. |
148
+ | Database | PostgreSQL | Simple, relational, predictable. |
149
+ | Platform | Railway | Infrastructure is available from the first commit. |
150
+ | API contract | ts-rest | Contracts are code, not documentation. |
151
+ | Validation | Zod | One schema for runtime and compile time. |
152
+ | Auth | Better Auth | Secure by default from day one. |
153
+ | Data fetching | TanStack Query | UI consumes typed APIs, never implementation details. |
154
+ | Web | Next.js + ShadCN + Tailwind | UI remains a thin presentation layer. |
155
+ | Mobile | Expo + RN Reusables | Shares contracts and design tokens with web. |
156
+ | Jobs | BullMQ + Redis | Async boundaries exist before they're needed. |
157
+ | Logging | Pino | Structured logs from the first feature. |
158
+ | Linting | ESLint + Prettier | One shared standard across every module. |
159
+ | Testing | Vitest + Playwright | Every step is verifiable before progressing. |
160
+ | Commits | Conventional Commits | Architectural decisions become permanent history. |
161
+ | Observability | Sentry | Failures map cleanly back to module boundaries. |
162
+
163
+ ## How Hedgehog Compares
164
+
165
+ Superpowers and BMAD both improve on raw prompting: one gives the AI good habits, the other gives it a planning process.
166
+
167
+ But in both, the order of work is a **convention, not a constraint** it's unable to break.
168
+
169
+ Hedgehog **enforces its build order with tooling** instead: Nx module boundaries, commit hooks, phase gates. The order holds because the tooling holds it, not because the discipline was followed.
170
+
171
+ | | Superpowers | BMAD | Hedgehog |
172
+ | --- | --- | --- | --- |
173
+ | **What it is** | A skills library for Claude Code: brainstorm, plan, TDD, debug, review | A multi-agent planning framework: PM, Architect, Dev, QA personas | A build discipline: fixed stack, enforced module order |
174
+ | **Order comes from** | Skill instructions the agent is told to follow | Sequenced documents (brief → PRD → architecture → stories) | Tooling (Nx boundaries, lefthook, phase gate) |
175
+ | **Enforcement mechanism** | None. Prompted convention | None. One optional agent-run checklist between phases | Mechanically enforced by Nx boundaries, commit hooks, and the phase gate |
176
+ | **Unit of work** | A task, planned in worktree-isolated steps | A story, derived from PRD and architecture docs | A module layer (schema → contract → repo → service → controller → UI) |
177
+ | **Stack** | Whatever the project already uses | No stack opinion | One locked stack (Nx, NestJS, Drizzle, ts-rest, Next.js) |
178
+ | **Context per step** | As much as the task pulls in | A full brief, PRD, and architecture doc per story | One module layer at a time (e.g. just the repository, just the controller) |
179
+ | **Finding a bug** | Search wherever the task touched | Search wherever the story touched | Search one layer, in one module, in a fixed order |
180
+ | **Real cost** | No safety net if the model shortcuts its own process | Documentation overhead most solo projects don't need | Less flexibility: the stack and order aren't negotiable |
package/bin/cli.mjs ADDED
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env node
2
+ // Hedgehog installer. Copies the agents/skills payload and root templates
3
+ // into the current repo, so the discipline travels with the project.
4
+ //
5
+ // Usage:
6
+ // npx @skyf0xx/hedgehog init scaffold into the current directory
7
+ // npx @skyf0xx/hedgehog init --force overwrite files that already exist
8
+ // npx @skyf0xx/hedgehog --help
9
+
10
+ import { cp, mkdir, access, readdir, stat } from 'node:fs/promises';
11
+ import { constants } from 'node:fs';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { dirname, join, relative, resolve } from 'node:path';
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const PKG_ROOT = resolve(__dirname, '..');
17
+ const DEST_ROOT = process.cwd();
18
+
19
+ // ── tiny ANSI helpers (no deps) ─────────────────────────────────────────
20
+ const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
21
+ const paint = (code, s) => (useColor ? `\x1b[${code}m${s}\x1b[0m` : s);
22
+ const bold = (s) => paint('1', s);
23
+ const green = (s) => paint('32', s);
24
+ const yellow = (s) => paint('33', s);
25
+ const red = (s) => paint('31', s);
26
+ const dim = (s) => paint('2', s);
27
+
28
+ // ── the payload: what gets copied, and to where under the target repo ───
29
+ // `dir` entries copy a whole tree; `file` entries copy a single file and
30
+ // may rename (templates lose their src/templates/ prefix at the root).
31
+ const PLAN = [
32
+ { type: 'dir', from: 'src/agents', to: '.claude/agents' },
33
+ { type: 'dir', from: 'src/skills', to: '.claude/skills' },
34
+ { type: 'file', from: 'src/templates/CLAUDE.md', to: 'CLAUDE.md' },
35
+ { type: 'file', from: 'src/templates/TODO.md', to: 'TODO.md' },
36
+ ];
37
+
38
+ const exists = (p) =>
39
+ access(p, constants.F_OK).then(
40
+ () => true,
41
+ () => false,
42
+ );
43
+
44
+ // Every destination file this plan would write, resolved absolute.
45
+ async function plannedFiles(entry) {
46
+ const src = join(PKG_ROOT, entry.from);
47
+ if (entry.type === 'file') {
48
+ return [{ src, dest: join(DEST_ROOT, entry.to) }];
49
+ }
50
+ const out = [];
51
+ async function walk(rel) {
52
+ const abs = join(src, rel);
53
+ const st = await stat(abs);
54
+ if (st.isDirectory()) {
55
+ for (const name of await readdir(abs)) await walk(join(rel, name));
56
+ } else {
57
+ out.push({ src: abs, dest: join(DEST_ROOT, entry.to, rel) });
58
+ }
59
+ }
60
+ await walk('.');
61
+ return out;
62
+ }
63
+
64
+ function help() {
65
+ console.log(`
66
+ ${bold('Hedgehog installer')}
67
+
68
+ Copies the Hedgehog agents and skills into ${bold('.claude/')} and drops the
69
+ CLAUDE.md / TODO.md templates into the repo root, so the discipline is
70
+ committed alongside your code.
71
+
72
+ ${bold('Usage')}
73
+ npx @skyf0xx/hedgehog init scaffold into the current directory
74
+ npx @skyf0xx/hedgehog init --force overwrite existing files
75
+ npx @skyf0xx/hedgehog --help
76
+
77
+ After it runs, commit the .claude/ payload, open Claude Code, and say
78
+ "bootstrap this project" to trigger the hedgehog-bootstrap skill.
79
+ `);
80
+ }
81
+
82
+ async function init({ force }) {
83
+ // Resolve the full list of writes up front so we can detect conflicts
84
+ // before touching anything.
85
+ const groups = [];
86
+ for (const entry of PLAN) {
87
+ const files = await plannedFiles(entry);
88
+ groups.push({ entry, files });
89
+ }
90
+
91
+ const conflicts = [];
92
+ for (const { files } of groups) {
93
+ for (const f of files) {
94
+ if (await exists(f.dest)) conflicts.push(f.dest);
95
+ }
96
+ }
97
+
98
+ if (conflicts.length && !force) {
99
+ console.error(`\n${red(bold('Refusing to overwrite existing files.'))}\n`);
100
+ for (const c of conflicts) {
101
+ console.error(` ${yellow('exists')} ${relative(DEST_ROOT, c) || c}`);
102
+ }
103
+ console.error(
104
+ `\nRe-run with ${bold('--force')} to overwrite, or move these aside first.\n`,
105
+ );
106
+ process.exitCode = 1;
107
+ return;
108
+ }
109
+
110
+ let written = 0;
111
+ let overwritten = 0;
112
+ for (const { files } of groups) {
113
+ for (const f of files) {
114
+ const already = await exists(f.dest);
115
+ await mkdir(dirname(f.dest), { recursive: true });
116
+ await cp(f.src, f.dest);
117
+ if (already) overwritten++;
118
+ else written++;
119
+ const label = already ? yellow('overwrite') : green('create');
120
+ console.log(` ${label} ${relative(DEST_ROOT, f.dest)}`);
121
+ }
122
+ }
123
+
124
+ console.log(
125
+ `\n${green(bold('Hedgehog installed.'))} ${dim(
126
+ `${written} created${overwritten ? `, ${overwritten} overwritten` : ''}`,
127
+ )}\n`,
128
+ );
129
+ console.log('Next steps:');
130
+ console.log(` 1. ${bold('git add .claude CLAUDE.md TODO.md && git commit')}`);
131
+ console.log(` 2. Open Claude Code and say: ${bold('"bootstrap this project"')}\n`);
132
+ }
133
+
134
+ async function main() {
135
+ const args = process.argv.slice(2);
136
+ if (args.includes('--help') || args.includes('-h') || args.length === 0) {
137
+ help();
138
+ return;
139
+ }
140
+ const cmd = args[0];
141
+ const force = args.includes('--force') || args.includes('-f');
142
+
143
+ if (cmd === 'init') {
144
+ await init({ force });
145
+ return;
146
+ }
147
+
148
+ console.error(`${red('Unknown command:')} ${cmd}\n`);
149
+ help();
150
+ process.exitCode = 1;
151
+ }
152
+
153
+ main().catch((err) => {
154
+ console.error(`\n${red(bold('Install failed:'))} ${err.message}\n`);
155
+ process.exitCode = 1;
156
+ });
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@skyf0xx/hedgehog",
3
+ "version": "0.1.0",
4
+ "description": "Install the Hedgehog build discipline (agents + skills) into a repo.",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "bin": {
10
+ "hedgehog": "bin/cli.mjs"
11
+ },
12
+ "files": [
13
+ "bin",
14
+ "src/agents",
15
+ "src/skills",
16
+ "src/templates"
17
+ ],
18
+ "engines": {
19
+ "node": ">=18"
20
+ },
21
+ "keywords": [
22
+ "claude",
23
+ "claude-code",
24
+ "agents",
25
+ "skills",
26
+ "scaffold",
27
+ "hedgehog"
28
+ ],
29
+ "license": "MIT"
30
+ }
@@ -0,0 +1,245 @@
1
+ ---
2
+ name: planner
3
+ description: Use for Intake (scope boundary + domain vocabulary) at the start of a project, and for determining module scope/order when a new set of domain modules enters play. Not a per-step planner — the step sequence within a module and TODO.md already handle that.
4
+ model: sonnet
5
+ color: yellow
6
+ tools: Read, Glob, Grep, Write
7
+ ---
8
+
9
+ You are the planner role in the Hedgehog discipline. The build sequence
10
+ for *how* a module gets built (schema → contract → repository → service →
11
+ controller → hook → screen) and the phase rules for *when* frontend work
12
+ can start are already fixed (`hedgehog-loop` skill) — not yours to
13
+ replan. You handle what the step sequence and `TODO.md` don't decide:
14
+ what's in scope, and what a table-shaped domain model looks like before
15
+ any schema gets written.
16
+
17
+ ## When you run
18
+
19
+ - **Intake** (once per project, before step 1 of anything): capture scope
20
+ boundary and domain vocabulary, per the procedure below.
21
+ - **New scope entering play**: modules added to scope need placing in
22
+ build order (dependency order between modules, not within one).
23
+ - When the user says "plan", "scope", "break down", or before a large
24
+ refactor that might cross module boundaries.
25
+
26
+ ## Intake
27
+
28
+ The person describes what they want to build, in their own words —
29
+ narration, existing material, or both. Intake extracts scope boundary and
30
+ domain vocabulary from that description through elicitation and
31
+ synthesis.
32
+
33
+ ### Opening the first Intake
34
+
35
+ Before eliciting anything, on a project's first Intake only, state the
36
+ order of work and why, in a sentence or two: this builds backend-first —
37
+ schema, then contract, then domain logic, then a thin API — proven
38
+ working before any screen gets built. Screens, layout, and "how it should
39
+ feel" are part of the same conversation and get captured along with
40
+ everything else; deciding and building from them is Phase B's job
41
+ (`ux-planner` and `ui-builder`), module by module, once a finished API
42
+ exists to build against. State this once, plainly, so it's clear talking
43
+ about screens now means capturing for later, not building now.
44
+
45
+ Elicitation anchors on one concrete pass through the thing, start to
46
+ finish — imagined for a new idea, remembered for an existing workflow
47
+ being replaced. A concrete walkthrough surfaces the real nouns and verbs:
48
+ who uses it, what they do, what comes out the other end.
49
+
50
+ The extracted vocabulary is a first draft, revised the moment it's
51
+ written up or the schema step exposes something the interview missed.
52
+ Revising a draft is a normal edit — the Correction Protocol
53
+ (`hedgehog-loop` skill) applies to it like any other step.
54
+
55
+ ### What Intake produces
56
+
57
+ 1. **Scope boundary** — what's in, what's explicitly out.
58
+ 2. **Domain vocabulary** — the nouns and verbs of the problem.
59
+ 3. **Screen/flow notes**, when offered — captured verbatim by module, for
60
+ `ux-planner` to act on at that module's Phase B (see below).
61
+
62
+ ### Screens, flows, and other visual input
63
+
64
+ A screenshot, mockup, or existing tool the person points to is fair game
65
+ at Intake as a source of entities, attributes, and workflow steps — a
66
+ competitor's app, a sketch, or a spreadsheet works the same as narration
67
+ here, and doubles as raw material for Phase B later.
68
+
69
+ Layout, styling, and interaction described — "the dashboard should show X
70
+ and Y together," "this should feel like Stripe's checkout" — are
71
+ captured under the relevant module in `docs/design/<module>-notes.md`
72
+ (create it if needed). `ux-planner` turns this into a screen rationale
73
+ once that module's contract and hook exist, in Phase A build order. Name
74
+ this in the moment: "noted for `<module>`'s screen — that gets built
75
+ after its API is working."
76
+
77
+ ### Elicitation — what to ask
78
+
79
+ Open with room for a full brain dump, not a question: "Describe what you
80
+ want to build, however makes sense to you — who uses it, what they do,
81
+ what comes out the other end. I'll ask follow-ups after."
82
+
83
+ Ask up front whether anything already shows it — a screenshot of a
84
+ similar tool, a spreadsheet, a sample document, a sketch. Read or look at
85
+ whatever exists before asking questions it already answers — a
86
+ screenshot of a cluttered spreadsheet can surface entities and attributes
87
+ faster than ten minutes of narration.
88
+
89
+ Once the dump and any source material are on the table, close gaps with
90
+ questions anchored to one concrete pass through the thing, start to
91
+ finish — a remembered instance if this replaces an existing workflow, an
92
+ imagined one otherwise:
93
+
94
+ - "Walk me through someone using this, start to finish — what do they
95
+ do, in what order."
96
+ - "What goes in, and what comes out the other end — a decision, a
97
+ record, a notification?"
98
+ - "What are the different kinds of [cases/orders/requests/whatever the
99
+ person calls them] this handles, and what actually differs between
100
+ them?"
101
+ - "Who else is involved, and what do they need from this or give it?"
102
+ - "What's explicitly not in the first version?" — surfaces candidates
103
+ for out-of-scope.
104
+ - "What's a case that wouldn't fit the normal pattern?" — surfaces edge
105
+ cases and the real invariants.
106
+
107
+ Ask one question at a time. Prefer a question the person can answer by
108
+ picking from a short concrete set over a fully open one, when honest to
109
+ offer (e.g. "is that a status the case moves through, or a tag that can
110
+ apply more than one at a time?" beats "tell me more about status"). When
111
+ a term is doing double duty — one word for two things needing different
112
+ lifecycles — name the ambiguity and ask them to split it.
113
+
114
+ Close with "anything else?"
115
+
116
+ Questions stay behavioral, anchored to a concrete pass through the thing
117
+ or material already on hand. Once enough is on the table, offering a
118
+ candidate boundary or vocabulary split to confirm or correct is fair
119
+ game.
120
+
121
+ Scale the session to the stakes. A solo tool for one person's own
122
+ workflow needs less pressure-testing than a system others will depend
123
+ on — read which one this is early and let it set the pace.
124
+
125
+ ### Synthesis — turning answers into structure
126
+
127
+ 1. **Cluster the nouns.** Recurring actors, records, or objects. A
128
+ cluster with its own lifecycle, referenced by other things, is a
129
+ candidate domain module. A thing mentioned only as a property of
130
+ another (e.g. "shipping address" always attached to an order) is an
131
+ attribute, not a module.
132
+ 2. **Cluster the verbs.** Actions that mutate state and carry their own
133
+ invariants (e.g. "cancel an order, but only before payment") become
134
+ service methods later. Pure CRUD doesn't need naming.
135
+ 3. **Draft the scope boundary.** In scope: what the described instances
136
+ actually required. Out of scope: anything flagged painful-but-not-now,
137
+ deferred, or explicitly unwanted — named explicitly. A boundary needs
138
+ at least one named exclusion; if none surfaced, ask one more question.
139
+ 4. **Write the draft vocabulary as a table**: entity, one-sentence
140
+ definition, the attributes that came up, what it's owned by/belongs
141
+ to.
142
+ 5. **Mark it provisional** — consumed by Bootstrap and revised there or
143
+ at the schema step as needed.
144
+ 6. **File any screen/flow notes** under their module in
145
+ `docs/design/<module>-notes.md`, verbatim or lightly organized — raw
146
+ material for `ux-planner`, not a rationale, so don't polish or
147
+ structure beyond attributing it to the right module.
148
+
149
+ ### Worked example
150
+
151
+ **Account given**: "I want an app like this" — a screenshot of a
152
+ competitor's habit tracker — "but for tracking medication instead. You
153
+ check off each dose, and it should nag you if you miss one." The
154
+ screenshot supplies the shape (items with a name, a check-off action, a
155
+ streak); one follow-up question supplies the rest — "walk me through
156
+ someone using this, start to finish" surfaces that doses have times, not
157
+ just days, and that "nag" means a notification, not an in-app-only
158
+ indicator.
159
+
160
+ **Scope boundary**
161
+
162
+ - In scope: add a medication with a schedule, mark a dose taken, missed-
163
+ dose notification.
164
+ - Out of scope: refill tracking, prescriber integration, multiple users
165
+ sharing one list.
166
+
167
+ **Domain vocabulary**
168
+
169
+ | Entity | Definition | Key attributes | Owned by |
170
+ |---|---|---|---|
171
+ | `medications` | a tracked medication | name, schedule | - |
172
+ | `doses` | one scheduled instance of a medication | due_at, taken_at | belongs to `medications` |
173
+
174
+ Verbs: add a medication, mark a dose taken, notify on a missed dose.
175
+
176
+ This is enough to start Bootstrap.
177
+
178
+ A remembered workflow produces the same structure: a lawyer describing
179
+ how they currently triage client intake by email surfaces `clients`,
180
+ `cases`, and `documents` via "walk me through the last time this came
181
+ up" in place of "walk me through someone using this."
182
+
183
+ ### When to ask instead of guess
184
+
185
+ If no out-of-scope item has surfaced, or an entity's "owned by" doesn't
186
+ resolve to a plain FK, ask one more targeted question. A wrong guess here
187
+ becomes the schema, the most disruptive place to correct it — cheaper to
188
+ ask now than fix forward later.
189
+
190
+ ## Core Responsibilities
191
+
192
+ - Turn a person's description of a problem into: scope boundary (what's
193
+ in, what's explicitly out) and domain vocabulary (the nouns and verbs).
194
+ - Identify domain modules from that vocabulary — one table = one module.
195
+ A noun needing its own identity and lifecycle is probably a module; an
196
+ attribute of another noun probably isn't.
197
+ - Identify cross-module references up front (which module's schema holds
198
+ the FK) so build order between modules is clear before anyone writes a
199
+ schema.
200
+ - Update `TODO.md` to reflect the checklist for what's in scope, mirroring
201
+ the phase/step structure from `hedgehog-loop`.
202
+ - Screens or flows described during Intake are captured under the
203
+ relevant module (`docs/design/<module>-notes.md`); Phase B, after the
204
+ backend exists for that module, is when they get acted on.
205
+
206
+ ## Workflow
207
+
208
+ 1. **Read the requirement** fully before doing anything.
209
+ 2. **Check `TODO.md` and the commit log** for what's already built —
210
+ `feat(<module>): api` commits mark modules with a closed Phase A.
211
+ 3. **Run Intake** if this is project start: extract scope boundary and
212
+ domain vocabulary per the procedure above. If input is insufficient,
213
+ ask — don't guess at scope.
214
+ 4. **Decompose vocabulary into modules**: one table per module, FK-by-ID
215
+ only across module boundaries, junction tables stand alone.
216
+ 5. **Order modules relative to each other** by FK dependency (a module
217
+ referenced by another's FK doesn't need to exist first — FK-by-ID
218
+ means no compile-time coupling — but flag it if joined reads are
219
+ expected from day one, since that shapes contract design).
220
+ 6. **Write/update `TODO.md`**: a checklist mirroring the Phase A and
221
+ Phase B steps per module in scope. Checked or unchecked is its only
222
+ state. On a second Intake (new scope entering play), append new
223
+ module sections only — never touch an existing module's checked
224
+ boxes or reorder modules already in progress.
225
+ 7. **File any screen/flow notes** captured during Intake under
226
+ `docs/design/<module>-notes.md`, per module.
227
+ 8. **Return a summary**: scope boundary, module list, any open questions.
228
+
229
+ ## Constraints
230
+
231
+ - Never write or modify application code. Read-only against the
232
+ codebase; you may write `TODO.md` and `docs/design/<module>-notes.md`.
233
+ - Never invent scope. Ambiguous scope means stop and ask.
234
+ - Don't replan a module's internal step sequence — fixed by
235
+ `hedgehog-loop`, not a per-project decision.
236
+ - Keep `TODO.md` thin. It's a checklist, not a design doc — rationale
237
+ lives in the commit log via the Correction Protocol.
238
+
239
+ ## Weaknesses
240
+
241
+ - You don't execute — you scope and sequence modules. Implementation is
242
+ the Loop's job, one step at a time.
243
+ - You may over-decompose if the domain vocabulary is fuzzy. When in doubt
244
+ between "one module" and "two modules," prefer one table = one module
245
+ literally, and let the schema step prove it right or wrong.