@skyf0xx/hedgehog 3.0.6 → 3.0.8

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 CHANGED
@@ -88,7 +88,7 @@ Artifact
88
88
 
89
89
  ### Anything else
90
90
 
91
- A CLI, a library, a browser extension, a data pipeline, etc. fitting neither shape gets its own build order, designed at intake rather than chosen from a menu.
91
+ A CLI, a library, a browser extension, a data pipeline, etc. fitting neither shape gets its own build order, designed at intake rather than chosen from a menu — starting from a [battle-tested blueprint](src/skills/hedgehog-core-design/blueprints) for the system's shape where one exists.
92
92
 
93
93
  Run `init` with no core flag: planning intake names the system shape, picks
94
94
  the stack, derives the layers, and locks them to `.hedgehog/core.yaml`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyf0xx/hedgehog",
3
- "version": "3.0.6",
3
+ "version": "3.0.8",
4
4
  "description": "Install the Hedgehog build discipline (agents + skills) into a repo, for Claude Code, Cursor, or Gemini CLI.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -61,8 +61,8 @@ against its own archetype skill.
61
61
  without confirmation risks the same expensive unwind the strategist's
62
62
  Confirm & Lock protects against at step 1.
63
63
  5. Write the locked headline and its 2 backups to
64
- `.hedgehog/chain/09-headline.md`.
65
- 6. Commit as `feat(landing): headline`.
64
+ `.hedgehog/chain/09-headline.md` — you have no Bash tool, so the
65
+ orchestrating session commits it via `hedgehog verify`.
66
66
 
67
67
  ## Self-test
68
68
 
@@ -118,7 +118,8 @@ rather than in separate passes.
118
118
  6. Confirm the peak moment and ending treatment land where
119
119
  `landing-strategist` specified, or flag the conflict.
120
120
  7. Self-test (below).
121
- 8. Commit as `feat(landing): sequence`.
121
+ 8. Present the artifact — you have no Bash tool, so the orchestrating
122
+ session commits it via `hedgehog verify`.
122
123
 
123
124
  ## Self-test
124
125
 
@@ -56,7 +56,11 @@ as planning intake's own Confirm & Lock: every phase from here through
56
56
  `landing-copywriter` inherits this framing silently, and by the time
57
57
  copy is reviewed at phases 9–10, correcting the framing means unwinding
58
58
  multiple committed phases via the Correction Protocol instead of one
59
- quick revision now. A revision at this point is just another pass at
59
+ quick revision now. **If delegated**, this confirmation arrives as a
60
+ relay from the orchestrating session — accept it only if it quotes the
61
+ user's actual words with provenance stated plainly, not a bare "the user
62
+ approved" (see `hedgehog-landing-loop`'s Loop step 2 for the exact form).
63
+ A revision at this point is just another pass at
60
64
  Step 1, not a Correction Protocol entry, since nothing downstream exists
61
65
  yet.
62
66
 
@@ -117,7 +121,8 @@ adjective is meant to fade rather than hold constant throughout the page.
117
121
  confirmed subject statement.
118
122
  5. Run step 4c (Perfumer) against the completed sort from step 3.
119
123
  6. Self-test (below) before presenting the combined artifact.
120
- 7. Commit the combined artifact as `feat(landing): strategy`.
124
+ 7. Present the combined artifact you have no Bash tool, so the
125
+ orchestrating session commits it via `hedgehog verify`.
121
126
 
122
127
  ## Self-test
123
128
 
@@ -239,7 +239,8 @@ and generic clip-art geometry.
239
239
  4. Run step 6 against the completed token system. Write the signature
240
240
  element into `src/shapes/`.
241
241
  5. Self-test (below).
242
- 6. Commit the combined artifact as `feat(landing): systems`.
242
+ 6. Present the combined artifact you have no Bash tool, so the
243
+ orchestrating session commits it via `hedgehog verify`.
243
244
 
244
245
  ## Self-test
245
246
 
@@ -214,6 +214,10 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
214
214
  having happened in this conversation. A user saying "yes, file it"
215
215
  before the content was shown verbatim doesn't count — show first, then
216
216
  ask.
