@lemoncode/lemony 0.2.0 → 0.4.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/README.md +19 -14
- package/catalog/VERSION +1 -1
- package/catalog/agents/architect.md +3 -1
- package/catalog/agents/implementer.md +43 -5
- package/catalog/agents/orchestrator.md +527 -60
- package/catalog/agents/partition.md +316 -0
- package/catalog/agents/reviewer.md +279 -67
- package/catalog/agents/spec-author.md +12 -3
- package/catalog/agents/triage.md +8 -5
- package/catalog/commands/add-capability.md +4 -4
- package/catalog/commands/define.md +7 -0
- package/catalog/commands/hotfix.md +15 -1
- package/catalog/commands/pause.md +5 -0
- package/catalog/commands/resume.md +38 -9
- package/catalog/commands/triage.md +2 -1
- package/catalog/harness.config.schema.json +40 -0
- package/catalog/hooks/init.sh +10 -3
- package/catalog/hooks/lib/merge-pr.sh +699 -0
- package/catalog/skills/mutation-testing/SKILL.md +78 -21
- package/catalog/skills/prd-to-spec/SKILL.md +48 -2
- package/catalog/skills/raise-discovery/SKILL.md +6 -0
- package/catalog/skills/resolve-discovery/SKILL.md +6 -5
- package/catalog/skills/security-review/SKILL.md +119 -6
- package/catalog/skills/spec-to-issue/SKILL.md +7 -1
- package/catalog/skills/task-closeout/SKILL.md +82 -18
- package/catalog/skills/triage-issue/SKILL.md +65 -4
- package/catalog/templates/claude-code/agents.md.tpl +42 -12
- package/catalog/templates/claude-code/harness.config.yml.tpl +37 -0
- package/dist/cli.mjs +748 -36
- package/package.json +10 -6
|
@@ -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.
|
|
68
|
+
### 5. Declare the risk surfaces
|
|
69
69
|
|
|
70
|
-
|
|
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
|
-
###
|
|
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,44 @@ 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 **auto-commit**
|
|
91
|
+
(config `implementation.auto_commit`; auto-commit OFF = zero commits — the human
|
|
92
|
+
reviews the work **uncommitted** until each checkpoint OK; auto-commit ON =
|
|
93
|
+
commit-as-you-go).
|
|
94
|
+
Authority: orchestrator §Implementation mode / §Auto-commit OFF.
|
|
81
95
|
8. **Review** — flip to `harness:status:in-review`, open the PR (`gh pr create`,
|
|
82
96
|
branch → default), Reviewer sub-agent reviews it (`senior-review`, fresh context). If
|
|
83
97
|
the task touched UI, the **UI Designer** reviews as a distinct design + a11y lens too
|
|
84
|
-
— either lens rejecting routes back to the Implementer.
|
|
98
|
+
— either lens rejecting routes back to the Implementer. Every APPROVE carries an
|
|
99
|
+
**evidence ledger** — a JSON sidecar under the task's state that a script validates
|
|
100
|
+
(`lemony review-ledger validate`), never an agent: a red ledger sends a fresh Reviewer
|
|
101
|
+
back once, then the human; it never routes to the Implementer and is never relayed as
|
|
102
|
+
an APPROVE.
|
|
85
103
|
9. **Merge gate** — never auto-merge. Surface the approved PR; the human merges (or
|
|
86
|
-
authorizes you to
|
|
104
|
+
authorizes you to — a conditional yes: the agent's merge runs through the
|
|
105
|
+
checks precondition (`.claude/hooks/lib/merge-pr.sh --approve-issue <issue>`)
|
|
106
|
+
and never lands on red, absent, or still-pending checks without asking — nor
|
|
107
|
+
content that no longer matches what the Reviewer's APPROVE reviewed (the
|
|
108
|
+
stale-approve guard; a clean update-branch stays valid, any content change
|
|
109
|
+
routes back to re-review). The task stays at `in-review`
|
|
110
|
+
until merged.
|
|
87
111
|
10. **Closeout** — `task-closeout`: confirm the merge via `gh`, run the three Architect
|
|
88
112
|
activations (`write-adr` — HITL offer per resolved discovery; `update-architecture` —
|
|
89
113
|
automatic when `docs/architecture.md` exists; `playbook-iterate` — HITL offer once
|
|
90
114
|
per task), archive the spec + discoveries to `_archive/<id>/` (drop
|
|
91
115
|
`progress.md`), and land `history.md` + the archival via a dedicated
|
|
92
|
-
`harness/closeout-<id>` PR
|
|
93
|
-
|
|
94
|
-
|
|
116
|
+
`harness/closeout-<id>` PR that self-merges **only on green checks**
|
|
117
|
+
(`.claude/hooks/lib/merge-pr.sh`) — never a direct push to the base.
|
|
118
|
+
A red on its own files (format/lint) it fixes and retries autonomously; any
|
|
119
|
+
other not-green outcome or protection needing approval parks the PR at
|
|
120
|
+
`closeout-pending`, and `/resume` finalizes. Then close the issue and delete
|
|
121
|
+
the branch.
|
|
95
122
|
|
|
96
123
|
## L2 round-trip (TRIAGE)
|
|
97
124
|
|
|
@@ -105,11 +132,14 @@ Authority for the steps: `.claude/agents/triage.md` (the Orchestrator's lazy com
|
|
|
105
132
|
3. **Implement** — Implementer sub-agent, `tdd` skill.
|
|
106
133
|
4. **Review** — flip to `harness:status:in-review`, open the PR, Reviewer sub-agent
|
|
107
134
|
(`senior-review`, fresh context).
|
|
108
|
-
5. **Merge gate** — the same human-explicit gate as L1: never auto-merge
|
|
135
|
+
5. **Merge gate** — the same human-explicit gate as L1: never auto-merge, and an
|
|
136
|
+
authorized merge runs the same checks precondition and stale-approve guard.
|
|
109
137
|
6. **Closeout** — `task-closeout`: confirm the merge, archive the spec + discoveries to
|
|
110
138
|
`_archive/<id>/`, and land `history.md` + the archival via a dedicated
|
|
111
|
-
`harness/closeout-<id>` PR
|
|
112
|
-
|
|
139
|
+
`harness/closeout-<id>` PR that self-merges only on green checks (own-file
|
|
140
|
+
format reds are self-fixed and retried); park at `closeout-pending` if checks
|
|
141
|
+
stay not-green or it needs approval. Then close the issue and delete the
|
|
142
|
+
branch. Same as L1.
|
|
113
143
|
|
|
114
144
|
## Discovery interrupts
|
|
115
145
|
|
|
@@ -46,6 +46,43 @@ 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
|
+
# auto_commit — does the agent commit automatically as it works? `on`: the
|
|
63
|
+
# Implementer commits and pushes as it goes; `off`: zero commits — the work
|
|
64
|
+
# accumulates in the worktree, you review it UNCOMMITTED (Source Control) and
|
|
65
|
+
# the branch gets its first commit on your OK (more control). `human` (default)
|
|
66
|
+
# asks at the gate, in the same interaction as the all-at-once / step-by-step
|
|
67
|
+
# choice, recommending OFF; `on` / `off` pin the answer and skip the question
|
|
68
|
+
# (a headless/bench run must pin `on`). Bare on/off are strings here (YAML 1.2).
|
|
69
|
+
# Replaces `pre_commit_review` (0.3.0, inverse polarity): the old key is
|
|
70
|
+
# tolerated and removed on the next config write; its value is not migrated.
|
|
71
|
+
# implementation:
|
|
72
|
+
# auto_commit: human
|
|
73
|
+
|
|
74
|
+
# Review gates. The mechanical gates a Reviewer must attest in its evidence
|
|
75
|
+
# ledger, one entry per name, beyond the always-required real run — a flat list of
|
|
76
|
+
# this project's script names (`package.json` scripts, or your CI's equivalents).
|
|
77
|
+
# Declare every gate your CI enforces, drift checks included: an undeclared project
|
|
78
|
+
# reviews against a floor of the real run only (honest, but thin). The agent may
|
|
79
|
+
# propose this list from your manifest at the approval gate — confirmed by a human
|
|
80
|
+
# and added by hand (this block is the shape); no tool writes it for you.
|
|
81
|
+
# gates:
|
|
82
|
+
# - lint
|
|
83
|
+
# - test
|
|
84
|
+
# - build
|
|
85
|
+
|
|
49
86
|
# Design tokens (`design-tokens validate`). The anti-hardcode scan inspects a built-in
|
|
50
87
|
# set of UI/style extensions (.css/.scss/.ts/.tsx/.vue/.svelte/.astro/.js/.mdx/.html/…).
|
|
51
88
|
# Add extra suffixes here for a stack the built-ins don't cover — additive, never a
|