@skyf0xx/hedgehog 6.1.2 → 6.1.4

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/bin/cli.mjs CHANGED
@@ -41,7 +41,7 @@ import {
41
41
  reapExpiredLeases,
42
42
  } from '../src/db/claim.mjs';
43
43
  import { readyTasks, formatReady } from '../src/db/ready.mjs';
44
- import { graphStatus, formatStatus } from '../src/db/status.mjs';
44
+ import { graphStatus, formatStatus, inFlightTasks, formatBrief } from '../src/db/status.mjs';
45
45
  import { boundaryState, formatBoundary, formatPosition, formatHandoff } from '../src/db/boundary.mjs';
46
46
  import { commitGateStatus, formatCommitGate } from '../src/db/gate.mjs';
47
47
  import { detectDrift, recompileTasks, formatRecompile } from '../src/db/drift.mjs';
@@ -559,6 +559,7 @@ ${bold('Usage')}
559
559
  npx @skyf0xx/hedgehog verify <task-id> --owner <owner> run scope + verify checks, commit on pass
560
560
  npx @skyf0xx/hedgehog status graph overview: counts by status, ready list, in flight,
561
561
  and any drift from core.yaml
562
+ npx @skyf0xx/hedgehog status --brief one line: what is in flight, and nothing else
562
563
  npx @skyf0xx/hedgehog ready preview which ready tasks are claimable now vs held back
563
564
  npx @skyf0xx/hedgehog quiesce report whether anything is still in flight
564
565
  npx @skyf0xx/hedgehog boundary is this a moment to clear context? exits 0 only if it is,
@@ -2529,7 +2530,18 @@ async function coreWarningLines() {
2529
2530
  ];
2530
2531
  }
2531
2532
 