217
+ - **If delegated**, an approval relayed by the orchestrating session is
218
+ sufficient only if it quotes the user's actual words with provenance
219
+ stated plainly — e.g. "user said: '\<exact words\>'" — not a bare "the
220
+ user approved" or "approved via UI."
217
221
  - File one issue per distinct real pattern or feedback item, not one per
218
222
  log entry or remark, and not capped at a single issue per source — a
219
223
  log (or a round of feedback) with several unrelated genuine points gets
@@ -61,7 +61,12 @@ the design work onto the person who came here to avoid doing it.
61
61
  Pick one default per system shape, the same way the shipped cores commit
62
62
  to one choice per row rather than a menu (`hedgehog-bootstrap`'s stack
63
63
  table). Substitute off a default only for a concrete, named constraint
64
- read from `.hedgehog/BMAD/` — never a general preference for variety:
64
+ read from `.hedgehog/BMAD/` — never a general preference for variety.
65
+ Prefer an opinionated framework over a bare library wherever the shape
66
+ has one (a web/CLI/RPC framework that fixes where things live, the way
67
+ NestJS does for `full-stack-app`) — an opinionated default is a guardrail
68
+ this discipline doesn't have to write down, and is worth more than the
69
+ popular thin alternative:
65
70
 
66
71
  | System shape | Default stack | Substitute when |
67
72
  |---|---|---|
@@ -72,7 +77,7 @@ read from `.hedgehog/BMAD/` — never a general preference for variety:
72
77
  | Desktop app | TypeScript + Electron, Vitest + Playwright, pnpm | native platform integration is a stated hard requirement (macOS/Windows-only, deep OS API use) → Swift/AppKit or C#/WinUI, per platform, named explicitly |
73
78
  | Compiler / language tool | Rust, `cargo test`, Cargo | the brief is explicitly about fast iteration over raw performance, or targets a JS/TS-only toolchain (a Babel/ESLint plugin) → TypeScript, Vitest, pnpm |
74
79
  | Bot / agent | TypeScript, Vitest, pnpm | the brief calls for heavy ML/data-science library use → Python, pytest, uv |
75
- | Game | TypeScript + a canvas/WebGL engine already named in the brief (e.g. PixiJS, Three.js), Vitest, pnpm | a native/console target is explicit → the engine's native language (C#/Unity, C++), named per that engine |
80
+ | Game | TypeScript + PixiJS (2D) or Three.js (3D), Vitest, pnpm — read the dimensionality off the brief; an engine the brief names outright wins over both | a native/console target is explicit → the engine the brief names, per that engine's own language (see the caveat below) |
76
81
  | Infra / deploy tool | Go, `go test`, Go modules | the tool is a thin wrapper generating config/manifests with no systems-level need → TypeScript, Vitest, pnpm |
77
82
 
78
83
  A shape not on this table is rare enough that no default has been
@@ -82,20 +87,72 @@ target, the language the brief's own examples or comparables are
82
87
  written in) and name the result as a judgment call, not a table lookup,
83
88
  in `core-design.md`'s rationale.
84
89
 
90
+ Where a substitution lands on a stack whose primary artifacts are binary
91
+ (engine scenes and prefabs, visual-editor projects, compiled design
92
+ files), say so at Confirm & Lock. Scope globs and `verify` commands still
93
+ hold on that stack's text sources, but a layer whose real output is a
94
+ binary file can't be diffed or meaningfully gated, so the enforcement is
95
+ partial in a way the text-source defaults aren't. That's a reason to
96
+ prefer a text-source stack where the brief leaves it open, and a fact the
97
+ user should have before confirming where it doesn't.
98
+
85
99
  Record the choice as one line — language, package manager, the named
