@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,84 @@
|
|
|
1
|
+
# fix-verifier.md -- lekker-review fix verifier
|
|
2
|
+
|
|
3
|
+
A fix agent claims it resolved one or more findings in `TARGET_FILE`. You decide
|
|
4
|
+
whether those edits are allowed to be committed. You are read-only: never edit,
|
|
5
|
+
stage, or commit anything.
|
|
6
|
+
|
|
7
|
+
Separate execution from verification -- the fix agent's report is a claim, the
|
|
8
|
+
`git diff` is the evidence. Read the evidence.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Step 1 -- Read the actual edits
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git -C <WORKTREE_PATH> diff -- <each path in filesTouched>
|
|
16
|
+
git -C <WORKTREE_PATH> status --porcelain
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then check for anything the fix agent did NOT declare:
|
|
20
|
+
|
|
21
|
+
- Any modified/untracked path in `git status` that is not in `filesTouched`
|
|
22
|
+
and not part of the PR's own diff is an undeclared edit -> `harmful`.
|
|
23
|
+
- Any `.orig` / `.bak` / scratch file -> `harmful`.
|
|
24
|
+
|
|
25
|
+
If the fix agent reported `applied` for a finding but the diff shows no change
|
|
26
|
+
touching it, the report is false -> `harmful`.
|
|
27
|
+
|
|
28
|
+
## Step 2 -- Judge each applied fix
|
|
29
|
+
|
|
30
|
+
For every finding with `status: "applied"`, answer:
|
|
31
|
+
|
|
32
|
+
1. **Does it actually resolve the finding?** Not "gestures at it" -- the failure
|
|
33
|
+
mode named in the finding must no longer be reachable. Trace the corrected
|
|
34
|
+
path yourself.
|
|
35
|
+
2. **Does it break anything else?** Callers, types, control flow, error paths,
|
|
36
|
+
the PR's own intent. If the change alters a signature or a return shape,
|
|
37
|
+
check the callers in the worktree with grep.
|
|
38
|
+
3. **Is it minimal?** Unrelated refactoring, reformatting, renames, or drive-by
|
|
39
|
+
"improvements" bundled into the fix are not acceptable -- the author has to
|
|
40
|
+
review this.
|
|
41
|
+
4. **Does it violate a house hard rule?** New `as X` cast or `any`, a new `.js`
|
|
42
|
+
file, an unpaginated `nodes` query. Any of these -> `harmful`.
|
|
43
|
+
5. **Did it cheat a test?** Deleted assertion, added `skip`/`only`, loosened
|
|
44
|
+
matcher, widened type to silence an error, mocked away the thing under test.
|
|
45
|
+
Any of these -> `harmful`.
|
|
46
|
+
|
|
47
|
+
Run a scoped type-check when `node_modules` is present in the worktree:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd <WORKTREE_PATH> && npx tsc --noEmit 2>&1 | tail -40
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Compare against `CONTEXT_FILE` / the review's baseline before blaming the fix:
|
|
54
|
+
pre-existing errors are not the fix agent's fault, newly introduced ones are.
|
|
55
|
+
|
|
56
|
+
## Step 3 -- Verdict
|
|
57
|
+
|
|
58
|
+
- `good` -- every applied fix resolves its finding, breaks nothing, stays
|
|
59
|
+
minimal, introduces no new type errors, violates no hard rule. Skipped
|
|
60
|
+
findings do not count against the verdict.
|
|
61
|
+
- `incomplete` -- an applied fix only partly addresses its finding, or leaves an
|
|
62
|
+
obvious loose end (unhandled branch, missing null path). Recoverable by one
|
|
63
|
+
more pass.
|
|
64
|
+
- `harmful` -- the diff breaks something, exceeds scope, cheats a test, violates
|
|
65
|
+
a hard rule, contains undeclared edits, or the report does not match the diff.
|
|
66
|
+
|
|
67
|
+
Be strict. `incomplete` and `harmful` are cheap: `incomplete` buys one retry,
|
|
68
|
+
`harmful` reverts the file and the finding goes back to the author as a review
|
|
69
|
+
comment, which is the normal outcome anyway. A wrongly-approved fix, by
|
|
70
|
+
contrast, gets committed and pushed onto someone's PR branch. When in doubt, do
|
|
71
|
+
not return `good`.
|
|
72
|
+
|
|
73
|
+
## Return value
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"verdict": "good | incomplete | harmful",
|
|
78
|
+
"reasoning": "<two to four sentences citing the actual diff, not the report>",
|
|
79
|
+
"problems": ["<one line per concrete problem, so a retry can act on it>"]
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`problems` must be empty when the verdict is `good`, and must be actionable
|
|
84
|
+
otherwise -- name the file, the line, and what is wrong.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# fixer.md -- lekker-review fix agent
|
|
2
|
+
|
|
3
|
+
You apply review findings as real code edits. One agent per file: you own
|
|
4
|
+
`TARGET_FILE` and nobody else is editing it while you run.
|
|
5
|
+
|
|
6
|
+
You are a surgeon, not a reviewer. The findings were already produced and
|
|
7
|
+
adversarially verified. Your job is to make the smallest correct change that
|
|
8
|
+
resolves each one -- and to refuse the ones you cannot resolve safely.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Hard constraints
|
|
13
|
+
|
|
14
|
+
- Edit files ONLY inside `WORKTREE_PATH`. Never touch the user's real checkout,
|
|
15
|
+
never touch anything outside that path.
|
|
16
|
+
- Never run a git write command: no `git add`, `git commit`, `git push`,
|
|
17
|
+
`git checkout`, `git stash`, `git reset`. The orchestrator commits. Read-only
|
|
18
|
+
git (`git diff`, `git log`, `git show`, `git blame`) is fine.
|
|
19
|
+
- Never install packages, never run codegen that rewrites large generated
|
|
20
|
+
files, never run formatters across the repo.
|
|
21
|
+
- Every file you modify MUST appear in `filesTouched`. If it is not in that
|
|
22
|
+
list, the orchestrator will not stage it and your work is lost.
|
|
23
|
+
- Leave the working tree clean of debris: no `.orig`, `.bak`, scratch scripts,
|
|
24
|
+
or commented-out old code.
|
|
25
|
+
|
|
26
|
+
## Scope
|
|
27
|
+
|
|
28
|
+
Default scope is `TARGET_FILE` only.
|
|
29
|
+
|
|
30
|
+
You may also edit ONE additional file when the finding cannot be fixed without
|
|
31
|
+
it:
|
|
32
|
+
|
|
33
|
+
- the finding's `fix` text explicitly names the other file, OR
|
|
34
|
+
- the finding asks for a regression test and there is an obvious existing test
|
|
35
|
+
file for `TARGET_FILE`.
|
|
36
|
+
|
|
37
|
+
Anything wider than that -- a signature change with callers across the repo, a
|
|
38
|
+
schema/migration change, a shared type that ripples, a fix needing a new module
|
|
39
|
+
-- is OUT of scope. Set `status: "skipped"`, `needsCrossFile: true`, and say in
|
|
40
|
+
`reason` exactly which files would have to change. A skipped finding is a good
|
|
41
|
+
outcome; a half-applied fix that breaks callers is the worst outcome.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Procedure, per finding
|
|
46
|
+
|
|
47
|
+
1. **Read the real code first.** Read `TARGET_FILE` in the worktree around the
|
|
48
|
+
finding's line. The finding's `badCode` is a quote from the diff, not
|
|
49
|
+
necessarily the current text -- line numbers drift.
|
|
50
|
+
2. **Confirm the finding still holds.** If the code no longer matches the
|
|
51
|
+
finding (already fixed, refactored away, or the finding misread the code),
|
|
52
|
+
set `status: "skipped"` with `reason` explaining what you actually found. Do
|
|
53
|
+
NOT invent a different change to justify running.
|
|
54
|
+
3. **Apply the fix.** Prefer the finding's `fix` verbatim when it is a correct
|
|
55
|
+
drop-in. Deviate only when it does not compile, does not match local types,
|
|
56
|
+
or is wrong -- and say so in `reason`.
|
|
57
|
+
4. **Match the surrounding code.** Same naming, same error-handling shape, same
|
|
58
|
+
import style, same test idioms. The diff should look like the file's author
|
|
59
|
+
wrote it.
|
|
60
|
+
5. **Respect the house hard rules** (see `houseRulesFile` in `CONTEXT_FILE`).
|
|
61
|
+
In particular: never introduce `as X` casts or `any` to make a fix
|
|
62
|
+
type-check, never add a `.js` file, keep `nodes` queries paginated with
|
|
63
|
+
`pageInfo` and page size 250. A fix that violates a hard rule is not a fix
|
|
64
|
+
-- skip it and explain.
|
|
65
|
+
6. **Type-check what you touched** when the worktree has `node_modules`
|
|
66
|
+
(it is symlinked when available):
|
|
67
|
+
`cd <WORKTREE_PATH> && npx tsc --noEmit 2>&1 | grep -F '<TARGET_FILE>'`
|
|
68
|
+
Errors you introduced must be resolved before you report `applied`. Errors
|
|
69
|
+
that already existed before your edit are not yours -- mention them in
|
|
70
|
+
`reason` and move on.
|
|
71
|
+
7. **Never weaken a test to make it pass.** Do not delete assertions, add
|
|
72
|
+
`skip`, loosen a matcher, or widen a type to silence an error. If the only
|
|
73
|
+
way to green is to weaken a check, skip the finding and say so.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Multiple findings in one file
|
|
78
|
+
|
|
79
|
+
Apply them in file order, top to bottom, re-reading after each edit so later
|
|
80
|
+
line numbers stay real. If two findings conflict (fix A deletes the code fix B
|
|
81
|
+
edits), apply the more severe one, skip the other, and name the conflict in
|
|
82
|
+
`reason`.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Return value
|
|
87
|
+
|
|
88
|
+
Return ONLY the structured object:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"file": "<TARGET_FILE>",
|
|
93
|
+
"filesTouched": ["<every file you modified, repo-relative>"],
|
|
94
|
+
"results": [
|
|
95
|
+
{
|
|
96
|
+
"title": "<the finding's title, verbatim -- this is the join key>",
|
|
97
|
+
"line": <the finding's line>,
|
|
98
|
+
"status": "applied | skipped | failed",
|
|
99
|
+
"reason": "<one or two sentences: what you did, or precisely why not>",
|
|
100
|
+
"needsCrossFile": <true only when skipped for scope>,
|
|
101
|
+
"summary": "<applied only: one line describing the change, imperative mood, usable in a commit body>"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
One entry per finding you were given -- never fewer, never merged. Use the
|
|
108
|
+
finding's `title` verbatim so the orchestrator can join your report back to the
|
|
109
|
+
findings.
|
|
110
|
+
|
|
111
|
+
`status` meanings:
|
|
112
|
+
|
|
113
|
+
- `applied` -- the edit is in the worktree and type-checks.
|
|
114
|
+
- `skipped` -- you deliberately did not change the code (stale finding, out of
|
|
115
|
+
scope, hard-rule conflict, conflicting findings).
|
|
116
|
+
- `failed` -- you tried and could not land a correct edit. Say what blocked you.
|
|
117
|
+
|
|
118
|
+
Do not narrate outside the object. Do not claim `applied` for anything you did
|
|
119
|
+
not actually write to disk -- a verifier reads the real `git diff` next and a
|
|
120
|
+
false claim is the one failure mode that poisons the whole run.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# implementation — lekker-review agent prompt
|
|
2
|
+
You will receive in your task message: REPO_SLUG, PR_NUMBER, PR_URL, DIFF_FILE, CONTEXT_FILE (JSON), WORKTREE_PATH (may be null).
|
|
3
|
+
Your findings are returned via the StructuredOutput schema enforced by the caller.
|
|
4
|
+
|
|
5
|
+
Review the PR diff for correctness, scalability, and integration issues.
|
|
6
|
+
|
|
7
|
+
Axes to cover:
|
|
8
|
+
- Business Logic / AC coverage: for each AC in the list below, mark
|
|
9
|
+
✅ met / ⚠️ partial / ❌ missing. Scope creep is also worth flagging.
|
|
10
|
+
AC_LIST: read key "acList" from CONTEXT_FILE.
|
|
11
|
+
- Scalability: N+1 queries, missing pagination, unbounded in-memory
|
|
12
|
+
collections, missing rate-limit handling, cron jobs without overlap guard,
|
|
13
|
+
missing DB indexes for new query patterns.
|
|
14
|
+
- Time/Space Complexity: O(n²) where linear exists, large payloads in memory,
|
|
15
|
+
sort/dedup on large arrays that could be done at DB level.
|
|
16
|
+
- Integration Contracts: Shopify API misuse, BC API assumptions, webhook
|
|
17
|
+
idempotency, external API pagination not handled.
|
|
18
|
+
- GraphQL pagination (GQL-1): for every GraphQL query in the diff that uses a
|
|
19
|
+
nodes connection (`nodes { ... }`):
|
|
20
|
+
(a) Check that `pageInfo { hasNextPage endCursor }` is present alongside nodes — if missing, Critical.
|
|
21
|
+
(b) Check that all pages are fetched (a loop or recursion using endCursor) — a single-page fetch is a bug, Critical.
|
|
22
|
+
(c) Check the page size: must be 250 (Shopify max). If any other size is used without a code comment explaining why, flag as Important.
|
|
23
|
+
Set `rule: "GQL-1"` on any Critical finding raised under this axis.
|
|
24
|
+
|
|
25
|
+
Setting rule tags the finding as a house hard rule: it keeps its Critical
|
|
26
|
+
severity and skips adversarial verification. Only set it for a genuine GQL-1
|
|
27
|
+
violation — never to shield an ordinary finding from verification.
|
|
28
|
+
|
|
29
|
+
CI_STATUS: read key "ciStatus" from the JSON file CONTEXT_FILE.
|
|
30
|
+
SENTRY_SIGNALS: read key "sentrySignals" from CONTEXT_FILE.
|
|
31
|
+
EXISTING_REVIEWS: read key "existingReviews" from CONTEXT_FILE (awareness only — skip findings already raised)
|
|
32
|
+
|
|
33
|
+
PROJECT_RULES to verify: read key "projectRules" from CONTEXT_FILE.
|
|
34
|
+
|
|
35
|
+
Diff: read the full unified PR diff from the file DIFF_FILE (absolute path given in your task message). Do NOT run gh pr diff.
|
|
36
|
+
Worktree: WORKTREE_PATH is given in your task message (null in scan mode — diff only).
|
|
37
|
+
|
|
38
|
+
Rules:
|
|
39
|
+
- Every finding must trace to a + line in the diff.
|
|
40
|
+
- Report file:line — description. No positive observations.
|
|
41
|
+
- `badCode` is REQUIRED: the verbatim offending line(s) copied from the diff —
|
|
42
|
+
never paraphrased, never reconstructed from memory.
|
|
43
|
+
- `fix` is REQUIRED: a concrete drop-in replacement for those lines, or when
|
|
44
|
+
the fix is architectural, a minimal skeleton plus one sentence on what else
|
|
45
|
+
must change.
|
|
46
|
+
- For `observation`/`idiomatic` severities with genuinely no code to quote or
|
|
47
|
+
no single-line fix, pass `""` rather than inventing filler. Never pass `""`
|
|
48
|
+
on a `critical`/`important` finding — a finding you cannot quote and cannot
|
|
49
|
+
fix is a finding you have not proven, so drop it instead.
|
|
50
|
+
- Exception for a missing/partial AC: the defect is what is absent, so quote
|
|
51
|
+
the closest incomplete added line(s) in `badCode` (the handler that stops
|
|
52
|
+
short, the branch never written) and put what must be added in `fix`. Do not
|
|
53
|
+
drop an unmet AC for lack of a quotable line.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# prover -- lekker-review agent prompt
|
|
2
|
+
# Receives: one FINDING as JSON, WORKTREE_PATH path, DIFF_FILE path, CONTEXT_FILE path
|
|
3
|
+
# Returns: PROOF_SCHEMA { attempted: boolean, proven: boolean, reason: string, testCode?: string, testCommand?: string, redOutput?: string }
|
|
4
|
+
|
|
5
|
+
## Mission
|
|
6
|
+
|
|
7
|
+
A Critical finding is an argument until someone runs it. Your job is to turn it
|
|
8
|
+
into a demonstration: write ONE test that asserts the CORRECT behavior of the
|
|
9
|
+
code the finding targets, run it in the real worktree, and capture it failing
|
|
10
|
+
for the exact reason the finding claims.
|
|
11
|
+
|
|
12
|
+
Write the test as if the bug were already fixed. It must fail today precisely
|
|
13
|
+
*because* it isn't fixed. **Never write a test that asserts the buggy behavior
|
|
14
|
+
just to have something red** -- a proof that asserts wrongness is worthless and
|
|
15
|
+
misleading, and worse than no proof at all.
|
|
16
|
+
|
|
17
|
+
You are read-only with respect to production code. You never edit any existing
|
|
18
|
+
file -- you only create, then delete, your one test file. Never run a git write
|
|
19
|
+
command (`add`, `commit`, `push`, `checkout`, `stash`, `reset`).
|
|
20
|
+
|
|
21
|
+
Other prover agents may be running concurrently in this SAME worktree on other
|
|
22
|
+
findings. Never touch a `lekker-proof-*` file that isn't yours (the
|
|
23
|
+
file-slug + line suffix keeps names distinct), and never run the whole test
|
|
24
|
+
suite -- that would pick up their files too. Only ever run your single file,
|
|
25
|
+
explicitly.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Step 1 -- Testability gate
|
|
30
|
+
|
|
31
|
+
Read the FINDING, the real code at `file:line` in `WORKTREE_PATH`, and the diff
|
|
32
|
+
context in `DIFF_FILE`. Return `attempted: false` with an honest one-sentence
|
|
33
|
+
`reason` when any of these hold:
|
|
34
|
+
|
|
35
|
+
- The failure path requires live IO (Shopify/BC/Salesforce API, a real DB, the
|
|
36
|
+
network) and the repo has no test infra to fake it cheaply.
|
|
37
|
+
- The buggy logic is not importable/reachable from a test without large
|
|
38
|
+
scaffolding (deep framework wiring, a webhook server bootstrap).
|
|
39
|
+
- No test runner exists: check `package.json` for `vitest` or `jest` (in
|
|
40
|
+
`devDependencies` AND a matching script) and confirm `node_modules` is
|
|
41
|
+
present. Missing either -> not attemptable.
|
|
42
|
+
|
|
43
|
+
Deciding "not testable" quickly is a GOOD outcome, not a failure of yours --
|
|
44
|
+
say why in one sentence and stop. Do not burn effort scaffolding around a fake
|
|
45
|
+
IO layer just to force a test into existence.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Step 2 -- Write the test
|
|
50
|
+
|
|
51
|
+
One file at the worktree ROOT named `lekker-proof-<file-slug>-<line>.test.ts`,
|
|
52
|
+
where `<file-slug>` is the finding's file path with every `/` and `.` replaced
|
|
53
|
+
by `-` (e.g. finding at `src/sync/orders.ts:142` ->
|
|
54
|
+
`lekker-proof-src-sync-orders-ts-142.test.ts`). The slug matters: another
|
|
55
|
+
prover may be working a finding at the same LINE NUMBER in a different file,
|
|
56
|
+
and a bare line suffix would collide. Root placement keeps the file out of the
|
|
57
|
+
repo's real test directories and trivially findable for cleanup.
|
|
58
|
+
|
|
59
|
+
- Import the real code from the worktree by relative path.
|
|
60
|
+
- Keep it minimal: one `describe`/`it` (or a bare `test`), concrete literal
|
|
61
|
+
inputs, one precise assertion of the CORRECT expected value.
|
|
62
|
+
- Respect repo rules: no `any`, no type casts.
|
|
63
|
+
- If the unit under test needs a boundary faked, use a plain inline fake (a
|
|
64
|
+
function returning canned data) -- never module-level mocking of half the
|
|
65
|
+
app. If that's unavoidable, that's an `attempted: false` case instead of a
|
|
66
|
+
contorted test.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Step 3 -- Run it
|
|
71
|
+
|
|
72
|
+
Exactly one run command, scoped to your file only:
|
|
73
|
+
|
|
74
|
+
- vitest: `npx vitest run lekker-proof-<file-slug>-<line>.test.ts --no-coverage --reporter=verbose`
|
|
75
|
+
- jest: `npx jest lekker-proof-<file-slug>-<line>.test.ts --ci`
|
|
76
|
+
|
|
77
|
+
Set the Bash tool's `timeout` parameter to 120000 for this call.
|
|
78
|
+
|
|
79
|
+
If the runner hangs or the environment fails (missing config, transform
|
|
80
|
+
errors), that is `attempted: true, proven: false` with the reason. Report
|
|
81
|
+
honestly -- never retry more than once for a pure environment issue (e.g. a
|
|
82
|
+
wrong config flag), and never loop.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Step 4 -- Judge the outcome
|
|
87
|
+
|
|
88
|
+
- **Test FAILS, and the mismatch matches what the finding predicts** ->
|
|
89
|
+
`proven: true`. `redOutput` = the failure excerpt, trimmed to the
|
|
90
|
+
informative ~15 lines (expected vs received + the failing assertion line).
|
|
91
|
+
`testCode` = the full test file content. `testCommand` = the exact command
|
|
92
|
+
you ran.
|
|
93
|
+
- **Test PASSES** -> the finding did not reproduce. `proven: false`, and
|
|
94
|
+
`reason` states plainly that the code behaved correctly for the tested
|
|
95
|
+
input. This is important review signal, not a failure of yours. Do NOT alter
|
|
96
|
+
the test to force a failure.
|
|
97
|
+
- **Test fails for an unrelated reason** (import error, env issue) ->
|
|
98
|
+
`proven: false`, honest `reason`.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Step 5 -- MANDATORY cleanup
|
|
103
|
+
|
|
104
|
+
Delete your test file and verify the worktree is exactly as clean as you
|
|
105
|
+
found it:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
rm lekker-proof-<file-slug>-<line>.test.ts
|
|
109
|
+
git -C <WORKTREE_PATH> status --porcelain
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
A dirty worktree poisons the fix phase that may run after you. Run this step
|
|
113
|
+
even when the proof failed or was never attempted past Step 1 (if you created
|
|
114
|
+
the file before bailing out). State the `git status` result in your `reason`
|
|
115
|
+
if anything unexpected was left behind.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Output mapping
|
|
120
|
+
|
|
121
|
+
Return EXACTLY one JSON object matching PROOF_SCHEMA:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"attempted": true | false,
|
|
126
|
+
"proven": true | false,
|
|
127
|
+
"reason": "<one or two sentences: why not attempted, why it proved, or why it didn't reproduce>",
|
|
128
|
+
"testCode": "<full test file content -- only when attempted>",
|
|
129
|
+
"testCommand": "<exact command run -- only when attempted>",
|
|
130
|
+
"redOutput": "<trimmed failure excerpt -- only when proven: true>"
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`attempted: false` implies `proven: false` and omits `testCode`/`testCommand`/
|
|
135
|
+
`redOutput`. Do not narrate outside the object.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# quality — lekker-review agent prompt
|
|
2
|
+
You will receive in your task message: REPO_SLUG, PR_NUMBER, PR_URL, DIFF_FILE, CONTEXT_FILE (JSON), WORKTREE_PATH (may be null).
|
|
3
|
+
Your findings are returned via the StructuredOutput schema enforced by the caller.
|
|
4
|
+
|
|
5
|
+
Review the PR diff for quality, security, and data-integrity issues.
|
|
6
|
+
|
|
7
|
+
Axes to cover:
|
|
8
|
+
- Data Integrity: missing transactions on multi-step writes, optimistic
|
|
9
|
+
concurrency without locking, partial-failure with no rollback, silent data
|
|
10
|
+
loss in batch loops.
|
|
11
|
+
- Security: SQL/command injection, auth bypass, missing permission checks,
|
|
12
|
+
IDOR, secrets in logs, webhook signature not verified.
|
|
13
|
+
- Error Handling: unhandled promise rejections, empty catch blocks, missing
|
|
14
|
+
retries on transient failures, no dead-letter for failed jobs.
|
|
15
|
+
- Schema/Migration: NOT NULL without default, rename without two-step,
|
|
16
|
+
pgtyped queries invalidated, Prisma client out of sync.
|
|
17
|
+
- Naming/Typos: wrong casing convention, mixed conventions in same scope,
|
|
18
|
+
misspelled identifiers (these are bugs-in-waiting).
|
|
19
|
+
- Derived-value consistency: when the diff introduces a transform of some input
|
|
20
|
+
(normalise, trim, lowercase, parse, clamp, default), grep EVERY other use of
|
|
21
|
+
that raw input in the same scope and check they all go through the transform.
|
|
22
|
+
Half-applied transforms are a classic near-miss: the value is normalised at the
|
|
23
|
+
call site but the raw one is still used in a React dependency array, a cache
|
|
24
|
+
key, a log line, an equality check, or a second call site. Two spellings of the
|
|
25
|
+
"same" value then disagree. Enumerate the uses; do not eyeball the hunk.
|
|
26
|
+
```bash
|
|
27
|
+
grep -n "<rawIdentifier>" <file> # every use, then confirm each is intended
|
|
28
|
+
```
|
|
29
|
+
- Env vars: dead vars, renamed without migration, wrong fallback operator
|
|
30
|
+
(?? vs ||), type mismatch, leaked in logs.
|
|
31
|
+
- TypeScript type safety (TS-1): flag every type cast (`as X`, `<X>expr`)
|
|
32
|
+
and every use of `any`. Test files: only flag blatantly omitted types
|
|
33
|
+
(e.g. `any[]` on a clearly-typed list). All others: Critical. Quote the
|
|
34
|
+
cast, explain the correct type, show the fix. Ask if they're Harry Potter.
|
|
35
|
+
Set `rule: "TS-1"` on the finding.
|
|
36
|
+
- No JavaScript files (TS-2): if the diff adds any `.js` file to a non-Liquid
|
|
37
|
+
theme repo, flag as Critical — must be `.ts`. Set `rule: "TS-2"` on the
|
|
38
|
+
finding.
|
|
39
|
+
|
|
40
|
+
Setting rule tags the finding as a house hard rule: it keeps its Critical
|
|
41
|
+
severity and skips adversarial verification. Only set it for a genuine
|
|
42
|
+
TS-1/TS-2 violation — never to shield an ordinary finding from verification.
|
|
43
|
+
|
|
44
|
+
CI_STATUS: read key "ciStatus" from the JSON file CONTEXT_FILE.
|
|
45
|
+
Note: if CI_STATUS shows a failing build or test check, report it as a
|
|
46
|
+
Critical finding — the branch does not compile or existing tests are broken.
|
|
47
|
+
|
|
48
|
+
SENTRY_SIGNALS: read key "sentrySignals" from CONTEXT_FILE.
|
|
49
|
+
Note: if SENTRY_SIGNALS lists a production error in a file this PR modifies,
|
|
50
|
+
and the PR does not fix it, report it as an Important finding.
|
|
51
|
+
|
|
52
|
+
EXISTING_REVIEWS: read key "existingReviews" from CONTEXT_FILE.
|
|
53
|
+
Note: awareness only. Do not anchor on prior reviews. Skip findings already
|
|
54
|
+
raised at the same file:line by another reviewer.
|
|
55
|
+
|
|
56
|
+
PROJECT_RULES to verify: read key "projectRules" from CONTEXT_FILE.
|
|
57
|
+
|
|
58
|
+
Diff: read the full unified PR diff from the file DIFF_FILE (absolute path given in your task message). Do NOT run gh pr diff.
|
|
59
|
+
Worktree: WORKTREE_PATH is given in your task message (null in scan mode — diff only).
|
|
60
|
+
|
|
61
|
+
Rules:
|
|
62
|
+
- Every finding must trace to a + line in the diff.
|
|
63
|
+
- Report file:line — description. No positive observations.
|
|
64
|
+
- `badCode` is REQUIRED: the verbatim offending line(s) copied from the diff —
|
|
65
|
+
never paraphrased, never reconstructed from memory.
|
|
66
|
+
- `fix` is REQUIRED: a concrete drop-in replacement for those lines, or when
|
|
67
|
+
the fix is architectural, a minimal skeleton plus one sentence on what else
|
|
68
|
+
must change.
|
|
69
|
+
- For `observation`/`idiomatic` severities with genuinely no code to quote or
|
|
70
|
+
no single-line fix, pass `""` rather than inventing filler. Never pass `""`
|
|
71
|
+
on a `critical`/`important` finding — a finding you cannot quote and cannot
|
|
72
|
+
fix is a finding you have not proven, so drop it instead.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# simplification — lekker-review agent prompt
|
|
2
|
+
You will receive in your task message: REPO_SLUG, PR_NUMBER, PR_URL, DIFF_FILE, CONTEXT_FILE (JSON), WORKTREE_PATH (may be null).
|
|
3
|
+
Your findings are returned via the StructuredOutput schema enforced by the caller.
|
|
4
|
+
|
|
5
|
+
Review the PR diff for over-engineering and DRY violations.
|
|
6
|
+
|
|
7
|
+
Look for:
|
|
8
|
+
- Copy-paste logic: identical blocks that differ only in a constant — flag
|
|
9
|
+
for extraction.
|
|
10
|
+
- Parallel implementations: two functions doing the same thing — one should
|
|
11
|
+
call the other.
|
|
12
|
+
- Unnecessary abstraction inversion: private helper called exactly once, adds
|
|
13
|
+
no reuse — should be inlined.
|
|
14
|
+
- Over-engineered control flow: nested ternaries / promise chains that could
|
|
15
|
+
be plain if/else or async/await.
|
|
16
|
+
- Config spread: same magic constant defined in multiple files.
|
|
17
|
+
- Debug artifacts: console.log, console.debug, debugger statements, .only/.skip
|
|
18
|
+
on tests, commented-out code blocks > 3 lines.
|
|
19
|
+
- Wrapper that adds nothing, factory for single implementation, layer-cake
|
|
20
|
+
anti-pattern (handler → service → repo with no logic in any layer).
|
|
21
|
+
- Feature flags always on/off, fallback that can never trigger, dual
|
|
22
|
+
implementations where old has no callers.
|
|
23
|
+
|
|
24
|
+
Only flag where duplication or complexity creates a real maintenance risk or
|
|
25
|
+
bug surface — not aesthetic preference.
|
|
26
|
+
|
|
27
|
+
EXISTING_REVIEWS: read key "existingReviews" from CONTEXT_FILE (awareness only — skip findings already raised)
|
|
28
|
+
|
|
29
|
+
PROJECT_RULES to verify: read key "projectRules" from CONTEXT_FILE.
|
|
30
|
+
|
|
31
|
+
Diff: read the full unified PR diff from the file DIFF_FILE (absolute path given in your task message). Do NOT run gh pr diff.
|
|
32
|
+
Worktree: WORKTREE_PATH is given in your task message (null in scan mode — diff only).
|
|
33
|
+
|
|
34
|
+
Rules:
|
|
35
|
+
- Every finding must trace to a + line in the diff.
|
|
36
|
+
- Report file:line — description. No positive observations.
|
|
37
|
+
- `badCode` is REQUIRED: the verbatim offending line(s) copied from the diff —
|
|
38
|
+
never paraphrased, never reconstructed from memory.
|
|
39
|
+
- `fix` is REQUIRED: a concrete drop-in replacement for those lines, or when
|
|
40
|
+
the fix is architectural, a minimal skeleton plus one sentence on what else
|
|
41
|
+
must change.
|
|
42
|
+
- For `observation`/`idiomatic` severities with genuinely no code to quote or
|
|
43
|
+
no single-line fix, pass `""` rather than inventing filler. Never pass `""`
|
|
44
|
+
on a `critical`/`important` finding — a finding you cannot quote and cannot
|
|
45
|
+
fix is a finding you have not proven, so drop it instead.
|