@skyf0xx/hedgehog 6.1.2 → 6.1.3
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 +30 -3
- package/package.json +1 -1
- package/src/agents/reviewer.md +6 -1
- package/src/agents/tweaker.md +31 -31
- package/src/db/status.mjs +21 -0
- package/src/hosts/gemini/gemini-extension.json +1 -1
- package/src/skills/filing-issues/SKILL.md +87 -0
- package/src/skills/hedgehog-daily/SKILL.md +125 -0
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
|
-
|
|
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
package/src/agents/reviewer.md
CHANGED
|
@@ -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.
|
package/src/agents/tweaker.md
CHANGED
|
@@ -59,29 +59,29 @@ style, a piece of behavior), the existing codebase, the commit log.
|
|
|
59
59
|
discipline as the rest of the build (`fix(<scope>): <what>` or
|
|
60
60
|
`style(<scope>): <what>`, whichever fits).
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
one applies depends on whether the core has a module axis to hang new
|
|
68
|
-
work on:
|
|
62
|
+
**Size every request with the `hedgehog-daily` skill.** That skill owns
|
|
63
|
+
the tweak / change-work / re-plan decision and its conditions, and it
|
|
64
|
+
reads them against the installed core's own `.hedgehog/core.yaml` — run
|
|
65
|
+
it rather than judging the size here. A completed build is extendable,
|
|
66
|
+
not sealed, so a request above the tweak line gets routed, not refused.
|
|
69
67
|
|
|
70
|
-
|
|
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.
|
|
68
|
+
What each exit means for you:
|
|
77
69
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
- **Tweak** — make it here, per that skill's tweak exit and this file's
|
|
71
|
+
Workflow step 3.
|
|
72
|
+
- **Change-work** — route it onward. On a module axis, that is `planner`
|
|
73
|
+
running `hedgehog-planning-intake`'s **Re-entry pass**, which adds
|
|
74
|
+
intents for the new work without re-running planning from scratch and
|
|
75
|
+
without disturbing anything already built. A core with no module axis
|
|
76
|
+
has no intent for `planner` to add, so it goes to the **Correction
|
|
77
|
+
Protocol's post-build entry** in the core's own loop skill instead,
|
|
78
|
+
which re-runs whichever phases the change reaches and rebuilds the
|
|
79
|
+
artifact.
|
|
80
|
+
- **Re-plan** — the locked planning artifact no longer holds. Route to
|
|
81
|
+
`planner`'s re-entry pass, or, where that artifact's failure means the
|
|
82
|
+
request is a different project rather than an extension of this one,
|
|
83
|
+
say so plainly instead of routing. Never rewrite that artifact to
|
|
84
|
+
accommodate new scope.
|
|
85
85
|
|
|
86
86
|
### Job 2 — Friction review, user feedback, and issue suggestion
|
|
87
87
|
|
|
@@ -211,11 +211,11 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
|
|
|
211
211
|
drop it either way; a "no" or no response is not a prompt to explain
|
|
212
212
|
further or ask again later in this session. If the user says yes,
|
|
213
213
|
hand off to the `hedgehog-contributing` skill.
|
|
214
|
-
3. **Job 1, every run**:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
commit
|
|
214
|
+
3. **Job 1, every run**: run the `hedgehog-daily` skill on the user's
|
|
215
|
+
request. On its tweak exit, make the change there — read the actual
|
|
216
|
+
code it touches (not a summary), edit, verify with the touched layer's
|
|
217
|
+
own `verify` command from `.hedgehog/core.yaml`, commit as its own
|
|
218
|
+
small conventional commit. On either other exit, route as above.
|
|
219
219
|
4. **Repeat step 3** for as many tweaks as the user has, one at a time —
|
|
220
220
|
don't batch unrelated tweaks into one commit.
|
|
221
221
|
|
|
@@ -257,11 +257,11 @@ discipline as `.hedgehog/BMAD/`. A later related incident is its own new
|
|
|
257
257
|
`reviewed:` row logged after every other row currently in the log?
|
|
258
258
|
- Never edit or delete a prior row in the `friction` table — it's
|
|
259
259
|
write-once per row, same as `.hedgehog/BMAD/`.
|
|
260
|
-
- Don't expand a tweak into a rebuild.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
260
|
+
- Don't expand a tweak into a rebuild. A request `hedgehog-daily` sizes
|
|
261
|
+
above the tweak line gets routed, never patched around here — and a
|
|
262
|
+
tweak that turns out mid-edit to reach a second layer or need a file
|
|
263
|
+
that doesn't exist stops and re-enters that gate.
|
|
264
|
+
- When the route is the Correction Protocol, use its **post-build entry**
|
|
265
265
|
(in this core's own loop skill): the build is already at its Stop
|
|
266
266
|
Condition, so there's no task in flight to stop and no loop to resume,
|
|
267
267
|
and the correction is fixed forward in new commits rather than by
|
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')
|
|
@@ -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.
|