@lemoncode/lemony 0.1.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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/PRIVACY.md +147 -0
  3. package/README.md +189 -0
  4. package/catalog/VERSION +1 -0
  5. package/catalog/agents/README.md +29 -0
  6. package/catalog/agents/architect.md +81 -0
  7. package/catalog/agents/fit-assessment.md +94 -0
  8. package/catalog/agents/implementer.md +67 -0
  9. package/catalog/agents/orchestrator.md +627 -0
  10. package/catalog/agents/reviewer.md +124 -0
  11. package/catalog/agents/spec-author.md +69 -0
  12. package/catalog/agents/ui-designer.md +25 -0
  13. package/catalog/commands/add-capability.md +69 -0
  14. package/catalog/commands/bypass.md +40 -0
  15. package/catalog/commands/define.md +24 -0
  16. package/catalog/commands/hotfix.md +47 -0
  17. package/catalog/commands/pause.md +52 -0
  18. package/catalog/commands/resume.md +56 -0
  19. package/catalog/commands/spinoff.md +59 -0
  20. package/catalog/commands/triage.md +24 -0
  21. package/catalog/harness.config.schema.json +116 -0
  22. package/catalog/hooks/README.md +56 -0
  23. package/catalog/hooks/init.sh +281 -0
  24. package/catalog/hooks/lib/lemony.sh +41 -0
  25. package/catalog/hooks/lib/playbook-scan.sh +394 -0
  26. package/catalog/hooks/lib/transcript-grep.sh +56 -0
  27. package/catalog/hooks/require-playbook.sh +97 -0
  28. package/catalog/hooks/session-close.sh +232 -0
  29. package/catalog/hooks/suggest-playbook.sh +72 -0
  30. package/catalog/playbook-format.md +198 -0
  31. package/catalog/schemas/README.md +13 -0
  32. package/catalog/schemas/tier2-events-history.md +104 -0
  33. package/catalog/schemas/tier2-events.md +286 -0
  34. package/catalog/skills/README.md +62 -0
  35. package/catalog/skills/bootstrap-architecture/SKILL.md +78 -0
  36. package/catalog/skills/code-explorer/SKILL.md +76 -0
  37. package/catalog/skills/grill-with-docs/ADR-FORMAT.md +49 -0
  38. package/catalog/skills/grill-with-docs/CONTEXT-FORMAT.md +77 -0
  39. package/catalog/skills/grill-with-docs/SKILL.md +270 -0
  40. package/catalog/skills/grill-with-docs/reference.md +236 -0
  41. package/catalog/skills/mutation-testing/SKILL.md +84 -0
  42. package/catalog/skills/note-side-finding/SKILL.md +89 -0
  43. package/catalog/skills/playbook-iterate/SKILL.md +78 -0
  44. package/catalog/skills/prd-to-spec/SKILL.md +181 -0
  45. package/catalog/skills/raise-discovery/SKILL.md +112 -0
  46. package/catalog/skills/resolve-discovery/SKILL.md +123 -0
  47. package/catalog/skills/review-pr/SKILL.md +106 -0
  48. package/catalog/skills/review-pr/reference.md +105 -0
  49. package/catalog/skills/security-review/SKILL.md +90 -0
  50. package/catalog/skills/senior-review/SKILL.md +99 -0
  51. package/catalog/skills/silent-failure-hunter/SKILL.md +76 -0
  52. package/catalog/skills/spec-compliance-check/SKILL.md +74 -0
  53. package/catalog/skills/spec-to-issue/SKILL.md +88 -0
  54. package/catalog/skills/task-closeout/SKILL.md +229 -0
  55. package/catalog/skills/tdd/SKILL.md +171 -0
  56. package/catalog/skills/test-gap-report/SKILL.md +71 -0
  57. package/catalog/skills/triage-issue/SKILL.md +102 -0
  58. package/catalog/skills/update-architecture/SKILL.md +69 -0
  59. package/catalog/skills/verify/SKILL.md +90 -0
  60. package/catalog/skills/write-adr/SKILL.md +77 -0
  61. package/catalog/templates/README.md +32 -0
  62. package/catalog/templates/claude-code/.claude/settings.json.tpl +34 -0
  63. package/catalog/templates/claude-code/agents.md.tpl +109 -0
  64. package/catalog/templates/claude-code/docs/playbooks/README.md.tpl +96 -0
  65. package/catalog/templates/claude-code/harness.config.yml.tpl +59 -0
  66. package/catalog/templates/claude-code/state/history.md.tpl +6 -0
  67. package/dist/cli.mjs +5691 -0
  68. package/package.json +80 -0
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: note-side-finding
3
+ description: Surface an independent, non-blocking defect you spotted mid-task in your return summary instead of pausing or fixing it. Use when a sub-agent (Spec Author, Implementer, Reviewer, Architect) notices a real bug that is unrelated to its current task — the task finishes fine without touching it — so it should be parked for later, not escalated. The non-pausing sibling of raise-discovery.
4
+ origin: vendor
5
+ vendor_version: '{{vendor_version}}'
6
+ invoked-by: [spec-author, implementer, reviewer, architect]
7
+ ---
8
+
9
+ # Note Side-Finding
10
+
11
+ ## Core Principle
12
+
13
+ While doing your task with fresh context, you sometimes spot a **real defect that has
14
+ nothing to do with the task you were given** — the task finishes correctly without
15
+ touching it ("while implementing the parser I noticed the unrelated CSV export drops
16
+ the last row"). You **cannot interrupt** the human (you run via `Task`, not in the
17
+ hat's conversation) and you should **not** silently fix it (it is outside your task's
18
+ scope) or pause for it (it is not blocking you). So you do neither: you **note it in
19
+ your return summary and keep going**. The Orchestrator collects it and offers the human
20
+ a `/spinoff` capture — nothing is lost, nothing is context-switched.
21
+
22
+ This is the **non-pausing** half of the discovery family. You write one bullet and
23
+ return; you do not create an issue, flip a label, write to `discoveries.md`, or stop.
24
+
25
+ ## Which channel — side-finding vs discovery vs just-do-it
26
+
27
+ Pick by **two questions: does it block your task, and is it in your task's scope?**
28
+
29
+ | Situation | Channel | What you do |
30
+ | --------------------------------------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------- |
31
+ | Defect is **in scope** for your task (your change touches it) | **Just fix it** | Fix it in your normal work — no note, no escalation. |
32
+ | Defect **blocks** your task / the plan forces it (T1–T6) | **`raise-discovery`** | Pause: write `discoveries.md`, return one line, stop. |
33
+ | Defect is **independent and non-blocking** (task finishes fine) | **note-side-finding** | Add a `## Side-findings` bullet, **keep working**. |
34
+ | A feature **idea** (not a defect) | mention it in prose | No capture channel here — drop it in your summary prose; the human may pick it up and `/define` it. |
35
+
36
+ The discriminator against `raise-discovery` is **blocking**: if you can complete your
37
+ task without the defect being touched, it is a side-finding (note and continue), never a
38
+ discovery (pause and stop). When genuinely unsure whether it blocks you, prefer
39
+ `raise-discovery` — a wrong pause is cheaper than coding past a real contradiction.
40
+
41
+ The same channel covers **architecturally-significant drift in `docs/architecture.md`**
42
+ (ADR 0011) — when you read the map to orient and find it states a boundary/seam the code no
43
+ longer matches, in an area your task doesn't touch. That is a defect of the _map_, not the
44
+ code: non-blocking and out of your scope, so it rides here. Tag such a bullet `kind: drift`
45
+ (see the contract below) so the Orchestrator routes it to the Architect's
46
+ `update-architecture` rather than a generic follow-up; don't fix the map yourself and don't
47
+ silently trust one side.
48
+
49
+ ## The contract
50
+
51
+ When you have one or more independent non-blocking defects, append **one** section to
52
+ the **end of your return summary** to the Orchestrator (omit it entirely when you have
53
+ none — never emit an empty block):
54
+
55
+ ```markdown
56
+ ## Side-findings
57
+
58
+ - **symptom:** <one line — what is wrong>
59
+ **location:** <file:line or the area you saw it>
60
+ **severity:** <low | medium | high | critical — optional>
61
+ **kind:** <drift — optional; only for architecture.md drift>
62
+ ```
63
+
64
+ One bullet per finding. `symptom` and `location` are required; `severity` is your
65
+ optional read. `kind` is optional and, today, only takes the value `drift` — set it
66
+ **only** for `docs/architecture.md` map staleness (above), so the Orchestrator routes the
67
+ stub to `update-architecture`; omit it for an ordinary code defect. Keep each to the
68
+ symptom + where you saw it — do **not** root-cause or propose a fix (the capture is
69
+ deliberately shallow; investigation happens at pickup). Everything else in your return
70
+ summary stays exactly as it was — the section is an addition, not a replacement.
71
+
72
+ Then **continue your task to its normal end** (or, if you were already done, just
73
+ return). Do not wait for a reply, do not act on the finding, do not open anything.
74
+
75
+ ## What the Orchestrator does with it
76
+
77
+ It reads the `## Side-findings` block from your summary and, for each entry, makes the
78
+ same single-line `/spinoff` offer it makes for a human-mentioned defect — lean toward
79
+ offering, one-tap dismissal, never re-offered twice, never pausing. The active task is
80
+ recorded as the parent. You are not involved past returning the bullet.
81
+
82
+ ## Uncontemplated Scenarios
83
+
84
+ When a scenario doesn't clearly fit these rules:
85
+
86
+ 1. Apply the closest matching channel with reasoning (when torn between side-finding and
87
+ discovery, default to `raise-discovery` — blocking is the safe assumption).
88
+ 2. **Flag it**: "This didn't clearly fit note-side-finding. I [noted it / raised it]
89
+ because [reason]. Want to refine the skill?"
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: playbook-iterate
3
+ description: Propose changes to a client playbook — or extract a new one from the codebase — when the spec collides with a documented pattern (a T6 PLAYBOOK_CONFLICT) or the client asks. Playbooks are client-owned (decision #8); the Architect proposes and the human decides. Use when the Orchestrator routes a T6 discovery resolution to the Architect, or on an explicit "capture how we do X" request.
4
+ origin: vendor
5
+ vendor_version: '{{vendor_version}}'
6
+ invoked-by: [architect]
7
+ trigger-condition: a T6 PLAYBOOK_CONFLICT needs the playbook changed, or the client asks to extract/iterate one
8
+ ---
9
+
10
+ # Playbook Iterate
11
+
12
+ ## Core Principle
13
+
14
+ A **playbook** describes _how to build_ a category of software (a backend service, an
15
+ SPA, a testing strategy) in **project-agnostic** terms — placeholder names, never a real
16
+ codebase's symbols. Playbooks are **client-owned** (decision #8): the vendor ships the
17
+ _format_ and the _lookup convention_, never the content. So this skill **proposes**; the
18
+ human **decides**. The Architect never rewrites a client playbook unilaterally.
19
+
20
+ ## Where playbooks live (the lookup convention)
21
+
22
+ Two layers, discovered by convention `<topic>.md` — **no index** (an index drifts):
23
+
24
+ 1. **Project-local** — `docs/playbooks/<topic>.md`. Harness-managed home, committed.
25
+ 2. **User-global** — `~/.claude/playbooks/<topic>.md`. The developer's own generic playbooks.
26
+
27
+ (Both locations are configurable via `paths.playbooks` / `paths.playbooks_global`
28
+ in `harness.config.yml`; the defaults above apply when those keys are unset.)
29
+
30
+ Lookup is **local → global**, and the **local entry overrides** the global one for the
31
+ same topic. A missing playbook is not an error — degrade gracefully. New project-local
32
+ playbooks land in `docs/playbooks/`.
33
+
34
+ ## Mode A — resolve a T6 PLAYBOOK_CONFLICT
35
+
36
+ The Orchestrator routes you here when a discovery resolution decided that honoring the
37
+ spec means the **playbook** should change (the playbook is the artifact being updated).
38
+
39
+ 1. **Read both sides.** The playbook section in conflict and the spec requirement that
40
+ collides with it. State the contradiction precisely.
41
+ 2. **Propose the smallest change** that resolves it, framed as a diff to the playbook
42
+ prose — and note the alternative (change the spec instead). The human already chose
43
+ the direction during `resolve-discovery`; you render that choice into the playbook.
44
+ 3. **Edit the project-local playbook** (`docs/playbooks/<topic>.md`), keeping it
45
+ project-agnostic — placeholder names, no symbols from this codebase. A rule that is
46
+ really project-specific belongs in `CLAUDE.md` / an ADR / `CONTEXT.md`, **not** a
47
+ playbook; say so if that's what the conflict actually reveals.
48
+ 4. **Return** the updated playbook path and a one-line summary to the Orchestrator, so it
49
+ can record the resolution and resume the paused sub-agent against the corrected source.
50
+
51
+ ## Mode B — extract a playbook from the codebase (client-triggered)
52
+
53
+ On an explicit request ("capture how we do X here"):
54
+
55
+ 1. **Find the pattern** in the code — the repeated shape, the convention the codebase
56
+ already follows (use `code-explorer` first if the codebase is unfamiliar).
57
+ 2. **Generalize it.** Strip the project's real names down to placeholders; describe the
58
+ _pattern_, not the instance. If it can't be generalized, it's project-specific and
59
+ doesn't belong in a playbook.
60
+ 3. **Write** `docs/playbooks/<topic>.md` following the playbook conventions documented
61
+ in `docs/playbooks/README.md` (project-agnostic, placeholder names), and report it for
62
+ the human to review.
63
+
64
+ ## Report
65
+
66
+ Return to the Orchestrator: the playbook path written/changed, a one-line summary, and —
67
+ for Mode A — confirmation it resolves the cited T6. If the change turned out to be
68
+ project-specific (belongs in `CLAUDE.md`/ADR, not a playbook), report that instead and
69
+ make no playbook edit.
70
+
71
+ ## Uncontemplated Scenarios
72
+
73
+ When a case doesn't clearly fit:
74
+
75
+ 1. Apply the closest matching approach with reasoning.
76
+ 2. **Flag it**: "This isn't covered by the playbook-iterate skill. I did [approach]
77
+ because [reason]. Want to refine the skill?"
78
+ 3. Offer to add a rule for the case.
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: prd-to-spec
3
+ description: Turn a completed PRD into a task spec — requirements.md (EARS), design.md, and tasks.md. Use when the Spec Author decomposes a PRD into an implementable specification, mentions "write the spec", "EARS requirements", or "requirements/design/tasks".
4
+ origin: vendor
5
+ vendor_version: '{{vendor_version}}'
6
+ phase: pre-implementation
7
+ invoked-by: [spec-author]
8
+ ---
9
+
10
+ # PRD to Spec
11
+
12
+ ## Core Principle
13
+
14
+ A spec is a contract, not a diff. It says **what** must be true and **why**, never
15
+ **how** line by line. The PRD captured intent through grilling; this skill turns that
16
+ intent into three artifacts an Implementer can build against and a Reviewer can check
17
+ against — without re-interviewing the human.
18
+
19
+ The Spec Author runs with **fresh context**. That is the point: if the PRD is too
20
+ vague to write a testable requirement from, the PRD is not done. Do not paper over
21
+ the gap by guessing — surface it (see "When the PRD is insufficient").
22
+
23
+ ## Inputs and outputs
24
+
25
+ - **Input**: a PRD at `docs/prds/<topic>-<date>.md` (owned by the Orchestrator via
26
+ `grill-with-docs`). This skill **consumes** the PRD — it never edits or closes it.
27
+ - **Output**: three files under `.claude/state/tasks/<id>/spec/`. The Orchestrator
28
+ created the issue and the task branch before invoking the Spec Author, so `<id>` is
29
+ real from the start — there is no `draft-<slug>` holder:
30
+ - `requirements.md` — EARS requirements with acceptance criteria
31
+ - `design.md` — files, functions, approach, edge cases, testing
32
+ - `tasks.md` — atomic, ordered, checkbox tasks
33
+
34
+ ## Process
35
+
36
+ ### 1. Read the PRD in full
37
+
38
+ Read the whole PRD, plus any `CONTEXT.md` glossary terms and `docs/adr/` it
39
+ references. Identify: the user stories, the decisions already closed, what's
40
+ explicitly out of scope, and the assumptions/risks flagged. The closed decisions are
41
+ constraints — the spec must honor them, not relitigate them.
42
+
43
+ ### 2. Write `requirements.md` (EARS)
44
+
45
+ Express every requirement in **EARS** (Easy Approach to Requirements Syntax). EARS is
46
+ five sentence patterns — pick the one that fits each requirement:
47
+
48
+ | Pattern | Template | Use for |
49
+ | --------------------- | ------------------------------------------------------------------ | ------------------------------------------------- |
50
+ | **Ubiquitous** | The `<system>` shall `<response>`. | Always-active properties, invariants |
51
+ | **Event-driven** | When `<trigger>`, the `<system>` shall `<response>`. | A response to a specific event/input |
52
+ | **State-driven** | While `<state>`, the `<system>` shall `<response>`. | Behavior that holds during a state |
53
+ | **Optional-feature** | Where `<feature>`, the `<system>` shall `<response>`. | Behavior that exists only if a feature is present |
54
+ | **Unwanted-behavior** | If `<unwanted condition>`, then the `<system>` shall `<response>`. | Error handling, invalid input, failure paths |
55
+
56
+ Complex requirements combine patterns, outer-clause first:
57
+ _"While `<state>`, when `<trigger>`, the system shall `<response>`."_
58
+
59
+ Rules:
60
+
61
+ - **Number every requirement** (`R1`, `R2`, …) so design and tasks can reference them.
62
+ - **Always include the unwanted-behavior path.** A spec with no `If … then …`
63
+ requirements is almost always incomplete — error and invalid-input handling is
64
+ where bugs live.
65
+ - **One requirement, one shall.** Split compound sentences.
66
+ - **Testable, not vague.** "shall respond quickly" is not a requirement; "shall
67
+ respond within 200ms" is.
68
+ - Group requirements under the user story or capability they serve.
69
+ - Add a short **Acceptance criteria** list per capability — the observable facts a
70
+ Reviewer checks.
71
+
72
+ Template:
73
+
74
+ ```markdown
75
+ # Requirements — <topic>
76
+
77
+ > Source PRD: docs/prds/<topic>-<date>.md
78
+
79
+ ## <Capability / user story>
80
+
81
+ - **R1** (event): When <trigger>, the system shall <response>.
82
+ - **R2** (unwanted): If <invalid condition>, then the system shall <response>.
83
+ - **R3** (ubiquitous): The system shall <invariant>.
84
+
85
+ ### Acceptance criteria
86
+
87
+ - [ ] <observable fact a reviewer can verify>
88
+ ```
89
+
90
+ ### 3. Write `design.md`
91
+
92
+ The _how_, at the level a competent implementer needs — not a transcript of the code.
93
+
94
+ ```markdown
95
+ # Design — <topic>
96
+
97
+ ## Approach
98
+
99
+ <2–5 sentences: the shape of the solution and why, honoring the PRD's closed decisions.>
100
+
101
+ ## Files
102
+
103
+ - `path/to/file.ts` — <created|modified> — <what it holds>
104
+
105
+ ## Functions / interfaces
106
+
107
+ - `functionName(args): ReturnType` — <contract: what it guarantees, which Rs it serves>
108
+
109
+ ## Edge cases
110
+
111
+ - <edge case> → <intended behavior> (maps to R#)
112
+
113
+ ## Testing approach
114
+
115
+ - <what to test and at which level — unit / integration; what NOT to test and why>
116
+ ```
117
+
118
+ Honor the project's playbooks (looked up by topic — `docs/playbooks/<topic>.md`, then
119
+ the global layer) and `coding-conventions` for structure, naming, and the testing
120
+ pyramid. If the design would contradict a playbook, that's a discovery, not a silent
121
+ deviation (T6).
122
+
123
+ ### 4. Write `tasks.md`
124
+
125
+ Atomic, ordered checkboxes. Each task is a **vertical slice** (a behavior, not a
126
+ layer) so the Implementer can run TDD red→green per task. Reference the requirements
127
+ each task satisfies.
128
+
129
+ ```markdown
130
+ # Tasks — <topic>
131
+
132
+ - [ ] T1 — <smallest behavior that proves the path end-to-end> (R1)
133
+ - [ ] T2 — <next behavior> (R2)
134
+ - [ ] T3 — <error path> (R2, R3)
135
+ ```
136
+
137
+ Rules: order so the first task is a tracer bullet; never "write all tests" then
138
+ "write all code"; keep each task small enough to verify on its own.
139
+
140
+ ### 5. Self-check before handing off
141
+
142
+ - [ ] Every PRD user story maps to at least one requirement.
143
+ - [ ] Every requirement is EARS-formatted and testable.
144
+ - [ ] At least one unwanted-behavior (`If … then …`) requirement exists.
145
+ - [ ] Every requirement is covered by at least one task.
146
+ - [ ] No closed PRD decision is contradicted.
147
+
148
+ ### 6. Emit `spec_created`
149
+
150
+ Telemetry — record that the spec landed. Count the EARS requirements in
151
+ `requirements.md` (each `R<N>` entry, e.g. `R1`, `R2`, …) and emit via Bash:
152
+
153
+ ```bash
154
+ .claude/hooks/lib/lemony.sh emit spec_created \
155
+ --task-id="<id>" \
156
+ --topic="<slug>" \
157
+ --requirements=<count>
158
+ ```
159
+
160
+ `<slug>` is the topic part of the task branch (`harness/<id>-<slug>`). The CLI
161
+ Zod-validates the line and appends it to `.claude/state/events.jsonl`.
162
+
163
+ Then hand off to `spec-to-issue` to fill the issue body with the externalized spec.
164
+
165
+ ## When the PRD is insufficient
166
+
167
+ If a requirement can't be written without choosing between >1 valid option the PRD
168
+ left open, that's a **T2 UNSPECIFIED_DECISION** discovery — the spec cannot be
169
+ self-sufficient. Do not guess. **Run the `raise-discovery` skill**: write the entry to
170
+ `discoveries.md`, return the one-line summary, and stop. The Orchestrator mediates the
171
+ question with the human, the PRD/spec improves, and you are re-invoked with the
172
+ decision.
173
+
174
+ ## Uncontemplated Scenarios
175
+
176
+ When a scenario doesn't clearly fit these rules:
177
+
178
+ 1. Apply the closest matching approach with reasoning.
179
+ 2. **Flag it**: "This scenario isn't covered by the prd-to-spec skill. I applied
180
+ [approach] because [reason]. Want to update the skill?"
181
+ 3. Offer to add a new rule for the case.
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: raise-discovery
3
+ description: Pause the task and escalate when reality contradicts or exceeds the plan, instead of improvising. Use when a sub-agent (Spec Author, Implementer, Reviewer, Architect) hits a T1–T6 case — a contradiction, an unspecified decision, scope drift, an existing solution, an infeasibility, or a playbook conflict — and needs a human decision before continuing.
4
+ origin: vendor
5
+ vendor_version: '{{vendor_version}}'
6
+ invoked-by: [spec-author, implementer, reviewer, architect]
7
+ ---
8
+
9
+ # Raise Discovery
10
+
11
+ ## Core Principle
12
+
13
+ A sub-agent does **not** improvise when reality contradicts or exceeds the plan. It
14
+ **escalates to the human** through the Orchestrator — like a compiler stopping on a
15
+ type error instead of guessing what you meant. The fresh-context sub-agent is the
16
+ sensor; the human is the arbiter. Guessing past a real ambiguity is how a confident,
17
+ wrong implementation gets built.
18
+
19
+ This skill is the **raising** half of the protocol. You write one entry, return a
20
+ one-line summary, and **stop**. You do not flip labels, you do not dialogue with the
21
+ human, and you do not resume yourself — the Orchestrator owns all of that (it runs
22
+ `resolve-discovery`) and will re-invoke you with the decision when it's settled.
23
+
24
+ ## When to raise — the taxonomy (T1–T6)
25
+
26
+ | Tag | Type | Raise when… |
27
+ | ------ | -------------------- | ---------------------------------------------------------- |
28
+ | **T1** | CONTRADICTION | Existing code/env contradicts the plan or spec. |
29
+ | **T2** | UNSPECIFIED_DECISION | The plan is silent and **>1 valid option** exists. |
30
+ | **T3** | SCOPE_DRIFT | Implementing the plan requires touching out-of-scope work. |
31
+ | **T4** | EXISTING_SOLUTION | The plan assumes building something that already exists. |
32
+ | **T5** | INFEASIBILITY | The plan is not implementable as written. |
33
+ | **T6** | PLAYBOOK_CONFLICT | Honoring the spec would contradict a client playbook. |
34
+
35
+ ## When NOT to raise (resolve it yourself)
36
+
37
+ Escalation is for decisions with architectural or scope impact, not for everything
38
+ unstated. Decide these yourself and note them in your normal output:
39
+
40
+ - Local naming, formatting, file layout with no downstream impact.
41
+ - Cases already covered by a playbook or `coding-conventions` — follow it.
42
+ - A single obviously-correct option (no genuine fork).
43
+
44
+ The bar for **T2** is the sharpest: raise only when the options are genuinely
45
+ different _and_ the choice has consequences a human would want to make. "The spec
46
+ didn't name the variable" is not a discovery; "the spec didn't say whether an empty
47
+ input errors or defaults, and both are defensible" is.
48
+
49
+ ## Process
50
+
51
+ ### 1. Confirm it's a real discovery
52
+
53
+ Re-read the relevant spec / PRD / playbook section. If it actually answers the
54
+ question, you don't have a discovery — proceed. If, and only if, it leaves a
55
+ consequential fork open, continue.
56
+
57
+ ### 2. Append an entry to `discoveries.md`
58
+
59
+ The file is `.claude/state/tasks/<id>/discoveries.md`, **append-only**. Create it with
60
+ an `# Discoveries — task <id>` heading if it doesn't exist yet. Read any existing
61
+ entries to pick the next sequential id (`D001`, `D002`, …). Append a new section —
62
+ never edit or delete a prior one:
63
+
64
+ ```markdown
65
+ ## D001 — T2 UNSPECIFIED_DECISION · raised <YYYY-MM-DD>
66
+
67
+ - **Subtask context:** <which agent + which subtask/step you were on>
68
+ - **Plan says:** <what the spec/PRD/plan states — quote or cite the line>
69
+ - **Reality:** <what you found that contradicts or exceeds it>
70
+ - **Proposed:** <the option(s) you see, with a one-line trade-off each>
71
+ - **Question:** <the single, precise decision the human must make>
72
+ ```
73
+
74
+ Fill **every** field. The entry must be self-sufficient: the Orchestrator and the
75
+ human resolve from this file alone, without your context. Leave the `**Resolution**`
76
+ block out — the Orchestrator appends it under this same header when the decision is
77
+ made. Leave `paused_from` out too: the Orchestrator records the state being left when
78
+ it pauses the task; that is its job, not yours.
79
+
80
+ ### 3. Return a one-line summary and stop
81
+
82
+ Return to the Orchestrator exactly this shape, nothing more:
83
+
84
+ ```
85
+ Discovery D001 (T2/UNSPECIFIED_DECISION) raised — see tasks/<id>/discoveries.md
86
+ ```
87
+
88
+ Then **stop**. Do not keep working, do not pick an option, do not transition labels.
89
+ The Orchestrator will move the task to `paused_for_clarification`, add the
90
+ `harness:discovery:T*` label, mediate with the human, and re-invoke you with the
91
+ resolution. (The issue exists from the start of `spec-in-progress`, before any
92
+ sub-agent runs, so there is always an issue to label.) When it does, you resume from
93
+ the decision in the entry's `**Resolution**` block — the `paused_from` state the
94
+ Orchestrator records at pause time tells it where you left off.
95
+
96
+ ## Scope note
97
+
98
+ T6 PLAYBOOK_CONFLICT (and any resolution that updates an ADR, `docs/architecture.md`,
99
+ or a client playbook) is owned by the **Architect**: raise it normally, and the
100
+ Orchestrator routes the artifact update to the on-demand Architect (`write-adr` /
101
+ `update-architecture` / `playbook-iterate`) before resuming you. Telemetry for
102
+ discoveries (a `discovery_raised` event) is deferred to a later phase; in this build the
103
+ durable record is `discoveries.md` plus the issue label.
104
+
105
+ ## Uncontemplated Scenarios
106
+
107
+ When a scenario doesn't clearly fit these rules:
108
+
109
+ 1. Apply the closest matching approach with reasoning.
110
+ 2. **Flag it**: "This scenario isn't covered by the raise-discovery skill. I applied
111
+ [approach] because [reason]. Want to update the skill?"
112
+ 3. Offer to add a new rule for the case.
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: resolve-discovery
3
+ description: Mediate a raised discovery with the human and resume the paused sub-agent. Use when the Orchestrator receives a "Discovery D00x raised" summary — it pauses the task, arbitrates the T1–T6 question with the human, routes the artifact update to its owner, records the resolution, and re-invokes the paused sub-agent with the decision.
4
+ origin: vendor
5
+ vendor_version: '{{vendor_version}}'
6
+ invoked-by: [orchestrator]
7
+ ---
8
+
9
+ # Resolve Discovery
10
+
11
+ ## Core Principle
12
+
13
+ This is the **resolving** half of the interrupt-on-discovery protocol; the sub-agent
14
+ side is `raise-discovery`. The Orchestrator is the only one who talks to the human and
15
+ the only one who moves labels, so it owns mediation end to end: pause the task,
16
+ arbitrate, route the fix to whoever owns the artifact, record the decision, and resume
17
+ the sub-agent that stopped. The discovery is not closed until the paused sub-agent has
18
+ been re-invoked with the decision.
19
+
20
+ You run this when a sub-agent returns a summary of the shape
21
+ `Discovery D001 (T2/UNSPECIFIED_DECISION) raised — see tasks/<id>/discoveries.md`.
22
+
23
+ ## Process
24
+
25
+ ### 1. Pause the task
26
+
27
+ The sub-agent already wrote the entry and stopped. Record where it stopped and flip
28
+ state:
29
+
30
+ 1. In the discovery's section in `.claude/state/tasks/<id>/discoveries.md`, add a
31
+ `paused_from:` line capturing the status the task is leaving (`spec-in-progress`,
32
+ `in-progress`, or `in-review`) — this is the state you'll resume to. You write this,
33
+ not the sub-agent.
34
+ 2. Reflect the pause onto the GitHub issue with the `discovery` CLI verb. In one
35
+ fail-loud call it flips the status label (mutually exclusive)
36
+ `harness:status:<current> → harness:status:paused-for-clarification`, adds the
37
+ discovery flag `harness:discovery:T<n>` (presence-based, multiple allowed), and posts
38
+ a comment with the entry so the pause is visible on GitHub, not just in local state:
39
+
40
+ ```bash
41
+ .claude/hooks/lib/lemony.sh discovery pause \
42
+ --task-id=<id> --tier=T<n> --status=<current> \
43
+ --note="<one-line gist of the question>"
44
+ ```
45
+
46
+ Keep `--note` to a single line — the full `Plan says / Reality / Question` entry
47
+ lives in `discoveries.md`; the comment only needs a pointer-gist (omit `--note`
48
+ entirely and it links to the file). The label flip is **load-bearing**: a non-zero
49
+ exit means it did not land — surface it and retry, do **not** proceed as if the task
50
+ were paused. The comment is best-effort; if only it fails you'll see a `Warning:` but
51
+ the pause still stands. The Orchestrator creates the issue at the start of
52
+ `spec-in-progress`, before any sub-agent runs, so the issue always exists by the time
53
+ a discovery is raised — even a spec-time T2 during `prd-to-spec`.
54
+
55
+ ### 2. Mediate with the human
56
+
57
+ Read the entry. Present it faithfully — the `Plan says` / `Reality` / `Proposed` /
58
+ `Question` — and ask the human the single question it poses. Add your own read if it
59
+ helps, but **do not decide for them**: a discovery exists precisely because the choice
60
+ has consequences worth a human's call. If the human's answer raises a _new_ fork, that
61
+ is a second discovery — append it, don't fold it in.
62
+
63
+ ### 3. Route the artifact update to its owner
64
+
65
+ The agent that **created** an artifact is the one that updates it. Map the decision to
66
+ the artifact it changes, then invoke that owner (fresh context, Task tool) with the
67
+ decision + the entry as context:
68
+
69
+ | Artifact changed by the decision | Owner to invoke |
70
+ | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
71
+ | `spec/requirements.md`, `spec/design.md`, `spec/tasks.md` | **Spec Author** |
72
+ | Implementation code, `progress.md`, `notes.md` | **Implementer** (often just the resumed sub-agent) |
73
+ | `docs/adr/NNNN-<slug>.md`, `docs/architecture.md`, `docs/playbooks/` | **Architect** (on-demand) — `write-adr` to record the decision, `update-architecture` to keep the map true, `playbook-iterate` for a `T6 PLAYBOOK_CONFLICT` |
74
+
75
+ Not every resolution needs an artifact update first. If the decision is simply "do X"
76
+ with no change to the contract, skip straight to recording it and resuming. If it
77
+ changes the contract (a spec requirement, an ADR), the owner updates the artifact
78
+ **before** the paused sub-agent resumes, so it resumes against the corrected source.
79
+
80
+ ### 4. Record the resolution
81
+
82
+ Append a `**Resolution**` block under the discovery's existing header (append-only —
83
+ do not edit the raise fields):
84
+
85
+ ```markdown
86
+ **Resolution** (Orchestrator)
87
+
88
+ - **Decision:** <the human's call, stated plainly>
89
+ - **Artifact updated:** <file + owner who changed it, or "none — decision only">
90
+ - **Resumed at:** <YYYY-MM-DD> — <agent> re-invoked from `paused_from: <state>`
91
+ ```
92
+
93
+ ### 5. Resume and clear the flag
94
+
95
+ 1. Reflect the resume onto the issue with the same `discovery` CLI verb — it removes
96
+ the `harness:discovery:T<n>` flag and flips the status back to `paused_from`
97
+ (`in-progress`, `in-review`, or `spec-in-progress`):
98
+
99
+ ```bash
100
+ .claude/hooks/lib/lemony.sh discovery resume \
101
+ --task-id=<id> --tier=T<n> --status=<paused_from>
102
+ ```
103
+
104
+ Same fail-loud contract: a non-zero exit means the flag/status did not flip back.
105
+
106
+ 2. Re-invoke the paused sub-agent (fresh context) with: the issue, the task-state
107
+ paths, the decision, and the updated artifact. It picks up from where it stopped.
108
+
109
+ ## Closeout invariant
110
+
111
+ At `task-closeout`, **no `discoveries.md` entry may lack a `Resolution` block** with
112
+ `Decision` / `Resumed at` filled, and **no `harness:discovery:*` label may remain** on
113
+ the issue. An unresolved discovery means a sub-agent is still paused — the task is not
114
+ done. If you find one at closeout, resolve it first.
115
+
116
+ ## Uncontemplated Scenarios
117
+
118
+ When a scenario doesn't clearly fit these rules:
119
+
120
+ 1. Apply the closest matching approach with reasoning.
121
+ 2. **Flag it**: "This scenario isn't covered by the resolve-discovery skill. I applied
122
+ [approach] because [reason]. Want to update the skill?"
123
+ 3. Offer to add a new rule for the case.