Solo PR Review
Review pull requests in hiero-ledger/solo the way the Solo Team reviews them. This skill encodes the conventions
enforced repeatedly across the project so reviews stay consistent whether they're authored by a human or generated here.
When to use
- The user supplies a PR number, PR URL, branch name, commit range, or file list and asks for a review.
- The user asks "what would you flag in this change?", "review my branch", or similar.
- The user is the PR author preparing to push and wants a self-review pass.
Do not use for: greenfield architecture proposals (use architecture-designer), security-only audits (use
security-review), or generic non-Solo TypeScript reviews (use code-reviewer).
Required reading before reviewing
Open these before writing any feedback. They are the rulebook — the review must cite them when something is off.
| File |
What it owns |
docs/contributing/typescript-code-style.md |
The full TS style guide (DRY/SOLID, naming, imports, types, etc.) |
CLAUDE.md |
Project-level conventions and gotchas (flags, env vars, etc.) |
eslint.config.mjs |
Enforced lint rules (errors, not warnings) |
.prettierrc.json |
Formatting (120 col, single quotes, etc.) |
Core workflow
Establish intent. Read the PR description (and any linked issue) and state the goal in one sentence. If the goal
is unclear, stop and ask the author — do not guess.
Inventory the diff. List every file changed and group them: source, tests, workflows, docs, examples, generated.
Note the size of each group. Big diffs that touch many groups warrant a structural pass before a line pass.
Structural pass. Walk the checklist in references/solo-review-checklist.md. This catches the recurring issues (
DRY violations, exported functions, generic-flag wording, error-handling drift, missing Windows support, etc.) before
getting into line-by-line nits.
Line pass. Read the actual diff. For each finding, decide:
- Critical — bug, security issue, data loss, broken backwards compatibility, build/CI break.
- Major — design/architecture issue, DRY/SOLID violation, missing default behavior, cross-platform regression,
drift from existing patterns.
- Minor — naming, comment hygiene, suggestion-block one-liners.
- Question — something that looks off but might have a reason. Ask before claiming.
Comment-to-implementation pass. For every changed behavioral comment, JSDoc, test name/comment, example,
documentation claim, and PR-description assertion, trace the claim to the final source and test behavior. Confirm
that APIs, control flow, process boundaries, logging, configuration propagation, and claimed coverage are exactly
what the text says. Treat wording left over from an earlier commit or implementation as a finding — not as reliable
context — and distinguish a documentation-only mismatch from behavior that is actually broken or concealed by the
stale wording.
Test pass. Are there tests? Are they unit (cheap, fast) or did the author reach for E2E/nightly when a unit test
would do? Do the tests execute the behavior their names and the PR description claim they cover? Flag missing or
overstated unit coverage explicitly.
Verification ledger. Before writing anything, tag every Critical and Major with the evidence actually behind it:
- executed — you ran a command and read its output. Quote the load-bearing lines in the finding itself.
- read-in-full — you read the entire file, issue, or rule the claim depends on.
- inferred — you reasoned from the diff without running or fully reading anything.
Verify or demote every inferred finding. A Question the author can answer costs a round-trip; an assertion they
can refute costs the whole review its credibility. Evidence attaches to an individual claim, never to the report —
a "what I verified locally" section does not vouch for the claims next to it. Traps that have each produced a
retracted finding:
- Negative claims ("issue N does not cover this", "this env var is undocumented", "the rule bans this here")
require reading the whole source. A positive claim needs one witness; a negative claim needs an exhaustive read.
Never assert what a document does not say from a truncated read.
- Suggestion blocks are one-click-appliable. Type-check any non-trivial code before posting it. A suggestion
that fails
tsc, or an invented API that fails open rather than erroring, is worse than no comment.
- Line numbers come from the source file at the head SHA, never from a saved diff — the coordinate systems
differ, and a wrong anchor makes a correct finding look careless.
- Contaminated environments. A worktree with a symlinked or stale
node_modules, a warm cache, or a
non-default toolchain invalidates any finding about dependency resolution, caching, or build behavior.
Reproduce cleanly or drop it.
- Rule citations. Re-read the scope line of every rule you cite — which paths it covers, whether it is an
error or a warning. Citing a rule you have misread is worse than citing nothing.
Write the report. Use the template in §Output. Lead with the critical/major findings; line-level suggestion
blocks come after.
Checkpoint: before delivering the report, re-read it and ask: "If I were the author, would I be able to act on
every comment without another round-trip?" If not, tighten the wording or add a code example. Then ask: "Which
findings would survive the author pushing back with a command output?" Anything that would not survive is not
ready to post.
Reference guide
Load these on demand — don't paste them into the report.
| Topic |
File |
Load when |
| Solo-specific review checklist |
references/solo-review-checklist.md |
Always — this is the structural-pass driver |
| Feedback voice and format |
references/solo-maintainer-feedback-style.md |
Always — covers tone, suggestion blocks, root-cause questions |
How to fetch the diff
# Metadata only — small, cheap, do this first
gh pr view <number> --json title,body,headRefName,baseRefName,headRefOid,files,additions,deletions,author,state,url
# Full diff (large for big PRs — paginate via Read once it's persisted)
gh pr diff <number>
# Per-file diff (preferred when you already know which files matter)
gh pr diff <number> -- <path>
# By branch (when working locally on the author's branch)
git diff origin/main...HEAD
git diff origin/main -- <path>
For URL-only inputs, parse the PR number out of the URL and use gh pr view / gh pr diff.
Token-efficiency tips:
gh pr view --json files returns the file list with line counts — use it to decide which files to fetch full diffs
for, instead of pulling the whole PR diff up front.
- For exact line numbers in inline-comment-anchor positions, prefer
gh pr diff <num> -- <path> over fetching the
entire file via gh api .../contents/.... The diff already shows line numbers on the RIGHT side.
- Only fetch a full file via
gh api 'repos/<owner>/<repo>/contents/<path>?ref=<sha>' --jq '.content' | base64 -d when
you genuinely need surrounding context the diff doesn't show.
- When iterating over multiple lookups, batch them into a single Bash call (one shell, multiple
gh api invocations)
rather than separate tool calls.
How to post the review
Always post feedback as a single PR review — never as standalone PR or issue comments. Every
finding (summary verdict and inline line comments) must be attached to one review so the author can
resolve them in one round-trip.
Critical behavior: leave the review in PENDING state. Never submit it. The human reviewer
will read the queued comments in the GitHub UI, edit if needed, and submit themselves. Submitting
automatically would post a review attributed to the human without giving them a chance to vet it.
The single-POST flow (preferred)
POST one review with all inline comments embedded and no event field — that creates the review
in PENDING state with every comment attached. This is one HTTP call and avoids the
"user_id can only have one pending review per pull request" failure that hits the multi-step flow
when a pending review already exists.
Check for an existing pending review. If one exists for the current reviewer, delete it
before starting fresh (the single-POST flow can't merge into an existing pending review):
existingId=$(gh api "repos/<owner>/<repo>/pulls/<number>/reviews" \
--jq '.[] | select(.user.login == "'"$(gh api user --jq .login)"'" and .state == "PENDING") | .id')
if [[ -n "${existingId}" ]]; then
gh api -X DELETE "repos/<owner>/<repo>/pulls/<number>/reviews/${existingId}"
fi
Write the review payload to a file. JSON shape:
{
"commit_id": "<head SHA from gh pr view headRefOid>",
"body": "<§Output-template summary as a single markdown string>",
"comments": [
{
"path": "<file path>",
"line": <line number on RIGHT side of the diff>,
"side": "RIGHT",
"body": "<comment, suggestion blocks OK>"
}
]
}
Do not include an event field. Its absence keeps the review in PENDING state.
POST the review:
gh api -X POST "repos/<owner>/<repo>/pulls/<number>/reviews" --input review-payload.json
The response includes "state": "PENDING" and an html_url pointing to the review on GitHub.
Tell the user what to do next. End the turn with a short message that:
- Links to the pending review (
html_url from the response).
- States that the review is queued in PENDING state with N inline comments + summary.
- Asks them to open it in GitHub, vet/edit the comments, and choose Comment,
Approve, or Request changes themselves.
- Does not call any API to submit, dismiss, or otherwise change the review state.
What never to do
- Never POST
/reviews/<id>/events with event=COMMENT/APPROVE/REQUEST_CHANGES —
that submits the review. The user submits, not the skill.
- Never include an
event field on the initial review POST for any value other than
omitting it. (event=PENDING is rejected as an invalid enum value.)
- Never use
gh pr comment, gh pr review --body, or POST to /issues/<n>/comments —
those create orphan comments outside the review thread.
- Never start a second pending review when one already exists. Delete the old one first
(step 1) or the POST fails with HTTP 422.
Output template
## Intent
<one-sentence recap of what the PR is trying to do>
## Verdict
<Approve | Request changes | Comment>
## Critical
- <issue> — `path/to/file.ts:LINE` — <why it blocks merge> <code example if useful>
## Major
- <issue> — `path/to/file.ts:LINE` — <why> <suggestion>
## Minor
- <issue> — `path/to/file.ts:LINE` — <suggestion>
## Questions for the author
- <question that needs an answer before this can be Approved>
## Comment and description consistency
- <State that each changed behavioral claim was checked against the final implementation, or list the stale/mismatched
claims with their source and actual behavior.>
## Positive
- <specific thing done well — be concrete, not generic>
## Companion work
- solo-docs PR: <linked / missing / N/A>
- solo-containers PR: <linked / missing / N/A>
Use GitHub suggestion blocks (```suggestion … ```) for any single-line or small-block edit — they let the author
one-click apply.
Constraints
MUST
- Post the review as a single PR review in PENDING state, with every inline finding attached
as a review comment and the summary verdict as the review body.
- End the turn by linking the pending review and asking the user to vet and submit it themselves.
- Cite the rule being applied (style-guide section, eslint rule, or prior PR convention) for every Critical and Major
finding, having re-read that rule's scope line rather than recalling its gist.
- Run the verification ledger (workflow step 7) before writing the report: tag every Critical and Major
executed,
read-in-full, or inferred, and verify or demote to a Question everything left inferred.
- Read the whole source — issue body, rule, file — before making any claim about what it does not say or cover.
- Type-check every non-trivial suggestion block before posting it.
- Take line numbers from the source file at the head SHA, not from a saved diff.
- Verify every changed behavioral comment and claim — including JSDoc, test names/comments, examples, documentation,
and the PR description — against the final source and test execution before reporting. Never rely on text that may
describe an earlier revision; report the actual final behavior and identify stale wording explicitly.
- Prefer fixing existing methods over adding new ones when they overlap (DRY).
- Push back when a CLI flag description leaks command-specific context — flags belong to the whole CLI.
- Ask "is this a workaround?" whenever the change adds polling loops, sleep/wait, or
kubectl exec of imperative shell
sequences against application state.
- Flag any
.github/ script that isn't TypeScript or lacks an SPDX header.
- Flag any binding of
main to an alpha / rc / -snapshot upstream version.
MUST NOT
- Submit the review. Never POST
/reviews/<id>/events and never set event on the review-create
call. The user submits. Phrasing like "Approve", "Request changes", or "Comment" belongs in the
summary body for the user to choose from — the skill never makes the submit call itself.
- Let a report-level "what I verified locally" framing vouch for claims you did not individually test. Findings that
rode in on a neighbouring finding's evidence are the ones that get retracted.
- Report a finding first observed in a knowingly contaminated environment without reproducing it cleanly — including
one you already suspected was an artifact. If you wrote down the confound, that is the finding to drop.
- Block on personal style preferences when a linter or formatter already enforces (or doesn't enforce) the choice.
- Repeat the same comment on every occurrence — leave one comment with "applies in N other places" and list them.
- Demand renames or refactors in files the PR didn't otherwise touch.
- Wave through an exported function just because the module already has others.
export function …
or export const fn = () => … at module scope is a Major finding every time — cite §10.3.1 and the
solo/no-exported-function lint rule (a hard error under src/integration/**, a warning elsewhere).
The "local pattern" leniency applies only to exported constants, types, and simple factories
(pure data), which §3.4.5 explicitly permits — never to behavior functions.
- Post findings as standalone PR comments (
gh pr comment), issue comments, or one-off review
comments outside the pending review — every comment must ride along with the single review.
1---2name: solo-pr-review3description: Review a Solo pull request the way the Solo Team reviews — enforce Solo's TypeScript style guide, DRY/SOLID, class-with-static-methods discipline, generic CLI flag descriptions, error-handling consistency (KubeApiResponse.throwError), backwards compatibility, default-storage-class style fallbacks, cross-platform (Windows) safety, user-experience-first defaults, and root-cause-over-workaround thinking. Use when the user asks to review a PR, a branch, a diff, or a file change set in the hiero-ledger/solo repo. Triggers on "review this PR", "PR review", "review the diff", "review my branch", "look at PR4license: Apache-2.05---67# Solo PR Review89Review pull requests in `hiero-ledger/solo` the way the Solo Team reviews them. This skill encodes the conventions10enforced repeatedly across the project so reviews stay consistent whether they're authored by a human or generated here.1112## When to use1314- The user supplies a PR number, PR URL, branch name, commit range, or file list and asks for a review.15- The user asks "what would you flag in this change?", "review my branch", or similar.16- The user is the PR author preparing to push and wants a self-review pass.1718Do **not** use for: greenfield architecture proposals (use `architecture-designer`), security-only audits (use19`security-review`), or generic non-Solo TypeScript reviews (use `code-reviewer`).2021## Required reading before reviewing2223Open these before writing any feedback. They are the rulebook — the review must cite them when something is off.2425| File | What it owns |26|----------------------------------------------|-------------------------------------------------------------------|27| `docs/contributing/typescript-code-style.md` | The full TS style guide (DRY/SOLID, naming, imports, types, etc.) |28| `CLAUDE.md` | Project-level conventions and gotchas (flags, env vars, etc.) |29| `eslint.config.mjs` | Enforced lint rules (errors, not warnings) |30| `.prettierrc.json` | Formatting (120 col, single quotes, etc.) |3132## Core workflow33341. **Establish intent.** Read the PR description (and any linked issue) and state the goal in one sentence. If the goal35 is unclear, stop and ask the author — do not guess.362. **Inventory the diff.** List every file changed and group them: source, tests, workflows, docs, examples, generated.37 Note the size of each group. Big diffs that touch many groups warrant a structural pass before a line pass.383. **Structural pass.** Walk the checklist in `references/solo-review-checklist.md`. This catches the recurring issues (39 DRY violations, exported functions, generic-flag wording, error-handling drift, missing Windows support, etc.) before40 getting into line-by-line nits.414. **Line pass.** Read the actual diff. For each finding, decide:42 - **Critical** — bug, security issue, data loss, broken backwards compatibility, build/CI break.43 - **Major** — design/architecture issue, DRY/SOLID violation, missing default behavior, cross-platform regression,44 drift from existing patterns.45 - **Minor** — naming, comment hygiene, suggestion-block one-liners.46 - **Question** — something that looks off but might have a reason. Ask before claiming.475. **Comment-to-implementation pass.** For every changed behavioral comment, JSDoc, test name/comment, example,48 documentation claim, and PR-description assertion, trace the claim to the final source and test behavior. Confirm49 that APIs, control flow, process boundaries, logging, configuration propagation, and claimed coverage are exactly50 what the text says. Treat wording left over from an earlier commit or implementation as a finding — not as reliable51 context — and distinguish a documentation-only mismatch from behavior that is actually broken or concealed by the52 stale wording.536. **Test pass.** Are there tests? Are they unit (cheap, fast) or did the author reach for E2E/nightly when a unit test54 would do? Do the tests execute the behavior their names and the PR description claim they cover? Flag missing or55 overstated unit coverage explicitly.567. **Verification ledger.** Before writing anything, tag every Critical and Major with the evidence actually behind it:57 - **executed** — you ran a command and read its output. Quote the load-bearing lines in the finding itself.58 - **read-in-full** — you read the entire file, issue, or rule the claim depends on.59 - **inferred** — you reasoned from the diff without running or fully reading anything.6061 Verify or demote every `inferred` finding. A Question the author can answer costs a round-trip; an assertion they62 can refute costs the whole review its credibility. Evidence attaches to an individual claim, never to the report —63 a "what I verified locally" section does not vouch for the claims next to it. Traps that have each produced a64 retracted finding:65 - **Negative claims** ("issue N does not cover this", "this env var is undocumented", "the rule bans this here")66 require reading the whole source. A positive claim needs one witness; a negative claim needs an exhaustive read.67 Never assert what a document does not say from a truncated read.68 - **Suggestion blocks are one-click-appliable.** Type-check any non-trivial code before posting it. A suggestion69 that fails `tsc`, or an invented API that fails open rather than erroring, is worse than no comment.70 - **Line numbers** come from the source file at the head SHA, never from a saved diff — the coordinate systems71 differ, and a wrong anchor makes a correct finding look careless.72 - **Contaminated environments.** A worktree with a symlinked or stale `node_modules`, a warm cache, or a73 non-default toolchain invalidates any finding about dependency resolution, caching, or build behavior.74 Reproduce cleanly or drop it.75 - **Rule citations.** Re-read the scope line of every rule you cite — which paths it covers, whether it is an76 error or a warning. Citing a rule you have misread is worse than citing nothing.778. **Write the report.** Use the template in §Output. Lead with the critical/major findings; line-level suggestion78 blocks come after.7980> **Checkpoint:** before delivering the report, re-read it and ask: *"If I were the author, would I be able to act on81> every comment without another round-trip?"* If not, tighten the wording or add a code example. Then ask: *"Which82> findings would survive the author pushing back with a command output?"* Anything that would not survive is not83> ready to post.8485## Reference guide8687Load these on demand — don't paste them into the report.8889| Topic | File | Load when |90|--------------------------------|------------------------------------------------|---------------------------------------------------------------|91| Solo-specific review checklist | `references/solo-review-checklist.md` | Always — this is the structural-pass driver |92| Feedback voice and format | `references/solo-maintainer-feedback-style.md` | Always — covers tone, suggestion blocks, root-cause questions |9394## How to fetch the diff9596```bash97# Metadata only — small, cheap, do this first98gh pr view <number> --json title,body,headRefName,baseRefName,headRefOid,files,additions,deletions,author,state,url99100# Full diff (large for big PRs — paginate via Read once it's persisted)101gh pr diff <number>102103# Per-file diff (preferred when you already know which files matter)104gh pr diff <number> -- <path>105106# By branch (when working locally on the author's branch)107git diff origin/main...HEAD108git diff origin/main -- <path>109```110111For URL-only inputs, parse the PR number out of the URL and use `gh pr view` / `gh pr diff`.112113**Token-efficiency tips:**114115- `gh pr view --json files` returns the file list with line counts — use it to decide which files to fetch full diffs116 for, instead of pulling the whole PR diff up front.117- For exact line numbers in *inline-comment-anchor positions*, prefer `gh pr diff <num> -- <path>` over fetching the118 entire file via `gh api .../contents/...`. The diff already shows line numbers on the RIGHT side.119- Only fetch a full file via `gh api 'repos/<owner>/<repo>/contents/<path>?ref=<sha>' --jq '.content' | base64 -d` when120 you genuinely need surrounding context the diff doesn't show.121- When iterating over multiple lookups, batch them into a single Bash call (one shell, multiple `gh api` invocations)122 rather than separate tool calls.123124## How to post the review125126**Always post feedback as a single PR review — never as standalone PR or issue comments.** Every127finding (summary verdict and inline line comments) must be attached to one review so the author can128resolve them in one round-trip.129130**Critical behavior: leave the review in PENDING state. Never submit it.** The human reviewer131will read the queued comments in the GitHub UI, edit if needed, and submit themselves. Submitting132automatically would post a review attributed to the human without giving them a chance to vet it.133134### The single-POST flow (preferred)135136POST one review with all inline comments embedded and **no `event` field** — that creates the review137in `PENDING` state with every comment attached. This is one HTTP call and avoids the138"user_id can only have one pending review per pull request" failure that hits the multi-step flow139when a pending review already exists.1401411. **Check for an existing pending review.** If one exists for the current reviewer, delete it142 before starting fresh (the single-POST flow can't merge into an existing pending review):143144 ```bash145 existingId=$(gh api "repos/<owner>/<repo>/pulls/<number>/reviews" \146 --jq '.[] | select(.user.login == "'"$(gh api user --jq .login)"'" and .state == "PENDING") | .id')147 if [[ -n "${existingId}" ]]; then148 gh api -X DELETE "repos/<owner>/<repo>/pulls/<number>/reviews/${existingId}"149 fi150 ```1511522. **Write the review payload to a file.** JSON shape:153154 ```json155 {156 "commit_id": "<head SHA from gh pr view headRefOid>",157 "body": "<§Output-template summary as a single markdown string>",158 "comments": [159 {160 "path": "<file path>",161 "line": <line number on RIGHT side of the diff>,162 "side": "RIGHT",163 "body": "<comment, suggestion blocks OK>"164 }165 ]166 }167 ```168169 **Do not include an `event` field.** Its absence keeps the review in `PENDING` state.1701713. **POST the review:**172173 ```bash174 gh api -X POST "repos/<owner>/<repo>/pulls/<number>/reviews" --input review-payload.json175 ```176177 The response includes `"state": "PENDING"` and an `html_url` pointing to the review on GitHub.1781794. **Tell the user what to do next.** End the turn with a short message that:180181- Links to the pending review (`html_url` from the response).182- States that the review is queued in PENDING state with N inline comments + summary.183- Asks them to open it in GitHub, vet/edit the comments, and choose **Comment**,184 **Approve**, or **Request changes** themselves.185- Does **not** call any API to submit, dismiss, or otherwise change the review state.186187### What never to do188189- **Never** POST `/reviews/<id>/events` with `event=COMMENT`/`APPROVE`/`REQUEST_CHANGES` —190 that submits the review. The user submits, not the skill.191- **Never** include an `event` field on the initial review POST for any value other than192 omitting it. (`event=PENDING` is rejected as an invalid enum value.)193- **Never** use `gh pr comment`, `gh pr review --body`, or POST to `/issues/<n>/comments` —194 those create orphan comments outside the review thread.195- **Never** start a second pending review when one already exists. Delete the old one first196 (step 1) or the POST fails with HTTP 422.197198## Output template199200```markdown201## Intent202203<one-sentence recap of what the PR is trying to do>204205## Verdict206207<Approve | Request changes | Comment>208209## Critical210211- <issue> — `path/to/file.ts:LINE` — <why it blocks merge> <code example if useful>212213## Major214215- <issue> — `path/to/file.ts:LINE` — <why> <suggestion>216217## Minor218219- <issue> — `path/to/file.ts:LINE` — <suggestion>220221## Questions for the author222223- <question that needs an answer before this can be Approved>224225## Comment and description consistency226227- <State that each changed behavioral claim was checked against the final implementation, or list the stale/mismatched228 claims with their source and actual behavior.>229230## Positive231232- <specific thing done well — be concrete, not generic>233234## Companion work235236- solo-docs PR: <linked / missing / N/A>237- solo-containers PR: <linked / missing / N/A>238```239240Use GitHub suggestion blocks (` ```suggestion ` … ` ``` `) for any single-line or small-block edit — they let the author241one-click apply.242243## Constraints244245### MUST246247- Post the review as a single PR review in **PENDING** state, with every inline finding attached248 as a review comment and the summary verdict as the review body.249- End the turn by linking the pending review and asking the user to vet and submit it themselves.250- Cite the rule being applied (style-guide section, eslint rule, or prior PR convention) for every Critical and Major251 finding, having re-read that rule's scope line rather than recalling its gist.252- Run the verification ledger (workflow step 7) before writing the report: tag every Critical and Major `executed`,253 `read-in-full`, or `inferred`, and verify or demote to a Question everything left `inferred`.254- Read the whole source — issue body, rule, file — before making any claim about what it does **not** say or cover.255- Type-check every non-trivial suggestion block before posting it.256- Take line numbers from the source file at the head SHA, not from a saved diff.257- Verify every changed behavioral comment and claim — including JSDoc, test names/comments, examples, documentation,258 and the PR description — against the final source and test execution before reporting. Never rely on text that may259 describe an earlier revision; report the actual final behavior and identify stale wording explicitly.260- Prefer fixing existing methods over adding new ones when they overlap (DRY).261- Push back when a CLI flag description leaks command-specific context — flags belong to the whole CLI.262- Ask "is this a workaround?" whenever the change adds polling loops, sleep/wait, or `kubectl exec` of imperative shell263 sequences against application state.264- Flag any `.github/` script that isn't TypeScript or lacks an SPDX header.265- Flag any binding of `main` to an `alpha` / `rc` / `-snapshot` upstream version.266267### MUST NOT268269- **Submit the review.** Never POST `/reviews/<id>/events` and never set `event` on the review-create270 call. The user submits. Phrasing like "Approve", "Request changes", or "Comment" belongs in the271 summary body for the user to choose from — the skill never makes the submit call itself.272- Let a report-level "what I verified locally" framing vouch for claims you did not individually test. Findings that273 rode in on a neighbouring finding's evidence are the ones that get retracted.274- Report a finding first observed in a knowingly contaminated environment without reproducing it cleanly — including275 one you already suspected was an artifact. If you wrote down the confound, that is the finding to drop.276- Block on personal style preferences when a linter or formatter already enforces (or doesn't enforce) the choice.277- Repeat the same comment on every occurrence — leave one comment with "applies in N other places" and list them.278- Demand renames or refactors in files the PR didn't otherwise touch.279- Wave through an exported **function** just because the module already has others. `export function …`280 or `export const fn = () => …` at module scope is a Major finding every time — cite §10.3.1 and the281 `solo/no-exported-function` lint rule (a hard **error** under `src/integration/**`, a warning elsewhere).282 The "local pattern" leniency applies **only** to exported **constants, types, and simple factories**283 (pure data), which §3.4.5 explicitly permits — never to behavior functions.284- Post findings as standalone PR comments (`gh pr comment`), issue comments, or one-off review285 comments outside the pending review — every comment must ride along with the single review.