@lemoncode/lemony 0.2.0 → 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.
@@ -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
  ```
@@ -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,7 +54,11 @@ 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
@@ -75,23 +81,43 @@ A task deserves the harness if it is **specifiable**, **verifiable**, or
75
81
  6. **Approval gate** — run by whoever implements (a RESUME of a spec-ready issue runs
76
82
  it). Present the spec; the human approves (or asks for changes → Spec Author
77
83
  revises). On approval, flip to `harness:status:in-progress`. The spec, not the code,
78
- 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).
79
87
  7. **Implement** — Implementer sub-agent, `tdd` skill, on the branch, keeping
80
- `.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.
81
94
  8. **Review** — flip to `harness:status:in-review`, open the PR (`gh pr create`,
82
95
  branch → default), Reviewer sub-agent reviews it (`senior-review`, fresh context). If
83
96
  the task touched UI, the **UI Designer** reviews as a distinct design + a11y lens too
84
- — 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.
85
102
  9. **Merge gate** — never auto-merge. Surface the approved PR; the human merges (or
86
- authorizes you to). The task stays at `in-review` until merged.
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.
87
110
  10. **Closeout** — `task-closeout`: confirm the merge via `gh`, run the three Architect
88
111
  activations (`write-adr` — HITL offer per resolved discovery; `update-architecture` —
89
112
  automatic when `docs/architecture.md` exists; `playbook-iterate` — HITL offer once
90
113
  per task), archive the spec + discoveries to `_archive/<id>/` (drop
91
114
  `progress.md`), and land `history.md` + the archival via a dedicated
92
- `harness/closeout-<id>` PR (`gh pr merge --auto`) never a direct push to the base.
93
- If protection needs approval the PR waits: park at `closeout-pending`, `/resume`
94
- 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.
95
121
 
96
122
  ## L2 round-trip (TRIAGE)
97
123
 
@@ -105,11 +131,14 @@ Authority for the steps: `.claude/agents/triage.md` (the Orchestrator's lazy com
105
131
  3. **Implement** — Implementer sub-agent, `tdd` skill.
106
132
  4. **Review** — flip to `harness:status:in-review`, open the PR, Reviewer sub-agent
107
133
  (`senior-review`, fresh context).
108
- 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.
109
136
  6. **Closeout** — `task-closeout`: confirm the merge, archive the spec + discoveries to
110
137
  `_archive/<id>/`, and land `history.md` + the archival via a dedicated
111
- `harness/closeout-<id>` PR (`gh pr merge --auto`); park at `closeout-pending` if it
112
- 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.
113
142
 
114
143
  ## Discovery interrupts
115
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