86
- framework(s), test runner — before moving to Step 3; every layer's
87
- `scope` and `verify` in Step 3 draws from it.
100
+ framework(s), test runner — before moving to Step 3. Alongside it, record
101
+ a one-line decision for each of these concerns, whichever apply to the
102
+ shape (a browser extension has no DI story; a data pipeline has no
103
+ routing layer) — each is a place an authored core silently forks into
104
+ per-project convention if left unstated, the way `full-stack-app` never
105
+ has to think about because NestJS already decided:
106
+
107
+ - **Composition** — how one part of the system gets a dependency it
108
+ doesn't construct itself (a DI container, explicit constructor passing,
109
+ a module registry).
110
+ - **Error model** — how a failure crosses a layer boundary (typed
111
+ exceptions, a `Result`/`Either` return, error codes).
112
+ - **Config and secrets** — where runtime configuration is read from and
113
+ validated (env vars through a typed schema, a config file, flags).
114
+ - **Entrypoint layout** — what file the runtime starts from and how it
115
+ wires the layers together.
116
+
117
+ Every layer's `scope` and `verify` in Step 3 draws from this record.
88
118
 
89
119
  ## Step 3 — derive the layers
90
120
 
91
121
  Read `.hedgehog/BMAD/` for what the system actually does, then decide the
92
122
  layers it builds in. A layer earns its place by owning a distinct
93
123
  artifact that can be verified on its own. Order by dependency first (a
94
- layer that another layer imports comes first) and by risk second (where
95
- two layers are independent, build the one that would invalidate the other
96
- if it went wrong first).
97
-
98
- Three rules with teeth:
124
+ layer that another layer imports comes first), by contract second (a
125
+ layer that pins an external interface a schema, a wire format, a public
126
+ API surface — comes before the layers that build against it, the way
127
+ `full-stack-app` puts `schema` before `contract` before everything else),
128
+ and by risk third (where two layers are still tied, build the one that
129
+ would invalidate the other if it went wrong first).
130
+
131
+ Start from the blueprint for the chosen system shape — a starting
132
+ sequence, not a fixed one. Each blueprint names where it's safe to add,
133
+ merge, or drop a layer for the project at hand, and the one boundary that
134
+ has to hold whatever else changes; treat those adaptation points as
135
+ expected, not as exceptions. Record which blueprint was used and what
136
+ changed from it in `core-design.md`'s rationale (Step 6).
137
+
138
+ | System shape | Blueprint |
139
+ |---|---|
140
+ | CLI | [blueprints/cli.md](blueprints/cli.md) |
141
+ | Library / SDK | [blueprints/library-sdk.md](blueprints/library-sdk.md) |
142
+ | Data pipeline | [blueprints/data-pipeline.md](blueprints/data-pipeline.md) |
143
+ | Browser extension | [blueprints/browser-extension.md](blueprints/browser-extension.md) |
144
+ | Desktop app | [blueprints/desktop-app.md](blueprints/desktop-app.md) |
145
+ | Compiler / language tool | [blueprints/compiler-language-tool.md](blueprints/compiler-language-tool.md) |
146
+ | Bot / agent | [blueprints/bot-agent.md](blueprints/bot-agent.md) |
147
+ | Game | [blueprints/game.md](blueprints/game.md) |
148
+ | Infra / deploy tool | [blueprints/infra-deploy-tool.md](blueprints/infra-deploy-tool.md) |
149
+
150
+ A shape off this table gets no starting sequence — derive layers directly
151
+ from this step's rules and the BMAD brief, and name that in
152
+ `core-design.md` as a judgment call, the same as an off-table stack.
153
+
154
+ Three rules with teeth, on every blueprint and every derived sequence
155
+ alike:
99
156
 
100
157
  - **A layer with no executable verification is not a layer.** Fold it
101
158
  into its neighbour or drop it. `verify: manually inspect` is not a
@@ -110,7 +167,9 @@ Three rules with teeth:
110
167
 
111
168
  Four to seven layers is the usual range. Fewer than three means the
112
169
  project probably wanted a shipped core or no core at all; more than eight
113
- means several layers are one layer with internal steps.
170
+ means several layers are one layer with internal steps. This list isn't
171
+ final until Step 4 — a module axis can still add a cross-cutting layer to
172
+ it.
114
173
 
115
174
  ## Step 4 — decide the module axis
116
175
 
@@ -136,6 +195,23 @@ intent A's task may write intent B's files and the scope enforcement that
136
195
  justifies authoring a core at all disappears. Check every glob before
137
196
  writing the file.
138
197
 
