# Findings

URL: https://codepanel.ai/docs/findings

What a finding contains: severity, location, evidence, its F-ref and status across rounds, and how to dismiss, reopen or apply one.

A finding is one problem the panel reports on a pull request, written for the coding agent that will act on it. It closes when a later round no longer reports it, or when it is dismissed. How to rate, dispute or ask about one is in [Feedback and disputes](/docs/feedback).

## Severity

| Severity | Meaning | Merge gate, at the default level |
| --- | --- | --- |
| `critical` | A defect that should block the merge | Blocks until fixed or answered |
| `warning` | A likely problem worth fixing, or answering with evidence | Blocks until fixed or answered |
| `suggestion` | An optional improvement | Blocks only at gate level `all` |

Findings are listed most severe first. Gate levels are on the [Merge gate](/docs/merge-gate) page.

## Location

Each finding names a file and, when it can, a line or line range in the new version of that file. Reviewers read line numbers from a gutter printed beside each diff line, and the orchestrator corrects lines it can check against the code. A finding about a whole file, or about a test that does not exist, may have no line.

The posted comment shows the location as `path:line` or `path:line-endLine`, and its header names the commit those line numbers refer to (`reviewedSha` in the payload). When this round's diff shows the lines around a finding, the comment quotes them. On the review page, the location links to that line on GitHub. Each finding also records which reviewers reported it; the review page shows them, and the posted comment names the panel once, in its footer.

## One finding, several places

When the same defect appears in several places, such as three mutations that each skip the same ownership check, CodePanel can report it once, at the first place, and list the others under "Also at", in the comment and in each inline comment. The payload's `instances` lists them as `{file, line}`. This is off unless CodePanel turns it on (`REVIEW_FINDING_INSTANCES`, a CodePanel setting); without it, `instances` is empty.

- **Fix every place.** The places are grouped for reading only. A round resolves the finding only once it has re-examined every place and found each one changed or gone, so fixing one copy never clears the others from the merge gate.
- **Fixed places drop off.** When a round sees some places changed and others not, the finding stays open, keeps its ref, and moves to the first place still open; the comment lists only what is left.
- **Rate it once.** A rating or dismissal answers the whole finding, every place with it. If one listed place is wrong or intended, rate the finding as usual and say which place in the note; there is no per-place rating.
- **Only code the orchestrator was shown.** It lists only places in files it read that round, so a copy elsewhere in the repository may not be listed.

## Evidence

Every finding has a message and often a suggested fix. Three more kinds of evidence are off unless CodePanel turns them on, because in the eval they did not change how many defects a review caught and they made each round dearer. Without them a finding has no `Trigger:`, `Check:` or `Patch:`, and the payload fields are `null`.

| Evidence | Shown as | Payload field | Turned on by |
| --- | --- | --- | --- |
| Failure scenario: the input or sequence that triggers the problem, and what goes wrong for whom | `Trigger:` | `failureScenario` | `REVIEW_FAILURE_SCENARIOS` |
| Check: a test to write, command to run or call to make that confirms the problem | `Check:` | `verify` | `REVIEW_FAILURE_SCENARIOS` |
| Patch: a unified diff against the file at the reviewed commit | `diff` block under `Patch:` | `patch` | `REVIEW_PATCHES`, or the repository's [inline suggestions](#inline-suggestions) |

The variables are CodePanel settings, not repository settings.

- **Failure scenarios.** With them on, every `critical` or `warning` finding carries one. When the orchestrator cannot give one, it demotes the finding to `suggestion`, so a warning always says what fails. A check lets an agent confirm a finding without taking the reviewer's word for it; one it cannot confirm is grounds to rate it down.
- **Patches.** Only for a `critical` or `warning` with a short, local fix, in a file the orchestrator was shown whole (24,000 characters or less). CodePanel keeps a patch only if every hunk applies cleanly, and stores it with standard headers and corrected line numbers, so `git apply` takes it as is. A patch that does not apply is dropped and the finding kept. A patch changes at most 40 lines, and a round keeps at most 6. It is a reviewer's proposal: read it before applying it.
- **Unfiltered rounds.** If the orchestrator could not run, the reviewers' findings are posted unfiltered with their own scenarios and checks, and none is demoted.

## Refs and statuses

Every finding gets a ref when it is first stored: `F1`, `F2`, `F3`. The ref stays the same across rounds, and the posted review, the [API](/docs/api), the [CLI](/docs/cli) and the [MCP server](/docs/mcp-server) all use it. CodePanel does not use `#3`, because GitHub links that to an issue.

| Status | In the API | Meaning |
| --- | --- | --- |
| New | `new` | First reported in this round |
| Still open | `persisting` | Reported in an earlier round and still present |
| Resolved | `resolved` | A round re-examined the code and did not report it again |
| Dismissed | `dismissed: true` | Closed by a person, a rebuttal or a withdrawn dispute |

The comment header counts them, for example "3 open (1 critical, 2 warning, 1 new) · 2 resolved since the last review". Round 1 shows only the open counts. From round 2, each finding's heading says "new" or "open since round N".

## Tracking across rounds

