@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,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.