@olegkoval/agent-skills 1.26.0 → 1.28.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/.claude-plugin/plugin.json +2 -1
- package/README.md +7 -3
- package/catalog/skills.json +18 -0
- package/package.json +5 -3
- package/packages/software-development/lekker-review/SKILL.md +519 -0
- package/packages/software-development/lekker-review/adapters/claude/plugin.json +5 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/SKILL.md +520 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/completeness-critic.md +21 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/conventions.md +124 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/fix-verifier.md +84 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/fixer.md +120 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/implementation.md +53 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/prover.md +135 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/quality.md +72 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/simplification.md +45 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/test-quality.md +170 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/triage-logic.md +27 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/triage-quality.md +41 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/verifier.md +295 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/artifact-page.md +143 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/context-gathering.md +162 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/fix-mode.md +329 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/github-post.md +205 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/house-rules.md +76 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/output-format.md +232 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/scripts/changed-files.sh +77 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/scripts/setup-worktree.sh +337 -0
- package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/scripts/verify-fixes.sh +231 -0
- package/packages/software-development/lekker-review/fix-workflow.js +273 -0
- package/packages/software-development/lekker-review/references/agents/completeness-critic.md +21 -0
- package/packages/software-development/lekker-review/references/agents/conventions.md +124 -0
- package/packages/software-development/lekker-review/references/agents/fix-verifier.md +84 -0
- package/packages/software-development/lekker-review/references/agents/fixer.md +120 -0
- package/packages/software-development/lekker-review/references/agents/implementation.md +53 -0
- package/packages/software-development/lekker-review/references/agents/prover.md +135 -0
- package/packages/software-development/lekker-review/references/agents/quality.md +72 -0
- package/packages/software-development/lekker-review/references/agents/simplification.md +45 -0
- package/packages/software-development/lekker-review/references/agents/test-quality.md +170 -0
- package/packages/software-development/lekker-review/references/agents/triage-logic.md +27 -0
- package/packages/software-development/lekker-review/references/agents/triage-quality.md +41 -0
- package/packages/software-development/lekker-review/references/agents/verifier.md +295 -0
- package/packages/software-development/lekker-review/references/artifact-page.md +143 -0
- package/packages/software-development/lekker-review/references/context-gathering.md +162 -0
- package/packages/software-development/lekker-review/references/fix-mode.md +329 -0
- package/packages/software-development/lekker-review/references/github-post.md +205 -0
- package/packages/software-development/lekker-review/references/house-rules.md +76 -0
- package/packages/software-development/lekker-review/references/output-format.md +232 -0
- package/packages/software-development/lekker-review/scripts/changed-files.sh +77 -0
- package/packages/software-development/lekker-review/scripts/setup-worktree.sh +337 -0
- package/packages/software-development/lekker-review/scripts/verify-fixes.sh +231 -0
- package/packages/software-development/lekker-review/workflow.js +602 -0
- package/site/assets/paperbag.css +707 -0
- package/site/assets/paperbag.js +218 -0
- package/site/build.mjs +380 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# verifier -- lekker-review agent prompt
|
|
2
|
+
# Receives: one FINDING as JSON, DIFF_FILE path, CONTEXT_FILE path, WORKTREE_PATH path
|
|
3
|
+
# Returns: VERDICT_SCHEMA { verdict: 'confirmed'|'downgraded'|'dropped', newSeverity?, reasoning }
|
|
4
|
+
|
|
5
|
+
## Mindset
|
|
6
|
+
|
|
7
|
+
The author's name, seniority, and past PRs are not evidence. Every assumption
|
|
8
|
+
in the code must be earned from the diff itself. When something *looks* right,
|
|
9
|
+
ask: what would have to be true for this to be wrong?
|
|
10
|
+
|
|
11
|
+
**Bot reviews are not evidence.** The PR body often contains automated reviews
|
|
12
|
+
(Greptile, Copilot, etc.). Do not use their findings as a starting point or
|
|
13
|
+
anchor. If you independently reach the same conclusion, that is fine -- but you
|
|
14
|
+
must earn it from the diff, not borrow it. Prior bot findings that you have not
|
|
15
|
+
verified yourself are not confirmed findings.
|
|
16
|
+
|
|
17
|
+
## Your task
|
|
18
|
+
|
|
19
|
+
You have received one candidate finding as JSON (field `FINDING` in your task
|
|
20
|
+
message). Run all applicable verification checks below against the finding using
|
|
21
|
+
`DIFF_FILE`, `CONTEXT_FILE`, and `WORKTREE_PATH` (read from the task message).
|
|
22
|
+
|
|
23
|
+
When in doubt, drop. A Critical must pass ALL FIVE challenges to remain Critical
|
|
24
|
+
-- unless Step 0 exempts it as a house hard rule, which is the one exception.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Step 0 -- Hard-rule exemption (check this FIRST)
|
|
29
|
+
|
|
30
|
+
If the FINDING JSON has a `rule` field set to `TS-1`, `TS-2`, `GQL-1`, or
|
|
31
|
+
`PR-1`, do NOT run the five adversarial challenges below. They ask
|
|
32
|
+
runtime-failure questions that a standards violation can never answer, and
|
|
33
|
+
answering them honestly would drop a finding that house-rules policy declares
|
|
34
|
+
Critical on standards grounds rather than on runtime behaviour.
|
|
35
|
+
|
|
36
|
+
Instead run exactly two checks:
|
|
37
|
+
|
|
38
|
+
1. **Anchor**: the flagged code genuinely appears on a `+` line of
|
|
39
|
+
`DIFF_FILE` (for PR-1, the PR title genuinely lacks a ticket present in
|
|
40
|
+
the commit history). Use the same technique as Step 1:
|
|
41
|
+
```bash
|
|
42
|
+
grep "^+" "$DIFF_FILE" | grep "<snippet>"
|
|
43
|
+
```
|
|
44
|
+
2. **Rule applicability**: the code really does violate the rule as written
|
|
45
|
+
in `references/house-rules.md` -- e.g. an `as const` is not a type cast in
|
|
46
|
+
the TS-1 sense; a `nodes` query that legitimately fetches a single known
|
|
47
|
+
node with a documented comment may satisfy GQL-1; a `.js` file inside a
|
|
48
|
+
Liquid theme repo is exempt from TS-2.
|
|
49
|
+
|
|
50
|
+
Outcome: both checks pass -> `confirmed` at Critical, with `reasoning` naming
|
|
51
|
+
the rule and quoting the violating snippet. Either check fails -> `dropped`,
|
|
52
|
+
with `reasoning` naming which check failed. There is no `downgraded` outcome
|
|
53
|
+
for a hard rule: it either violates the rule or it does not.
|
|
54
|
+
|
|
55
|
+
Then **stop** -- do not continue to Step 1 or the five challenges.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Step 1 -- Diff-anchor check
|
|
60
|
+
|
|
61
|
+
Re-read the actual code at `file:line` in `WORKTREE_PATH` (full context,
|
|
62
|
+
approximately 20-30 lines around the flagged line). Confirm:
|
|
63
|
+
|
|
64
|
+
- The line genuinely appears as a `+` line in `DIFF_FILE`.
|
|
65
|
+
**If the bad code only appears on a `-` line (being removed), the PR is
|
|
66
|
+
already fixing it -- this is not a finding. Drop immediately.**
|
|
67
|
+
- The issue is not already mitigated by surrounding code the review agent did
|
|
68
|
+
not have in context.
|
|
69
|
+
|
|
70
|
+
To check whether it is a `+` line:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
grep "^+" "$DIFF_FILE" | grep "<flagged_symbol_or_snippet>"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If the flagged code is absent from `+` lines: **drop**.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Step 2 -- Rename / missing-update false positive check
|
|
81
|
+
|
|
82
|
+
When the finding claims "symbol X was renamed but consumer Y was not updated,"
|
|
83
|
+
you MUST run:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
grep "^+" "$DIFF_FILE" | grep "<new_symbol_name>"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If the replacement already appears in `+` lines of the diff (i.e., the consumer
|
|
90
|
+
was updated in the same PR), this is a **false positive** -- drop silently.
|
|
91
|
+
Only confirm if the new symbol is absent from all `+` lines in consumer files.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Step 3 -- Internal library source check
|
|
96
|
+
|
|
97
|
+
If the finding depends on how a `your org's shared internal` package behaves (message
|
|
98
|
+
format, error shape, method signature), do NOT infer from indirect evidence
|
|
99
|
+
(Sentry titles, email subjects, other projects). Before confirming, run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
find <your local workspace root, if any> -name "*.ts" ! -path "*/node_modules/*" \
|
|
103
|
+
| xargs grep -l "<ClassName or symbol>" 2>/dev/null | head -5
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Read the actual implementation. If you cannot find the source and cannot prove
|
|
107
|
+
the claim from the code in `WORKTREE_PATH`, **drop the finding** -- "I could not
|
|
108
|
+
find the source" is not a finding.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Step 4 -- Convention findings: precedent check
|
|
113
|
+
|
|
114
|
+
For every finding from the conventions dimension, the cited precedent MUST be
|
|
115
|
+
real. Re-open the `file:line` the finding cites as the existing pattern (in
|
|
116
|
+
`WORKTREE_PATH` or a sibling repo, if you keep one checked out locally) and confirm
|
|
117
|
+
the idiom actually lives there. If the helper/type/convention does not exist
|
|
118
|
+
where claimed, the finding is a taste suggestion in disguise -- **drop it.** A
|
|
119
|
+
convention finding with no verifiable precedent does not ship.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Step 5 -- Fix validation
|
|
124
|
+
|
|
125
|
+
Before confirming the finding, identify the callers and consumers of the changed
|
|
126
|
+
code in `WORKTREE_PATH`. Ask: *"Does the proposed fix break anything
|
|
127
|
+
downstream?"* A fix that silently removes a designed feature (e.g., turning a
|
|
128
|
+
synchronous result into fire-and-forget when the caller renders the result) is
|
|
129
|
+
worse than the original bug. If the fix requires changes beyond the single file,
|
|
130
|
+
note that in `reasoning` rather than silently showing an incomplete patch -- but
|
|
131
|
+
this does not by itself cause a drop.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Step 6 -- Severity test for Critical
|
|
136
|
+
|
|
137
|
+
A finding is Critical only if the failure path is reachable under **normal
|
|
138
|
+
operating conditions**, not only in a worst-case or adversarial scenario. Ask:
|
|
139
|
+
*"Would this fail on a typical production execution today?"* If the answer is
|
|
140
|
+
*only under specific conditions* (large dataset, concurrent load, wrong env
|
|
141
|
+
config), that is **Important**. Reserve Critical for failures that are
|
|
142
|
+
unconditional or highly likely given the feature's intended use.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## The five adversarial challenges
|
|
147
|
+
|
|
148
|
+
Every candidate finding in scope must survive five explicit challenges before
|
|
149
|
+
it is allowed in its severity tier. Work through every challenge question in
|
|
150
|
+
order. Write the answer to yourself before deciding the outcome. If you cannot
|
|
151
|
+
answer a question with evidence from the diff and the worktree, that is itself a
|
|
152
|
+
signal the claim is uncertain.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
### Challenge 1 -- Unconditional reachability
|
|
157
|
+
|
|
158
|
+
> "Under normal production use of this feature, does this failure path trigger
|
|
159
|
+
> without any unusual setup, timing, or configuration?"
|
|
160
|
+
|
|
161
|
+
Re-read the exact code path that leads to the failure. Trace it from the entry
|
|
162
|
+
point (route handler, webhook, cron job, etc.) through the changed code.
|
|
163
|
+
|
|
164
|
+
If the answer is "only under concurrent load" -> **Important**
|
|
165
|
+
If the answer is "only with a specific bad input the API already validates" -> **drop**
|
|
166
|
+
If the answer is "only in a specific env config that is not the default" -> **Important**
|
|
167
|
+
If the answer is "yes, on any normal execution of this feature" -> **passes**
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### Challenge 2 -- Mitigation in wider context
|
|
172
|
+
|
|
173
|
+
> "Is there any guard, validation, transaction, retry, or framework behaviour
|
|
174
|
+
> within 50 lines of the finding that already prevents or contains this
|
|
175
|
+
> failure?"
|
|
176
|
+
|
|
177
|
+
Re-read **50 lines** around the flagged line in `WORKTREE_PATH` (not just 20-30).
|
|
178
|
+
Also check the caller one level up. Agents often miss:
|
|
179
|
+
- Wrapping `try/catch` in the caller
|
|
180
|
+
- Prisma implicit transactions on `$transaction` calls
|
|
181
|
+
- Zod validation at the route boundary that prevents the bad value from
|
|
182
|
+
ever reaching this code
|
|
183
|
+
- A feature flag / kill switch that keeps this path inactive at deploy time
|
|
184
|
+
|
|
185
|
+
If mitigation exists and fully covers the failure -> **drop** (finding already
|
|
186
|
+
handled)
|
|
187
|
+
If mitigation exists but only partially -> **downgrade to Important** + note the
|
|
188
|
+
gap in `reasoning`
|
|
189
|
+
If no mitigation exists -> **passes**
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### Challenge 3 -- PR direction
|
|
194
|
+
|
|
195
|
+
> "Is this PR improving this situation compared to before, even if not
|
|
196
|
+
> fully fixing it?"
|
|
197
|
+
|
|
198
|
+
Run:
|
|
199
|
+
```bash
|
|
200
|
+
grep "^-" "$DIFF_FILE" | grep "<key symbol from finding>"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
If the `-` lines show the PR is removing or reducing the problem, this is a
|
|
204
|
+
step forward -- the code was already broken before this PR. Reporting it as
|
|
205
|
+
Critical on a PR that is making things better is misleading.
|
|
206
|
+
|
|
207
|
+
If the PR introduced the problem fresh -> **passes**
|
|
208
|
+
If the PR is reducing an existing problem but not eliminating it -> **Important**
|
|
209
|
+
If the PR is not changing this code path at all (finding traces to unchanged
|
|
210
|
+
code) -> **drop** (not diff-anchored -- should have been caught in the diff-anchor
|
|
211
|
+
check above)
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### Challenge 4 -- Demonstrability
|
|
216
|
+
|
|
217
|
+
> "Can I write a failing test case in my head -- with specific inputs and
|
|
218
|
+
> expected vs. actual output -- that demonstrates this failure?"
|
|
219
|
+
|
|
220
|
+
This is the strongest signal a Critical finding is real. If you cannot
|
|
221
|
+
articulate the test, you do not fully understand the failure.
|
|
222
|
+
|
|
223
|
+
Write it silently: *"Given input X, function Y returns Z instead of W because
|
|
224
|
+
of line L."*
|
|
225
|
+
|
|
226
|
+
If you can articulate it precisely -> **passes**
|
|
227
|
+
If you can articulate the symptom but not the exact failure mechanism -> **downgrade to Important**
|
|
228
|
+
If you cannot articulate it at all -> **drop** -- "this feels wrong" is not a
|
|
229
|
+
Critical finding
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Challenge 5 -- Certainty gate
|
|
234
|
+
|
|
235
|
+
> "Am I relying on any inference, assumption, or indirect evidence that I
|
|
236
|
+
> have not verified from the actual source?"
|
|
237
|
+
|
|
238
|
+
Common failure modes here:
|
|
239
|
+
- Assuming how a `your org's shared internal` package behaves without reading the source
|
|
240
|
+
- Assuming the DB schema based on the model name rather than the Prisma schema
|
|
241
|
+
- Assuming the Shopify API behaviour from memory rather than the docs
|
|
242
|
+
- Assuming a variable is always truthy/falsy without checking where it is set
|
|
243
|
+
|
|
244
|
+
If any assumption is unverified -> resolve it now (read the source, check the
|
|
245
|
+
schema, look up the API). Then re-evaluate.
|
|
246
|
+
|
|
247
|
+
If the finding is fully grounded in code you have read -> **passes**
|
|
248
|
+
If any link in the chain is inference -> **Important at best**, or **drop** if
|
|
249
|
+
the inference is the crux of the claim
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Outcome rules
|
|
254
|
+
|
|
255
|
+
The one exception to "a Critical must pass ALL FIVE challenges" is the
|
|
256
|
+
hard-rule path in Step 0: a `rule`-tagged finding is judged solely on the
|
|
257
|
+
anchor + rule-applicability checks and never runs the five challenges.
|
|
258
|
+
|
|
259
|
+
A Critical finding must pass ALL FIVE challenges. Any failure downgrades:
|
|
260
|
+
- One downgrade -> **Important**
|
|
261
|
+
- Two or more downgrades, or any **drop** verdict -> remove from Critical entirely
|
|
262
|
+
(either move to Important with the reason noted, or drop)
|
|
263
|
+
|
|
264
|
+
If the finding survives all five: keep as Critical. Write the verdict
|
|
265
|
+
in one sentence: *"This is Critical because it fails unconditionally on any
|
|
266
|
+
[webhook/sync/button press] due to [specific mechanism], with no mitigation, and
|
|
267
|
+
the PR introduced it."*
|
|
268
|
+
|
|
269
|
+
If you cannot write that sentence cleanly -> it is not Critical.
|
|
270
|
+
|
|
271
|
+
Apply the same five challenges to Important findings when there is doubt --
|
|
272
|
+
the downgrade path is "Important -> Observation -> drop" for that tier.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Output mapping
|
|
277
|
+
|
|
278
|
+
Return EXACTLY one JSON object matching VERDICT_SCHEMA:
|
|
279
|
+
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"verdict": "confirmed" | "downgraded" | "dropped",
|
|
283
|
+
"newSeverity": "important" | "observation", // only when verdict is "downgraded"
|
|
284
|
+
"reasoning": "<one sentence stating outcome and why>"
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
- **confirmed**: finding passed all applicable checks and all five challenges.
|
|
289
|
+
`reasoning` = the one-sentence Critical verdict (or equivalent for Important).
|
|
290
|
+
- **downgraded**: finding survived but at a lower severity due to one downgrade
|
|
291
|
+
outcome above. Set `newSeverity` to the resulting tier. `reasoning` = which
|
|
292
|
+
challenge caused the downgrade and why.
|
|
293
|
+
- **dropped**: finding failed any check -- bad diff anchor, false positive,
|
|
294
|
+
unverifiable precedent, two or more downgrade outcomes, or could not articulate
|
|
295
|
+
the failure. `reasoning` = one sentence naming the disqualifying check.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# artifact-page.md -- lekker-review -- living web artifact procedure
|
|
2
|
+
|
|
3
|
+
Execute this procedure AFTER the review file has been saved to `~/code-reviews/`,
|
|
4
|
+
as part of the MAIN loop (not a reviewer/verifier agent). Skip the entire
|
|
5
|
+
procedure silently when `--no-artifact` was passed.
|
|
6
|
+
|
|
7
|
+
This publishes the review as a claude.ai Artifact page whose URL stays STABLE
|
|
8
|
+
across re-reviews of the same PR -- the author watches findings flip from open
|
|
9
|
+
to fixed, commit after commit, at one link. Rendering is delegated to a single
|
|
10
|
+
background subagent so no session-model (Fable) tokens are spent writing HTML.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Step 1 -- Gather inputs
|
|
15
|
+
|
|
16
|
+
All of the following are already in hand after Step 3 of SKILL.md:
|
|
17
|
+
|
|
18
|
+
- `findings.json` path (scratchpad) -- each finding carries: `file`, `line`,
|
|
19
|
+
`severity`, `title`, `description`, `badCode`, `fix`, `rule?`, `precedent?`,
|
|
20
|
+
`agreedBy?`, `verifierReasoning?`, `proof?` (proof = `{attempted, proven,
|
|
21
|
+
reason, testCode?, testCommand?, redOutput?}`).
|
|
22
|
+
- The saved review file path: `~/code-reviews/YYYY-MM-DD-pr-N-repo.md`.
|
|
23
|
+
- PR metadata: `REPO_SLUG`, `PR_NUMBER`, `PR_URL`, title, author, `headRefName`
|
|
24
|
+
→ `baseRefName`, head sha, depth, verdict, `isDraft`, `mergeStateStatus`, CI
|
|
25
|
+
status.
|
|
26
|
+
- `PREV_ARTIFACT_URL` -- `null` on first review; on re-review, extracted from
|
|
27
|
+
the prior review file's `**Artifact:** <url>` header line (SKILL.md Step 0
|
|
28
|
+
handles the extraction).
|
|
29
|
+
- Since-last-review data when in re-review mode (fixed vs. still-open lists).
|
|
30
|
+
- The `--no-artifact` flag -- when set, skip this whole procedure silently.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 2 -- Launch the renderer subagent (background)
|
|
35
|
+
|
|
36
|
+
Launch exactly ONE `general-purpose` agent, `model: sonnet`, in the
|
|
37
|
+
background. Do not block printing the review on it (see Hard rules).
|
|
38
|
+
|
|
39
|
+
Brief template -- copy verbatim, filling in `<placeholders>`:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Load the `artifact-design` skill (Skill tool) FIRST -- mandatory before
|
|
43
|
+
writing any HTML.
|
|
44
|
+
|
|
45
|
+
Read the findings at <findings.json path> and the saved review at
|
|
46
|
+
<review file path>.
|
|
47
|
+
|
|
48
|
+
Write ONE self-contained HTML file to the session scratchpad:
|
|
49
|
+
review-pr-<PR_NUMBER>-<repo-short>.html
|
|
50
|
+
|
|
51
|
+
Follow the page specification below exactly. Then publish it with the
|
|
52
|
+
Artifact tool using:
|
|
53
|
+
- favicon: "🥩" (keep this IDENTICAL on every republish)
|
|
54
|
+
- title: "Review: <repo-short> #<PR_NUMBER>"
|
|
55
|
+
- description: <one sentence, e.g. "Living code review for PR #<N> --
|
|
56
|
+
findings update as commits land">
|
|
57
|
+
- url: <PREV_ARTIFACT_URL> (include ONLY when non-null, so the SAME
|
|
58
|
+
artifact updates in place instead of minting a new URL; omit the `url`
|
|
59
|
+
parameter entirely on first publish)
|
|
60
|
+
|
|
61
|
+
Return ONLY the resulting artifact URL as your final text. No other output.
|
|
62
|
+
|
|
63
|
+
--- PAGE SPECIFICATION ---
|
|
64
|
+
<paste Step 3 verbatim here>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Step 3 -- Page specification (the subagent's design contract)
|
|
70
|
+
|
|
71
|
+
Hard requirements for the HTML page:
|
|
72
|
+
|
|
73
|
+
- **Self-contained and theme-aware.** No external fonts/scripts/images/CDNs
|
|
74
|
+
(CSP blocks them). Honor `prefers-color-scheme` as the default signal AND
|
|
75
|
+
`:root[data-theme="dark"]` / `:root[data-theme="light"]` overrides.
|
|
76
|
+
- **Header card:** verdict badge (✅ LGTM / ⚠️ LGTM with changes / 🚫 Needs
|
|
77
|
+
work -- color-coded), PR title linking to `PR_URL`, author, branch → base,
|
|
78
|
+
head sha (short, `code` style), depth chip, findings count by severity, CI
|
|
79
|
+
status. When `isDraft`: a DRAFT banner. When the PR title's ⛔ CANNOT MERGE
|
|
80
|
+
block applies (see output-format.md): an unmissable banner above everything
|
|
81
|
+
else on the page.
|
|
82
|
+
- **Timeline section (re-review mode):** "Since last review" -- one row per
|
|
83
|
+
prior finding: ✅ fixed (title struck through) or ⚠️ still open, each with
|
|
84
|
+
`file:line`. This is the living part of the page. On first review, show
|
|
85
|
+
"First review of this PR" with the head sha and the review's date filled in
|
|
86
|
+
from the review file (do not leave the date as a literal placeholder in the
|
|
87
|
+
output).
|
|
88
|
+
- **Findings**, grouped Critical → Important → Observations → Idiomatic. Each
|
|
89
|
+
finding is an expandable `<details>` block:
|
|
90
|
+
- summary row: severity dot + title + `file:line`
|
|
91
|
+
- body: description, `badCode` in a `<pre>`, `fix` in a `<pre>`, a small
|
|
92
|
+
hard-rule chip (e.g. "TS-1 · hard rule") when `rule` is set, `agreedBy`
|
|
93
|
+
chips when 2+ dimensions agreed, `verifierReasoning` as a muted footnote.
|
|
94
|
+
- **Proof block:** when `proof.proven === true`, render a visually distinct
|
|
95
|
+
"PROVEN -- failing test ran in the worktree" panel: `redOutput` in a
|
|
96
|
+
`<pre>`, a one-line explanation that the test asserts correct behavior, and
|
|
97
|
+
`testCode` collapsed behind its own `<details>`. This is the page's
|
|
98
|
+
centerpiece -- make it prominent (e.g. a red left border) but not garish.
|
|
99
|
+
- **Test Quality + Review Cost sections**, mirrored from the review file,
|
|
100
|
+
kept concise (verdict + gaps + cost table; no need to reproduce every
|
|
101
|
+
sentence).
|
|
102
|
+
- **Layout:** every code block (`badCode`, `fix`, `redOutput`, `testCode`)
|
|
103
|
+
horizontally scrollable within its own container; the page body itself must
|
|
104
|
+
never scroll horizontally. Keep total page weight sane -- plain `<pre>`
|
|
105
|
+
with a theme-aware background, no syntax-highlighting library.
|
|
106
|
+
- **No praise language anywhere** (house rule, same as the saved review):
|
|
107
|
+
state what the code does and the risks it carries, never compliment it.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Step 4 -- Record the URL (fresh post-condition)
|
|
112
|
+
|
|
113
|
+
When the subagent returns:
|
|
114
|
+
|
|
115
|
+
**On success (URL returned):**
|
|
116
|
+
1. Append or refresh a `**Artifact:** <url>` line in the saved review file's
|
|
117
|
+
header block. Idempotent: replace an existing `**Artifact:**` line if
|
|
118
|
+
present, never duplicate it.
|
|
119
|
+
2. Re-read the review file to confirm the line landed -- this is the receipt
|
|
120
|
+
(per VERIFICATION.md: a write is not done until re-read from source).
|
|
121
|
+
3. Print one line to the user: `🔗 Living review: <url>`
|
|
122
|
+
|
|
123
|
+
**On failure (no URL, or the agent errored):**
|
|
124
|
+
- Say so in one line to the user.
|
|
125
|
+
- Do NOT fail or roll back the review over this -- the saved review file is
|
|
126
|
+
the source of truth; the artifact is an enhancement layered on top of it.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Hard rules
|
|
131
|
+
|
|
132
|
+
- The renderer subagent runs in the BACKGROUND -- never block printing or
|
|
133
|
+
delivering the review on its completion.
|
|
134
|
+
- Same PR → same URL, always. Pass `PREV_ARTIFACT_URL` whenever one exists. A
|
|
135
|
+
fresh URL minted for a PR that already has one is a bug -- treat it as such
|
|
136
|
+
if you spot it in the receipt.
|
|
137
|
+
- The artifact is private by default; sharing it is the user's decision, not
|
|
138
|
+
the skill's.
|
|
139
|
+
- Never include secrets or tokens from context. The page contains only what
|
|
140
|
+
the saved review file already contains -- nothing pulled fresh from
|
|
141
|
+
scratchpad context that isn't already in the review.
|
|
142
|
+
- Favicon stays `🥩` forever for this artifact -- never change it on
|
|
143
|
+
republish.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Context gathering (Step 1)
|
|
2
|
+
|
|
3
|
+
## Step 1 — Gather Context (run in parallel)
|
|
4
|
+
|
|
5
|
+
### 1a. PR metadata
|
|
6
|
+
```bash
|
|
7
|
+
gh pr view <PR_NUMBER> --repo <REPO_SLUG> \
|
|
8
|
+
--json number,title,body,author,headRefName,baseRefName,labels,\
|
|
9
|
+
linkedBranches,mergeStateStatus,additions,deletions,changedFiles,isDraft,headRefOid
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**PR-1 title check (run immediately after 1a, before other steps)** — only if
|
|
13
|
+
your `house-rules.md` defines a title/ticket-prefix rule:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Collect ticket IDs from the commit log of this PR
|
|
17
|
+
gh pr view <PR_NUMBER> --repo <REPO_SLUG> --json commits \
|
|
18
|
+
--jq '[.commits[].messageHeadline | scan("\\[[A-Z]+-[0-9]+\\]")] | unique | join(",")'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
1. Check that the PR title matches whatever prefix convention `house-rules.md` defines.
|
|
22
|
+
2. Extract all ticket references from commit messages and merged PR titles in the commit log.
|
|
23
|
+
3. If the PR title is missing the prefix, or is missing any ticket from the commit history:
|
|
24
|
+
- Record `PR_TITLE_ISSUE = true` and `RECOMMENDED_PREFIX = "<all tickets comma-separated>"`
|
|
25
|
+
- This will produce an `⛔ CANNOT MERGE` block at the top of the review output (Step 4), before the Summary.
|
|
26
|
+
4. If all tickets are present: `PR_TITLE_ISSUE = false`.
|
|
27
|
+
|
|
28
|
+
### 1b. Full diff
|
|
29
|
+
```bash
|
|
30
|
+
gh pr diff <PR_NUMBER> --repo <REPO_SLUG> > "$DIFF_FILE" # fetched ONCE; all agents read this file
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 1c. Issue tracker (optional — skip if you have no ticket-tracker MCP configured)
|
|
34
|
+
Search for tickets referenced in the PR title, body, or branch name using
|
|
35
|
+
whatever issue-tracker MCP tool (Linear, Jira, GitHub Issues, etc.) is
|
|
36
|
+
available in your setup.
|
|
37
|
+
|
|
38
|
+
Extract: ticket description, acceptance criteria, linked issues, comments.
|
|
39
|
+
Collect ACs as a numbered list — this becomes `AC_LIST` used in Step 3.
|
|
40
|
+
|
|
41
|
+
If no issue-tracker MCP is configured, skip silently — the review still runs
|
|
42
|
+
fine on the PR body + diff alone.
|
|
43
|
+
|
|
44
|
+
### 1d. Team chat *(scan: skip, optional)*
|
|
45
|
+
If a chat-search MCP tool (Slack, Discord, etc.) is available, search for the
|
|
46
|
+
PR title keywords / branch name / ticket ID to surface design decisions or
|
|
47
|
+
trade-offs the team discussed outside the ticket. Skip silently if none is
|
|
48
|
+
configured.
|
|
49
|
+
|
|
50
|
+
### 1e. Docs / wiki *(scan: skip, optional)*
|
|
51
|
+
If a docs-search MCP tool (Notion, Confluence, internal wiki, etc.) is
|
|
52
|
+
available, search for specs, runbooks, ADRs, or design docs related to this
|
|
53
|
+
work. Skip silently if none is configured.
|
|
54
|
+
|
|
55
|
+
### 1f. Framework/API docs *(scan: skip, optional)*
|
|
56
|
+
If the diff touches a specific framework or third-party API and a docs-search
|
|
57
|
+
MCP for it is available, verify the implementation matches current API
|
|
58
|
+
behaviour and best practices. Skip if not relevant or not configured.
|
|
59
|
+
|
|
60
|
+
### 1g. Repo placement check — see references/house-rules.md
|
|
61
|
+
Only applicable if your org splits work across sibling repos and you've
|
|
62
|
+
filled in the repo-taxonomy table in `house-rules.md`.
|
|
63
|
+
|
|
64
|
+
### 1h. Prior review pattern recall *(scan: skip, optional)*
|
|
65
|
+
If you maintain a persistent memory/notes system across review sessions (a
|
|
66
|
+
wiki page, a memory MCP, or even a running Markdown file of "patterns we keep
|
|
67
|
+
seeing in this repo"), pull relevant entries here: known conventions not yet
|
|
68
|
+
in the repo's own CLAUDE.md/README, confirmed false positives from past
|
|
69
|
+
reviews, and recurring bug classes to watch for. Skip entirely if you don't
|
|
70
|
+
have such a system — this step adds value but nothing depends on it.
|
|
71
|
+
|
|
72
|
+
Do NOT recall or store author-specific patterns ("author X tends to...") —
|
|
73
|
+
scope any such memory to the repo, not the person, so the review stays about
|
|
74
|
+
the code, not the author.
|
|
75
|
+
|
|
76
|
+
### 1i. Production error monitoring *(scan: skip, optional)*
|
|
77
|
+
If an error-monitoring MCP (Sentry, Rollbar, Bugsnag, etc.) is available,
|
|
78
|
+
search for production errors in the code paths touched by this PR:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
query: "<repo-short-name> <key module or filename from diff>"
|
|
82
|
+
query: "<key function/export names introduced or modified in the diff>"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Collect into `MONITORING_SIGNALS`. For each match, note:
|
|
86
|
+
- Issue title and link
|
|
87
|
+
- Event count and affected users in a recent window
|
|
88
|
+
- First seen / last seen — chronic vs. newly introduced
|
|
89
|
+
- Whether the culprit or stack trace references a file in the diff
|
|
90
|
+
|
|
91
|
+
If `MONITORING_SIGNALS` is non-empty, include a `## 🔥 Production Signals`
|
|
92
|
+
section in the review output (place it immediately after the Summary, before
|
|
93
|
+
findings). Format each entry as:
|
|
94
|
+
```
|
|
95
|
+
- [<title>](<url>) — <N> events / <M> users (recent window) · first seen <date>
|
|
96
|
+
Files: <relevant files from stack trace>
|
|
97
|
+
Note: <one sentence — does this PR fix, worsen, or not affect this error?>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If an error traces directly to a function this PR modifies and the PR does
|
|
101
|
+
not fix it, escalate: add a finding under `## ⚠️ Important` noting the
|
|
102
|
+
pre-existing production error in modified code.
|
|
103
|
+
|
|
104
|
+
If no monitoring MCP is configured or no matches found, skip the section
|
|
105
|
+
silently. Never write "monitoring unavailable" into a review off the back of
|
|
106
|
+
a single failed call; either produce the signals or state the actual reason
|
|
107
|
+
(auth, no project, genuinely zero matches).
|
|
108
|
+
|
|
109
|
+
An error in the subsystem that corroborates a finding is worth reporting even
|
|
110
|
+
when this PR neither causes nor fixes it — say so explicitly ("not caused or
|
|
111
|
+
worsened by this PR") and tie it to the finding it supports. Check the
|
|
112
|
+
environment tag: a staging-only error is weaker evidence than a production
|
|
113
|
+
one, and claiming otherwise overstates the case.
|
|
114
|
+
|
|
115
|
+
### 1j. CI check results
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
gh pr checks <PR_NUMBER> --repo <REPO_SLUG> 2>/dev/null
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Collect into `CI_STATUS`. Rules:
|
|
122
|
+
- Any **failing** TypeScript/build check → treat as a Critical finding: the
|
|
123
|
+
branch doesn't compile. Quote the check name and link in the finding.
|
|
124
|
+
- Any **failing** test check → Critical finding: existing tests are broken.
|
|
125
|
+
- Any **failing** lint check → Important finding.
|
|
126
|
+
- All checks passing → note `✅ CI passing` in the review header line.
|
|
127
|
+
- Checks pending → note `⏳ CI pending` in the header.
|
|
128
|
+
- `gh pr checks` unavailable or no checks configured → omit the header note.
|
|
129
|
+
|
|
130
|
+
### 1k. Existing reviewer comments
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
gh pr reviews <PR_NUMBER> --repo <REPO_SLUG> --json author,state,body 2>/dev/null
|
|
134
|
+
gh api "repos/<REPO_SLUG>/pulls/<PR_NUMBER>/comments" \
|
|
135
|
+
--jq '.[].body' 2>/dev/null | head -80
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Collect into `EXISTING_REVIEWS`. Purpose:
|
|
139
|
+
- **Awareness only** — do NOT anchor your findings on what other reviewers said.
|
|
140
|
+
If you independently reach the same conclusion, that is fine — but earn it
|
|
141
|
+
from the diff, not from their comment.
|
|
142
|
+
- **Deduplication** — if an existing review already raised a finding at a
|
|
143
|
+
specific `file:line`, skip that finding in your output and note
|
|
144
|
+
`(already raised by <reviewer>)` internally in your deduplication pass.
|
|
145
|
+
- **Design decisions** — if the author replied to a review comment explaining
|
|
146
|
+
an intentional choice, that context informs whether a pattern is a bug or
|
|
147
|
+
a deliberate trade-off.
|
|
148
|
+
|
|
149
|
+
### 1 post-gather — Draft / state check
|
|
150
|
+
|
|
151
|
+
After Step 1a completes, check the `isDraft` field in the PR metadata.
|
|
152
|
+
|
|
153
|
+
If `isDraft: true`, prepend this notice to the final review output (before
|
|
154
|
+
the Summary):
|
|
155
|
+
|
|
156
|
+
> ⚠️ **Draft PR** — this review is on a work-in-progress branch. Some findings
|
|
157
|
+
> may reflect intentionally incomplete work.
|
|
158
|
+
|
|
159
|
+
Also check `mergeStateStatus`:
|
|
160
|
+
- `BLOCKED` → note in the review header as `🚫 Merge blocked`
|
|
161
|
+
- `BEHIND` → note as `⏰ Branch is behind base`
|
|
162
|
+
- `CLEAN` → no note needed
|