@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,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
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# fix-mode.md -- lekker-review `--fix` procedure
|
|
2
|
+
|
|
3
|
+
Run this AFTER the review has been printed and saved to `~/code-reviews/`, and
|
|
4
|
+
ONLY when `FIX_MODE=true` (either `--fix` was passed, or the user answered yes to
|
|
5
|
+
the post-review offer).
|
|
6
|
+
|
|
7
|
+
Fix mode turns verified findings into real commits on the PR branch. It edits
|
|
8
|
+
only the isolated review worktree, never the user's checkout, and it never
|
|
9
|
+
pushes without explicit confirmation.
|
|
10
|
+
|
|
11
|
+
**Never fix and push in the same breath as reporting.** Committing is local and
|
|
12
|
+
reversible; pushing writes to someone else's branch and is outward-facing.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 1 -- Preconditions (all must hold, else stop and report)
|
|
17
|
+
|
|
18
|
+
| Precondition | Check | If it fails |
|
|
19
|
+
|--------------|-------|-------------|
|
|
20
|
+
| Worktree exists | `WORKTREE_PATH` non-null and the dir exists | Run `scripts/setup-worktree.sh` now, then continue. Fix mode cannot work from the diff alone. |
|
|
21
|
+
| Worktree is clean | `git -C <WORKTREE_PATH> status --porcelain` is empty | Stop. Report the dirty paths -- something already edited it. |
|
|
22
|
+
| Head still current | `git -C <repoRoot> fetch origin <PR_BRANCH>` then compare `git rev-parse origin/<PR_BRANCH>` to `headSha` | Head moved during the review. Stop, report both shas, tell the user to re-run: the review is stale and fixes could clobber new work. |
|
|
23
|
+
| PR is open | `gh pr view <PR_NUMBER> --repo <REPO_SLUG> --json state,mergedAt` | Stop if MERGED or CLOSED. |
|
|
24
|
+
| PR is not from a fork you cannot write to | `gh pr view --json headRepositoryOwner,maintainerCanModify` | If the head repo is a fork and `maintainerCanModify` is false, fixes can be committed locally but NOT pushed. Say so up front, before spending agents. |
|
|
25
|
+
|
|
26
|
+
The worktree checkout is a **detached HEAD** at `origin/<PR_BRANCH>` (see
|
|
27
|
+
`setup-worktree.sh`). That is intentional -- do not create or check out a
|
|
28
|
+
branch in it. Commits land on the detached HEAD and are pushed with an explicit
|
|
29
|
+
refspec in Step 6.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Step 2 -- Select the findings to fix
|
|
34
|
+
|
|
35
|
+
Eligible finding = severity `critical` or `important`, has a non-empty `fix`
|
|
36
|
+
field, and its `file` exists in the worktree.
|
|
37
|
+
|
|
38
|
+
- Findings without a `fix` field are review-only. List them as "not
|
|
39
|
+
auto-fixable" in the report; never guess a fix.
|
|
40
|
+
- `observation` and `idiomatic` findings are NEVER auto-fixed. They are
|
|
41
|
+
judgment calls and non-blocking by definition.
|
|
42
|
+
- `PR-1` (title prefix) is not a code fix. Never edit the PR title as part of
|
|
43
|
+
fix mode -- it stays a `⛔ CANNOT MERGE` instruction for the author.
|
|
44
|
+
- Skip any finding whose `file` is generated (`*/generated/*`, lockfiles,
|
|
45
|
+
`*.snap`, build output). Report it as skipped-generated.
|
|
46
|
+
|
|
47
|
+
If the user chose "Critical only" at the offer prompt, filter to `critical`.
|
|
48
|
+
|
|
49
|
+
If nothing is eligible: say so in one line and skip to Step 8. Do not run the
|
|
50
|
+
workflow with an empty finding list.
|
|
51
|
+
|
|
52
|
+
Write the selected findings to `<scratchpad>/fix-findings.json` (receipt), then
|
|
53
|
+
state the plan before spending agents:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Fixing <N> finding(s) across <M> file(s): <file list>
|
|
57
|
+
Not auto-fixable: <N> (<reasons>)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Step 3 -- Run the fix workflow
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Workflow tool:
|
|
66
|
+
scriptPath: ${CLAUDE_PLUGIN_ROOT}/fix-workflow.js
|
|
67
|
+
args: {
|
|
68
|
+
repoSlug,
|
|
69
|
+
prNumber,
|
|
70
|
+
worktreePath: "<WORKTREE_PATH>",
|
|
71
|
+
diffFile: "<scratchpad>/pr.diff",
|
|
72
|
+
contextFile: "<scratchpad>/context.json",
|
|
73
|
+
promptDir: "${CLAUDE_PLUGIN_ROOT}/references/agents",
|
|
74
|
+
findings: [ <the selected finding objects, verbatim> ]
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Pass `findings` as a real JSON array, not a stringified one. The workflow groups
|
|
79
|
+
by file (one agent per file, so no two agents ever edit the same file), applies
|
|
80
|
+
the fix, then runs a read-only fix-verifier over the actual `git diff`. A
|
|
81
|
+
verdict other than `good` buys exactly one retry, then stops.
|
|
82
|
+
|
|
83
|
+
Return value:
|
|
84
|
+
`{groups, droppedGroups, agentCount, retryCount, outputTokens, turnTokensTotal}`,
|
|
85
|
+
one `groups` entry per file with `results[]`, `filesTouched[]`, `verdict`,
|
|
86
|
+
`problems[]`, `committable`. `outputTokens` is the fix workflow's own spend
|
|
87
|
+
(already excluding the review workflow that ran before it); `turnTokensTotal` is
|
|
88
|
+
the whole turn's pool. Report the former on the `Fix agents:` cost line.
|
|
89
|
+
|
|
90
|
+
If the Workflow tool is unavailable: fall back to launching one Agent per file
|
|
91
|
+
group on `sonnet` with `references/agents/fixer.md`, then one Agent per group
|
|
92
|
+
with `references/agents/fix-verifier.md`. Same rules, same verdict handling.
|
|
93
|
+
State the fallback in the report.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Step 4 -- Revert what did not earn a commit
|
|
98
|
+
|
|
99
|
+
For every group with `committable: false` that touched files:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
git -C <WORKTREE_PATH> checkout -- <each path in filesTouched>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then confirm the revert landed:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
git -C <WORKTREE_PATH> status --porcelain
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Only committable groups' files may remain modified. Any leftover untracked file
|
|
112
|
+
from a reverted group gets removed explicitly (`rm -f <path>`), never with
|
|
113
|
+
`git clean -fd` (too blunt for a shared worktree).
|
|
114
|
+
|
|
115
|
+
`harmful` verdicts are a normal outcome, not a failure of the run: the finding
|
|
116
|
+
simply stays a review comment for the author. Report it as such.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Step 5 -- Verify the fixed tree (fresh post-condition)
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
~/.claude/skills/lekker-review/scripts/verify-fixes.sh \
|
|
124
|
+
<WORKTREE_PATH> <scratchpad>/fix-verify.json tests
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Pass `tests` only when the diff touched logic and the repo has a `test` script;
|
|
128
|
+
pass `no-tests` for doc/config-only fixes or when the suite needs live infra.
|
|
129
|
+
|
|
130
|
+
Read the JSON and compare against the pre-fix baseline in `worktree.json`:
|
|
131
|
+
|
|
132
|
+
- `tscChangedTail` / `tscErrorCount` -- compare against the same two baseline
|
|
133
|
+
keys. `tscChangedTail` is the attributable set (errors in files this branch
|
|
134
|
+
touched, which now includes the files the fix agents wrote); an entry there
|
|
135
|
+
that is not in the baseline was introduced by the fixes. A rise in
|
|
136
|
+
`tscErrorCount` with no new `tscChangedTail` entry means the fix broke a file
|
|
137
|
+
it does not own - treat that as introduced too. Revert the offending group's
|
|
138
|
+
files (Step 4) and mark those findings `failed`. Never commit a tree with
|
|
139
|
+
newly-introduced type errors.
|
|
140
|
+
- `eslintTail` -- same comparison. Both runs lint only changed files, so the
|
|
141
|
+
comparison is like-for-like; check `eslintScope` matches the baseline's
|
|
142
|
+
(`changed-files` vs `full-fallback`) before trusting a diff between the two.
|
|
143
|
+
- `testTail` / `testExitCode` -- a newly failing test caused by a fix means
|
|
144
|
+
revert that group. A test that already failed on the baseline head is not
|
|
145
|
+
yours; say so explicitly rather than silently ignoring it.
|
|
146
|
+
- `dirtyPaths` -- must contain only files declared by committable groups. An
|
|
147
|
+
undeclared path is a red flag: revert it and report.
|
|
148
|
+
|
|
149
|
+
If a check was skipped (no `node_modules`, no config), say `skipped` in the
|
|
150
|
+
report. Skipped is a state, not a pass.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Step 5b -- Proof flip (red → green)
|
|
155
|
+
|
|
156
|
+
For every group that is still `committable` after Step 5, collect the
|
|
157
|
+
findings in that group that carry `proof.proven === true` (the
|
|
158
|
+
`<scratchpad>/fix-findings.json` sidecar written in Step 2 has the `proof`
|
|
159
|
+
objects, including `testCode` and `testCommand`, alongside each finding). If a
|
|
160
|
+
committable group has no proven findings, skip it -- there is nothing to flip.
|
|
161
|
+
|
|
162
|
+
For each proven finding in a committable group:
|
|
163
|
+
|
|
164
|
+
1. **Re-materialize the test**: write `proof.testCode` back to its original
|
|
165
|
+
filename (the same `lekker-proof-<file-slug>-<line>.test.ts` name it was captured
|
|
166
|
+
under) at the worktree root.
|
|
167
|
+
2. **Run** exactly `proof.testCommand` (Bash `timeout` 120000).
|
|
168
|
+
3. **Judge**:
|
|
169
|
+
- **PASSES now** -> the fix demonstrably resolves the finding. Record
|
|
170
|
+
`proofFlip: green` for that finding in the Step 8 status table.
|
|
171
|
+
- **STILL FAILS with the same assertion** -> the fix did not fix the bug.
|
|
172
|
+
The group is NOT committable regardless of the fix-verifier's `good`
|
|
173
|
+
verdict -- revert it (Step 4 procedure) and mark its findings `failed`
|
|
174
|
+
with reason `proof still red after fix`. An executed test outranks a
|
|
175
|
+
reviewer agent's opinion.
|
|
176
|
+
- **Fails for a NEW, unrelated reason** (import broke, different error) ->
|
|
177
|
+
the fix likely broke something else; same outcome: revert the group,
|
|
178
|
+
mark its findings `failed`, and quote the new error in the reason.
|
|
179
|
+
4. **Delete the test file** and verify with `git -C <WORKTREE_PATH> status
|
|
180
|
+
--porcelain` that only the fix edits remain -- no stray proof file, no
|
|
181
|
+
other drift.
|
|
182
|
+
|
|
183
|
+
A group reverted at this step no longer participates in Step 6 (Commit) --
|
|
184
|
+
treat it exactly like a Step 4 revert. Re-run the `git status --porcelain`
|
|
185
|
+
check after any revert triggered here before moving on.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Step 6 -- Commit (local only)
|
|
190
|
+
|
|
191
|
+
One commit per file group, in group order. Stage explicitly -- never `git add -A`,
|
|
192
|
+
never `git add .`:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
git -C <WORKTREE_PATH> add -- <filesTouched for this group>
|
|
196
|
+
git -C <WORKTREE_PATH> commit -m "<subject>" -m "<body>"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Subject: `<TICKET_PREFIX> review fix: <short label>` where `TICKET_PREFIX` is the
|
|
200
|
+
`[TICKET-NNN]` from the PR title when there is one, omitted otherwise. Keep the
|
|
201
|
+
subject under 72 chars.
|
|
202
|
+
|
|
203
|
+
Body: one `- ` line per applied finding, using the fixer's `summary`, then:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
Applied from lekker-review: <REVIEW_FILE>
|
|
207
|
+
|
|
208
|
+
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
If two groups declared the same file, commit them together as one commit and
|
|
212
|
+
say so in the report.
|
|
213
|
+
|
|
214
|
+
Receipt after committing:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
git -C <WORKTREE_PATH> log --oneline <headSha>..HEAD
|
|
218
|
+
git -C <WORKTREE_PATH> status --porcelain # must be empty
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Step 7 -- Push (requires explicit confirmation)
|
|
224
|
+
|
|
225
|
+
Show the user, before asking:
|
|
226
|
+
|
|
227
|
+
- the commit list (`git log --oneline <headSha>..HEAD`)
|
|
228
|
+
- the full diffstat (`git diff --stat <headSha>..HEAD`)
|
|
229
|
+
- the per-finding table from Step 8
|
|
230
|
+
|
|
231
|
+
Then ask, in a single question: push these `<N>` commit(s) to
|
|
232
|
+
`<PR_BRANCH>` on `<REPO_SLUG>`, or leave them local?
|
|
233
|
+
|
|
234
|
+
**Unattended runs (cron, `/loop`, background agent): never push, never ask.**
|
|
235
|
+
Stop after Step 6, keep the worktree, and report the worktree path plus the
|
|
236
|
+
exact push command so a human can release it. This matches the standing
|
|
237
|
+
unattended-run rule: stage the artifact, a human releases it.
|
|
238
|
+
|
|
239
|
+
On confirmed push:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
git -C <repoRoot> fetch origin <PR_BRANCH>
|
|
243
|
+
# guard: origin must still be at the sha we based the fixes on
|
|
244
|
+
git -C <repoRoot> rev-parse origin/<PR_BRANCH> # must equal <headSha>
|
|
245
|
+
git -C <WORKTREE_PATH> push origin HEAD:refs/heads/<PR_BRANCH>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
- If the guard sha differs, ABORT the push. Report that the branch moved and
|
|
249
|
+
leave the commits local. Never `--force`, never `--force-with-lease`, never
|
|
250
|
+
rebase someone else's branch.
|
|
251
|
+
- Never push to `main`, `master`, `staging`, or `develop`, whatever the branch
|
|
252
|
+
variables say. Stop if `PR_BRANCH` is one of those.
|
|
253
|
+
|
|
254
|
+
Post-condition (fresh source, not the push output):
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
gh pr view <PR_NUMBER> --repo <REPO_SLUG> --json headRefOid,mergeStateStatus
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Confirm `headRefOid` equals the local HEAD sha. Print
|
|
261
|
+
`✓ Pushed <N> commit(s) -> <PR_URL> (head now <new short sha>)`. If it does not
|
|
262
|
+
match, say the push is unconfirmed and stop -- do not retry.
|
|
263
|
+
|
|
264
|
+
Do NOT also post the fixed findings as inline review comments. When `--post` and
|
|
265
|
+
`--fix` both ran, post only the findings that were NOT applied; a comment asking
|
|
266
|
+
for a change you already committed is noise.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Step 8 -- Report and record
|
|
271
|
+
|
|
272
|
+
Print a table:
|
|
273
|
+
|
|
274
|
+
| # | Finding | File | Status | proofFlip | Note |
|
|
275
|
+
|---|---------|------|--------|-----------|------|
|
|
276
|
+
| 1 | <title> | `<file>:<line>` | ✅ applied | green | <fixer summary> |
|
|
277
|
+
| 2 | <title> | `<file>:<line>` | ↩️ reverted | still-red | <verifier problem, or "proof still red after fix"> |
|
|
278
|
+
| 3 | <title> | `<file>:<line>` | ⏭️ skipped | n/a | <reason, e.g. needs cross-file change> |
|
|
279
|
+
| 4 | <title> | `<file>:<line>` | ❌ failed | n/a | <what blocked it> |
|
|
280
|
+
|
|
281
|
+
`proofFlip` is `green` (proof re-ran and passed), `still-red` (proof re-ran and
|
|
282
|
+
still failed, so the group was reverted per Step 5b), or `n/a` (the finding
|
|
283
|
+
carried no `proof.proven === true`, so Step 5b never ran for it).
|
|
284
|
+
|
|
285
|
+
Then append this section to `REVIEW_FILE` (the saved review), so the record and
|
|
286
|
+
the review never drift apart:
|
|
287
|
+
|
|
288
|
+
```markdown
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 🔧 Fixes applied
|
|
292
|
+
|
|
293
|
+
**Base:** `<headShaShort>` · **Commits:** <N> · **Pushed:** <yes, head now `<sha>` | no, local only at <WORKTREE_PATH>>
|
|
294
|
+
**Checks:** tsc <clean | N new errors | skipped> · eslint <...> · tests <passed | failed | skipped>
|
|
295
|
+
**Fix agents:** <N> (<retryCount> retried)
|
|
296
|
+
**Proof flips:** <M green / K still-red / rest n/a> *(include only when at least one finding carried `proof.proven === true`)*
|
|
297
|
+
|
|
298
|
+
| # | Finding | File | Status | proofFlip | Note |
|
|
299
|
+
...same table...
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Re-read the file after writing and emit `✓ Fixes recorded -> <REVIEW_FILE>`.
|
|
303
|
+
|
|
304
|
+
Add one line to the `## 💰 Review Cost` block for fix-mode spend:
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
Fix agents: <N> (sonnet) — <outputTokens> output tokens, ~$<X.XX>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Step 9 -- Cleanup override
|
|
313
|
+
|
|
314
|
+
The normal cleanup step removes the worktree. In fix mode:
|
|
315
|
+
|
|
316
|
+
- **Pushed successfully** -> clean up as usual.
|
|
317
|
+
- **Commits exist but were not pushed** -> KEEP the worktree and the repo clone.
|
|
318
|
+
Print the path and the push command. Deleting it would destroy the only copy
|
|
319
|
+
of the work.
|
|
320
|
+
- **Nothing was committed** -> clean up as usual.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Failure rules
|
|
325
|
+
|
|
326
|
+
- Two identical failures = stop and diagnose. No loops.
|
|
327
|
+
- Never claim a fix landed without the `git log` / `git status` receipt.
|
|
328
|
+
- Never present the review's proposed `fix` text as though it were applied. Only
|
|
329
|
+
a committed diff counts.
|