@lemoncode/lemony 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/catalog/VERSION +1 -1
- package/catalog/agents/architect.md +11 -4
- package/catalog/agents/implementer.md +46 -5
- package/catalog/agents/orchestrator.md +143 -345
- package/catalog/agents/reviewer.md +131 -8
- package/catalog/agents/spec-author.md +4 -1
- package/catalog/agents/spinoff.md +100 -0
- package/catalog/agents/triage.md +38 -0
- package/catalog/agents/ui-design.md +147 -0
- package/catalog/agents/ui-designer.md +3 -2
- package/catalog/commands/resume.md +1 -1
- package/catalog/commands/triage.md +2 -2
- package/catalog/schemas/tier2-events-history.md +17 -0
- package/catalog/schemas/tier2-events.md +10 -10
- package/catalog/skills/mutation-testing/SKILL.md +6 -2
- package/catalog/skills/prd-to-spec/SKILL.md +28 -2
- package/catalog/skills/resolve-discovery/SKILL.md +6 -2
- package/catalog/skills/spec-compliance-check/SKILL.md +8 -4
- package/catalog/skills/task-closeout/SKILL.md +3 -2
- package/catalog/skills/test-gap-report/SKILL.md +4 -0
- package/catalog/skills/verify/SKILL.md +3 -0
- package/catalog/templates/claude-code/agents.md.tpl +9 -4
- package/dist/cli.mjs +8 -2
- package/package.json +1 -1
|
@@ -16,6 +16,23 @@ invokes sub-agents with fresh context, runs the human approval gate, manages the
|
|
|
16
16
|
issue label lifecycle, and runs closeout. The entry-protocol summary lives in
|
|
17
17
|
`agents.md`; this file is the operational detail.
|
|
18
18
|
|
|
19
|
+
## Companion files (lazy — read on trigger only)
|
|
20
|
+
|
|
21
|
+
Three procedures live in sibling files, kept out of boot context by design (a fourth
|
|
22
|
+
sibling, `.claude/agents/fit-assessment.md`, is a reference doc for the task-fit
|
|
23
|
+
dial — not a procedure; consult it on a borderline classification). Read the
|
|
24
|
+
file **when its trigger fires**, then run it as if it were a section here:
|
|
25
|
+
|
|
26
|
+
- **`.claude/agents/triage.md`** — the L2 lightweight round-trip. Trigger: dispatch
|
|
27
|
+
lands on TRIAGE, or a pending stub's fit assessment lands L2.
|
|
28
|
+
- **`.claude/agents/ui-design.md`** — UI design (DEFINE + REVIEW). Trigger: the
|
|
29
|
+
DEFINE activation gate fires (L1 step 3), an implemented UI change reaches
|
|
30
|
+
review (`ui-handoff.md` exists), a resume lands on the sub-state
|
|
31
|
+
`awaiting design definition`, or `/sync-design-tokens`.
|
|
32
|
+
- **`.claude/agents/spinoff.md`** — mid-task capture (the `/spinoff` offer). Trigger:
|
|
33
|
+
the human mentions what may be an independent, non-blocking defect, or a sub-agent
|
|
34
|
+
summary carries a `## Side-findings` block.
|
|
35
|
+
|
|
19
36
|
## Dispatch
|
|
20
37
|
|
|
21
38
|
Parse the first prompt's intent (or honor a slash command):
|
|
@@ -29,9 +46,7 @@ Parse the first prompt's intent (or honor a slash command):
|
|
|
29
46
|
— a `spec-ready` issue resumes at the approval gate, an `in-progress` one at the
|
|
30
47
|
active subtask. A **`harness:status:spec-in-progress`** task whose `progress.md` records
|
|
31
48
|
the sub-state **`awaiting design definition`** (+ `harness:needs-design`) is a design
|
|
32
|
-
parked at "stop for handoff"
|
|
33
|
-
yourself** to finish `ui-handoff.md` (the UI Designer then critiques it), then remove
|
|
34
|
-
`harness:needs-design` and continue toward spec-ready. A **`harness:status:closeout-pending`** task is an exception with
|
|
49
|
+
parked at "stop for handoff": read `.claude/agents/ui-design.md` and re-enter there. A **`harness:status:closeout-pending`** task is an exception with
|
|
35
50
|
nothing to check out: its task PR already merged and its state is archived under
|
|
36
51
|
`_archive/<id>/`. Its issue is **closed** (the task PR's `Closes #<id>` fired), so it
|
|
37
52
|
surfaces in the queue only when you list closed issues too (`--state all`) — an
|
|
@@ -52,7 +67,8 @@ Parse the first prompt's intent (or honor a slash command):
|
|
|
52
67
|
only at this commit point (entering a level, or closing) — so an **abandoned pickup
|
|
53
68
|
correctly stays in the queue** rather than vanishing half-done. **A stub carrying
|
|
54
69
|
`harness:architecture-drift`** is an `docs/architecture.md` map-fix, not code: run
|
|
55
|
-
the ordinary L2 machinery (branch, PR, the merge
|
|
70
|
+
the ordinary L2 machinery per `.claude/agents/triage.md` (branch, PR, the merge
|
|
71
|
+
gate — a map-fix _is_ reviewable: does
|
|
56
72
|
the map now match reality?), but dispatch the **Architect with `update-architecture`**
|
|
57
73
|
(it reads the map plus the cited divergent area and makes the surgical edit) in place of
|
|
58
74
|
the Implementer; closeout's `update-architecture` then re-runs over that diff as a no-op,
|
|
@@ -61,8 +77,8 @@ Parse the first prompt's intent (or honor a slash command):
|
|
|
61
77
|
run the task-fit assessment as usual, never break on the absent routing target.
|
|
62
78
|
- **DEFINE** — "define / new task / I have an idea" → the **L1 full-SDD round-trip**
|
|
63
79
|
below.
|
|
64
|
-
- **TRIAGE** — "bug / error in / broken / fails when" → the **L2 lightweight
|
|
65
|
-
|
|
80
|
+
- **TRIAGE** — "bug / error in / broken / fails when" → the **L2 lightweight
|
|
81
|
+
round-trip**: read `.claude/agents/triage.md` and run it.
|
|
66
82
|
- **ORIENT** — the first prompt carries **no clear intent**: a bare greeting ("hi",
|
|
67
83
|
"hola", "¿qué hay?"), an orientation question ("what should I pick up?", "¿qué
|
|
68
84
|
toca?"), or effectively nothing. This is the proactive half of the session-orient
|
|
@@ -94,9 +110,6 @@ the prompt is ambiguous **between** harness modes (not intentless), ask
|
|
|
94
110
|
**one** disambiguation question, then proceed. Worst case is benign either way (menu not
|
|
95
111
|
rendered at all → the human types `/resume`/`/define` as today, a true no-op; menu shown
|
|
96
112
|
when unwanted → it is ignored), so the boundary is a comfort, not a correctness, call.
|
|
97
|
-
Note this "not rendered" no-op is distinct from the in-menu degradations above (empty
|
|
98
|
-
queue / no `gh`), where the menu **is** rendered with the start options and only the
|
|
99
|
-
listing is skipped.
|
|
100
113
|
|
|
101
114
|
## Task-fit assessment (light, non-blocking)
|
|
102
115
|
|
|
@@ -127,24 +140,27 @@ sibling `fit-assessment.md`; consult it for a borderline classification.
|
|
|
127
140
|
(`git fetch && git checkout -b harness/<id>-<slug> origin/<default>`). All task
|
|
128
141
|
work — spec **and** code — lives on this branch; nothing touches the default
|
|
129
142
|
branch until the human merge gate.
|
|
130
|
-
3. **Design the UI (if it touches UI)** —
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
touch UI skips straight to the spec.
|
|
138
|
-
4. **Dispatch the Spec Author** — invoke the **Spec Author** sub-agent (fresh context
|
|
143
|
+
3. **Design the UI (if it touches UI)** — before any spec work, evaluate the
|
|
144
|
+
**activation gate** (your own LLM judgment, no keyword scorer), two parts both
|
|
145
|
+
true: (1) the repo has a frontend — UI to
|
|
146
|
+
design, not a pure library / CLI / backend — and (2) this task adds or alters
|
|
147
|
+
something a user sees or interacts with. Bias to include on a borderline call.
|
|
148
|
+
Only when it fires, read `.claude/agents/ui-design.md` and run its DEFINE flow
|
|
149
|
+
(design-stop offer → `grill-ui` → UI Designer critique). A task that doesn't
|
|
150
|
+
touch UI skips straight to the spec — without reading the companion.
|
|
151
|
+
4. **Dispatch the Spec Author** — invoke the **Spec Author** sub-agent (fresh context,
|
|
152
|
+
spawn by reference — §Sub-agent invocation) with
|
|
139
153
|
the PRD path (and the `ui-handoff.md` if one was authored), the issue `<id>`, and the
|
|
140
154
|
branch. It runs `prd-to-spec` (→ `requirements.md` EARS + `design.md` + `tasks.md` under
|
|
141
155
|
`tasks/<id>/spec/` — no draft holder, the id is real from the start) then `spec-to-issue`
|
|
142
156
|
(fills the issue **body** from the spec; it creates nothing and moves no labels). It
|
|
143
157
|
returns a summary.
|
|
144
|
-
5. **Reach spec-ready** — on its return
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
158
|
+
5. **Reach spec-ready** — on its return: **before** flipping to spec-ready,
|
|
159
|
+
`ui-handoff.md` must be complete and `harness:needs-design` removed — a
|
|
160
|
+
precondition, not a cleanup: a spec-ready task never carries the label
|
|
161
|
+
(`.claude/agents/ui-design.md`). Then flip
|
|
162
|
+
`harness:status:spec-in-progress → harness:status:spec-ready`,
|
|
163
|
+
then commit and push the task state to the branch so
|
|
148
164
|
anyone can pick it up:
|
|
149
165
|
`git add .claude/state/tasks/<id>/ && git commit -m "spec(<id>): <topic>" && git push -u origin harness/<id>-<slug>`.
|
|
150
166
|
The committed-and-pushed spec plus the spec-ready issue **are** the handoff; the
|
|
@@ -160,16 +176,17 @@ harness:status:spec-ready`, then commit and push the task state to the branch so
|
|
|
160
176
|
`harness:status:in-progress` and proceed **per the mode chosen at the gate**
|
|
161
177
|
(§Implementation mode): **all-at-once** invokes the **Implementer** sub-agent (fresh
|
|
162
178
|
context) once with the `tdd` skill and the branch — it keeps `progress.md` live and
|
|
163
|
-
signals done; **step-by-step** runs the per-
|
|
164
|
-
implementation instead, and rejoins this flow at step 8 after the last
|
|
179
|
+
signals done; **step-by-step** runs the per-group loop in §Step-by-step
|
|
180
|
+
implementation instead, and rejoins this flow at step 8 after the last group.
|
|
165
181
|
8. **Review** — flip to `harness:status:in-review` and **open the PR**
|
|
166
182
|
(`gh pr create`, `harness/<id>-<slug> → <default>`, with `Closes #<id>` in the PR
|
|
167
183
|
body so the provider auto-links and closes the issue on merge). Invoke
|
|
168
184
|
the **Reviewer** sub-agent (fresh context) with the `senior-review` skill to review
|
|
169
185
|
that PR. Fresh context is what prevents the Implementer's confirmation bias. **If the
|
|
170
|
-
task touched UI
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
task touched UI** — the durable signal is that `tasks/<id>/spec/ui-handoff.md`
|
|
187
|
+
exists — also invoke the **UI Designer** as a distinct design + a11y lens
|
|
188
|
+
(REVIEW in `.claude/agents/ui-design.md`). Either lens rejecting routes back to the
|
|
189
|
+
Implementer (rejection is transient — no dedicated
|
|
173
190
|
label); on approval (both lenses), go to the merge gate.
|
|
174
191
|
9. **Merge gate** — see below. Human-explicit, never auto-merged.
|
|
175
192
|
10. **Closeout** — see below.
|
|
@@ -184,7 +201,9 @@ spec-ready queue (a RESUME of a `spec-ready` issue — the typical handoff), che
|
|
|
184
201
|
its branch, read the spec cold, and run this gate before writing any code.
|
|
185
202
|
|
|
186
203
|
1. Present the spec to the human: a short summary plus links to
|
|
187
|
-
`tasks/<id>/spec/{requirements,design,tasks}.md` and the issue.
|
|
204
|
+
`tasks/<id>/spec/{requirements,design,tasks}.md` and the issue. `tasks.md`
|
|
205
|
+
carries the **step grouping** the step-by-step loop would follow (risk-sized
|
|
206
|
+
headers, one-line rationale each) — approving the spec approves the grouping.
|
|
188
207
|
2. Wait for an explicit decision:
|
|
189
208
|
- **Approve** → ask the **implementation mode** in the same interaction
|
|
190
209
|
(§Implementation mode — the human just read `tasks.md` cold, the best moment to
|
|
@@ -207,7 +226,7 @@ its branch, read the spec cold, and run this gate before writing any code.
|
|
|
207
226
|
3. Never self-approve. Whoever implements signs off — catching a misunderstanding here,
|
|
208
227
|
before any code, is far cheaper than at review. The `/define`, `/resume`, `/triage`
|
|
209
228
|
slash commands are thin mode-forcers layered on this same behavior; the urgency
|
|
210
|
-
override `/hotfix` (which
|
|
229
|
+
override `/hotfix` (which defers the wait while the Reviewer still runs async) and the
|
|
211
230
|
`/bypass` escape hatch (L3) are documented in `.claude/commands/`. The gate itself is
|
|
212
231
|
permanent — the commands force a mode, they never remove a human gate (only `/hotfix`
|
|
213
232
|
defers one, by contract).
|
|
@@ -224,13 +243,14 @@ these descriptions:
|
|
|
224
243
|
> you evaluate the final result once. Choose this for small or low-risk
|
|
225
244
|
> specs, or when you'd rather not be interrupted.
|
|
226
245
|
>
|
|
227
|
-
> **Step-by-step** — The Implementer completes ONE
|
|
228
|
-
>
|
|
246
|
+
> **Step-by-step** — The Implementer completes ONE group of tasks at a time
|
|
247
|
+
> (the risk-sized groups in the `tasks.md` you just approved). Each group is
|
|
248
|
+
> reviewed in isolation (implementer↔reviewer fix-loop until clean, max 3
|
|
229
249
|
> rejections), then paused for you: inspect the code, run it, and answer
|
|
230
250
|
> **OK** / **request changes** / **OK and switch to all-at-once**. After the
|
|
231
|
-
> last
|
|
251
|
+
> last group, the normal flow resumes unchanged (full-pass review + merge
|
|
232
252
|
> gate). Choose this for large or risky specs where a single end-of-task
|
|
233
|
-
> review dump would be too much to evaluate. Note:
|
|
253
|
+
> review dump would be too much to evaluate. Note: groups with no runnable
|
|
234
254
|
> surface (internal refactors) still checkpoint — inspect and OK.
|
|
235
255
|
|
|
236
256
|
Record the answer in `progress.md` (`Mode: …`) — it is execution state, not a label and
|
|
@@ -239,55 +259,64 @@ applies. The mode is switchable **downward only** (step-by-step → all-at-once,
|
|
|
239
259
|
at every checkpoint); there is no upgrade path — all-at-once has no stop where the
|
|
240
260
|
switch could be offered.
|
|
241
261
|
|
|
242
|
-
## Step-by-step implementation (the per-
|
|
243
|
-
|
|
244
|
-
One step = one `tasks.md`
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
262
|
+
## Step-by-step implementation (the per-group loop)
|
|
263
|
+
|
|
264
|
+
One step = one `tasks.md` **group**, 1:1 with the grouping the human approved at the
|
|
265
|
+
spec gate. Tasks inside a group stay atomic — the grouping sets how often review and
|
|
266
|
+
the human checkpoint run, never how the Implementer works. A `tasks.md` without group
|
|
267
|
+
headers (a legacy or hand-written spec) runs **one task per group** — the pre-grouping
|
|
268
|
+
cadence. Tasks added mid-implementation (a resolved discovery) default to **their own
|
|
269
|
+
group**, appended at the end of the loop — M grows, and already-resolved step numbers
|
|
270
|
+
never shift. For each group, in order:
|
|
271
|
+
|
|
272
|
+
1. **Implement the group** — invoke the **Implementer** sub-agent (fresh context, as
|
|
273
|
+
always) scoped to **this one group**: give it the branch, the task-state paths, and
|
|
274
|
+
the group's id + header line in `tasks.md` — by reference (§Sub-agent invocation),
|
|
275
|
+
it reads the group's tasks from the file itself (`tdd` skill — checkbox by checkbox
|
|
276
|
+
with small commits, as always). It commits to the branch, logs to
|
|
277
|
+
`progress.md`, and signals done. **No PR yet** — the PR opens after the last group,
|
|
251
278
|
as in all-at-once; the human inspects and runs the **local checkout** (a checkpoint
|
|
252
|
-
never needs GitHub
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
279
|
+
never needs GitHub; the branch is pushed best-effort at each checkpoint — step 3).
|
|
280
|
+
2. **Per-step review** — invoke the **Reviewer** sub-agent (fresh context) **by
|
|
281
|
+
reference** (§Sub-agent invocation): the group id + its header line — it reads the
|
|
282
|
+
group's tasks and requirements itself — scoped to the **group's diff against its
|
|
283
|
+
slice of the spec**. The verdict is **local**
|
|
257
284
|
(`progress.md` + session narration) — no issue comment; only the final full-pass
|
|
258
285
|
posts one. **On a UI-touching step**, also run the deterministic design gates here —
|
|
259
|
-
`design-tokens validate` + `design-tokens contrast`, agent-free and cheap — and let the
|
|
286
|
+
`lemony design-tokens validate` + `lemony design-tokens contrast`, agent-free and cheap — and let the
|
|
260
287
|
project's a11y lint ride the step's lint; a failure is an early-catch REJECT so a bad
|
|
261
288
|
token pair or hardcoded value can't propagate to a later step. The **judgment** design
|
|
262
289
|
lenses (`design-critique` / `a11y-audit`) do **not** run per-step — they are full-pass
|
|
263
|
-
only (
|
|
290
|
+
only (REVIEW in `.claude/agents/ui-design.md`). On REJECT, re-invoke the Implementer (fresh) with the
|
|
264
291
|
feedback and re-review — the fix-loop runs until clean, **capped at 3 REJECTs on the
|
|
265
292
|
same step**:
|
|
266
293
|
at the cap, stop the loop and bring the disagreement to the human as an
|
|
267
|
-
**anticipated checkpoint** (
|
|
268
|
-
an ambiguous spec or a real disagreement — the human arbitrates). The anticipated
|
|
294
|
+
**anticipated checkpoint** (the human arbitrates). The anticipated
|
|
269
295
|
checkpoint **is** the checkpoint of step 3 — same three answers, same
|
|
270
296
|
`step_completed` emit (here `review_iterations` is 3) and the same transient
|
|
271
297
|
`awaiting human checkpoint (step N/M)` line in `progress.md` — except you present
|
|
272
298
|
the unresolved disagreement (both positions, the spec slice) instead of a clean
|
|
273
299
|
step.
|
|
274
|
-
3. **Human checkpoint** — first
|
|
275
|
-
|
|
300
|
+
3. **Human checkpoint** — first set the open step's `progress.md` line to
|
|
301
|
+
`awaiting human checkpoint (step N/M)` (step 5), then commit the task state and
|
|
302
|
+
**push the branch, best-effort**, as **one composite invocation** (§Turn economy).
|
|
303
|
+
This commit and step 4's OK-side twin are **yours, anchored to your checkpoint
|
|
304
|
+
turns** — never delegated to a sub-agent's return path (a commit left to a
|
|
305
|
+
sub-agent may never land, and the checkpoint is then invisible to a cold
|
|
306
|
+
`/resume`):
|
|
276
307
|
|
|
277
308
|
```bash
|
|
278
309
|
git add .claude/state/tasks/<id>/ && \
|
|
279
|
-
git commit -m "step(<id>): step <N> awaiting checkpoint"
|
|
280
|
-
|
|
310
|
+
git commit -m "step(<id>): step <N> awaiting checkpoint"; \
|
|
311
|
+
git push # best-effort — a failure warns, never blocks
|
|
281
312
|
```
|
|
282
313
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
This is the long human wait where a session is likeliest to die, so the push is
|
|
287
|
-
what lets another machine's `/resume` see the step and its pending checkpoint.
|
|
314
|
+
A failed push — offline, auth — warns and never blocks; the next push carries
|
|
315
|
+
it. This long wait is where a session likeliest dies — the push is what lets
|
|
316
|
+
another machine's `/resume` see the pending checkpoint.
|
|
288
317
|
Then present the step: what was built, where to look, how to run it. Three
|
|
289
318
|
answers:
|
|
290
|
-
- **OK** → emit `step_completed` (below), next
|
|
319
|
+
- **OK** → emit `step_completed` (below), next group.
|
|
291
320
|
- **Changes** (with feedback) → fresh Implementer with the feedback → per-step
|
|
292
321
|
review again (step 2; the review-iteration count resets) → checkpoint again.
|
|
293
322
|
Human-requested changes go through review like any other fix — **nothing reaches
|
|
@@ -308,7 +337,11 @@ order:
|
|
|
308
337
|
step sub-state back up from `progress.md`.
|
|
309
338
|
|
|
310
339
|
4. **Telemetry** — every **resolved checkpoint** emits one event (so a step the human
|
|
311
|
-
sent back emits more than once, same `--step`)
|
|
340
|
+
sent back emits more than once, same `--step`); the emit, the step's resolved
|
|
341
|
+
`progress.md` line (step 5) and the resolution state commit (on OK, plain or
|
|
342
|
+
downgrade: `step(<id>): step <N> checkpoint OK`) + best-effort push ride as
|
|
343
|
+
**one composite turn** (§Turn economy) — without that commit a cold `/resume`
|
|
344
|
+
still reads `awaiting` after the last group. `<review-iterations>` is the number
|
|
312
345
|
of Reviewer invocations that preceded this checkpoint (≥ 1; resets after a
|
|
313
346
|
"changes"):
|
|
314
347
|
|
|
@@ -360,9 +393,9 @@ order:
|
|
|
360
393
|
on: the awaiting line re-presents the pending checkpoint, the fix-loop line
|
|
361
394
|
re-enters the implement→review loop at that iteration.
|
|
362
395
|
|
|
363
|
-
After the **last
|
|
396
|
+
After the **last group**, rejoin the normal flow unchanged (L1 step 8): flip to
|
|
364
397
|
`in-review`, open the PR, and run the **full-pass Reviewer** over everything against
|
|
365
|
-
the spec. The full-pass may reject anything, **including human-OK'd
|
|
398
|
+
the spec. The full-pass may reject anything, **including human-OK'd steps** — a
|
|
366
399
|
checkpoint OK means "right direction and it runs", not a review waiver; the full-pass
|
|
367
400
|
wins, and the human still holds the merge gate to disagree.
|
|
368
401
|
|
|
@@ -380,104 +413,12 @@ When you get that summary, run the **`resolve-discovery`** skill. It pauses the
|
|
|
380
413
|
`paused_from`), has you arbitrate the question with the human, routes the artifact
|
|
381
414
|
update to its owner (the agent that created it), records the resolution in
|
|
382
415
|
`discoveries.md`, clears the discovery flag, restores the status, and re-invokes the
|
|
383
|
-
paused sub-agent with the decision.
|
|
416
|
+
paused sub-agent with the decision. A discovery can also be raised by **you** (e.g. a
|
|
417
|
+
checkpoint "changes" request that contradicts the spec): the same skill runs, with
|
|
418
|
+
nothing to re-invoke — the resolution re-enters the loop where it paused. You are the
|
|
419
|
+
only one who talks to the human and
|
|
384
420
|
moves labels — never let a sub-agent self-resolve.
|
|
385
421
|
|
|
386
|
-
## Mid-task capture (`/spinoff` offer)
|
|
387
|
-
|
|
388
|
-
While you (the hat) are driving the conversation — between sub-agent dispatches, at
|
|
389
|
-
gates, in ordinary back-and-forth — the human will sometimes mention an **independent,
|
|
390
|
-
non-blocking** defect: one the current task does **not** need to touch, and that doesn't
|
|
391
|
-
have to be fixed now ("oh, the export button is also broken on Safari"). Don't let it
|
|
392
|
-
evaporate and don't context-switch to it: **offer to spin it off**. The discriminator is
|
|
393
|
-
_independence_ — is this something the current task touches anyway?
|
|
394
|
-
|
|
395
|
-
This is distinct from three neighbours:
|
|
396
|
-
|
|
397
|
-
- **Just fix it** — if the defect is **in scope for the current task** (something this
|
|
398
|
-
change already touches), fix it in the current PR. No offer, no stub — spinning off
|
|
399
|
-
in-scope trivia only pollutes the backlog.
|
|
400
|
-
- **T3 SCOPE_DRIFT** (discovery) — when completing **the current task** _forces_ you to
|
|
401
|
-
touch out-of-scope work (the task can't finish without it). That pauses via
|
|
402
|
-
`resolve-discovery`. `/spinoff` is the opposite: the current task doesn't need the
|
|
403
|
-
defect touched, so it never pauses and keeps going.
|
|
404
|
-
- **`/define`** — a feature _idea_, not a defect. Route those to DEFINE, not `/spinoff`.
|
|
405
|
-
|
|
406
|
-
Calibration — **lean toward offering** so nothing slips, but keep it
|
|
407
|
-
frictionless and noise-free:
|
|
408
|
-
|
|
409
|
-
- Offer only when you'd bet it's a **genuine, independent defect worth a tracked issue**
|
|
410
|
-
— not for every stray observation, and not for anything you can fix in place. When in
|
|
411
|
-
doubt _whether to track a real independent defect_, lean toward offering; when in doubt
|
|
412
|
-
_whether it's even a real, independent bug_, stay quiet.
|
|
413
|
-
- The offer is a **single line**, in the human's language: _"This looks like an
|
|
414
|
-
independent bug — want me to `/spinoff` it and keep going?"_ One tap to dismiss; if the
|
|
415
|
-
human says no, drop it and continue without comment.
|
|
416
|
-
- **Never re-offer the same finding twice in a session.** "Same finding" = the same
|
|
417
|
-
underlying defect even if re-described; when unsure, treat a clearly new symptom as new.
|
|
418
|
-
This rule is the **only** human-side dedup (the capture verb is non-idempotent by
|
|
419
|
-
design — each run opens a fresh stub), so honor it.
|
|
420
|
-
- The offer **never pauses** the current task and never blocks on a reply — if the human
|
|
421
|
-
ignores it and keeps working, so do you.
|
|
422
|
-
|
|
423
|
-
On **accept**, capture it exactly as the `/spinoff` command does — the `spinoff` CLI
|
|
424
|
-
verb via the launcher, with the **current task's id** as the parent (recover it the same
|
|
425
|
-
way `/spinoff` does — from the `harness/<id>-…` branch or active task state; omit
|
|
426
|
-
`--parent` if there is no active task):
|
|
427
|
-
|
|
428
|
-
```bash
|
|
429
|
-
.claude/hooks/lib/lemony.sh spinoff \
|
|
430
|
-
--title="<one-line symptom>" \
|
|
431
|
-
--body="<where it was seen; a code pointer if you have one>" \
|
|
432
|
-
--parent=<current task id> \
|
|
433
|
-
--severity=<low|medium|high|critical>
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
Stub creation is **fail-loud** (a non-zero exit means it did not open — surface it, don't
|
|
437
|
-
pretend it was captured); the telemetry emit is **best-effort** (a `Warning:` means only
|
|
438
|
-
the event failed, the stub stands). Relay the verb's own `Captured #<id>…` line (it
|
|
439
|
-
carries the parent link) and **return to the current task**. The stub waits in the backlog as `harness:status:pending`
|
|
440
|
-
for a later pickup. The human can also trigger this directly with the `/spinoff` command;
|
|
441
|
-
the offer is the safety net for when they don't remember it mid-flow.
|
|
442
|
-
|
|
443
|
-
### From a sub-agent (the side-finding channel)
|
|
444
|
-
|
|
445
|
-
The same offer applies when the source is **not the human but a sub-agent's return
|
|
446
|
-
summary**. A sub-agent runs in fresh context and cannot interrupt you, so when it spots a
|
|
447
|
-
defect that is **independent of its task** (the task finished fine without touching it) it
|
|
448
|
-
**notes it instead of pausing** — that is the `note-side-finding` skill, the non-pausing
|
|
449
|
-
sibling of `raise-discovery`. It appends a `## Side-findings` block to its summary, one
|
|
450
|
-
bullet per finding (`symptom` / `location` / optional `severity`), and keeps working. (A
|
|
451
|
-
**blocking** defect is the opposite case — the sub-agent raises a T1–T6 discovery and
|
|
452
|
-
stops; you handle that with `resolve-discovery`, above.)
|
|
453
|
-
|
|
454
|
-
When you **read back a sub-agent's summary**, scan for a `## Side-findings` block. For each
|
|
455
|
-
bullet, make the **same single-line `/spinoff` offer** as for a human-mentioned defect —
|
|
456
|
-
pre-filled from the bullet (`--title` ← symptom, `--body` ← location, `--severity` ← the
|
|
457
|
-
read if given), the active task as `--parent`. Same calibration applies verbatim: lean
|
|
458
|
-
toward offering, one-tap dismissal, **never re-offer the same finding twice** (a
|
|
459
|
-
sub-agent's finding and a later human mention of the same defect are the _same_ finding),
|
|
460
|
-
and it **never pauses** the task. A side-finding is a candidate for the offer, not an
|
|
461
|
-
auto-capture — you still make the call and the human still decides.
|
|
462
|
-
|
|
463
|
-
A bullet tagged **`kind: drift`** is `docs/architecture.md` map staleness,
|
|
464
|
-
not a code defect: add **`--kind=architecture-drift`** to the `/spinoff` so the stub carries
|
|
465
|
-
the `harness:architecture-drift` routing label and a later pickup resolves it via the
|
|
466
|
-
Architect's `update-architecture` (a targeted map-fix), not a code change. **Fallback:** if
|
|
467
|
-
`update-architecture` is not installed (the project keeps no `architecture.md`), drop the
|
|
468
|
-
`--kind` and capture it as a generic stub — never let the offer fail because the routing
|
|
469
|
-
target is absent.
|
|
470
|
-
|
|
471
|
-
Two things you own because the sub-agent can't: **(1) cross-round dedup.** A sub-agent
|
|
472
|
-
re-invoked with fresh context (e.g. a Reviewer you rejected and re-ran) has **no memory of
|
|
473
|
-
what it side-noted before** and will re-emit the same `## Side-findings` block every round.
|
|
474
|
-
You hold the continuous context, so dedup is yours: an identical or re-described bullet
|
|
475
|
-
from a later round is the _same_ finding — don't re-offer it. **(2) gate ordering.** When
|
|
476
|
-
the read-back lands at a gate (a Reviewer returns right before the merge gate), make the
|
|
477
|
-
side-finding offer **after** the gate prompt, never before — the gate decision is primary;
|
|
478
|
-
the offer trails it as a secondary, dismissable line so it never splits attention at the
|
|
479
|
-
high-stakes moment.
|
|
480
|
-
|
|
481
422
|
## Architect (on-demand)
|
|
482
423
|
|
|
483
424
|
The **Architect** is always installed but invoked **on-demand** — it is not a step in
|
|
@@ -505,172 +446,24 @@ Dispatch it (fresh context, Task tool) when:
|
|
|
505
446
|
- **Orientation is needed** — before a decision or spec in a large or unfamiliar
|
|
506
447
|
codebase, dispatch it with `code-explorer` for a read-only map.
|
|
507
448
|
- **Closeout — the Architect's reliable activation checkpoint** — the `task-closeout`
|
|
508
|
-
skill drives durable
|
|
509
|
-
discretionary triggers otherwise lose to "unblock the paused
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
Give it the context (the discovery entry + its resolution, the change, or the request)
|
|
518
|
-
and read back its summary. The Architect is **not a gate** — it produces an artifact and
|
|
449
|
+
skill drives three durable-capture activations at the end of every task, in cold
|
|
450
|
+
blood, where the discretionary triggers otherwise lose to "unblock the paused
|
|
451
|
+
sub-agent". The full list and its asymmetry live in §Closeout.
|
|
452
|
+
|
|
453
|
+
Give it the context — the branch when no PR exists yet, the `discoveries.md` entry
|
|
454
|
+
by path with the decision (**in full** pre-record — `resolve-discovery` step 3 —
|
|
455
|
+
its gist once recorded), the change or the human's request as a synthesized delta
|
|
456
|
+
(§Sub-agent invocation) — and read back its summary. The Architect is **not a gate** — it produces an artifact and
|
|
519
457
|
reports; it never moves the status machine. If it reports that the trigger didn't
|
|
520
458
|
warrant the artifact (an ADR that fails the three tests, a change that isn't
|
|
521
459
|
architecturally significant, a "playbook" change that's really project-specific), record
|
|
522
460
|
that and move on — no artifact is forced.
|
|
523
461
|
|
|
524
|
-
## UI design (DEFINE + REVIEW)
|
|
525
|
-
|
|
526
|
-
UI design threads into an L1 task that touches UI — never a linear step. **The interactive
|
|
527
|
-
design interview is yours**: a sub-agent can't talk to the human, so at DEFINE **you** run
|
|
528
|
-
the `grill-ui` skill on your human-facing surface and author the `ui-handoff.md` contract.
|
|
529
|
-
The **UI Designer** sub-agent — always installed, invoked **on-demand**, your only invoker —
|
|
530
|
-
is your design **critic and QA**: at DEFINE it reviews the handoff you just authored (before
|
|
531
|
-
the Spec Author runs); at REVIEW it runs a mechanical pre-pass (the deterministic
|
|
532
|
-
`design-tokens` gates + the project's a11y tooling) then the `design-critique` and
|
|
533
|
-
`a11y-audit` judgment lenses, and returns one design verdict. You own the human dialogue, the
|
|
534
|
-
`ui-handoff.md` artifact, and the labels; it critiques and reports.
|
|
535
|
-
|
|
536
|
-
A third, on-demand affordance sits outside those two moments: **design-tool token sync**.
|
|
537
|
-
When the human runs `/sync-design-tokens` (or accepts the DEFINE offer when a drift check
|
|
538
|
-
shows an export is pending), dispatch the UI Designer to run its `design-tool-sync` skill.
|
|
539
|
-
It is human-reviewed both ways and tokens-only; the design tool is a projection of
|
|
540
|
-
`docs/design-tokens.json`, never a peer source of truth.
|
|
541
|
-
|
|
542
|
-
### Activation gate
|
|
543
|
-
|
|
544
|
-
After the grill produces the PRD and the task issue exists, judge — **your own LLM
|
|
545
|
-
call**, no runtime keyword scorer — whether this task needs design, as **two parts both
|
|
546
|
-
true**:
|
|
547
|
-
|
|
548
|
-
1. **The repo has a frontend** — there is UI to design (a SPA/app surface, components,
|
|
549
|
-
styles), not a pure library / CLI / backend.
|
|
550
|
-
2. **This task touches UI** — the change adds or alters something a user sees or
|
|
551
|
-
interacts with.
|
|
552
|
-
|
|
553
|
-
**Bias to include** on a borderline call: a wasted handoff stub is cheaper than UI
|
|
554
|
-
shipped with no design pass. When both hold, the task needs design.
|
|
555
|
-
|
|
556
|
-
### Design-stop offer
|
|
557
|
-
|
|
558
|
-
When the gate fires, **put `harness:needs-design`** on the issue and offer the human,
|
|
559
|
-
inline, in one line — three choices:
|
|
560
|
-
|
|
561
|
-
> This task touches UI. (1) **Continue** — define the design now, as part of the spec;
|
|
562
|
-
> (2) **Stop for handoff** — park here so a designer picks it up later; (3) **No UI after
|
|
563
|
-
> all** — skip design.
|
|
564
|
-
|
|
565
|
-
- **Continue** → **run `grill-ui` yourself** — the interactive design interview on your
|
|
566
|
-
human-facing surface — authoring `ui-handoff.md` under `tasks/<id>/spec/`. Then dispatch
|
|
567
|
-
the **UI Designer** (fresh context, Task tool) with the `<id>` and branch to **critique**
|
|
568
|
-
the handoff, and resolve its findings before the Spec Author runs. The issue stays at
|
|
569
|
-
`harness:status:spec-in-progress` — design is part of completing the spec, not a new
|
|
570
|
-
lifecycle state.
|
|
571
|
-
- **Stop for handoff** → record the sub-state `awaiting design definition` in
|
|
572
|
-
`progress.md`, commit and push the task state to the branch, and stop. The task waits
|
|
573
|
-
at `spec-in-progress` (+ `harness:needs-design`) for a `/resume` (below).
|
|
574
|
-
- **No UI after all** → **remove `harness:needs-design`** and proceed with the ordinary
|
|
575
|
-
spec flow — the gate was a false positive, which bias-to-include accepts.
|
|
576
|
-
|
|
577
|
-
### Persisting personas (offer)
|
|
578
|
-
|
|
579
|
-
`docs/personas.md` is **client-owned** — the harness consumes it, never imposes it. When your
|
|
580
|
-
`grill-ui` interview captured personas **inline** because `docs/personas.md` was **absent** (§1
|
|
581
|
-
of the handoff), make the offer — a human-facing choice, so it is yours:
|
|
582
|
-
|
|
583
|
-
> The design defined these personas inline. Persist them to `docs/personas.md` so future UI
|
|
584
|
-
> tasks reuse them? (yes / no)
|
|
585
|
-
|
|
586
|
-
- **Yes** → write a minimal `docs/personas.md` from the personas already in the handoff's §1
|
|
587
|
-
— the client's own words, not an invented cast. Then continue toward spec-ready.
|
|
588
|
-
- **No** → write nothing; the inline personas live on in the handoff for this task. The next
|
|
589
|
-
UI task simply asks again.
|
|
590
|
-
|
|
591
|
-
Only offer when the file was **absent and personas were captured inline** — never when
|
|
592
|
-
`docs/personas.md` already exists (it was consumed, nothing to persist) and never unasked.
|
|
593
|
-
This is opt-in surfacing of the client's own answers, not the harness authoring a persona set.
|
|
594
|
-
|
|
595
|
-
### Design-tokens & design-tool on-ramp (offer)
|
|
596
|
-
|
|
597
|
-
`docs/design-tokens.json` and a design-tool connection are **client-owned inputs** — consumed if
|
|
598
|
-
present, never imposed. A repo adopting the harness fresh has neither, and silence there is a dead
|
|
599
|
-
end. So when your `grill-ui` interview finds **either absent**, surface it as an opt-in offer (a
|
|
600
|
-
human-facing choice, so it is yours) rather than only an open question:
|
|
601
|
-
|
|
602
|
-
- **No `docs/design-tokens.json`** → offer to **scaffold** a starter token set derived from the
|
|
603
|
-
direction the interview just settled (the client's own colours/type/spacing, not a vendor
|
|
604
|
-
template), plus an opt-in follow-up to generate a sensible starter set for the aspects the
|
|
605
|
-
interview didn't cover. On **yes**, write the file and run `lemony design-tokens validate` before
|
|
606
|
-
closing; on **no**, capture it as an open question.
|
|
607
|
-
- **No `com.lemony.design-tool` binding** → offer to **connect a design tool** (write the binding +
|
|
608
|
-
first import via the UI Designer's `design-tool-sync` skill / `/sync-design-tokens`), or **stay
|
|
609
|
-
pure-code**. Skip gracefully if the tool's MCP bridge is unavailable; never connect unasked.
|
|
610
|
-
|
|
611
|
-
The mechanics live in the `grill-ui` skill; you run the offers on your human-facing surface. Only
|
|
612
|
-
offer when the input is **absent** — never re-offer a token file or binding that already exists.
|
|
613
|
-
|
|
614
|
-
### Label put/remove
|
|
615
|
-
|
|
616
|
-
`harness:needs-design` is an **orthogonal presence flag** (same family as
|
|
617
|
-
`harness:architecture-drift`), never a status:
|
|
618
|
-
|
|
619
|
-
- **Put** it as soon as the gate classifies the task as touching UI and design is not
|
|
620
|
-
yet complete.
|
|
621
|
-
- **Remove** it the moment `ui-handoff.md` is **complete** — at or before the flip to
|
|
622
|
-
`harness:status:spec-ready`. **Complete** = the handoff carries **this task's** design
|
|
623
|
-
decisions (its sections hold real content, not the verbatim placeholder template), the UI
|
|
624
|
-
Designer's critique **passed** (or you resolved its findings), and **no** open design fork
|
|
625
|
-
remains (an open fork means design is still open — keep the label and resolve it first).
|
|
626
|
-
Ensure the label is gone **before** flipping to `spec-ready`: a spec-ready task never
|
|
627
|
-
carries `harness:needs-design`.
|
|
628
|
-
|
|
629
|
-
### `awaiting design definition` sub-state + /resume re-entry
|
|
630
|
-
|
|
631
|
-
A task parked at "stop for handoff" sits at `harness:status:spec-in-progress` with
|
|
632
|
-
`progress.md` recording the sub-state `awaiting design definition`. It is the design
|
|
633
|
-
analogue of the step-by-step `awaiting human checkpoint` line — execution state, not a
|
|
634
|
-
label. `/resume <id>` re-enters there: check out the branch, read the captured context,
|
|
635
|
-
resume the `grill-ui` interview yourself to finish `ui-handoff.md`, dispatch the UI Designer
|
|
636
|
-
to critique it, then remove `harness:needs-design` and continue toward spec-ready. The resume
|
|
637
|
-
queue surfaces the parked design (`resume.md` lists `spec-in-progress` too).
|
|
638
|
-
|
|
639
|
-
### REVIEW — the design lens
|
|
640
|
-
|
|
641
|
-
When an implemented UI change reaches review (L1 step 8), invoke the **UI Designer** as
|
|
642
|
-
a **distinct lens** alongside the Reviewer (code). The **durable "this task touched UI"
|
|
643
|
-
signal is the existence of `tasks/<id>/spec/ui-handoff.md`** — `harness:needs-design` is
|
|
644
|
-
already gone by spec-ready, so it can't be the cue; the handoff artifact persists and
|
|
645
|
-
survives a cold `/resume`, so it is what to check. Either lens rejecting routes back to
|
|
646
|
-
the Implementer (rejection is transient — no dedicated label); both passing reaches the
|
|
647
|
-
single human merge gate (two inputs, one gate).
|
|
648
|
-
|
|
649
|
-
The UI Designer's lens mirrors the Reviewer's own shape — a **mechanical pre-pass** (the
|
|
650
|
-
deterministic `design-tokens validate` + `design-tokens contrast` gates, plus the
|
|
651
|
-
project's a11y tooling), then **judgment** (`design-critique` + `a11y-audit`), returning
|
|
652
|
-
**one design verdict** with findings grouped by source (tokens / accessibility / craft).
|
|
653
|
-
The Reviewer's code lens stays design-unaware; you still see exactly two review inputs.
|
|
654
|
-
|
|
655
|
-
**Deterministic vs judgment, by level.** The two deterministic gates are cheap, agent-free
|
|
656
|
-
facts, so they run **per-step** on UI-touching steps in step-by-step mode (a bad contrast
|
|
657
|
-
in step 2 must not ride to step 6 — see §Step-by-step implementation); the project's a11y
|
|
658
|
-
lint rides the per-step lint the same way. The **judgment lenses run full-pass only** —
|
|
659
|
-
design is holistic, and a mid-component critique is noise. There is no per-step design
|
|
660
|
-
agent and no new cap: a full-pass design rejection routes back like any other rejection.
|
|
661
|
-
(`design-tokens validate` / `contrast` also run in CI independently of review.)
|
|
662
|
-
|
|
663
|
-
### Closeout
|
|
664
|
-
|
|
665
|
-
`ui-handoff.md` lives in `tasks/<id>/spec/`, so closeout archives it with the rest of
|
|
666
|
-
the spec (`task-closeout` `git mv`s the whole `spec/` into `_archive/<id>/`) — no
|
|
667
|
-
special handling.
|
|
668
|
-
|
|
669
462
|
## Merge gate (`in-review → merged`)
|
|
670
463
|
|
|
671
464
|
When the Reviewer approves, **do not merge automatically.** Merging the PR is the one
|
|
672
|
-
action that touches the default branch
|
|
673
|
-
|
|
465
|
+
action that touches the default branch, so it stays a human decision. Surface it and
|
|
466
|
+
wait:
|
|
674
467
|
|
|
675
468
|
> Reviewed and approved — PR #<pr> is here: <url>.
|
|
676
469
|
> (1) merge it yourself, (2) I'll merge it (`gh pr merge`), or
|
|
@@ -730,7 +523,8 @@ RESUME).
|
|
|
730
523
|
**Closeout is the Architect's reliable activation point**: before
|
|
731
524
|
archiving, the skill drives three durable-capture activations, **asymmetric by design** —
|
|
732
525
|
`write-adr` (HITL offer per resolved discovery), `update-architecture` (**automatic**
|
|
733
|
-
dispatch
|
|
526
|
+
dispatch when `docs/architecture.md` exists, handing the PR and the `spec/design.md`
|
|
527
|
+
path (the Architect reads the merged diff itself) — no pre-offer, the map
|
|
734
528
|
tracks reality and the edit is reviewed in the closeout PR), and `playbook-iterate` (HITL
|
|
735
529
|
offer once per task, for a reusable pattern no `T6` conflict already routed). Closeout
|
|
736
530
|
never drafts the artifact itself — it lights up the Architect, who owns the criteria
|
|
@@ -767,29 +561,33 @@ When the gate choice was step-by-step, also pass `--steps` (the count of
|
|
|
767
561
|
## Sub-agent invocation
|
|
768
562
|
|
|
769
563
|
Each sub-agent runs with **fresh context** (a Task-tool invocation), not the hat's
|
|
770
|
-
accumulated conversation.
|
|
771
|
-
the
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
564
|
+
accumulated conversation. Read back its returned summary; you own the human dialogue,
|
|
565
|
+
the approval gate, and the label lifecycle. When a summary carries a
|
|
566
|
+
`## Side-findings` block, read `.claude/agents/spinoff.md` and run its offer —
|
|
567
|
+
after any gate prompt the read-back lands on, never before.
|
|
568
|
+
|
|
569
|
+
**Spawn prompts go by reference, never by quotation.** The prompt carries the issue
|
|
570
|
+
link, the relevant task-state and spec **paths**, the skill to run — plus, in
|
|
571
|
+
step-by-step mode, the group id and its header line — and a short **synthesized
|
|
572
|
+
delta**: only what exists nowhere on disk (reject feedback being addressed, the
|
|
573
|
+
one-line gist of a **recorded** discovery resolution — the full entry lives in
|
|
574
|
+
`discoveries.md`, reference it; pre-record, `resolve-discovery` step 3 routes the
|
|
575
|
+
owner with the decision **stated in full** — or a human instruction from this
|
|
576
|
+
conversation). Never paste spec
|
|
577
|
+
content (`requirements.md` / `design.md` / `tasks.md` text) into the prompt — the
|
|
578
|
+
sub-agent reads those files itself from the paths, always fresher than a quotation.
|
|
579
|
+
One exception is never trimmed: when the delta **is** the payload (a REJECT's
|
|
580
|
+
findings), route the reviewer's full findings verbatim. Scope: this rule binds the
|
|
581
|
+
task loop's role sub-agents; a user-invoked analysis flow (e.g. a PR-review
|
|
582
|
+
command spawning a stateless analysis agent) follows its own skill's prompt shape.
|
|
583
|
+
|
|
584
|
+
## Turn economy
|
|
585
|
+
|
|
586
|
+
Latency is paid **per turn**, not per command: run mechanical sequences whose
|
|
587
|
+
intermediate output needs no judgment as **one composite invocation**, and batch
|
|
588
|
+
independent read-only lookups in **one parallel turn**. The step-by-step checkpoint
|
|
589
|
+
is the canonical case (single chained commit+push; post-resolution, the resolved
|
|
590
|
+
step line + state commit + emit ride together). Never compact across a judgment point — reading a
|
|
591
|
+
summary, arbitrating a gate, classifying a discovery each deserve their own turn.
|
|
592
|
+
Checkpoint **narration** is exempt from all dieting: the gate presentation to the
|
|
593
|
+
human is the product, never overhead.
|