@lemoncode/lemony 0.1.2 → 0.3.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.
Files changed (37) hide show
  1. package/README.md +19 -14
  2. package/catalog/VERSION +1 -1
  3. package/catalog/agents/architect.md +13 -4
  4. package/catalog/agents/implementer.md +87 -8
  5. package/catalog/agents/orchestrator.md +643 -386
  6. package/catalog/agents/partition.md +316 -0
  7. package/catalog/agents/reviewer.md +356 -21
  8. package/catalog/agents/spec-author.md +16 -4
  9. package/catalog/agents/spinoff.md +100 -0
  10. package/catalog/agents/triage.md +41 -0
  11. package/catalog/agents/ui-design.md +147 -0
  12. package/catalog/agents/ui-designer.md +3 -2
  13. package/catalog/commands/add-capability.md +4 -4
  14. package/catalog/commands/define.md +7 -0
  15. package/catalog/commands/hotfix.md +15 -1
  16. package/catalog/commands/pause.md +5 -0
  17. package/catalog/commands/resume.md +38 -10
  18. package/catalog/commands/triage.md +4 -3
  19. package/catalog/harness.config.schema.json +40 -0
  20. package/catalog/hooks/lib/merge-pr.sh +699 -0
  21. package/catalog/schemas/tier2-events-history.md +17 -0
  22. package/catalog/schemas/tier2-events.md +10 -10
  23. package/catalog/skills/mutation-testing/SKILL.md +80 -19
  24. package/catalog/skills/prd-to-spec/SKILL.md +74 -2
  25. package/catalog/skills/raise-discovery/SKILL.md +6 -0
  26. package/catalog/skills/resolve-discovery/SKILL.md +12 -7
  27. package/catalog/skills/security-review/SKILL.md +119 -6
  28. package/catalog/skills/spec-compliance-check/SKILL.md +8 -4
  29. package/catalog/skills/spec-to-issue/SKILL.md +7 -1
  30. package/catalog/skills/task-closeout/SKILL.md +85 -20
  31. package/catalog/skills/test-gap-report/SKILL.md +4 -0
  32. package/catalog/skills/triage-issue/SKILL.md +65 -4
  33. package/catalog/skills/verify/SKILL.md +3 -0
  34. package/catalog/templates/claude-code/agents.md.tpl +50 -16
  35. package/catalog/templates/claude-code/harness.config.yml.tpl +33 -0
  36. package/dist/cli.mjs +744 -37
  37. package/package.json +10 -6
@@ -27,7 +27,8 @@ Three moves, in this order:
27
27
  `_archive/<id>/`; drop only `progress.md` (true scratch). The high-value memory stays
28
28
  live and grep-able.
29
29
  3. **Land via a PR** — the `history.md` append, the archival move, and any new ADR ride a
30
- dedicated `harness/closeout-<id>` PR merged with `--auto`. No direct push to the base.
30
+ dedicated `harness/closeout-<id>` PR that self-merges **only on green checks**
31
+ (through `.claude/hooks/lib/merge-pr.sh`). No direct push to the base.
31
32
 
32
33
  Run this only when the **Reviewer has approved** and the task PR is merged. The merge is a
33
34
  human decision (the merge gate) — closeout never merges the task; it **confirms** the
@@ -87,8 +88,9 @@ The three differ in **who decides** — and the asymmetry is deliberate:
87
88
 
88
89
  - **`update-architecture` — automatic dispatch, no pre-offer.** Only when
89
90
  `docs/architecture.md` exists (the skill installs solely then). Dispatch the
90
- **Architect** (`update-architecture`, fresh context) with the task's **merged diff**
91
- (`gh pr diff <pr>`) plus the task's `spec/design.md` (still live here — archival is
91
+ **Architect** (`update-architecture`, fresh context) with the task's **PR number**
92
+ (it runs `gh pr diff <pr>` itself) plus the **path** of the task's `spec/design.md`
93
+ (still live here — archival is
92
94
  step 4 below). The Architect reads the change, makes
93
95
  the smallest true edit if the system's **shape** moved (referencing any ADR just
94
96
  written — `see ADR-NNNN`), or reports **no-op** when nothing architectural changed.
@@ -157,34 +159,74 @@ working scratch are gone. A UI task's **`ui-handoff.md`** is a sibling **inside*
157
159
  `spec/`, so the single `git mv` of `spec/` archives it with the rest — no special