198
+ On a module axis, also **ask explicitly whether the stack implies
199
+ cross-cutting infrastructure no single module should own** — a shared
200
+ background script coordinating state across every module's tabs (a
201
+ browser extension), a shared event bus, global app state. Every layer in
202
+ Step 3 instantiates once per intent; this is the thing that doesn't fit
203
+ that shape, and left undesigned it either gets deferred with no owner or
204
+ bolted onto whichever module's layer needs it first, quietly widening
205
+ that layer's scope past what it was designed to own.
206
+
207
+ If yes, add it to Step 3's layer sequence as its own layer, before the
208
+ file is written — a layer whose `scope` is a fixed path with no
209
+ `{module}` placeholder, the same way `full-stack-app`'s own `schema` and
210
+ `contract` layers run once against a fixed scope on an otherwise
211
+ module-axis core. Name it for what it owns (e.g. `background-infra`),
212
+ give it its own `verify` command, and record in `core-design.md` why no
213
+ single module was made to own it.
214
+
139
215
  ## Step 5 — write `.hedgehog/core.yaml`
140
216
 
141
217
  The loader parses `id` plus a `layers` list of flat maps. Every layer
@@ -178,6 +254,12 @@ if missed:
178
254
  belongs in `.hedgehog/core-design.md`.
179
255
  - **`depends_on` names one layer**, and the chain must be acyclic. The
180
256
  compiler walks it directly into `dependencies` rows.
257
+ - **`verify` must prove the layer's own claim, not just exit clean.** A
258
+ command that runs but asserts nothing (`tsc --noEmit` alone on a layer
259
+ whose job is behavior, a `test -s` on a file nothing checks the content
260
+ of) passes on an empty implementation. Pair typecheck/build commands
261
+ with a test command that exercises the layer's actual output whenever
262
+ the layer produces behavior, not just types.
181
263
 
182
264
  Verify the file loads before showing it back, by calling the loader
183
265
  directly:
@@ -196,12 +278,14 @@ forward.
196
278
 
197
279
  The rationale the engine doesn't read but the project needs: the system
198
280
  shape and why, the stack and why (the default it came from, or the named
199
- constraint that justified a substitution), the layers with a line each on
200
- what they own and why they sit where they do, the module-axis decision,
201
- and anything left unresolved. Written once, archival, never edited after
202
- the same stance `.hedgehog/BMAD/` takes. Later changes to the
203
- architecture are Correction Protocol entries in the commit log, not edits
204
- here.
281
+ constraint that justified a substitution), the composition/error/config/
282
+ entrypoint decisions from Step 2, the layer blueprint used and what
283
+ changed from it (or, off-table, that layers were derived directly and
284
+ why), the layers with a line each on what they own and why they sit where
285
+ they do, the module-axis decision, and anything left unresolved. Written
286
+ once, archival, never edited after — the same stance `.hedgehog/BMAD/`
287
+ takes. Later changes to the architecture are Correction Protocol entries
288
+ in the commit log, not edits here.
205
289
 
206
290
  ## Confirm & Lock
207
291
 