When only suggestions are open and the gate level is not `all`, the comment adds "Only suggestions are open": rate each one with `/feedback` and fold any fix into a commit you were pushing anyway, rather than pushing a commit for suggestions alone. Every push starts another round. From the third round, a **Step back:** line counts the findings first reported after round 1 and advises reconsidering the approach ([Round limits](/docs/triggering-reviews#step-back)).

A round resolves a finding only if it could have seen it. In an incremental round, that means its reviewers were shown the finding's line: inside a changed hunk, or inside the code shown around the changes, which is the whole file when the file is small. A finding in a file the push did not touch stays open. A fixed finding that comes back later is reported as new.

<details>
<summary>Edge cases</summary>

- A fix made elsewhere in a small file still closes the finding, because reviewers see the whole file and are told to re-report a finding they can still see.
- In a large file, only the lines shown around the changes count.
- If a reviewer failed that round, only the changed hunks count.
- A finding with no line counts as re-examined when its file changed.

</details>

## Dismiss a finding

Dismiss a finding that is wrong or that you will not fix here. Do not dismiss one you fixed: rate it `up fixed` and the next round resolves it. A coding agent that says a finding is wrong [disputes](/docs/feedback#disputes) it instead of dismissing it.

| From | How | Who |
| --- | --- | --- |
| The review page | **Dismiss**, then pick a reason | The repository owner |
| The pull request | `/feedback F3 down <reason>` with a rebuttal reason, or `deferred` either way ([verdict reasons](/docs/feedback#verdict-reasons)) | People with write access replying as themselves (`deferred` also with `--agent`) |
| API | `POST /api/v1/findings/dismiss` without `agent` | A token with `reviews:write` |
| CLI | `codepanel findings dismiss <findingId>` | As the API; with `CODEPANEL_AGENT` set it disputes |
| MCP | `dismiss_finding` | Always names the agent, so it disputes |

| Reason | API value | Use it when |
| --- | --- | --- |
| False positive | `false_positive` | The problem is not real |
| Wrong location | `wrong_location` | The issue exists, but the line or file is wrong |
| Not worth fixing | `not_worth_fixing` | It is real, but you will not act on it |
| Duplicate | `duplicate` | Another finding already covers it |
| Deferred | `deferred` | It is real, and will be handled outside this pull request |
| Other | `other` | None of the above |

A dismissed finding:

- Stops counting toward the merge gate immediately.
- Leaves the posted comment the next time a round rewrites it. Dismissing does not edit the comment.
- Stays closed. A later round that reports it again is suppressed (below).

The review page always asks for a reason; the API treats it as optional. Dismissing an already dismissed finding only updates the reason.

## Suppressed re-reports

When a later round reports a dismissed finding again, it stays closed, and the round says so:

- The posted comment carries one line naming each such finding, who dismissed it and why, for example: "2 findings dismissed earlier were reported again and not reopened: F3 (false-positive, by claude-code), F7 (deferred, by alice)." The line also gives the command that reopens one.
- The payload (`get_review`, `GET /api/v1/review`, `codepanel review --json`) lists each under `suppressed`: its ref, the round and commit of the latest re-report, and the dismissal it kept (`reason`, `by`, `via`, `at`, and the orchestrator's reason when a withdrawn dispute closed it).

Suppressed findings do not count toward the verdict or the merge gate. A finding leaves `suppressed` once a later round re-reads its code and does not report it.

## Reopen a finding

| From | How |
| --- | --- |
| The review page | **Undo dismiss** |
| API | `POST /api/v1/findings/reopen` with `repo`, `pr` and `ref` (`F3`), or `findingId` |
| CLI | `codepanel findings reopen <owner/name#123> F3` |
| MCP | `reopen_finding` |

The finding comes back open with its dispute cleared, and the next round that re-examines it closes it if it was fixed. Reopening one that is not dismissed changes nothing and returns `reopened: false`. Any token with `reviews:write`, an agent's included, may reopen. No `/feedback` reply reopens a finding: rating it `up` leaves it closed. The posted comment is not rewritten when you reopen; the next round shows the finding as open.

## Inline suggestions

An optional second view of the review for people reading the diff, off by default. When a repository turns on **Inline suggestions**, each round also posts a GitHub review whose comments sit on the changed lines: one per open `critical` or `warning` finding whose patch is a single replacement of lines the diff shows. Each holds the finding's ref, severity and one-line problem, and the patch as a GitHub suggestion that applies with one click. The patch is model output, so check it before applying.

- **Patches.** Turning inline suggestions on asks the orchestrator for patches on that repository's rounds, even when the deployment leaves `REVIEW_PATCHES` off. Patches make a round about 22% dearer in the eval, and they then also appear in the summary comment and the payload.
- **The summary comment stays the review.** The verdict, every finding and the data agents read are there. A patch that spans several places, only inserts lines, or touches lines outside the diff gets no inline comment. At most 20 are posted per round.
- **One comment per finding across rounds.** A later round that changes the finding edits its comment; if the code under it moved, the suggestion is replaced by a note to read the summary comment. When the finding is resolved or dismissed, its thread is resolved, or, if GitHub refuses, the comment is edited to say so.
- **Replies.** `/feedback up fixed` or `/feedback down false-positive <why>` in the thread rates that finding, and `/ask <question>` asks about it, with no ref needed ([commands](/docs/commands#feedback)). Some repositories need their webhook updated first ([Triggering reviews](/docs/triggering-reviews#inline-suggestion-threads)).
- **Never fails a round.** If GitHub refuses the comments, the review is unaffected and the reason goes to the deployment's logs.

Turn it on in the repository's **Settings** tab, with `inlineSuggestions` in `POST /api/v1/repos/settings`, `codepanel repos set <owner/name> --inline-suggestions on`, or the MCP tool `update_repo_settings`.

## Copy a review into an agent

The posted GitHub comment is already written as a prompt for a coding agent: it opens with instructions to fix the open findings and rate them with `/feedback`, then lists each finding once with its ref. When the merge gate is on, it also says the pull request is not done until each gated finding is fixed or answered. The format is described in [How it works](/docs/how-it-works).

Each review page also has two buttons:

- **Copy as Markdown** copies the review as formatted text.
- **Copy for a coding agent** copies a prompt listing the open findings by severity, each with its location, problem and suggested fix, and tells the agent to keep each change minimal and run the tests afterward.

To read findings as data instead, see [The review loop](/docs/agents).