158
160
  handling.
159
161
 
160
- ### 5. Open the closeout PR and auto-merge
162
+ ### 5. Open the closeout PR and self-merge on green
161
163
 
162
- Commit the record, push the branch, open a PR, and let GitHub apply the repo's own rules:
164
+ Commit the record, push the branch, open a PR, and self-merge it **through the
165
+ checks-precondition executor** — never a bare `gh pr merge`. There is no standing human
166
+ authorization on this path, so the precondition stands alone: **the executor merges
167
+ only on green; every other outcome takes one of the exits below** (some end in a
168
+ human's informed decision — what never happens is an autonomous merge on not-green).
169
+ The executor verifies the check status the platform reports for
170
+ the PR, waiting — bounded (`merge.checks_timeout_secs`, default ~10 min) — for pending
171
+ checks:
163
172
 
164
173
  ```bash
165
174
  git commit -m "closeout(<id>): archive task state, record in history.md"
166
175
  git push -u origin harness/closeout-<id>
167
176
  gh pr create --base <default> --head harness/closeout-<id> \
168
177
  --title "closeout(<id>): <topic>" --body "Closeout record for #<id>."
169
- gh pr merge harness/closeout-<id> --auto --squash --delete-branch
178
+ .claude/hooks/lib/merge-pr.sh harness/closeout-<id> --squash --delete-branch
170
179
  ```
171
180
 
181
+ (If the human recorded a standing merge answer at this task's merge gate — a
182
+ `merge.allow_no_checks: true` line sitting uncommitted in `harness.config.yml` —
183
+ stage it into the record commit above: the answer rides the closeout PR to the base.)
184
+
172
185
  The closeout PR **must not** carry `Closes #<id>` — the task PR already auto-closed the
173
186
  issue on merge; closeout only flips the label and finalizes.
174
187
 
175
- `gh pr merge` `--auto` defers to branch protection:
176
-
177
- - **Protection is PR + checks only** the PR self-merges once checks pass. Continue to
178
- step 6 (finalize) once the closeout PR reports merged.
179
- - **Protection requires human approval** the PR waits. **Park** (see below).
180
- - **Auto-merge is disabled repo-wide** `gh pr merge` `--auto` **errors** ("auto-merge is
181
- not allowed for this repository") rather than queuing. This is a repo setting,
182
- independent of branch protection. Treat the error as the wait case: **park**. (You may
183
- instead merge it immediately with a plain `gh pr merge` `--squash --delete-branch` if the
184
- human has authorized you to merge same gesture as the task merge gate.)
188
+ Act on the executor's exit code:
189
+
190
+ - **0 merged.** Continue to step 6 (finalize).
191
+ - **10 checks red.** Red does **not** automatically mean the base is broken — look at
192
+ what failed (`gh run view` / the check's output), then take one of three exits:
193
+ 1. **Failure in the closeout's own files** (format/lint on the moved docs): fixable
194
+ by you alone run the formatter, commit, push, re-run the executor; green ⇒
195
+ self-merge normally. No human interruption; fixing format on your own docs-only PR
196
+ is harmless and autonomous.
197
+ 2. **Failure in the base** (main was already broken): **park** and surface with the
198
+ diagnosis — the human's informed merge-on-red decision is legitimate precisely
199
+ here, since the red isn't this PR's (on their explicit yes, re-run with
200
+ `--force`). Free side effect: every closeout is a broken-main detector.
201
+ 3. **Can't tell:** **park** and surface what you saw — in doubt, the human.
202
+
203
+ The uniform rule stands: **never merge on red alone** — no "it's only docs"
204
+ exception (automatic exceptions are how the bug comes back).
205
+
206
+ - **20 — no checks reported (after the grace window).** Never merge alone, whatever the
207
+ cause — don't auto-classify (no CI, CI dead, path filters all look identical). The
208
+ once-per-repo memory is the **standing answer only**: if `merge.allow_no_checks: true`
209
+ is recorded (or sits uncommitted on this branch, staged per step 5), the executor
210
+ applies it itself — you won't see exit 20. A **one-shot** yes given at an earlier
211
+ merge (including this task's merge gate) authorized **that merge only** and does
212
+ **not** carry over — never re-apply it here on your own. Seeing exit 20 means no
213
+ standing answer exists, so ask: "I saw no checks on the closeout PR — merge?". A
214
+ standing answer ("this repo has no CI — merge without checks") is recorded as
215
+ `merge.allow_no_checks: true` in `harness.config.yml` — add the line on this very
216
+ closeout branch, push, and re-run the executor (it reads the working tree, and the
217
+ answer lands on the base with the record). A one-shot yes ⇒ re-run with `--force`.
218
+ No human available ⇒ **park**.
219
+ - **30 — checks still pending past the bound.** **No merge**: **park**. The closeout is
220
+ docs-only archival — leaving it pending blocks nothing already merged.
221
+ - **1 (or any other non-zero) — no verdict.** Read the executor's stderr: either the
222
+ check status could not be read (`gh`/auth/network — the precondition is
223
+ unverifiable), or the merge attempt itself was rejected (branch protection requires
224
+ human approval, a conflict). Both ⇒ **park**, surfacing that stderr — a
225
+ protection-parked record PR is merged by the human by hand.
185
226
 
186
227
  **Park:** flip the issue to `harness:status:closeout-pending`, tell the human the closeout
187
- PR is open and awaiting their merge, and stop. The task issue is **already closed** (the
228
+ PR is open, why it did not merge (the executor's output failing checks, no checks,
229
+ pending past the bound, or protection), and stop. The task issue is **already closed** (the
188
230
  task PR's `Closes #<id>` fired on its merge), so `/resume` finds the parked closeout only
189
231
  by listing closed issues too (`--state all`) — a default open-only queue would miss it. A
190
232
  later `/resume` picks up at step 6 once the PR is merged. (Authority for the RESUME entry:
@@ -192,7 +234,10 @@ the Orchestrator.)
192
234
 
193
235
  ### 6. Finalize (once the closeout PR is merged)
194
236
 
195
- Confirm the closeout PR merged (`gh pr view <pr> --json state,mergedAt` `MERGED`; on a
237
+ On a `/resume` that finds the record PR **still open**, first re-run the executor on it
238
+ (step 5's `merge-pr.sh` line, verbatim): a park on pending or red checks is transient
239
+ and may have settled green — a repeat not-green outcome just re-parks. Then confirm the
240
+ closeout PR merged (`gh pr view <pr> --json state,mergedAt` → `MERGED`; on a
196
241
  `/resume`, pass the deterministic branch `harness/closeout-<id>` as `<pr>` — the
197
242
  merge-confirm accepts a branch name in place of a PR number), land the merged base
198
243
  (`git checkout <default> && git pull`), then:
@@ -208,11 +253,31 @@ single emit point for either path). You compute the envelope (cycle time, review
208
253
  rejections, level) as the Orchestrator running this skill; the fields and the `emit`
209
254
  command line are in `orchestrator.md` §Closeout. `events.jsonl` is local-only/gitignored, so the emit never dirties the base.
210
255
 
256
+ **If the task is a part of a partitioned feature** — its issue body (read it with
257
+ `gh issue view <id> --json body`; the issue is closed by now) carries a
258
+ `Part <k> of #<parent>` trace line — update the parent **partition-plan** issue here, in
259
+ the same finalize, **read-modify-write**: read the parent body immediately before
260
+ editing (`gh issue view <parent> --json body`), tick only your row and set it to
261
+ `- [x] Part <k> — <slice> → #<id> merged`, write it back with
262
+ `gh issue edit <parent> --body-file`, then re-read to confirm the tick is present — if another row moved
263
+ underneath you (a sibling closing out elsewhere), redo it **once** on the fresh body
264
+ (match rows tolerant of a trailing `\r`: a body edited on the web may carry CRLF); still
265
+ absent → leave the tick to the human and say so. Idempotent on a retried finalize: an
266
+ already-ticked row is left alone, and the all-ticked check still runs. When that
267
+ leaves **every** row ticked (merged or dropped), close the parent with a summary comment
268
+ (`gh issue close <parent> --comment "<what shipped, part by part>"`) — mechanical, no
269
+ human prompt: each part's merge already passed the human gate; a parent the human already
270
+ closed takes the tick and the close is a no-op. A parent with unticked rows stays open;
271
+ `/resume` surfaces its next part. The contract is the Orchestrator's companion
272
+ `.claude/agents/partition.md`.
273
+
211
274
  ### 7. Report
212
275
 
213
276
  Return a one-line summary: the task id, the `history.md` entry, the archive path
214
- (`_archive/<id>/`), any ADR raised, and confirmation that the issue is closed (or that
215
- closeout is parked at `closeout-pending` awaiting the record PR's merge).
277
+ (`_archive/<id>/`), any ADR raised, confirmation that the issue is closed (or that
278
+ closeout is parked at `closeout-pending` awaiting the record PR's merge), and — for a
279
+ partition part — that the parent row was ticked (and the parent closed, on the last
280
+ part).
216
281
 
217
282
  ## Scope note
218
283
 
@@ -52,6 +52,10 @@ For each file in the "always" set:
52
52
 
53
53
  ### 3. Report
54
54
 
55
+ Destination: the full-pass **issue comment**. In your return summary — and always on
56
+ a per-step review, which posts no comment — carry only the counts + the gaps, per
57
+ the Reviewer's verdict-size rule (a REJECT lifts the cap entirely).
58
+
55
59
  ```
56
60
  ## Test Gap Report — <task name>
57
61
 
@@ -44,7 +44,7 @@ Look at:
44
44
  Determine:
45
45
 
46
46
  - The minimal change needed to fix the root cause
47
- - Which modules/interfaces are affected
47
+ - Which modules/interfaces are affected, and **which files the fix will change**
48
48
  - What behaviors need to be verified via tests
49
49
  - Whether this is a regression, missing feature, or design flaw
50
50
 
@@ -65,12 +65,70 @@ Rules:
65
65
  For TDD philosophy → see the **tdd** skill. For test recipes → see your project's
66
66
  testing playbook.
67
67
 
68
- ### 5. Confirm with the user
68
+ ### 5. Declare the risk surfaces
69
69
 
70
- Present the issue draft: problem summary, root cause analysis, and TDD fix plan.
70
+ This is the L2 counterpart of the `[risk: …]` tag a spec's group header carries at L1:
71
+ the declaration of **what kind of damage this change can do**, made at the structuring
72
+ moment, outside the Reviewer, and visible to the human before execution.
73
+
74
+ One line per surface — a class paired with **one concrete file the fix changes**, never
75
+ a module in the abstract — using the same vocabulary as `prd-to-spec`; each class names
76
+ what kind of damage the surface can do:
77
+
78
+ <!-- risk-vocabulary:start -->
79
+
80
+ | Class | Surface |
81
+ | ----------------- | ---------------------------------------------------------------- |
82
+ | `auth` | authentication, authorization, session or token handling |
83
+ | `payments` | money movement, billing, pricing |
84
+ | `shell-process` | shell invocation, subprocess spawning, argument construction |
85
+ | `data-loss` | writes, deletes, migrations, anything that can destroy user data |
86
+ | `secrets` | credentials, keys, tokens — at rest or in transit |
87
+ | `executable-mode` | file permissions, exec bits, anything that changes what can run |
88
+
89
+ <!-- risk-vocabulary:end -->
90
+
91
+ A fix that carries one class into three files declares three lines:
92
+
93
+ ```
94
+ ## Risk surfaces
95
+ - data-loss: src/storage/sync.ts
96
+ - shell-process: src/hooks/run-hook.ts
97
+ ```
98
+
99
+ A fix that touches no such surface carries the section with a single line — `- none` —
100
+ never an omitted section: the absence of a declaration and a declaration of absence are
101
+ different claims, and only the second is auditable. `- none` is a claim about the change,
102
+ so make it only when it is true.
103
+
104
+ Declare it **now**, before the fix is written: a surface named afterwards describes what
105
+ happened, it does not declare what could. The human reviews it with the rest of the draft
106
+ in the next step and edits it in the issue like any other section — that review is the
107
+ first thing the section buys. The second comes at review time: the Reviewer hands the
108
+ declared surfaces to `security-review`, which presses hardest where they point. Nothing
109
+ checks it automatically.
110
+
111
+ If a surface has no home in the vocabulary, declare it as `unclassified` and say what it
112
+ can do:
113
+
114
+ ```
115
+ - unclassified: src/queue/drain.ts — replays messages, can double-deliver
116
+ ```
117
+
118
+ **Never fold it into `- none`.** `- none` claims no such surface exists, and that claim
119
+ would be false — an unnameable surface is the one most worth seeing. Do not invent a
120
+ one-off class either, and do not edit the table here: it is vendor-owned — generated into
121
+ this skill and `prd-to-spec` from one source, so the two always agree — and a local edit
122
+ is discarded on the next update. Say in the next step that the vocabulary came up short,
123
+ so the human can decide whether it grows.
124
+
125
+ ### 6. Confirm with the user
126
+
127
+ Present the issue draft: problem summary, root cause analysis, TDD fix plan, and the
128
+ declared risk surfaces.
71
129
  Ask: "Does this look right? Should I create the issue?"
72
130
 
73
- ### 6. Create the GitHub issue
131
+ ### 7. Create the GitHub issue
74
132
 
75
133
  After confirmation, create with `gh issue create` and the `harness:managed` label.
76
134
  Use a structure like:
@@ -86,6 +144,9 @@ Use a structure like:
86
144
  - [ ] RED: <test capturing behavior 1> → GREEN: <minimal change>
87
145
  - [ ] RED: <test capturing behavior 2> → GREEN: <minimal change>
88
146
 
147
+ ## Risk surfaces
148
+ - <class>: <path the fix writes to>
149
+
89
150
  ## Affected
90
151
  <modules / interfaces touched>
91
152
  ```
@@ -84,6 +84,9 @@ and the error output (unexpected warnings/errors even when the happy path worked
84
84
  **Verdict**: works / does not work — <one-line reason>
85
85
  ```
86
86
 
87
+ This block is your working record; a capped return summary condenses it to the
88
+ verdict line (plus any ❌ detail — failures are signal, never trimmed).
89
+
87
90
  On a failure, read the **full** error, find the origin (not where it surfaced), fix
88
91
  the root cause, and re-run from the failed gate. If a failure reveals the spec itself
89
92
  is wrong or silent, that's a **discovery** — run `raise-discovery`, don't paper over
@@ -27,7 +27,9 @@ surface the menu.
27
27
  - **DEFINE** — the L1 full-SDD round-trip (see below).
28
28
  - **RESUME** — for an SDD task, `git fetch` and check out `harness/<id>-<slug>` first
29
29
  (the task state and spec live only on the branch until merge), then reload
30
- `.claude/state/tasks/<id>/` and continue from `progress.md`.
30
+ `.claude/state/tasks/<id>/` and continue from `progress.md`. An issue carrying
31
+ `harness:partition-plan` is a partition parent, not a task — start its next part per
32
+ `.claude/agents/partition.md`.
31
33
  - **TRIAGE** — the L2 lightweight path (see below). Invoke the `triage-issue` skill.
32
34
  - **ORIENT** — an intentless entry (greeting / "what should I pick up?" / nothing).
33
35
  Render the **dispatch menu**: the parked queue (the same listing `/resume` runs with
@@ -52,12 +54,17 @@ A task deserves the harness if it is **specifiable**, **verifiable**, or
52
54
  ## L1 round-trip (DEFINE)
53
55
 
54
56
  1. **Grill** — `grill-with-docs`: interview the idea into a PRD at
55
- `docs/prds/<topic>-<date>.md`.
57
+ `docs/prds/<topic>-<date>.md`. If the closed PRD bundles separable, independently
58
+ mergeable wants, ask the **partition question** before opening the task (authority:
59
+ `.claude/agents/partition.md`, read on trigger): an approved cut opens a parent
60
+ partition-plan issue (`harness:partition-plan`, never a task) and Part 1 as a normal
61
+ task; later parts open at their turn.
56
62
  2. **Open the task** — create the issue (skeleton body + `harness:managed` +
57
63
  `harness:sdd` + `harness:status:spec-in-progress`) and the branch
58
64
  `harness/<id>-<slug>`. `<id>` is the GitHub issue number in this build; spec and code
59
65
  both live on that branch — nothing touches the default branch until the merge gate.
60
- 3. **UI design (if it touches UI)** — **UI design gate** (§UI design in `orchestrator.md`):
66
+ 3. **UI design (if it touches UI)** — **UI design gate** (canonical: the orchestrator's
67
+ L1 step 3, evaluated core-only — read `.claude/agents/ui-design.md` only when it fires):
61
68
  if the repo has a frontend AND the task touches UI, put `harness:needs-design`, offer the
62
69
  design-stop, and on "continue" **run `grill-ui` yourself** (the interactive design
63
70
  interview) to author `ui-handoff.md` under `tasks/<id>/spec/`, then dispatch the **UI
@@ -67,31 +74,55 @@ A task deserves the harness if it is **specifiable**, **verifiable**, or
67
74
  under `tasks/<id>/spec/`) then `spec-to-issue` (fills the issue body — it creates nothing
68
75
  and moves no labels).
69
76
  5. **Spec-ready + handoff** — remove `harness:needs-design` once `ui-handoff.md` is
70
- complete (a spec-ready task never carries it), flip to `harness:status:spec-ready`,
77
+ complete (a spec-ready task never carries the label), flip to `harness:status:spec-ready`,
71
78
  commit and push the task state to the branch. DEFINE can stop here: the spec-ready
72
79
  queue (`gh issue list -l harness:status:spec-ready`) is the handoff. Ask: implement
73
80
  now or hand off?
74
81
  6. **Approval gate** — run by whoever implements (a RESUME of a spec-ready issue runs
75
82
  it). Present the spec; the human approves (or asks for changes → Spec Author
76
83
  revises). On approval, flip to `harness:status:in-progress`. The spec, not the code,
77
- is the source of intent — never self-approve.
84
+ is the source of intent — never self-approve. If `harness.config.yml` declares no
85
+ `gates` list, propose one here (from the manifest + CI; hand-edited on
86
+ confirmation) — never mid-review (orchestrator §Approval gate).
78
87
  7. **Implement** — Implementer sub-agent, `tdd` skill, on the branch, keeping
79
- `.claude/state/tasks/<id>/progress.md` live.
88
+ `.claude/state/tasks/<id>/progress.md` live. The gate interaction settles two
89
+ knobs, both recorded in `progress.md`: the **implementation mode** (all-at-once,
90
+ or step-by-step with per-group human checkpoints) and **pre-commit review**
91
+ (config `implementation.pre_commit_review`; ON = the human reviews the work
92
+ **uncommitted** — zero commits until each checkpoint OK). Authority:
93
+ orchestrator §Implementation mode / §Pre-commit review ON.
80
94
  8. **Review** — flip to `harness:status:in-review`, open the PR (`gh pr create`,
81
95
  branch → default), Reviewer sub-agent reviews it (`senior-review`, fresh context). If
82
96
  the task touched UI, the **UI Designer** reviews as a distinct design + a11y lens too
83
- — either lens rejecting routes back to the Implementer.
97
+ — either lens rejecting routes back to the Implementer. Every APPROVE carries an
98
+ **evidence ledger** — a JSON sidecar under the task's state that a script validates
99
+ (`lemony review-ledger validate`), never an agent: a red ledger sends a fresh Reviewer
100
+ back once, then the human; it never routes to the Implementer and is never relayed as
101
+ an APPROVE.
84
102
  9. **Merge gate** — never auto-merge. Surface the approved PR; the human merges (or
85
- authorizes you to). The task stays at `in-review` until merged.
86
- 10. **Closeout** `task-closeout`: confirm the merge via `gh`, offer durable discoveries
87
- to the Architect (`write-adr`, HITL), archive the spec + discoveries to `_archive/<id>/` (drop
103
+ authorizes you to a conditional yes: the agent's merge runs through the
104
+ checks precondition (`.claude/hooks/lib/merge-pr.sh --approve-issue <issue>`)
105
+ and never lands on red, absent, or still-pending checks without asking nor
106
+ content that no longer matches what the Reviewer's APPROVE reviewed (the
107
+ stale-approve guard; a clean update-branch stays valid, any content change
108
+ routes back to re-review). The task stays at `in-review`
109
+ until merged.
110
+ 10. **Closeout** — `task-closeout`: confirm the merge via `gh`, run the three Architect
111
+ activations (`write-adr` — HITL offer per resolved discovery; `update-architecture` —
112
+ automatic when `docs/architecture.md` exists; `playbook-iterate` — HITL offer once
113
+ per task), archive the spec + discoveries to `_archive/<id>/` (drop
88
114
  `progress.md`), and land `history.md` + the archival via a dedicated
89
- `harness/closeout-<id>` PR (`gh pr merge --auto`) never a direct push to the base.
90
- If protection needs approval the PR waits: park at `closeout-pending`, `/resume`
91
- finalizes. Then close the issue and delete the branch.
115
+ `harness/closeout-<id>` PR that self-merges **only on green checks**
116
+ (`.claude/hooks/lib/merge-pr.sh`) never a direct push to the base.
117
+ A red on its own files (format/lint) it fixes and retries autonomously; any
118
+ other not-green outcome or protection needing approval parks the PR at
119
+ `closeout-pending`, and `/resume` finalizes. Then close the issue and delete
120
+ the branch.
92
121
 
93
122
  ## L2 round-trip (TRIAGE)
94
123
 
124
+ Authority for the steps: `.claude/agents/triage.md` (the Orchestrator's lazy companion).
125
+
95
126
  1. **Triage** — `triage-issue`: investigate, find root cause, draft a TDD-based fix
96
127
  plan, and create the issue with `harness:managed` (no `harness:sdd` — its absence
97
128
  marks the lightweight path).
@@ -100,11 +131,14 @@ A task deserves the harness if it is **specifiable**, **verifiable**, or
100
131
  3. **Implement** — Implementer sub-agent, `tdd` skill.
101
132
  4. **Review** — flip to `harness:status:in-review`, open the PR, Reviewer sub-agent
102
133
  (`senior-review`, fresh context).
103
- 5. **Merge gate** — the same human-explicit gate as L1: never auto-merge.
134
+ 5. **Merge gate** — the same human-explicit gate as L1: never auto-merge, and an
135
+ authorized merge runs the same checks precondition and stale-approve guard.
104
136
  6. **Closeout** — `task-closeout`: confirm the merge, archive the spec + discoveries to
105
137
  `_archive/<id>/`, and land `history.md` + the archival via a dedicated
106
- `harness/closeout-<id>` PR (`gh pr merge --auto`); park at `closeout-pending` if it
107
- needs approval. Then close the issue and delete the branch. Same as L1.
138
+ `harness/closeout-<id>` PR that self-merges only on green checks (own-file
139
+ format reds are self-fixed and retried); park at `closeout-pending` if checks
140
+ stay not-green or it needs approval. Then close the issue and delete the
141
+ branch. Same as L1.
108
142
 
109
143
  ## Discovery interrupts
110
144
 
@@ -46,6 +46,39 @@ rollback:
46
46
  # telemetry:
47
47
  # enabled: false
48
48
 
49
+ # Agent-executed merges. Before the agent runs any `gh pr merge` (an authorized
50
+ # task-PR merge, or the closeout record PR), the shared executor
51
+ # `.claude/hooks/lib/merge-pr.sh` verifies the check status the platform reports
52
+ # for the PR and only merges on green — red, absent, or still-pending checks are
53
+ # surfaced to a human instead. Defaults shown — declare only overrides.
54
+ # merge:
55
+ # # Max seconds to wait for pending checks before surfacing instead of merging.
56
+ # checks_timeout_secs: 600
57
+ # # Standing answer for a repo with no CI: `true` lets the executor merge when
58
+ # # the platform reports no checks at all (otherwise it asks, every time).
59
+ # allow_no_checks: false
60
+
61
+ # Implementation-phase knobs the Orchestrator reads at the L1 approval gate.
62
+ # pre_commit_review — human review of the UNCOMMITTED work before anything is
63
+ # committed (zero-commit mode): `human` (default) asks at the gate, in the same
64
+ # interaction as the all-at-once / step-by-step choice, suggesting OFF (today's
65
+ # commit-as-you-go flow); `on` / `off` pin the answer and skip the question
66
+ # (bench/headless runs pin `off`). Bare on/off are strings here (YAML 1.2).
67
+ # implementation:
68
+ # pre_commit_review: human
69
+
70
+ # Review gates. The mechanical gates a Reviewer must attest in its evidence
71
+ # ledger, one entry per name, beyond the always-required real run — a flat list of
72
+ # this project's script names (`package.json` scripts, or your CI's equivalents).
73
+ # Declare every gate your CI enforces, drift checks included: an undeclared project
74
+ # reviews against a floor of the real run only (honest, but thin). The agent may
75
+ # propose this list from your manifest at the approval gate — confirmed by a human
76
+ # and added by hand (this block is the shape); no tool writes it for you.
77
+ # gates:
78
+ # - lint
79
+ # - test
80
+ # - build
81
+
49
82
  # Design tokens (`design-tokens validate`). The anti-hardcode scan inspects a built-in
50
83
  # set of UI/style extensions (.css/.scss/.ts/.tsx/.vue/.svelte/.astro/.js/.mdx/.html/…).
51
84
  # Add extra suffixes here for a stack the built-ins don't cover — additive, never a