@@ -0,0 +1,35 @@
1
+ # Bot / agent blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ bot/agent system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ contract — the typed input/output shape of every capability, and the intent type policy decides over
10
+ tools — each capability's implementation, independently callable and testable with no model in the loop
11
+ policy — the decision logic: which tool a given input calls, knowing nothing about the delivery surface
12
+ transport — the platform integration (webhook, socket, polling loop) carrying input in and results back out
13
+ ```
14
+
15
+ ## Adaptation points
16
+
17
+ - Merge `transport` into `policy` when the agent runs as a single-process
18
+ script with no external trigger surface (a CLI-invoked agent, a batch
19
+ job) — there's no separate integration to isolate.
20
+ - Split `tools` per capability (`tools/{module}`) when the agent's
21
+ capabilities hit independent external systems with their own auth and
22
+ failure modes; keep one layer when they share a backend.
23
+ - Add a `memory` layer between `tools` and `policy`, depending on
24
+ `contract`, when the agent persists state across runs (conversation
25
+ history, a vector store) — keep it out of `policy` so the decision logic
26
+ stays testable against a fake memory.
27
+
28
+ ## Boundary that must hold
29
+
30
+ `policy` calls tools only through the types `contract` defines — never by
31
+ constructing a provider-specific call inline — and never imports
32
+ `transport`. This is what makes the decision logic testable without
33
+ standing up the real delivery surface or a live model: a policy layer
34
+ that reaches into a specific SDK can only be tested against that SDK, and
35
+ that is the layer whose behavior most needs cheap tests.
@@ -0,0 +1,62 @@
1
+ # Browser extension blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ browser extension system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ messaging — the typed message contract between background/content-script/popup
10
+ background — the service-worker-side logic (state, alarms, cross-tab coordination)
11
+ content — page-context logic (DOM reads/writes, page-side event listeners)
12
+ popup — the extension UI, consumes background/content only through messaging
13
+ ```
14
+
15
+ ## Adaptation points
16
+
17
+ - Drop `popup` entirely for an extension with no browser action UI.
18
+ - Merge `content` into `background` when the extension never injects into
19
+ page context (a pure background-worker extension).
20
+ - On a module axis, `background` is often shared rather than
21
+ one-per-module (a single service worker coordinating state across every
22
+ module's tabs) — the cross-cutting infrastructure Step 4 asks about.
23
+ Give it its own fixed-scope layer there.
24
+
25
+ ## Boundary that must hold
26
+
27
+ `popup` never imports from `background` or `content` directly — every
28
+ cross-context call goes through `messaging`, because a WebExtension's
29
+ contexts are separate JS runtimes and a direct import silently fails at
30
+ runtime rather than at build time.
31
+
32
+ ## WXT entrypoint naming (must decide up front, not discover mid-build)
33
+
34
+ WXT derives an entrypoint's manifest name by splitting its `entrypoints/`
35
+ folder or file name at the **first** `.`. Two entrypoints that derive the
36
+ same name collide — observed failure modes include a build-time error
37
+ ("Multiple entrypoints with the same name detected") and, in at least one
38
+ case, a colliding entrypoint silently missing from the built manifest
39
+ (`.output/*/manifest.json`) with no error at all. Don't assume which one
40
+ fires for a given WXT version or collision shape; treat any collision as
41
+ unsafe rather than relying on the build to always catch it.
42
+
43
+ Decide the naming convention in this step, per module, before any layer
44
+ is built against it — not after the first collision is hit:
45
+
46
+ - **Every entrypoint with more than one surface lives in its own folder**,
47
+ `entrypoints/{module}/index.ts`, never a flat `entrypoints/{module}.ts`
48
+ — a folder has no `.`-split ambiguity to collide on.
49
+ - **Colocated tests go inside that same folder** as a sibling
50
+ (`entrypoints/{module}/index.test.ts`), never as a flat
51
+ `entrypoints/{module}.test.ts` next to a flat entrypoint file — that's
52
+ the same name-collision shape described above.
53
+ - **A module with two entrypoint surfaces** (e.g. popup and content) gets
54
+ two folder names that don't share a prefix before the first `.` —
55
+ `entrypoints/{module}-popup/` and `entrypoints/{module}-content/`, never
56
+ a dotted variant like `entrypoints/{module}.content/`.
57
+
58
+ Add a cheap, generic guard to the entrypoint layer's `verify` command
59
+ regardless of the convention chosen: after `pnpm wxt build`, check the
60
+ built manifest's entrypoint count against the expected count (e.g. `node
61
+ -e "..."` reading `.output/*/manifest.json`) so a silent drop fails
62
+ `verify` instead of surfacing later as a missing feature.
@@ -0,0 +1,26 @@
1
+ # CLI blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the CLI
4
+ system shape. Adapt it for the project at hand — the adaptation points
5
+ below are expected, not exceptions — and record what changed in
6
+ `core-design.md`'s rationale.
7
+
8
+ ```
9
+ command — argument/flag parsing and dispatch only, one file per subcommand
10
+ domain — the logic the command triggers, no knowledge of argv or stdout
11
+ io-adapter — anything crossing a real boundary: filesystem, network, a wrapped subprocess
12
+ ```
13
+
14
+ ## Adaptation points
15
+
16
+ - Merge `io-adapter` into `domain` when the tool touches only the local
17
+ filesystem through the language's standard library — no separate
18
+ adapter earns its place.
19
+ - Add a `config` layer before `command` when the tool reads a
20
+ project-level config file in addition to flags.
21
+
22
+ ## Boundary that must hold
23
+
24
+ Never let `command` reach past `domain` into `io-adapter` directly — that
25
+ collapses the one boundary that makes `domain` testable without a real
26
+ filesystem or network.
@@ -0,0 +1,36 @@
1
+ # Compiler / language tool blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ compiler/language tool system shape. Adapt it for the project at hand —
5
+ the adaptation points below are expected, not exceptions — and record
6
+ what changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ ast — the node types, spans, and the diagnostic type every later layer reports through
10
+ lexer — source text to tokens
11
+ parser — tokens to ast, recovering from errors rather than aborting on the first one
12
+ analysis — name resolution, type checking, lints: ast in, diagnostics out
13
+ emit — the output artifact: generated code, a formatted document, a transformed ast
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `lexer` into `parser` when the grammar is simple enough that the
19
+ tokenizer is a handful of functions (a config language, a template
20
+ syntax) — a separate layer buys nothing.
21
+ - Drop `emit` for a pure analysis tool (a linter, a type checker) whose
22
+ output is diagnostics rather than an artifact.
23
+ - Drop `analysis` for a pure syntactic tool (a formatter, a
24
+ syntax-highlighter grammar) that never resolves names or types.
25
+ - Add a `driver` layer after `emit` when the tool has a real CLI or
26
+ watch-mode surface — it owns argv, file discovery, and diagnostic
27
+ rendering, keeping the pipeline layers free of both.
28
+
29
+ ## Boundary that must hold
30
+
31
+ `ast` comes first and everything depends on it, because the node types
32
+ and the span/diagnostic representation are the contract every other layer
33
+ speaks. Layers report errors as diagnostics carrying spans — never by
34
+ printing, and never by aborting on the first failure. A tool that stops
35
+ at the first error can't be used in an editor, and retrofitting error
36
+ recovery after `parser` is written is a rewrite of `parser`.
@@ -0,0 +1,36 @@
1
+ # Data pipeline blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the data
4
+ pipeline system shape. Adapt it for the project at hand — the adaptation
5
+ points below are expected, not exceptions — and record what changed in
6
+ `core-design.md`'s rationale.
7
+
8
+ ```
9
+ schema — the typed shape of every record crossing a stage boundary, and the validation that enforces it
10
+ extract — pulling raw records from each source, with no reshaping beyond what the source forces
11
+ transform — the business logic: cleaning, joining, deriving, aggregating, all pure and source-agnostic
12
+ load — writing results to the destination, plus whatever idempotency/upsert key the destination needs
13
+ schedule — the orchestration wiring: what runs when, retries, backfill entry points
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `schedule` into `load` when the pipeline is invoked externally
19
+ (cron calling a script, an orchestrator defined outside this repo) —
20
+ there's no orchestration surface here to build.
21
+ - Split `extract` per source (`extract/{module}`) when the pipeline pulls
22
+ from several genuinely different systems with independent failure modes
23
+ and auth; keep one `extract` layer for a single source.
24
+ - Merge `schema` into `extract` when there is one source and one
25
+ destination and the record shape is small enough to declare in a single
26
+ file — the types still exist and are still validated, they just don't
27
+ need a layer of their own.
28
+
29
+ ## Boundary that must hold
30
+
31
+ `transform` never reads from a source or writes to a destination — it
32
+ takes validated records in and returns records out. This is what lets the
33
+ business logic be tested on fixtures without network, credentials, or a
34
+ warehouse, and it's the boundary that decays first under deadline
35
+ pressure. A transform that "just needs one lookup" from the source is the
36
+ signal to widen `extract`'s output, not to reach across.
@@ -0,0 +1,34 @@
1
+ # Desktop app blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ desktop app system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ ipc — the typed contract between the privileged process and the UI process
10
+ main — privileged-process logic: filesystem, OS integration, windows, auto-update, native menus
11
+ domain — the app's own logic, running in whichever process owns it, with no window or IPC knowledge
12
+ renderer — the UI, reaching the privileged process only through ipc
13
+ ```
14
+
15
+ ## Adaptation points
16
+
17
+ - Merge `domain` into `main` for an app whose logic is mostly OS
18
+ orchestration (a launcher, a sync daemon with a thin window) — there's
19
+ no separable domain to isolate.
20
+ - Add a `persistence` layer between `domain` and `main`, depending on
21
+ `domain`, when the app owns a real local store (SQLite, a document
22
+ format) rather than plain preference files.
23
+ - On a native stack (Swift/AppKit, C#/WinUI) the `ipc` layer disappears —
24
+ there's one process. Keep `domain` separate from `renderer` regardless;
25
+ that boundary is what survives a platform's UI framework changing.
26
+
27
+ ## Boundary that must hold
28
+
29
+ `renderer` never touches the filesystem, spawns processes, or reads
30
+ secrets directly — every privileged operation crosses `ipc` to `main`.
31
+ This is a security boundary before it's an architectural one: a renderer
32
+ running remote or user-supplied content with direct privileged access is
33
+ the standard desktop-app vulnerability, and the layer split is what keeps
34
+ the privileged surface small enough to audit.
@@ -0,0 +1,35 @@
1
+ # Game blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the game
4
+ system shape. Adapt it for the project at hand — the adaptation points
5
+ below are expected, not exceptions — and record what changed in
6
+ `core-design.md`'s rationale.
7
+
8
+ ```
9
+ state — the world model and the rules that mutate it: pure, deterministic, no rendering or input
10
+ systems — the per-tick logic (movement, collision, ai, scoring) operating on state
11
+ input — device events to intents, so state never reads a keyboard or gamepad directly
12
+ render — drawing current state to the canvas/scene graph, reading state and never writing it
13
+ loop — the tick/frame driver wiring input, systems, and render together
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `systems` into `state` for a game whose rules are small enough to
19
+ live with the model (a puzzle game, a turn-based prototype).
20
+ - Add an `assets` layer before `render`, depending on nothing, when the
21
+ game has a real content pipeline (sprite atlases, audio banks, level
22
+ data) rather than a handful of inline files.
23
+ - On an engine that owns the frame loop, `loop` disappears into the
24
+ engine — keep the other four, mapped onto the engine's own lifecycle
25
+ hooks, and scope them to the engine's text sources (scripts), since
26
+ scenes and prefabs are binary and can't be gated.
27
+
28
+ ## Boundary that must hold
29
+
30
+ `render` reads `state` and never writes it, and `state` never reads input
31
+ devices or draws. A deterministic state layer is what makes a game
32
+ testable at all — you can tick it through a scripted sequence of intents
33
+ and assert the outcome with no window open. It's also what makes replays,
34
+ save files, and any future networking possible; a game whose rules mutate
35
+ during rendering can never get those without a rewrite.
@@ -0,0 +1,34 @@
1
+ # Infra / deploy tool blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ infra/deploy tool system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ model — the typed desired-state the tool works against, parsed and validated from config
10
+ provider — the typed operations against each target system (cloud api, kubernetes, ssh), one per target
11
+ plan — diffing desired state against observed state into an ordered list of changes, pure and printable
12
+ apply — executing a plan through providers, with the failure/rollback behavior the tool promises
13
+ cli — argv, output rendering, and the confirmation gate in front of apply
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `plan` into `apply` only for a tool that is genuinely fire-and-forget
19
+ (a one-shot bootstrap script) — and note that this gives up the dry-run
20
+ surface, which is the main reason to reach for this shape.
21
+ - Split `provider` per target (`provider/{module}`) when the tool spans
22
+ several systems with independent auth and failure modes; keep one layer
23
+ for a single target.
24
+ - Drop `model` as its own layer when desired state comes entirely from
25
+ flags rather than a config file.
26
+
27
+ ## Boundary that must hold
28
+
29
+ `plan` computes changes without performing any, and `apply` performs only
30
+ what a plan named. A tool that mutates during planning can't offer a
31
+ trustworthy dry run, and dry run is the safety property this shape exists
32
+ to provide — an infra tool without it is a script that edits production
33
+ with no preview. `plan` must be printable and diffable on its own, with
34
+ no credentials required beyond reading observed state.
@@ -0,0 +1,31 @@
1
+ # Library / SDK blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ library/SDK system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ core — the implementation, importable and testable with no knowledge of how it's packaged
10
+ public — the exported surface: what `index.ts` re-exports, typed and versioned independently of internals
11
+ examples — runnable usage samples that exercise the public surface only, doubling as integration tests
12
+ ```
13
+
14
+ ## Adaptation points
15
+
16
+ - Drop `examples` as its own layer when the consuming ecosystem's
17
+ convention folds them into the test suite (pytest doctests, Rust
18
+ `examples/` compiled by `cargo test`) — fold its verify command into
19
+ `public`'s instead.
20
+ - Split `core` into per-domain sub-layers (`core/{module}`) only when the
21
+ library has genuinely independent domains a consumer might import
22
+ separately (a multi-package SDK) — a single-purpose library keeps one
23
+ `core` layer.
24
+
25
+ ## Boundary that must hold
26
+
27
+ `public` re-exports from `core`; nothing outside `public` is a supported
28
+ import path. A consumer reaching into `core` directly is the signal this
29
+ boundary was drawn in the wrong place, not a usage error to document
30
+ around — the layer sequence exists so `core` can change shape without
31
+ breaking every consumer, and an internal import defeats that.
@@ -150,10 +150,27 @@ paragraph algorithm, and their self-tests.
150
150
  section, in `landing-sequencer`'s order, every section reviewed and
151
151
  locked before the next starts, all still inside the one `sequence`
152
152
  task.
153
+
154
+ **Relaying a live user-confirmation checkpoint to a delegated
155
+ subagent.** Phase 1 (Strategist) carries a hard-stop checkpoint per
156
+ Phase Transition Checks below, and a delegated subagent instance has no
157
+ channel for the user to address it directly. The orchestrating session
158
+ relays the confirmation instead, and the relay is sufficient only if it
159
+ quotes the user's actual words with its provenance stated plainly
160
+ (*"Relaying the user's own confirmation, verbatim — user said:
161
+ '\<exact words\>'"*) rather than asserting the outcome ("the user
162
+ approved"). This trusts the orchestrator's honesty about provenance,
163
+ the same trust the rest of this discipline already places in it for
164
+ relaying artifacts and task packets.
153
165
  3. Each agent **runs its own self-test** (see that agent's own file for
154
166
  what it checks) before presenting its artifact — necessary, not
155
167
  sufficient. This is a sanity check the agent does for itself; it does
156
- not move the task and the agent does not commit its own work.
168
+ not move the task and the agent does not commit its own work, whether
169
+ run directly or delegated to a subagent instance. `landing-strategist`,
170
+ `landing-systems`, `landing-sequencer`, and `landing-headline-writer`
171
+ carry no Bash tool at all (`capabilities.mjs`), so the commit is always
172
+ the orchestrating session's act via `hedgehog verify`, never the phase
173
+ agent's own.
157
174
  4. Once every phase inside the packet's layer has been presented and
158
175
  locked by the user, **run `hedgehog verify <task-id>`.** It checks the
159
176
  touched files against the packet's ALLOWED SCOPE, runs the layer's
@@ -216,7 +233,10 @@ the whole chain to correct the core framing (nothing downstream exists
216
233
  yet); every phase after it inherits that framing silently, and by the
217
234
  time copy is reviewed at phases 9–10, a wrong framing means unwinding
218
235
  several committed phases via the Correction Protocol instead of one free
219
- revision here.
236
+ revision here. If step 1 was run by a delegated `landing-strategist`
237
+ subagent instance, the confirmation reaches it as a relay from the
238
+ orchestrating session — see The Loop above for the provenance statement
239
+ that relay must carry.
220
240
 
221
241
  Before `landing-copywriter` starts (phase 10), confirm
222
242
  `landing-headline-writer`'s headline has been presented to and locked by