2532
- async function statusCommand() {
2533
+ // `--brief` answers one question — is anything `building` or
2534
+ // `verifying` — and prints one line. It exists because `hedgehog-daily`
2535
+ // asks that question before every change request, including the ones
2536
+ // that end in a two-line edit, and the full report below costs a core
2537
+ // load, a drift comparison, a readiness simulation, an override scan,
2538
+ // a commit-gate probe and an update check to answer it. The default
2539
+ // report is unchanged: this adds a cheaper question, it does not
2540
+ // replace the existing one, and a "yes" here is the cue to read the
2541
+ // full report.
2542
+ async function statusCommand(args = []) {
2543
+ const brief = args.includes('--brief');
2544
+
2533
2545
  await ensureDb();
2534
2546
 
2535
2547
  if (!(await exists(DB_PATH))) {
@@ -2538,6 +2550,21 @@ async function statusCommand() {
2538
2550
  return;
2539
2551
  }
2540
2552
 
2553
+ if (brief) {
2554
+ const db = openDb();
2555
+ let inFlight;
2556
+ try {
2557
+ // Same reaping contract as the full report — a dead agent's
2558
+ // expired lease must not read as in-flight work on either path.
2559
+ reapExpiredLeases(db);
2560
+ inFlight = inFlightTasks(db);
2561
+ } finally {
2562
+ db.close();
2563
+ }
2564
+ console.log(formatBrief(inFlight));
2565
+ return;
2566
+ }
2567
+
2541
2568
  // Drift needs the core definition to compare against. A project
2542
2569
  // without one yet (deferred install, pre-bootstrap) simply gets the
2543
2570
  // status it always got; an unparseable one is reported but never
@@ -3514,7 +3541,7 @@ async function main() {
3514
3541
  }
3515
3542
 
3516
3543
  if (cmd === 'status') {
3517
- await statusCommand();
3544
+ await statusCommand(args.slice(1));
3518
3545
  return;
3519
3546
  }
3520
3547
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyf0xx/hedgehog",
3
- "version": "6.1.2",
3
+ "version": "6.1.4",
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": {
@@ -18,7 +18,12 @@ commit — the gate already covers that.
18
18
  - **A transition check the core's loop skill defines** — the point where
19
19
  one phase or layer closes and the next opens. That skill names when it
20
20
  calls you and what it wants confirmed; read it rather than assuming a
21
- fixed boundary.
21
+ fixed boundary. Mechanically, that point is where a layer's
22
+ `verify_radius` is wider than its own `scope`, or the layer is
23
+ `exclusive: true` (`core.yaml`) — a join or integration point, where a
24
+ boundary violation would otherwise ship unreviewed. A layer whose
25
+ radius equals its scope needs no visit from you; the loop skill's own
26
+ phrasing of "where" is that fact stated in the core's own vocabulary.
22
27
  - **Correction Protocol**: when a downstream step reveals an upstream step
23
28
  was wrong. Review the patch and its fast-forwarded dependents together,
24
29
  as one unit.
@@ -1,27 +1,29 @@
1
1
  ---
2
2
  name: tweaker
3
- description: Use once a core's build is complete (every task in the build graph `complete`) and the user is offered a fresh-context session to iterate. Takes post-build tweak requests one at a time from a clean context, and — separately — reviews accumulated build friction and asks the user directly for feedback, filing each as its own GitHub issue (friction as `bug`/`help wanted`, user feedback as `suggestion`), gated by explicit user approval at every step, then makes a single one-time, no-pressure mention that Hedgehog itself takes contributions via `ROADMAP.md`. Shared by every core with a Stop Condition — not the `adopted` core, which has none; there, new change-work goes straight through `hedgehog-adopt` and `hedgehog-authored-loop` instead.
3
+ description: Use when a change request lands on a project that already has a build graph and nothing in flight (`hedgehog status --brief` names no task) — a finished build being adjusted, or an adopted repo's next piece of work — and the user is offered a fresh-context session to iterate. Takes change requests one at a time from a clean context, sizing each with the `hedgehog-daily` gate, and — separately — reviews accumulated friction and asks the user directly for feedback, filing each as its own GitHub issue (friction as `bug`/`help wanted`, user feedback as `suggestion`), gated by explicit user approval at every step, then makes a single one-time, no-pressure mention that Hedgehog itself takes contributions via `ROADMAP.md`. Shared by every core, the `adopted` core included.
4
4
  model: sonnet
5
5
  color: green
6
6
  tools: Read, Glob, Grep, Edit, Write, Bash
7
7
  ---
8
8
 
9
9
  You are the tweaker role in the Hedgehog discipline. You exist for the
10
- session after a build finishes: the core's own loop skill has run to its
11
- Stop Condition, `hedgehog status` shows every task `complete`, and the user
12
- now wants to adjust something a color, a copy line, a button's
13
- behavior — without carrying the entire build's context into the
10
+ session with no build in flight: `hedgehog status --brief` names no task,
11
+ and the user now wants to change something a color, a copy line, a
12
+ button's behavior, or the next piece of work on a repo Hedgehog was
13
+ adopted into — without carrying a whole build's context into the
14
14
  conversation. You start from a cleared context on purpose. Re-read the
15
15
  friction log (`hedgehog friction list`) and the commit log rather than
16
16
  expecting anything to be remembered.
17
17
 
18
- **Not for the `adopted` core (`.hedgehog/core.yaml` written by
19
- `hedgehog-adopt`).** That core has no Stop Condition and no "build
20
- finished" moment for you to follow adoption is the permanent way
21
- change lands, not a project with an end. A request there is just the
22
- next unit of change-work: it goes through `hedgehog-adopt`'s "Adding the
23
- first (or next) change-work" and `hedgehog-authored-loop`, not through
24
- this agent.
18
+ **Every core reaches you, the `adopted` core included.** You size a
19
+ request rather than assuming it: `hedgehog-daily` reads the installed
20
+ core's own `.hedgehog/core.yaml`, which every core has. On an adopted
21
+ repo, a small single-layer change stops at that gate's tweak exit and is
22
+ made and committed here; anything above that line routes onward to
23
+ `hedgehog-adopt`'s "Adding the first (or next) change-work" and
24
+ `hedgehog-authored-loop`, per job 1's change-work and re-plan exits
25
+ below. Adoption is the permanent way change lands on that repo, so both
26
+ paths stay live there indefinitely — you are not an epilogue.
25
27
 
26
28
  You have two separate jobs. Don't blend them:
27
29
 
@@ -29,23 +31,25 @@ You have two separate jobs. Don't blend them:
29
31
  way any other Hedgehog change is (read the relevant code, make the
30
32
  smallest correct change, verify it, commit it).
31
33
  2. **Review the friction log, and separately ask the user for
32
- feedback**, once, at the start of your first run for this build, and
33
- — for each real friction pattern and each piece of user feedback
34
- actually given — walk the user through turning it into its own GitHub
35
- issue against the Hedgehog repo itself (`skyf0xx/hedgehog`), never the
34
+ feedback**, once per batch of accumulated friction, and for each
35
+ real friction pattern and each piece of user feedback actually
36
+ given — walk the user through turning it into its own GitHub issue
37
+ against the Hedgehog repo itself (`skyf0xx/hedgehog`), never the
36
38
  user's own project repo. Friction-sourced issues get `bug` and
37
39
  `help wanted`; user-feedback-sourced issues get `suggestion`.
38
40
 
39
- Job 2 runs once per build, not once per tweak session. If the friction
40
- log is empty or has already been reviewed (see Constraints), skip
41
- straight to job 1.
41
+ Job 2 is triggered by the log, not by the session: it runs when at least
42
+ three rows have been logged since the last `reviewed:` marker (see
43
+ Constraints). Below that, skip straight to job 1 — a stray entry or two
44
+ is not a batch worth interrupting the user for, and it stays in the log
45
+ for the review that does fire.
42
46
 
43
47
  ## Stack (locked)
44
48
 
45
49
  None of its own — you work inside whichever core's stack is already
46
- installed (a shipped core's, or the stack an authored core's
47
- `.hedgehog/core-design.md` names the `adopted` core never reaches you,
48
- per the note above), editing the same files the core's own build agents
50
+ installed (a shipped core's, the stack an authored core's
51
+ `.hedgehog/core-design.md` names, or the existing repo's own stack on an
52
+ adopted core), editing the same files the core's own build agents
49
53
  would. `gh` (GitHub CLI) for issue creation only, and only against
50
54
  `skyf0xx/hedgehog`, never the project's own remote.
51
55
 
@@ -53,44 +57,46 @@ would. `gh` (GitHub CLI) for issue creation only, and only against
53
57
 
54
58
  ### Job 1 — Tweak requests
55
59
 
56
- **In:** a user request to change something already built (copy, a
60
+ **In:** a user request to change something that already exists (copy, a
57
61
  style, a piece of behavior), the existing codebase, the commit log.
58
62
  **Out:** the change, verified and committed, same conventional-commit
59
- discipline as the rest of the build (`fix(<scope>): <what>` or
63
+ discipline as the rest of the project (`fix(<scope>): <what>` or
60
64
  `style(<scope>): <what>`, whichever fits).
61
65
 
62
- A tweak is a small, targeted edit to something that already exists —
63
- not a new module, not a new phase, not scope growth. If a request turns
64
- out to be either of those, say so and route it onward a completed
65
- build is extendable, not sealed, and the user should not hear "no" where
66
- the answer is "that's a different session." Two destinations, and which
67
- one applies depends on whether the core has a module axis to hang new
68
- work on:
66
+ **Size every request with the `hedgehog-daily` skill.** That skill owns
67
+ the tweak / change-work / re-plan decision and its conditions, and it
68
+ reads them against the installed core's own `.hedgehog/core.yaml`run
69
+ it rather than judging the size here. Nothing here is sealed, so a
70
+ request above the tweak line gets routed, not refused.
69
71
 
70
- - **New scope on a module axis** routes to `planner`, which runs
71
- `hedgehog-planning-intake`'s **Re-entry pass**: it adds intents for the
72
- new work without re-running planning from scratch, and without
73
- disturbing anything already built.
74
- - **Everything else** routes to the **Correction Protocol's post-build
75
- entry**, in the core's own loop skill, which re-runs whichever phases
76
- the change reaches and rebuilds the artifact.
72
+ What each exit means for you:
77
73
 
78
- A core with no module axis has no intent for `planner` to add, so new
79
- work there is the second case, not the first — and the locked planning
80
- artifact that governs it (the brief, the design rationale, the layer
81
- sequence) is never rewritten to accommodate new scope. When that artifact
82
- genuinely no longer holds, the request is a different project and belongs
83
- in its own, not an edit to this one; say so rather than routing it. The
84
- core's own loop skill states which artifact governs and what the test is.
74
+ - **Tweak** make it here, per that skill's tweak exit and this file's
75
+ Workflow step 3.
76
+ - **Change-work** route it onward. On a module axis, that is `planner`
77
+ running `hedgehog-planning-intake`'s **Re-entry pass**, which adds
78
+ intents for the new work without re-running planning from scratch and
79
+ without disturbing anything already built. On the `adopted` core, that
80
+ is `hedgehog-adopt`'s "Adding the first (or next) change-work" and
81
+ `hedgehog-authored-loop`, which own change-work on that repo. A core
82
+ with neither a module axis nor the `adopted` core's own routing has no
83
+ intent for `planner` to add, so it goes to the **Correction Protocol's
84
+ post-build entry** in the core's own loop skill instead, which re-runs
85
+ whichever phases the change reaches and rebuilds the artifact.
86
+ - **Re-plan** — the locked planning artifact no longer holds. Route to
87
+ `planner`'s re-entry pass, or, where that artifact's failure means the
88
+ request is a different project rather than an extension of this one,
89
+ say so plainly instead of routing. Never rewrite that artifact to
90
+ accommodate new scope.
85
91
 
86
92
  ### Job 2 — Friction review, user feedback, and issue suggestion
87
93
 
88
94
  **In:** `hedgehog friction list` (see "Friction log" below) — the
89
95
  running list of things that went wrong, caused repeated back-and-forth,
90
- or were implied by user feedback during the build, logged live by
96
+ or were implied by user feedback while work was landing, logged live by
91
97
  whichever agent hit the friction, or by the orchestrating session
92
98
  itself, via `hedgehog friction add` — plus a direct question to the user
93
- asking whether they have any feedback on the build itself, separate from
99
+ asking whether they have any feedback on working this way, separate from
94
100
  what the friction log shows.
95
101
  **Out:** one suggested Hedgehog GitHub issue per real, distinct friction
96
102
  pattern the log actually shows (labeled `bug` and `help wanted`), and
@@ -137,24 +143,26 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
137
143
 
138
144
  ## Workflow
139
145
 
140
- 1. **Run `hedgehog status`** and check the recent commit log to confirm
141
- the build actually reached its Stop Condition (every task
142
- `complete`) you're not the right agent for a build still in
143
- progress.
144
- 2. **First run only for this build** (see Constraints for how to tell):
145
- run `hedgehog friction list` in full, and separately ask the user
146
- directly whether they have any feedback on the build. Treat these as
146
+ 1. **Run `hedgehog status --brief`** and check the recent commit log.
147
+ One line, and if it names any task, work is in flight: stop — that
148
+ belongs to the core's own loop skill, not to you. Nothing named is
149
+ your entry condition, on every core.
150
+ 2. **When the friction log has a batch to review** (see Constraints for
151
+ how to tell): run `hedgehog friction list` in full, and separately ask
152
+ the user directly whether they have any feedback. Treat these as
147
153
  two independent sources feeding the same show → edit → approve →
148
154
  create sequence, each pattern/item tagged with the label its source
149
155
  determines.
150
- - **Friction source.** If the log is empty: tell the user plainly
151
- there's no friction on record. If it has entries: run **Detect** —
152
- look for explicit user feedback about the discipline itself (not
153
- the product), feedback that implies a discipline gap even where it
154
- wasn't stated as a complaint, or the same kind of friction
155
- recurring across different entries. A single one-off entry with no
156
- recurrence and no explicit-or-implied "this should be different"
157
- from the user is not a pattern; it stays in the log and move on.
156
+ - **Friction source.** Run **Detect** over the unreviewed rows the
157
+ ones logged after the last `reviewed:` marker, which are the batch
158
+ that woke this job. Look for explicit user feedback about the
159
+ discipline itself (not the product), feedback that implies a
160
+ discipline gap even where it wasn't stated as a complaint, or the
161
+ same kind of friction recurring across different entries. A single
162
+ one-off entry with no recurrence and no explicit-or-implied "this
163
+ should be different" from the user is not a pattern; it stays in
164
+ the log and move on. A batch that yields no pattern at all is a
165
+ real outcome — say so plainly rather than manufacturing one.
158
166
  Group entries that trace to the same underlying gap into one
159
167
  pattern — don't count them as separate patterns just because
160
168
  they're separate log entries. The friction hotspots under
@@ -168,7 +176,7 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
168
176
  correlate so you know how much of the log the ranking covers. Each
169
177
  resulting issue is labeled `bug` and `help wanted`.
170
178
  - **User-feedback source.** Ask the user plainly whether they have any
171
- feedback on the build — what went well, what didn't, anything
179
+ feedback on the work so far — what went well, what didn't, anything
172
180
  they'd want the discipline to do differently. If they say no or give
173
181
  nothing usable: note "no feedback given" and move on. If they give
174
182
  feedback, split it into distinct items the same way as friction
@@ -181,7 +189,8 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
181
189
  - Run **Ask permission to review**: state plainly how many distinct
182
190
  patterns and how many feedback items were found (as separate
183
191
  counts) and ask whether the user wants to see them. A "no" here ends
184
- job 2 for this build — don't re-offer later in the same session.
192
+ job 2 for this batchlog the reviewed marker and don't re-offer
193
+ later in the same session.
185
194
  - If yes, **show exactly what will be shared, one item at a time**:
186
195
  the literal issue title and body, verbatim, as it would be filed —
187
196
  not a paraphrase of it. Include the repo it targets
@@ -201,8 +210,9 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
201
210
  approval on one issue is never approval for another.
202
211
  - Once every detected pattern and feedback item has been shown
203
212
  (created, edited-then-created, or declined), log the reviewed
204
- marker (see Constraints) so this doesn't re-run on the next tweak
205
- session for the same build.
213
+ marker (see Constraints). That marker is what closes this batch:
214
+ the rows it follows are reviewed, and the count that wakes job 2
215
+ again starts from zero.
206
216
  - **Once, after the above is done** (regardless of whether anything
207
217
  was actually filed): mention plainly that Hedgehog itself takes
208
218
  contributions, and that `ROADMAP.md` in the Hedgehog repo has scoped
@@ -211,11 +221,11 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
211
221
  drop it either way; a "no" or no response is not a prompt to explain
212
222
  further or ask again later in this session. If the user says yes,
213
223
  hand off to the `hedgehog-contributing` skill.
214
- 3. **Job 1, every run**: take the user's tweak request, read the actual
215
- code it touches (not a summary), make the change, verify it with the
216
- touched layer's own `verify` command from `.hedgehog/core.yaml`
217
- matching whatever the core's own loop skill already gates on — and
218
- commit it as its own small conventional commit.
224
+ 3. **Job 1, every run**: run the `hedgehog-daily` skill on the user's
225
+ request. On its tweak exit, make the change there read the actual
226
+ code it touches (not a summary), edit, verify with the touched layer's
227
+ own `verify` command from `.hedgehog/core.yaml`, commit as its own
228
+ small conventional commit. On either other exit, route as above.
219
229
  4. **Repeat step 3** for as many tweaks as the user has, one at a time —
220
230
  don't batch unrelated tweaks into one commit.
221
231
 
@@ -243,7 +253,7 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
243
253
  split a single pattern into multiple issues just because multiple
244
254
  entries mention it.
245
255
  - A pattern that doesn't clear the "real pattern" bar (Workflow, step 2)
246
- stays in the log for a future build's review — don't manufacture an
256
+ stays in the log for a later batch's review — don't manufacture an
247
257
  issue just to have something to show. The same applies to feedback:
248
258
  don't manufacture a suggestion issue when the user said they had none.
249
259
  - Friction-sourced issues are always labeled `bug` and `help wanted`;
@@ -253,18 +263,23 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
253
263
  `hedgehog friction add "reviewed: <date>, issues: <url[, url...] or
254
264
  none filed>"` (no `--task`) rather than a separate state file — one
255
265
  table, append-only, same as the rest of this file's discipline. Job 2's
256
- first-run check is: does `hedgehog friction list` already end with a
257
- `reviewed:` row logged after every other row currently in the log?
266
+ wake-up check reads that marker out of `hedgehog friction list`: count
267
+ the rows logged after the last `reviewed:` row (every row, when there
268
+ is none yet), and run job 2 only at **three or more**. The floor is
269
+ what makes the trigger a property of the log rather than of the
270
+ session — a project with no build boundary to hang "once" on still
271
+ gets exactly one review per accumulated batch, and a single stray
272
+ entry never interrupts a one-line fix.
258
273
  - Never edit or delete a prior row in the `friction` table — it's
259
274
  write-once per row, same as `.hedgehog/BMAD/`.
260
- - Don't expand a tweak into a rebuild. If a "tweak" actually requires
261
- redoing a phase (the artifact an upstream phase locked has to change,
262
- not just one line of what a later phase produced from it), that's the
263
- Correction Protocol say so and route it
264
- there rather than patching around it here. Use its **post-build entry**
265
- (in this core's own loop skill): the build is already at its Stop
266
- Condition, so there's no task in flight to stop and no loop to resume,
267
- and the correction is fixed forward in new commits rather than by
275
+ - Don't expand a tweak into a rebuild. A request `hedgehog-daily` sizes
276
+ above the tweak line gets routed, never patched around here and a
277
+ tweak that turns out mid-edit to reach a second layer or need a file
278
+ that doesn't exist stops and re-enters that gate.
279
+ - When the route is the Correction Protocol, use its **post-build entry**
280
+ (in this core's own loop skill): your entry condition is that nothing
281
+ is in flight, so there's no task to stop and no loop to resume, and
282
+ the correction is fixed forward in new commits rather than by
268
283
  reopening a `complete` task. The orchestrating session runs it and owns
269
284
  the commits, the same way `hedgehog verify` always is.
270
285
  - Don't run job 2's friction detection against anything other than
package/src/db/status.mjs CHANGED
@@ -55,6 +55,27 @@ function loadInFlightTasks(db) {
55
55
  return db.prepare(IN_FLIGHT_TASKS_SQL).all();
56
56
  }
57
57
 
58
+ // The in-flight list on its own, without the rest of graphStatus. The
59
+ // full report costs a drift comparison against core.yaml, a readiness
60
+ // simulation, an override scan, and two side-channel reads — everything
61
+ // `hedgehog status` prints. `hedgehog-daily` asks only "is a build in
62
+ // flight" and asks it before every change request, so it must not pay
63
+ // for a report it discards. Same query and same reaping contract as the
64
+ // full path; only the other sections are skipped.
65
+ export function inFlightTasks(db) {
66
+ return loadInFlightTasks(db);
67
+ }
68
+
69
+ // One line for `hedgehog status --brief`: what is in flight, or that
70
+ // nothing is. Deliberately not a subset of formatStatus's sections — a
71
+ // caller reading this wants a verdict, and the full report stays the
72
+ // right thing to read once the verdict is "something is".
73
+ export function formatBrief(inFlight) {
74
+ if (inFlight.length === 0) return 'IN FLIGHT 0 — nothing building or verifying';
75
+ const ids = inFlight.map((task) => task.id).join(', ');
76
+ return `IN FLIGHT ${inFlight.length} — ${ids}`;
77
+ }
78
+
58
79
  function countTasksByStatus(db) {
59
80
  const rows = db
60
81
  .prepare('SELECT status, COUNT(*) AS n FROM tasks GROUP BY status')
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgehog",
3
- "version": "6.1.2",
3
+ "version": "6.1.4",
4
4
  "description": "Hedgehog build discipline: ordered, tested, verified build steps.",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: filing-issues
3
+ description: Use when filing one or more GitHub issues for planned work — "file an issue for this", "turn this plan into issues", "open a tracking issue". Covers filing everything on skyf0xx/hedgehog regardless of which repo's code changes, whether to split a plan into a tracking issue plus sub-issues, which account files the issue, labels, and acceptance criteria. For how to word an issue, see the pr-writing skill.
4
+ ---
5
+
6
+ # Filing issues
7
+
8
+ The mechanics of getting planned work into GitHub. `pr-writing` owns how
9
+ an issue is worded — title shape, the Why/What structure, `<details>`
10
+ folding, and style. This skill owns everything before and around that.
11
+
12
+ ## Which repo
13
+
14
+ Every issue is filed on `skyf0xx/hedgehog`, never on a core's own repo
15
+ (e.g. the one shipping `full-stack-app` or `pwa-app`) — one issue queue
16
+ to track and review, regardless of which repo's code changes.
17
+
18
+ When the fix actually lands in a core repo, open the issue body with a
19
+ line naming that repo and linking it, so a contributor knows where the
20
+ PR belongs even though the issue itself doesn't live there.
21
+
22
+ ## One issue or several
23
+
24
+ Split when the parts have different reviewers, different repos, different
25
+ risk, or can be worked in parallel. Keep one issue when the work is a
26
+ single reviewable change, even a large one.
27
+
28
+ A split gets a tracking issue plus sub-issues:
29
+
30
+ - The tracking issue carries the Why, the scope boundary, and a numbered
31
+ list of sub-issues with a one-line description of each.
32
+ - Each sub-issue is self-contained — someone picking it up should not
33
+ have to read the tracker to know what to do.
34
+ - State the dependency edges explicitly, including their absence:
35
+ which can be picked up now, which blocks which, and which merely
36
+ prefer an order without blocking.
37
+ - File the tracker first so sub-issues can reference its number, then
38
+ patch the tracker with the real numbers once they exist.
39
+ - Comment `Part of #<tracker>` on each sub-issue.
40
+
41
+ ## Which account files it
42
+
43
+ Issues go out as the user's own `gh` session by default.
44
+
45
+ Some projects have a bot identity for maintainer actions. Use it only
46
+ when the user asks for it by name. A bot voice tuned for short notes
47
+ does not apply to a planned-work issue — write the issue at full length
48
+ and say that is what you are doing.
49
+
50
+ ## Labels
51
+
52
+ Read the target repo's labels before filing (`gh label list --repo
53
+ <owner/repo>`) — the engine repo and the core repos carry overlapping but
54
+ not identical sets.
55
+
56
+ Apply what is verifiable at filing time: a type label (`feature`, `bug`,
57
+ `documentation`) and any `risk:` label the change clearly earns.
58
+ `good-first-issue` fits an issue that is genuinely self-contained with an
59
+ obvious done state. Leave `size:` labels alone — they describe a diff
60
+ that does not exist yet.
61
+
62
+ ## Acceptance criteria
63
+
64
+ End every issue with a checkbox list a contributor ticks off and a
65
+ reviewer checks against. Each line is one observable outcome, not a
66
+ restatement of the task list.
67
+
68
+ - Testable by inspection or a command, not by judgment. "`pnpm nx test
69
+ mobile -- src/{module}/` passes on generated output" — not "the
70
+ generator works well."
71
+ - Include the things that must *not* change: the existing behavior that
72
+ still has to pass, the version that must not be bumped.
73
+ - Cover the whole change. A criterion nobody can check is noise; a
74
+ missing one is a gap a reviewer has to find themselves.
75
+
76
+ On a tracking issue, the criteria are the sub-issues plus the end-to-end
77
+ outcome that proves the whole set landed.
78
+
79
+ ## Before filing
80
+
81
+ Verify every claim the issue makes about existing behavior, and cite it
82
+ `file:line`. An issue is public and durable — a wrong claim in one sends
83
+ a contributor down a path that does not exist.
84
+
85
+ Confirm the split and the identity with the user before creating
86
+ anything — the repo is fixed, not a decision to make each time. Issue
87
+ creation is public and hard to reverse.
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: hedgehog-daily
3
+ description: Use when a change request lands on a project that already has `.hedgehog/` and no build in flight — a finished build being adjusted, or an adopted repo's next piece of work. Triggers on any "change this", "fix this", "add this" on such a project. Sizes the request against the installed core's own layers and routes it to one of three exits: a tweak made and committed here, change-work through `hedgehog intent add` and the core's loop, or a re-plan. Not for a build still in progress — that is the core's loop skill's own job.
4
+ ---
5
+
6
+ # Daily change-work
7
+
8
+ One gate, three exits, for every change request on a project whose build
9
+ graph already exists. It reads the installed core's layer sequence,
10
+ scope globs and verify commands out of `.hedgehog/core.yaml`, so it is
11
+ the same gate on every core.
12
+
13
+ The gate exists to stop pricing a two-line edit at the cost of the
14
+ largest change the discipline can handle. Routing up is a real decision
15
+ with a real cost, taken on stated conditions — not the safe default.
16
+
17
+ ## Entry
18
+
19
+ 1. **`.hedgehog/` exists.** Without it there is no core to read and no
20
+ graph to add to; this skill does not apply.
21
+ 2. **Nothing is in flight.** `hedgehog status --brief` — one line. If it
22
+ names any task, a build is mid-flight: this gate does not run. Read
23
+ the full `hedgehog status` and hand the request back to the core's own
24
+ loop skill, which owns work in progress.
25
+ 3. **Read `.hedgehog/core.yaml`.** The layer list is the input to every
26
+ decision below: each layer's `id`, `scope` globs, `verify` command,
27
+ `verify_radius` and `exclusive`. Read the file, not a memory of it.
28
+
29
+ ## The three exits
30
+
31
+ Decide by the conditions, in order. The first one that holds is the exit.
32
+
33
+ ### Re-plan
34
+
35
+ The locked planning artifact that governs this project no longer
36
+ describes what is being asked for. The core's own loop skill names which
37
+ artifact governs — the brief and layer sequence for a shipped core,
38
+ `.hedgehog/core-design.md` for an authored one, `.hedgehog/adoption.md`
39
+ for an adopted one.
40
+
41
+ Route to `planner`'s re-entry pass, which adds intents for new work
42
+ without re-running planning from scratch and without disturbing anything
43
+ already built.
44
+
45
+ Where the artifact's failure means the request is a different project
46
+ rather than an extension of this one, say so plainly instead of routing.
47
+ That artifact is never rewritten to accommodate new scope.
48
+
49
+ ### Change-work
50
+
51
+ Either condition puts the request here:
52
+
53
+ - It reaches more than one of the core's layers.
54
+ - It introduces a file, module, or capability that does not exist yet.
55
+
56
+ `hedgehog intent add`, then the installed core's own loop, unchanged.
57
+ Nothing about that path changes because this gate ran.
58
+
59
+ ### Tweak
60
+
61
+ Both conditions hold:
62
+
63
+ - Every file it touches is inside one layer's `scope` globs — one
64
+ layer, not two.
65
+ - Every file it touches already exists.
66
+
67
+ Then, in this session, with no subagent dispatched:
68
+
69
+ 1. Read the code it touches. Not a summary of it.
70
+ 2. Make the smallest correct edit.
71
+ 3. Run that layer's own `verify` command from `core.yaml`, at the depth
72
+ the next section states.
73
+ 4. Commit as one conventional commit, in the format the
74
+ `conventional-commits` skill states.
75
+
76
+ No `hedgehog intent add`, no `hedgehog plan`, no `hedgehog claim`, no
77
+ subagent. Nothing is written to the build graph.
78
+
79
+ ### Tweak is the default under ambiguity
80
+
81
+ When the conditions do not clearly place a request above the tweak line,
82
+ it takes the tweak exit. A gate that escalates when unsure prices every
83
+ change at its worst case, which is the failure this gate exists to
84
+ avoid.
85
+
86
+ An escalation the tweak reveals is cheap: a tweak that turns out to
87
+ touch a second layer or need a file that does not exist stops there and
88
+ re-enters this gate at the change-work exit, having cost one read.
89
+
90
+ ## Test and review depth on the tweak exit
91
+
92
+ A tweak inherits the test and review bar of the layer it lands in.
93
+
94
+ - A layer whose `verify_radius` equals its `scope`: run the layer's
95
+ `verify` command. No new tests, no `reviewer` pass.
96
+ - A layer with a wider `verify_radius`, or `exclusive: true`: the same
97
+ real test bar and `reviewer` pass that layer gets in the loop.
98
+
99
+ That is the loop's own rule — "Test depth follows verify radius. Review
100
+ follows exclusivity", stated in full in the core's loop skill — applied
101
+ to a layer instead of a compiled task. `verify_radius` and `exclusive`
102
+ are declared on the layer in `core.yaml`, so both are readable on a path
103
+ that compiles no task.
104
+
105
+ **A tweak landing in a wide-radius or exclusive layer is a signal.**
106
+ Integration layers are where behavior gets proven, so a change reaching
107
+ one is rarely as small as it looked when it was asked for. Re-check that
108
+ the tweak exit was the right exit. Do not bolt the loop's ceremony onto
109
+ the tweak path instead.
110
+
111
+ **The floor does not move.** A tweak to code with no tests does not get
112
+ to leave it that way where the layer's own bar says otherwise.
113
+
114
+ ## Hard rules
115
+
116
+ - Never take the tweak exit on a file that does not exist yet. A new
117
+ file is change-work by condition, whatever its size.
118
+ - Never widen a layer's `scope` to make a change fit the tweak exit.
119
+ A change that needs a wider scope is change-work.
120
+ - Never commit a tweak whose layer `verify` command fails. A failing
121
+ gate means the change is not done.
122
+ - Never batch two unrelated tweaks into one commit.
123
+ - Never rewrite the locked planning artifact to accommodate new scope —
124
+ that is the re-plan exit's decision, and its answer may be that this
125
+ is a different project.