@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.
Files changed (54) hide show
  1. package/.claude-plugin/plugin.json +2 -1
  2. package/README.md +7 -3
  3. package/catalog/skills.json +18 -0
  4. package/package.json +5 -3
  5. package/packages/software-development/lekker-review/SKILL.md +519 -0
  6. package/packages/software-development/lekker-review/adapters/claude/plugin.json +5 -0
  7. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/SKILL.md +520 -0
  8. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/completeness-critic.md +21 -0
  9. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/conventions.md +124 -0
  10. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/fix-verifier.md +84 -0
  11. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/fixer.md +120 -0
  12. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/implementation.md +53 -0
  13. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/prover.md +135 -0
  14. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/quality.md +72 -0
  15. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/simplification.md +45 -0
  16. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/test-quality.md +170 -0
  17. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/triage-logic.md +27 -0
  18. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/triage-quality.md +41 -0
  19. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/agents/verifier.md +295 -0
  20. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/artifact-page.md +143 -0
  21. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/context-gathering.md +162 -0
  22. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/fix-mode.md +329 -0
  23. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/github-post.md +205 -0
  24. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/house-rules.md +76 -0
  25. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/references/output-format.md +232 -0
  26. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/scripts/changed-files.sh +77 -0
  27. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/scripts/setup-worktree.sh +337 -0
  28. package/packages/software-development/lekker-review/adapters/claude/skills/lekker-review/scripts/verify-fixes.sh +231 -0
  29. package/packages/software-development/lekker-review/fix-workflow.js +273 -0
  30. package/packages/software-development/lekker-review/references/agents/completeness-critic.md +21 -0
  31. package/packages/software-development/lekker-review/references/agents/conventions.md +124 -0
  32. package/packages/software-development/lekker-review/references/agents/fix-verifier.md +84 -0
  33. package/packages/software-development/lekker-review/references/agents/fixer.md +120 -0
  34. package/packages/software-development/lekker-review/references/agents/implementation.md +53 -0
  35. package/packages/software-development/lekker-review/references/agents/prover.md +135 -0
  36. package/packages/software-development/lekker-review/references/agents/quality.md +72 -0
  37. package/packages/software-development/lekker-review/references/agents/simplification.md +45 -0
  38. package/packages/software-development/lekker-review/references/agents/test-quality.md +170 -0
  39. package/packages/software-development/lekker-review/references/agents/triage-logic.md +27 -0
  40. package/packages/software-development/lekker-review/references/agents/triage-quality.md +41 -0
  41. package/packages/software-development/lekker-review/references/agents/verifier.md +295 -0
  42. package/packages/software-development/lekker-review/references/artifact-page.md +143 -0
  43. package/packages/software-development/lekker-review/references/context-gathering.md +162 -0
  44. package/packages/software-development/lekker-review/references/fix-mode.md +329 -0
  45. package/packages/software-development/lekker-review/references/github-post.md +205 -0
  46. package/packages/software-development/lekker-review/references/house-rules.md +76 -0
  47. package/packages/software-development/lekker-review/references/output-format.md +232 -0
  48. package/packages/software-development/lekker-review/scripts/changed-files.sh +77 -0
  49. package/packages/software-development/lekker-review/scripts/setup-worktree.sh +337 -0
  50. package/packages/software-development/lekker-review/scripts/verify-fixes.sh +231 -0
  51. package/packages/software-development/lekker-review/workflow.js +602 -0
  52. package/site/assets/paperbag.css +707 -0
  53. package/site/assets/paperbag.js +218 -0
  54. 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