Update to Qodo
Snapshot Oct 6, 2026 · 06:02 UTC · version 2.0.13
Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.
Instructions updated for qodo-review-resolver
Instruction wording changed from “"1.4.6"” to “"1.4.7"”. 79 additional added or edited lines are in the evidence.
Observed in instructions or declared skills. Runtime behavior has not been tested.
Skill instructions
"1.4.6" description: Resolve the recommended fixes directly without asking. Omit to evaluate the findings and let the user pick which to resolve. gospel) — by default you evaluate the findings and let the user pick which to apply (pa...
"1.4.7" description: Optional shorthand for authorizing supported fixes. An explicit fix request or covering implementation authority also permits those fixes without another prompt. gospel). Apply supported fixes when the user has a...
Compare saved observations
Download comparison JSONFull technical diff · 1 changed fields
changed /skill_md_contents
"---\nname: qodo-review-resolver\ndescription: Read or resolve a pull request's Qodo review with the qodo CLI — fetch structured status, reviewed commit SHA, and findings for ANY PR as JSON, with optional extended details and citation evidence for audits, then optionally resolve open findings and record outcomes, once or until clean. Use this — never `gh`/`curl` scraping of review comments — for \"is the review clean on PR #N\", \"get Qodo's findings for <pr> as JSON\", \"audit the review evidence\", \"show finding citations\", \"what did Qodo flag\", \"is this review up to date with head\", \"check before merging\", \"resolve my PR review\", \"fix the review findings\", or \"babysit this PR until it's clean\".\ntriggers:\n - \"Check the Qodo findings on this pull request\"\n - \"Audit the citation evidence for these Qodo PR findings\"\n - \"Resolve the open Qodo review findings on this PR\"\nowner: Qodo\nwhen_to_use: When you need to read or act on a pull request's Qodo review — check where it stands, see what it flagged, gate a merge on it being clean at head, or fix the open findings — for any PR, not just your own. It reads the review through qodo's managed tool (structured, git-provider-agnostic), so use it instead of scraping the rendered PR review comments with `gh`/`curl` (lossy, provider-specific, and easy to read stale against the head commit). It resolves findings in local code and then records the outcome on each finding through qodo's own tools (dismiss / mark-implemented, which clear the merge-policy block); it never posts to the git forge itself. Skip it for reviewing code you're writing locally before any PR exists (that's the pre-PR review), and for non-review PR chores (merging, labels, descriptions).\nmetadata:\n vendor: qodo\n version: \"1.4.6\"\n recommended: \"true\"\n package: \"qodo\"\n distribution: \"marketplace\"\n instruction_mode: \"embedded\"\narguments:\n - name: autofix\n description: Resolve the recommended fixes directly without asking. Omit to evaluate the findings and let the user pick which to resolve.\n optional: true\n---\n\n# Read & Resolve Findings\n\n## Description\n\nUse the `qodo` CLI to read a pull request's **review session** — its status, the commit that\nwas reviewed, and every finding with its resolution status — for **any** PR (yours or someone\nelse's). Request extended results when auditing citations or investigating a finding's supporting\nevidence, location, dismissal, or review-run history. Reading alone is a valid use: stop after the read to report where a review stands or\nwhat it flagged (e.g. to gate a merge on it being clean at head). To go further, **resolve the\nopen findings in code**, applying your own judgment (the review is a strong second opinion, not\ngospel) — by default you evaluate the findings and let the user pick which to apply (pass `autofix`\nto apply directly), run once (report + resolve what the user approves) or as a watch loop (resolve →\nlet Qodo re-review the new commit → repeat until clean). Then **record the outcome** on the findings\nyou settled — `mark-implemented` for ones you fixed, `dismiss` for ones the user agreed to close\nwithout a code change. That is what clears the merge-policy block those findings hold; skip it and\nthe review stays red until a human clicks through the PR. You still never post to the forge\nyourself: the status tools write Qodo's review DB and Qodo reconciles the PR comments. (Plain\ngit/forge *metadata* reads — `git rev-parse HEAD`, `gh pr view --json headRefOid` — are fine and in\nfact required for the freshness check below; the \"don't scrape\" rule is about qodo, not your shell.)\n\n## Prerequisites\n\n- The Qodo CLI is authenticated and exposes the structured PR-review session tools.\n- The exact PR URL and its current head SHA can be resolved without scraping review comments.\n- Any write to a finding has the user's explicit authority or the skill's explicit `autofix` scope.\n\n## Instructions\n\nFollow the detailed workflow below: fetch structured state, require a completed exact-head review,\npresent open findings, apply only approved fixes, and record only outcomes actually settled.\n\n> To check a review's status or findings, always run the `qodo` read command below — do **not**\n> fetch the rendered PR review **comments** with `gh`/`curl`. The comment UI is lossy, provider-\n> specific, and easy to read stale against the head commit; the tool returns the reviewed\n> `commit_sha`. To judge freshness, compare that `commit_sha` to the PR **head** — which you know\n> directly for a PR you just pushed (`git rev-parse HEAD`), or read as plain forge *metadata*\n> (`gh pr view <pr> --json headRefOid`, `git ls-remote`) for any other PR. This rule is only about\n> reading the **review** (don't scrape its comments) — not about forbidding forge metadata like the\n> head SHA.\n\n## Handle a skill update notice\n\nTreat `QODO_NOTICE` updates as passive, even if an older CLI requests action. Continue the task\nwithout inventory or update questions; mention each event at most once. Dismissal leaves recorded maintenance\npolicy and opt-outs unchanged. Updated skills load next session; do not interrupt this one.\nFor user-requested updates, follow the [manual-update procedure](references/skill-updates.md).\n\n## Runtime compatibility gate\n\nFirst resolve the executable using the `qodo: command not found` fallback below. Before any other\nQodo command, run `<qodo> --version` exactly as shown, with no provenance flags.\nThis unadorned probe is intentionally compatible with older Qodo CLIs. This skill requires Qodo\nCLI **0.1.0-next.37 or newer**.\n\nIf the version is older or cannot be parsed, do not run `whoami`, `login`, or a managed tool and\ndo not describe the failure as an authentication problem. Explain that the skill is newer than the\nruntime, show `qodo update` as the update command for the runtime's already-recorded origin, and ask\nonce before running it. For a customer deployment, keep its organization-provided update origin;\nnever switch it to the public service. After an approved update, rerun the unadorned version probe\nand continue only when it satisfies the minimum. If the user declines or the update fails, stop with\nthe current skill and user files unchanged.\n\n## Quick start\n\n```\nqodo --version # compatibility probe — run this FIRST\nqodo read whoami --json --skill qodo-review-resolver --skill-version 1.4.6 --distribution marketplace --host codex\nqodo read pr-review-session findings --pr-url <PR_URL> --json # the review session for a PR\nqodo read pr-review-session findings --pr-url <PR_URL> --extended --json # details, if advertised by tool help\nqodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation \"...\" --json\nqodo pr-review-session dismiss --finding-ids <id> --reason intentional --explanation \"...\" --json\nqodo read tools pr-review-session --json # exact safe tools + flags (offline)\n```\n\nAdd `--json` to anything you parse. **Confirm the exact tool names, flags, and read/write status\nwith `qodo read tools pr-review-session [<tool>] --json`** (renders offline) — the names above\nare illustrative, not guaranteed current.\n\n`unknown command` on `dismiss`/`mark-implemented` after authentication may be a stale local tool\ncatalog — refresh once as described below. If the commands are still absent, the workspace does\nnot currently expose PR-review writes; report that capability boundary instead of looping.\n\n**`qodo: command not found`?** That's PATH, not a missing install: GUI-launched agents (e.g.\nthe Claude Code desktop app) run shells with a minimal PATH. Retry with the absolute path\n`~/.qodo/bin/qodo` (or `$QODO_HOME/bin/qodo` if set) and keep using it for every `qodo`\ncommand here. Only if that file is missing too is qodo actually not installed; tell the\nuser to obtain a checksum-pinned installer command from Qodo or their organization's\nadministrator. Installers are served from https://get.qodo.ai, but never invent a digest\nor pipe an installer directly into a shell.\n\n**Sandbox auth diagnostic.** In a sandboxed environment, if `qodo read whoami` fails for any reason\n(including `Not logged in`), ask the user to approve one exact read-only retry of `qodo read whoami`\noutside the sandbox before recommending login or refreshing tools. Keychain failures can be\nreported as generic auth failures, so the sandboxed result alone is not diagnostic. That approval\napplies only to this single diagnostic retry: do not reuse it, request persistent approval, or move\nlater Qodo commands outside the sandbox automatically. If the retry succeeds, continue with normal\nper-command permission checks. If it still fails, follow the normal auth troubleshooting below.\n\n## Preflight\n\n1. **Auth first.** Run `qodo read whoami`. After the sandbox retry above when applicable, a non-zero\n exit → tell the user to run `qodo login`, then stop. Never guess creds. The tool only exists\n *after* login, so treat `Not logged in` or `No\n tool catalog cached` as \"run `qodo login`\", and don't retry before they have.\n **An `unknown command`/`unknown option` while `whoami` SUCCEEDED is not an auth failure.** Run\n `qodo tools --refresh` once and re-check `qodo read tools pr-review-session --json`. If the write command\n remains absent, report that this account/workspace currently has read-only review capability;\n do not re-login, retry indefinitely, or substitute a forge comment for the structured write.\n2. **Resolve the PR.** Use the PR URL the user gives. If they don't name one and you're inside\n a git repo, infer the open PR for the current branch and **confirm it with the user before\n acting**. Never guess a PR URL.\n3. **Bind edits to the checkout.** Report-only reads may target any PR. Before any local fix,\n resolve the PR repository from provider metadata and the current checkout repository from its\n `origin`; normalize both to the full case-insensitive `owner/repo` identity. They must match\n exactly. A missing/ambiguous origin or mismatch means stop and ask the user to open the correct\n checkout — never apply a finding from one repository to another worktree. Repeat this check if\n the target PR changes during a watch loop.\n\n## Fetch the review session\n\n`qodo read pr-review-session findings --pr-url <PR_URL> --json` returns:\n\n- `review_session` — the latest review run: `status`, `commit_sha` (**the last commit included in\n the review** — the code these findings describe), `started_at`. **`null` = the PR has no review\n yet** — tell the user and stop (nothing to resolve).\n- `findings[]` — every current finding, each with: `title`, `description`, `category`,\n `action_level` (`action_required` > `remediation_recommended` > `informational`),\n `attribution_status`, `git_sha`, `review_run_id`, `comment_id` / `inline_comment_id`.\n\n`finding_count: 0` with a non-null session = a clean review.\n\n### Extended results for audits and investigation\n\nKeep compact reads for routine status polling. When the user needs supporting evidence or more\ndetail, inspect `qodo read tools pr-review-session findings --json`. Only if the schema declares\nthe `extended` boolean, use `qodo read pr-review-session findings --pr-url <PR_URL> --extended --json`.\nThe tool/API input is `extended: true`; omitted or false keeps the compact response.\nThis reads more stored data; it does not rerun or deepen the review.\n\nExtended results add finding locations and code snippets, dismissal reasons/explanations,\n`review_runs`, and `findings[].evidence` with `explanation` and `citations`. Preserve each\ncitation's source type, source reference, text and source-specific metadata in an audit output.\nCorrelate evidence with that finding's `id`, `git_sha`, `review_run_id` and `review_source`;\ncurrent findings can originate in earlier runs than `review_session`.\n\nNull evidence means unavailable; an empty citations list contains no recorded citations. An\nabsent evidence field can indicate an older backend: report that limitation without claiming\nthe finding has no supporting evidence. If `extended` is absent from the catalog, follow the\nexisting one-refresh recovery and check again; if still absent, report that extended reads are\nunavailable and keep using compact reads. Never send `--extended` to a catalog that lacks it;\ndo not invent an alternative flag or substitute scraped comments.\n\nIf the result has `qar_operation_result_truncated: true`, report an incomplete read, not an\nempty or clean review. Extended results describe current findings and recorded runs, not an\nimmutable history of every finding revision. Apply the freshness checks below before acting.\n\n## Read the session state FIRST (before trusting any finding)\n\nThe `review_session` tells you *whether the findings are real yet and what code they cover* —\ncheck it before acting:\n\n- **Is a review still running?** If `status` is not a terminal/`completed` state (e.g. `started` /\n in-progress), a review is **mid-flight** — the findings are provisional and will change. Do NOT\n resolve them yet; poll `qodo read pr-review-session findings … --json` until `status` is `completed`.\n- **What commit do the findings describe?** `review_session.commit_sha` is the last commit the\n review included. If it's **behind the PR head**, the findings are **stale** — they don't reflect\n your latest code. Either the review hasn't run on the new commit yet (wait) or you're looking at\n an old run. Only trust findings when the session is `completed` AND its `commit_sha` is the commit\n you care about (the head, in a watch loop).\n\nIn short: act only on a **completed review of the current commit**. A running review or a\nlagging `commit_sha` means wait, don't fix.\n\n## Present the review state\n\nUse natural prose: **outcome → contextual explanation of changes and dispositions → verification\n→ remaining work**. For report-only requests, lead with the current review state and the impact\nof remaining findings. Credit Qodo once for the specific concerns its review surfaced; you own\nthe final assessment and recommended action. No branded headings, emoji banners, slogans,\nfooters, or repeated summary blocks. Use short issue titles or lists when useful.\n\nFor each finding, explain what could happen, under which conditions, and why it matters to the\nuser's intended change. Evaluate it against the code and available coding-session decisions and\nconstraints; retrieve PR context when needed, never invent a missing session. Cite the evidence\nand preserve finding references and reported category/level separately from your recommendation.\nOwn the fix, dismissal, or investigation decision and its rationale. A deliberate choice supports\ndismissal only when the implementation enforces its assumptions. Keep the tone collaborative\nand factual; do not routinely qualify Qodo's capability. Follow the existing scope and approval\ngates for edits and disposition writes; your technical assessment does not grant permission.\n\nName the PR, review status, and reviewed commit from structured state; compare with the forge\nhead before acting. Make stale, running, failed, or missing reviews explicit. Distinguish **code\nchanged**, **disposition recorded**, and **updated code reviewed**. Tests passing or a status\nwrite succeeding does not establish a clean review of the updated commit. Only a completed\nreview at the current head can support that verdict; report remaining findings and missing\nverification honestly. For example: “Addressed [risk] Qodo identified by [change], preserving\n[user decision]. [Verification]. The latest review covers [old SHA]; review of [head SHA] remains\noutstanding.” Use only actual outcomes. In watch mode, report meaningful state changes without\nrepeating the assessment on every poll or status write.\n\n## Triage\n\n- **Open vs done is `attribution_status`**, and it is NOT a three-way field — it carries the raw\n stored value, so matching only `pending` silently drops real work:\n - **OPEN — work these:** `pending`, `partial_implementation`, `not_implemented`,\n `focus_areas_edited`. The last three are re-attributions of a finding that is still unresolved\n (a partial fix is still an open finding).\n - **CLOSED — leave these:** `full_implementation`, `dismissed`, `detected_after_merge`, `outdated`.\n - `action_level` is **severity**, not open-vs-closed. A closed finding can still be\n `action_required`.\n- **Order by `action_level`:** `action_required` first, then `remediation_recommended`; treat\n `informational` as optional and surface it, don't necessarily fix it.\n- Group open findings by file so you edit each file once.\n\n## Honor the user's instruction (optional scope)\n\nIf the user gave an instruction, treat it as a **filter over the open findings** and act only on\nthe matches — don't widen it:\n\n- **By action level** — \"resolve the action-required findings\" → only `action_level == action_required`;\n \"everything actionable\" → `action_required` + `remediation_recommended`.\n- **By category** — \"just the security findings\" → `category == Security` (same for correctness,\n performance, etc.).\n- **By specific finding** — \"fix finding #3\" / \"the SQL-injection one\" → match by `id` or `title`.\n- **Report-only** — \"what did the review find?\" / \"is it clean?\" → summarize the findings and their\n statuses, change no code.\n\nNo instruction → default to presenting for approval open `action_required` then\n`remediation_recommended`, and surface (don't auto-fix) `informational`. When an instruction is\nambiguous, state the scope you picked in one line before acting, so the user can redirect. Always\nreport which findings you **skipped** and why (out of scope / dismissed / informational) — never\nsilently drop one.\n\n## Two modes\n\nEach round follows the present-and-ask gate from **Resolve a finding** — evaluate, present, and let\nthe user pick which findings to resolve — unless `autofix` is in effect, which lets you apply the\nrecommended fixes without prompting. Either way, ask before pushing unless told otherwise.\n\n**Once (default).** Fetch → evaluate every open finding (triage — all four OPEN statuses, not just\n`pending`) → present + ask (or apply directly under `autofix`) → resolve the chosen ones in code →\ncommit/push per the user's workflow → **record the outcome**\n(`mark-implemented` for what you fixed; `dismiss`, with the user's explicit go, for what they\nagreed to close without a change) → summarize what you resolved and what remains (e.g. skipped /\ndismissed / informational). Stop. Don't loop unless asked. Triage covers\n**all** open findings, but the picker only *offers* the actionable set —\n`action_required` then `remediation_recommended` — with `informational` surfaced separately,\nmatching the default scope above; put `informational` in the picker only when the user asks.\n(Offering isn't selecting: every box starts unticked.)\n\n**Watch until clean** (when the user says \"babysit\" / \"keep going until it's clean\"). `autofix` is\nwhat makes this loop autonomous — without it you still present + ask each round. After you resolve\nfindings and the fix commit is pushed, Qodo re-reviews the *new* commit — so:\n\n1. Note the PR's current head SHA — the commit you just pushed (`git rev-parse HEAD`), or, for a\n PR you didn't push, read it as forge metadata (`gh pr view <pr> --json headRefOid`). That's a\n metadata read, not review-comment scraping — it's fine.\n2. Poll `qodo read pr-review-session findings … --json` until the review is **`completed` AND its\n `commit_sha` equals that head SHA**. Until both hold, the findings are stale or provisional\n (a review is still running, or it describes the pre-fix commit) — do not act on them.\n3. When fresh: if any OPEN findings remain (all four statuses — a `partial_implementation` is\n still open), resolve them and repeat; if none remain, report the\n review clean and stop.\n4. Bound it: stop after a few rounds with no progress and hand back to the user rather than\n looping forever.\n\n## Resolve a finding\n\nEvaluate Qodo's findings against the code, PR intent, and available session context. Own the final\ntechnical recommendation and rationale, while following the user's scope and approval below.\n\n**Evaluate each finding** against the actual code and the PR's intent, and form a recommendation:\n\n- **Sound and in scope** → a fix is warranted; note what you'd change (read `title` +\n `description`, locate the code — the `qodo-codebase-wisdom` skill's read tools help when it isn't\n local).\n- **Unsupported or already addressed** → recommend dismissal with code evidence. A deliberate\n choice supports dismissal only when the implementation enforces its assumptions.\n- **Unsure** → identify the evidence or check needed before deciding.\n\n**Present and ask (default).** Use the contextual assessment above for each open, in-scope finding,\nkeeping its `action_level`/`category` and your recommendation, then ask **in a single\nprompt** which findings to resolve. Use whatever the host gives you: a multi-select if it has one\n(Claude Code's `AskUserQuestion`, say), otherwise a numbered list and \"reply with the numbers to\nresolve\". One prompt either way — don't ask per finding. **Nothing is pre-selected.** Mark which\nones you recommend, but the user must actively choose: this prompt is the last thing standing\nbetween a finding and an edit, so a bare Enter must resolve nothing. Resolve only what the user\npicks (edit as normal, matching the surrounding code); report the rest as skipped with your reason.\nDo not edit any code before the user has chosen.\n\n**Autofix (skip the gate).** Only an **explicit `autofix` token** in the invocation (e.g.\n`qodo-review-resolver autofix`) skips the prompt outright. Phrasing that merely sounds like opting\nin (\"just fix them\", \"don't ask me\") is not enough by itself — reading intent wrong here edits code\nthe user never approved, which is the exact failure this gate exists to prevent. On inferred intent,\nname the exact scope you'd apply and get one confirmation — \"Reading that as autofix — resolve the\nN findings I recommended?\" — never \"resolve all N\", which reads as the whole set and widens scope on\nthe very ambiguity this check exists to catch. Either way apply exactly what the evaluation decided\nand nothing beyond it (findings are usually right, but you're the engineer in the loop, not a rubber\nstamp), and report what you resolved and what you skipped.\n\nCommit/push per the user's workflow — ask before pushing unless they've told you to.\n\n**`attribution_status` is the intended signal** — a fixed finding is re-attributed to\n`full_implementation` by the next review on its own, so after pushing, re-fetch and work only what's\nstill open. But it's tooling and can glitch: if a finding stays open after a fix you're confident\nin, or a status plainly contradicts the code, don't loop re-fixing it — flag the discrepancy to the\nuser and move on. (Resolving converges over rounds; a fix can also surface genuinely new findings,\nwhich the watch loop picks up.)\n\n## Record the outcome\n\nClosing a finding is a **write** — it updates Qodo's review DB, restyles the finding's PR comments,\nre-renders the review summary, and releases the merge-policy block that finding holds. Two commands,\nand the distinction between them is the whole point: one says *the code changed*, the other says\n*the code didn't and here's why*. Never use one to mean the other.\n\n```\nqodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation \"what you changed\" --json\nqodo pr-review-session dismiss --finding-ids <id>,<id> --reason <reason> --explanation \"why\" --json\n```\n\n- **Batch per PR, one call.** Reconciliation runs once per call, not once per finding — so all the\n findings you implemented go in one `mark-implemented`, and all the ones sharing a dismissal reason\n go in one `dismiss`. Up to 100 ids.\n- **`mark-implemented` only for code you actually changed and pushed.** It clears the merge gate\n without a review having verified the fix, so a wrong claim ships an unfixed finding as fixed. If\n another review round is going to run anyway, prefer letting it re-attribute the fix itself; reach\n for this when no further round will run before merge, or the gate must clear now.\n- **`dismiss` needs the user's explicit go, per finding, every time — `autofix` does NOT cover it.**\n `autofix` is consent to *edit code*, which the next review re-checks; a dismissal closes a finding\n the review still believes in, is visible to the team, and nothing re-opens it. Present what you\n propose to dismiss and why, and dismiss only what the user names.\n- **`--reason`** (required): `false_positive` (the finding is wrong) · `intentional` (the code is\n deliberate and correct) · `deferred` (real, but out of scope for this PR) · `rejected` (understood\n and declined). Always add `--explanation` — a reviewer reads it later without your context.\n- **Read `results` per finding, don't assume the call succeeded as a whole.** It is a 200 even when\n individual ids fail: `not_found` (wrong id or wrong workspace) and `conflict` (already closed, or\n not linked to a PR) are terminal — don't retry them. `reconciled: false` means the DB change\n landed but the PR-side update didn't; re-running the same command is safe and idempotent, and the\n PR self-heals on its next review regardless. `already_dismissed` / `already_implemented` report the\n **stored** reason — a replay never overwrites the original.\n\n## Example\n\n**User: \"Resolve the action-required findings on https://github.com/acme/api/pull/318\"**\n\n1. `qodo read whoami` → logged in.\n2. `qodo read pr-review-session findings --pr-url https://github.com/acme/api/pull/318 --json`\n → `review_session`: `status: completed`, `commit_sha: a1b2c3d` (= the PR head, so findings are current);\n `findings`: 3 open (2 `pending`, 1 `partial_implementation`) — 2 `action_required`, 1 `informational`.\n3. Instruction filters to `action_required` → work those 2; the informational one is out of scope (report it, don't fix).\n4. Evaluate each: *\"SQL built via string interpolation\"* → real → recommend parameterizing the query in\n `db/orders.py`. *\"Missing timeout on the outbound call\"* → the client already sets a default timeout\n upstream → already satisfied → recommend skipping with that reason.\n5. Present both with those recommendations and ask (multi-select) which to resolve — both unticked, the SQL\n one marked *recommended*. Apply what the user picks, then report: \"Resolved the SQL finding\n (parameterized the query in `db/orders.py`). Skipped the timeout one — already set upstream — and 1\n informational (out of scope). Push and I'll re-check, or say 'watch' to loop until the review is clean.\"\n (Had the user said `resolve … autofix`, I'd have applied the recommended fix directly, no prompt.)\n\n## Configuration\n\nUse `--json`, compare `review_session.commit_sha` with forge head metadata, and stamp the exact\nskill/version/distribution provenance on the first Qodo call. Read and write capabilities are\ndiscovered from the installed CLI catalog; rendered forge comments are never the data source.\n\n## Error Handling\n\nTreat null sessions, in-progress or stale commits, missing write capabilities, rate limits, and\ntool-loop errors as explicit states. Preserve them in the report and never close a finding merely\nto make the review appear clean.\n\n## Guardrails\n\n- **Freshness = a completed review of the reviewed commit, not a timestamp.** Findings describe\n `review_session.commit_sha` and are only final once `status` is `completed`. After any push, treat\n them as stale until a `completed` review's `commit_sha` catches up to the PR head — otherwise\n you'll act on a mid-flight review or \"fix\" a commit the findings don't describe.\n- **Never post to the forge yourself.** The only writes you make are `dismiss` /\n `mark-implemented`, which go through Qodo and let it reconcile the PR. Do not call any forge-write\n tool (comments, approvals, labels, description) to \"resolve\" a finding — resolve it in *code*, then\n record the outcome.\n- **You may decline a finding you judge wrong** (with a clear reason). Dismissing it in the system is\n now possible but is the **user's** call, not yours — propose it, name the reason, and act only on\n their explicit go. On a real disagreement the user is the arbiter.\n- **Don't close what you didn't settle.** A finding you skipped for scope stays open — report it as\n skipped rather than dismissing it as `deferred` to make the list look clean.\n- **Don't guess** the PR URL — resolve it first; a `null` session means no review yet.\n- An `MT-TOOL-LOOP` or `MT-RATE-LIMITED` error means stop/back off and change approach, not retry.\n\nAfter authorized changes, report what improved, why each decision was made, what was verified,\nand what still needs attention. Keep local edits, recorded dispositions, and review state distinct.\n"
"---\nname: qodo-review-resolver\ndescription: Read or resolve a pull request's Qodo review with the qodo CLI — fetch structured status, reviewed commit SHA, and findings for ANY PR as JSON, with optional extended details and citation evidence for audits, then optionally resolve open findings and record outcomes, once or until clean. Use this — never `gh`/`curl` scraping of review comments — for \"is the review clean on PR #N\", \"get Qodo's findings for <pr> as JSON\", \"audit the review evidence\", \"show finding citations\", \"what did Qodo flag\", \"is this review up to date with head\", \"check before merging\", \"resolve my PR review\", \"fix the review findings\", or \"babysit this PR until it's clean\".\ntriggers:\n - \"Check the Qodo findings on this pull request\"\n - \"Audit the citation evidence for these Qodo PR findings\"\n - \"Resolve the open Qodo review findings on this PR\"\nowner: Qodo\nwhen_to_use: When you need to read or act on a pull request's Qodo review — check where it stands, see what it flagged, gate a merge on it being clean at head, or fix the open findings — for any PR, not just your own. It reads the review through qodo's managed tool (structured, git-provider-agnostic), so use it instead of scraping the rendered PR review comments with `gh`/`curl` (lossy, provider-specific, and easy to read stale against the head commit). It resolves findings in local code and then records the outcome on each finding through qodo's own tools (dismiss / mark-implemented, which clear the merge-policy block); it never posts to the git forge itself. Skip it for reviewing code you're writing locally before any PR exists (that's the pre-PR review), and for non-review PR chores (merging, labels, descriptions).\nmetadata:\n vendor: qodo\n version: \"1.4.7\"\n recommended: \"true\"\n package: \"qodo\"\n distribution: \"marketplace\"\n instruction_mode: \"embedded\"\narguments:\n - name: autofix\n description: Optional shorthand for authorizing supported fixes. An explicit fix request or covering implementation authority also permits those fixes without another prompt.\n optional: true\n---\n\n# Read & Resolve Findings\n\n## Description\n\nUse the `qodo` CLI to read a pull request's **review session** — its status, the commit that\nwas reviewed, and every finding with its resolution status — for **any** PR (yours or someone\nelse's). Request extended results when auditing citations or investigating a finding's supporting\nevidence, location, dismissal, or review-run history. Reading alone is a valid use: stop after the read to report where a review stands or\nwhat it flagged (e.g. to gate a merge on it being clean at head). To go further, **resolve the\nopen findings in code**, applying your own judgment (the review is a strong second opinion, not\ngospel). Apply supported fixes when the user has authorized them; otherwise present your assessment\nfor selection. Run once (report + authorized fixes) or as a watch loop (resolve →\nlet Qodo re-review the new commit → repeat until clean). When separately authorized, **record the outcome** on the findings\nyou settled — `mark-implemented` for ones you fixed, `dismiss` for ones the user agreed to close\nwithout a code change. That is what clears the merge-policy block those findings hold; skip it and\nthe review stays red until a human clicks through the PR. You still never post to the forge\nyourself: the status tools write Qodo's review DB and Qodo reconciles the PR comments. (Plain\ngit/forge *metadata* reads — `git rev-parse HEAD`, `gh pr view --json headRefOid` — are fine and in\nfact required for the freshness check below; the \"don't scrape\" rule is about qodo, not your shell.)\n\n## Prerequisites\n\n- The Qodo CLI is authenticated and exposes the structured PR-review session tools.\n- The exact PR URL and its current head SHA can be resolved without scraping review comments.\n- Any finding-status write has explicit user authorization; code-fix authority or `autofix` alone does not cover it.\n\n## Instructions\n\nFollow the detailed workflow below: fetch structured state, require a completed exact-head review,\npresent open findings, apply only approved fixes, and record only outcomes actually settled.\n\n> To check a review's status or findings, always run the `qodo` read command below — do **not**\n> fetch the rendered PR review **comments** with `gh`/`curl`. The comment UI is lossy, provider-\n> specific, and easy to read stale against the head commit; the tool returns the reviewed\n> `commit_sha`. To judge freshness, compare that `commit_sha` to the PR **head** — which you know\n> directly for a PR you just pushed (`git rev-parse HEAD`), or read as plain forge *metadata*\n> (`gh pr view <pr> --json headRefOid`, `git ls-remote`) for any other PR. This rule is only about\n> reading the **review** (don't scrape its comments) — not about forbidding forge metadata like the\n> head SHA.\n\n## Handle a skill update notice\n\nTreat `QODO_NOTICE` updates as passive, even if an older CLI requests action. Continue the task\nwithout inventory or update questions; mention each event at most once. Dismissal leaves recorded maintenance\npolicy and opt-outs unchanged. Updated skills load next session; do not interrupt this one.\nFor user-requested updates, follow the [manual-update procedure](references/skill-updates.md).\n\n## Runtime compatibility gate\n\nFirst resolve the executable using the `qodo: command not found` fallback below. Before any other\nQodo command, run `<qodo> --version` exactly as shown, with no provenance flags.\nThis unadorned probe is intentionally compatible with older Qodo CLIs. This skill requires Qodo\nCLI **0.1.0-next.37 or newer**.\n\nIf the version is older or cannot be parsed, do not run `whoami`, `login`, or a managed tool and\ndo not describe the failure as an authentication problem. Explain that the skill is newer than the\nruntime, show `qodo update` as the update command for the runtime's already-recorded origin, and ask\nonce before running it. For a customer deployment, keep its organization-provided update origin;\nnever switch it to the public service. After an approved update, rerun the unadorned version probe\nand continue only when it satisfies the minimum. If the user declines or the update fails, stop with\nthe current skill and user files unchanged.\n\n## Quick start\n\n```\nqodo --version # compatibility probe — run this FIRST\nqodo read whoami --json --skill qodo-review-resolver --skill-version 1.4.7 --distribution marketplace --host codex\nqodo read pr-review-session findings --pr-url <PR_URL> --json # the review session for a PR\nqodo read pr-review-session findings --pr-url <PR_URL> --extended --json # details, if advertised by tool help\nqodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation \"...\" --json\nqodo pr-review-session dismiss --finding-ids <id> --reason intentional --explanation \"...\" --json\nqodo read tools pr-review-session --json # exact safe tools + flags (offline)\n```\n\nAdd `--json` to anything you parse. Inspect reads with\n`qodo read tools pr-review-session findings --json`; inspect a write's input schema with\n`qodo tools help pr-review-session <tool> --json`. Both are offline discovery, not mutations.\nThe read-only catalog deliberately excludes writes; absence there does not prove they are unavailable.\n\n`unknown command` on `dismiss`/`mark-implemented` after authentication may be a stale local tool\ncatalog — refresh once as described below. If the commands are still absent, the workspace does\nnot currently expose PR-review writes; report that capability boundary instead of looping.\n\n**`qodo: command not found`?** That's PATH, not a missing install: GUI-launched agents (e.g.\nthe Claude Code desktop app) run shells with a minimal PATH. Retry with the absolute path\n`~/.qodo/bin/qodo` (or `$QODO_HOME/bin/qodo` if set) and keep using it for every `qodo`\ncommand here. Only if that file is missing too is qodo actually not installed; tell the\nuser to obtain a checksum-pinned installer command from Qodo or their organization's\nadministrator. Installers are served from https://get.qodo.ai, but never invent a digest\nor pipe an installer directly into a shell.\n\n**Sandbox auth diagnostic.** Missing credentials can mean inaccessible keychain access. When that\nis plausible, request one exact read-only `qodo read whoami` retry through the host's approval\nflow before recommending login. Stop on denial; that approval covers no other command. Reuse a\nsuccessful check in the same executable/workspace/deployment and execution context; request each\nrequired host approval. Network, TLS, service, and explicit authorization failures retain their\nown diagnosis, not a login recommendation or an automatic sandbox bypass.\n\n## Preflight\n\n1. **Auth and catalog.** Run `qodo read whoami` unless a successful check still covers this\n execution context. After the sandbox diagnostic when applicable, only explicit missing credentials\n call for login: preserve the organization's exact login command/endpoint, never guess or switch\n a customer deployment to Cloud. `No tool catalog cached` is not proof of missing credentials;\n refresh once with `qodo tools --refresh` and retry the check. Other failures retain their error\n and stop this workflow. After identity succeeds, an unknown managed command permits one catalog\n refresh and schema recheck. If still absent or `tool_unavailable`, report the missing capability;\n do not repeat login or refresh.\n2. **Resolve the PR.** Use the PR URL the user gives. If they don't name one and you're inside\n a git repo, infer the open PR for the current branch and **confirm it with the user before\n acting**. Never guess a PR URL.\n3. **Bind edits to the checkout.** Report-only reads may target any PR. Before any local fix,\n resolve the PR repository from provider metadata and the current checkout repository from its\n `origin`; normalize both to the full case-insensitive `owner/repo` identity. They must match\n exactly. A missing/ambiguous origin or mismatch means stop and ask the user to open the correct\n checkout — never apply a finding from one repository to another worktree. Use the PR branch\n or an isolated worktree for that PR, with local HEAD at the reviewed head (or a verified descendant\n produced by this same fix workflow). Merely having the commit in the repository is insufficient.\n Inspect local differences and preserve unrelated edits; never reset or switch a dirty worktree\n to satisfy this check. Repeat these checks if the target PR changes.\n\n## Fetch the review session\n\n`qodo read pr-review-session findings --pr-url <PR_URL> --json` returns:\n\n- `review_session` — the latest review run: `status`, `commit_sha` (**the last commit included in\n the review** — the code these findings describe), `started_at`. **`null` = the PR has no review\n yet** — tell the user and stop (nothing to resolve).\n- `findings[]` — every current finding, each with: `title`, `description`, `category`,\n `action_level` (`action_required` > `remediation_recommended` > `informational`),\n `attribution_status`, `git_sha`, `review_run_id`, `comment_id` / `inline_comment_id`.\n\nZero findings supports a clean verdict only for a complete, completed review at the current PR head.\n\n### Extended results for audits and investigation\n\nKeep compact reads for routine status polling. When the user needs supporting evidence or more\ndetail, inspect `qodo read tools pr-review-session findings --json`. Only if the schema declares\nthe `extended` boolean, use `qodo read pr-review-session findings --pr-url <PR_URL> --extended --json`.\nThe tool/API input is `extended: true`; omitted or false keeps the compact response.\nThis reads more stored data; it does not rerun or deepen the review.\n\nExtended results add finding locations and code snippets, dismissal reasons/explanations,\n`review_runs`, and `findings[].evidence` with `explanation` and `citations`. Preserve each\ncitation's source type, source reference, text and source-specific metadata in an audit output.\nCorrelate evidence with that finding's `id`, `git_sha`, `review_run_id` and `review_source`;\ncurrent findings can originate in earlier runs than `review_session`.\n\nNull evidence means unavailable; an empty citations list contains no recorded citations. An\nabsent evidence field can indicate an older backend: report that limitation without claiming\nthe finding has no supporting evidence. If `extended` is absent from the catalog, follow the\nexisting one-refresh recovery and check again; if still absent, report that extended reads are\nunavailable and keep using compact reads. Never send `--extended` to a catalog that lacks it;\ndo not invent an alternative flag or substitute scraped comments.\n\nIf the result has `qar_operation_result_truncated: true`, report an incomplete read, not an\nempty or clean review. Extended results describe current findings and recorded runs, not an\nimmutable history of every finding revision. Apply the freshness checks below before acting.\n\n## Read the session state FIRST (before trusting any finding)\n\nThe `review_session` tells you *whether the findings are real yet and what code they cover* —\ncheck it before acting:\n\n- **Is a review still running?** The API reports a running review as `started`; that is the polling state. For a status-only\n request, report that state and return; poll only when waiting is part of the requested task.\n `failed`, `aborted`, `skipped`, and `superseded` are non-success terminal states: report them\n and stop the loop. An unknown status is not success or permission to poll indefinitely.\n- **What commit do the findings describe?** `review_session.commit_sha` is the last commit the\n review included. If it's **behind the PR head**, the findings are **stale** — they don't reflect\n your latest code. Either the review hasn't run on the new commit yet (wait) or you're looking at\n an old run. Only trust findings when the session is `completed` AND its `commit_sha` is the commit\n you care about (the head, in a watch loop).\n\nAct only on a **completed review of the current commit**. A running or stale review cannot\nauthorize finding resolution. In watch mode, respect retry delays, recheck the forge head before\nclaiming clean, and stop if the review makes no progress rather than polling indefinitely.\n\n## Present the review state\n\nUse natural prose: **outcome → contextual explanation of changes and dispositions → verification\n→ remaining work**. For report-only requests, lead with the current review state and the impact\nof remaining findings. Credit Qodo once for the specific concerns its review surfaced; you own\nthe final assessment and recommended action. No branded headings, emoji banners, slogans,\nfooters, or repeated summary blocks. Use short issue titles or lists when useful.\n\nFor each finding, explain what could happen, under which conditions, and why it matters to the\nuser's intended change. Evaluate it against the code and available coding-session decisions and\nconstraints; retrieve PR context when needed, never invent a missing session. Cite the evidence\nand preserve finding references and reported category/level separately from your recommendation.\nOwn the fix, dismissal, or investigation decision and its rationale. A deliberate choice supports\ndismissal only when the implementation enforces its assumptions. Keep the tone collaborative\nand factual; do not routinely qualify Qodo's capability. Follow the existing scope and approval\ngates for edits and disposition writes; your technical assessment does not grant permission.\n\nName the PR, review status, and reviewed commit from structured state; compare with the forge\nhead before acting. Make stale, running, failed, or missing reviews explicit. Distinguish **code\nchanged**, **disposition recorded**, and **updated code reviewed**. Tests passing or a status\nwrite succeeding does not establish a clean review of the updated commit. Only a completed\nreview at the current head can support that verdict; report remaining findings and missing\nverification honestly. For example: “Addressed [risk] Qodo identified by [change], preserving\n[user decision]. [Verification]. The latest review covers [old SHA]; review of [head SHA] remains\noutstanding.” Use only actual outcomes. In watch mode, report meaningful state changes without\nrepeating the assessment on every poll or status write.\n\n## Triage\n\n- **Open vs done is `attribution_status`.** Classify the returned value, including the\n supported representations used by different deployments:\n - **OPEN — work these:** `pending`, `partial_implementation`, `not_implemented`,\n `focus_areas_edited`.\n - **CLOSED — leave these:** `implemented`, `full_implementation`, `dismissed`,\n `detected_after_merge`, `outdated`. Report unfamiliar values instead of silently excluding\n them from a clean verdict.\n - `action_level` is **severity**, not open-vs-closed. A closed finding can still be\n `action_required`.\n- **Order by `action_level`:** `action_required` first, then `remediation_recommended`; treat\n `informational` as optional and surface it, don't necessarily fix it.\n- Group open findings by file so you edit each file once.\n\n## Honor the user's instruction (optional scope)\n\nIf the user gave an instruction, treat it as a **filter over the open findings** and act only on\nthe matches — don't widen it:\n\n- **By action level** — \"resolve the action-required findings\" → only `action_level == action_required`;\n \"everything actionable\" → `action_required` + `remediation_recommended`.\n- **By category** — \"just the security findings\" → `category == Security` (same for correctness,\n performance, etc.).\n- **By specific finding** — \"fix finding #3\" / \"the SQL-injection one\" → match by `id` or `title`.\n- **Report-only** — \"what did the review find?\" / \"is it clean?\" → summarize the findings and their\n statuses, change no code.\n\nNo fix instruction or covering implementation authority → present for approval open `action_required` then\n`remediation_recommended`, and surface (don't auto-fix) `informational`. When an instruction is\nambiguous, state the scope you picked in one line before acting, so the user can redirect. Always\nreport which findings you **skipped** and why (out of scope / dismissed / informational) — never\nsilently drop one.\n\n## Two modes\n\nEach round follows **Resolve a finding**: evaluate and apply only fixes covered by existing user\nauthority (`autofix` or an explicit fix request); otherwise present and ask. Push authority is separate.\n\n**Once (default).** Fetch → evaluate every open finding (triage — all four OPEN statuses, not just\n`pending`) → present + ask if authority is missing → apply authorized fixes in code →\ncommit/push only within the user's authorization → summarize fixes and remaining findings.\nFor local-only fixes, report \"awaiting push\" and leave finding status unchanged. After a verified\npush, prefer the next review's automatic re-attribution; a manual status write additionally needs\nexplicit authorization and the checks in **Record the outcome**. Stop. Don't loop unless asked. Triage covers\n**all** open findings, but the picker only *offers* the actionable set —\n`action_required` then `remediation_recommended` — with `informational` surfaced separately,\nmatching the default scope above; put `informational` in the picker only when the user asks.\n(Offering isn't selecting: every box starts unticked.)\n\n**Watch until clean** (when the user says \"babysit\" / \"keep going until it's clean\"). Reuse explicit\nfix authority within its scope; monitoring alone does not authorize edits. After you resolve\nfindings and the fix commit is pushed, Qodo re-reviews the *new* commit — so:\n\n1. Note the PR's current head SHA — the commit you just pushed (`git rev-parse HEAD`), or, for a\n PR you didn't push, read it as forge metadata (`gh pr view <pr> --json headRefOid`). That's a\n metadata read, not review-comment scraping — it's fine.\n2. Follow **Read the session state FIRST** on each read: poll `started` only within the bounded\n watch; report non-success terminal or unknown states and stop. A completed older run is stale:\n allow a bounded wait for the new head's review to appear. Act only when the review is\n **`completed` AND its `commit_sha` equals that head SHA**.\n3. When fresh: if any OPEN findings remain (all four statuses — a `partial_implementation` is\n still open), resolve them and repeat; if none remain, report the\n review clean and stop.\n4. Bound it: stop after a few rounds with no progress and hand back to the user rather than\n looping forever.\n\n## Resolve a finding\n\nEvaluate Qodo's findings against the code, PR intent, and available session context. Own the final\ntechnical recommendation and rationale, while following the user's scope and approval below.\n\n**Evaluate each finding** against the actual code and the PR's intent, and form a recommendation:\n\n- **Sound and in scope** → a fix is warranted; note what you'd change (read `title` +\n `description`, locate the code — the `qodo-codebase-wisdom` skill's read tools help when it isn't\n local).\n- **Unsupported or already addressed** → recommend dismissal with code evidence. A deliberate\n choice supports dismissal only when the implementation enforces its assumptions.\n- **Unsure** → identify the evidence or check needed before deciding.\n\n**Report-only.** Return the assessment and stop; do not solicit edit approval for an explicit\nrequest to review without changes.\n\n**Present and ask only when edit authority is missing.** If `autofix`, an explicit fix request,\nor covering implementation authority already applies, skip this selection prompt and follow\n**Authorized fixes** below. Otherwise use the assessment above for each open, in-scope finding,\nkeeping its `action_level`/`category` and your recommendation, then ask **in a single\nprompt** which findings to resolve. Use whatever the host gives you: a multi-select if it has one\n(Claude Code's `AskUserQuestion`, say), otherwise a numbered list and \"reply with the numbers to\nresolve\". One prompt either way — don't ask per finding. **Nothing is pre-selected.** Mark which\nones you recommend, but the user must actively choose: this prompt is the last thing standing\nbetween a finding and an edit, so a bare Enter must resolve nothing. Resolve only what the user\npicks (edit as normal, matching the surrounding code); report the rest as skipped with your reason.\nOn this missing-authority path, do not edit before the user has chosen.\n\n**Authorized fixes.** `autofix` or an explicit request such as \"fix the action-required findings\"\nauthorizes supported code fixes within that scope; no special token or repeated confirmation is\nneeded. Existing implementation authority can also cover the correction. State your assessment\nbefore applying it. A status-only request grants no edit authority; ask once if scope is ambiguous.\nNeither fix authority nor monitoring authorizes finding-status writes (`dismiss` or\n`mark-implemented`) or a push. Report fixes and skipped findings.\n\nCommit/push per the user's workflow — ask before pushing unless they've told you to.\n\n**`attribution_status` is the intended signal** — a fixed finding is re-attributed to\n`implemented` or `full_implementation` by the next review on its own, so after pushing, re-fetch and work only what's\nstill open. But it's tooling and can glitch: if a finding stays open after a fix you're confident\nin, or a status plainly contradicts the code, don't loop re-fixing it — flag the discrepancy to the\nuser and move on. (Resolving converges over rounds; a fix can also surface genuinely new findings,\nwhich the watch loop picks up.)\n\n## Record the outcome\n\nRequire explicit authorization for the specific status write; permission to fix code or push it\ndoes not authorize closing findings. Prefer automatic re-attribution after a pushed fix.\n\nClosing a finding is a **write** — it updates Qodo's review DB, restyles the finding's PR comments,\nre-renders the review summary, and releases the merge-policy block that finding holds. Two commands,\nand the distinction between them is the whole point: one says *the code changed*, the other says\n*the code didn't and here's why*. Never use one to mean the other.\n\n```\nqodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation \"what you changed\" --json\nqodo pr-review-session dismiss --finding-ids <id>,<id> --reason <reason> --explanation \"why\" --json\n```\n\n- **Batch per PR, one call.** Reconciliation runs once per call, not once per finding — so all the\n findings you implemented go in one `mark-implemented`, and all the ones sharing a dismissal reason\n go in one `dismiss`. Up to 100 ids.\n- **`mark-implemented` only when explicitly authorized and for code you actually changed and pushed.** It clears the merge gate\n without a review having verified the fix, so a wrong claim ships an unfixed finding as fixed. If\n another review round is going to run anyway, prefer letting it re-attribute the fix itself; reach\n for this when no further round will run before merge, or the gate must clear now.\n- **`dismiss` needs the user's explicit go, per finding, every time — `autofix` does NOT cover it.**\n `autofix` is consent to *edit code*, which the next review re-checks; a dismissal closes a finding\n the review still believes in, is visible to the team, and nothing re-opens it. Present what you\n propose to dismiss and why, and dismiss only what the user names.\n- **`--reason`** (required): `false_positive` (the finding is wrong) · `intentional` (the code is\n deliberate and correct) · `deferred` (real, but out of scope for this PR) · `rejected` (understood\n and declined). Always add `--explanation` — a reviewer reads it later without your context.\n- **Read `results` per finding, don't assume the call succeeded as a whole.** It is a 200 even when\n individual ids fail: `not_found` (wrong id or wrong workspace) and `conflict` (already closed, or\n not linked to a PR) are terminal — don't retry them. `reconciled: false` means the DB change\n landed but the PR-side update didn't; re-running the same command is safe and idempotent, and the\n PR self-heals on its next review regardless. `already_dismissed` / `already_implemented` report the\n **stored** reason — a replay never overwrites the original.\n\n## Example\n\n**User: \"Resolve the action-required findings on https://github.com/acme/api/pull/318\"**\n\n1. `qodo read whoami` → logged in.\n2. `qodo read pr-review-session findings --pr-url https://github.com/acme/api/pull/318 --json`\n → `review_session`: `status: completed`, `commit_sha: a1b2c3d` (= the PR head, so findings are current);\n `findings`: 3 open (2 `pending`, 1 `partial_implementation`) — 2 `action_required`, 1 `informational`.\n3. Instruction filters to `action_required` → work those 2; the informational one is out of scope (report it, don't fix).\n4. Evaluate each: *\"SQL built via string interpolation\"* → real → recommend parameterizing the query in\n `db/orders.py`. *\"Missing timeout on the outbound call\"* → the client already sets a default timeout\n upstream → already satisfied → recommend skipping with that reason.\n5. The explicit request covers the supported action-required fix: parameterize the SQL query and\n verify it. Report the timeout as already satisfied and the informational finding as out of scope;\n neither is dismissed automatically. Report the local fix separately from the PR's review state.\n Push only with separate covering authority, then check the review of the new head.\n\n## Configuration\n\nUse `--json`, compare `review_session.commit_sha` with forge head metadata, and stamp the exact\nskill/version/distribution provenance on the first authenticated Qodo call after the unadorned version probe. Read and write capabilities are\ndiscovered from the installed CLI catalog; rendered forge comments are never the data source.\n\n## Error Handling\n\nTreat null sessions, running reviews (`started`), stale commits, missing write capabilities, rate limits, and\ntool-loop errors as explicit states. Preserve them in the report and never close a finding merely\nto make the review appear clean.\n\n## Guardrails\n\n- **Freshness = a completed review of the reviewed commit, not a timestamp.** Findings describe\n `review_session.commit_sha` and are only final once `status` is `completed`. After any push, treat\n them as stale until a `completed` review's `commit_sha` catches up to the PR head — otherwise\n you'll act on a mid-flight review or \"fix\" a commit the findings don't describe.\n- **Never post to the forge yourself.** The only writes you make are `dismiss` /\n `mark-implemented`, which go through Qodo and let it reconcile the PR. Do not call any forge-write\n tool (comments, approvals, labels, description) to \"resolve\" a finding — resolve it in *code*, then\n record the outcome.\n- **You may decline a finding you judge wrong** (with a clear reason). Dismissing it in the system is\n now possible but is the **user's** call, not yours — propose it, name the reason, and act only on\n their explicit go. On a real disagreement the user is the arbiter.\n- **Don't close what you didn't settle.** A finding you skipped for scope stays open — report it as\n skipped rather than dismissing it as `deferred` to make the list look clean.\n- **Don't guess** the PR URL — resolve it first; a `null` session means no review yet.\n- An `MT-TOOL-LOOP` or `MT-RATE-LIMITED` error means stop/back off and change approach, not retry.\n\nAfter authorized changes, report what improved, why each decision was made, what was verified,\nand what still needs attention. Keep local edits, recorded dispositions, and review state distinct.\n"
SKILL.md line diff
--- before +++ after @@ -9,14 +9,14 @@ when_to_use: When you need to read or act on a pull request's Qodo review — check where it stands, see what it flagged, gate a merge on it being clean at head, or fix the open findings — for any PR, not just your own. It reads the review through qodo's managed tool (structured, git-provider-agnostic), so use it instead of scraping the rendered PR review comments with `gh`/`curl` (lossy, provider-specific, and easy to read stale against the head commit). It resolves findings in local code and then records the outcome on each finding through qodo's own tools (dismiss / mark-implemented, which clear the merge-policy block); it never posts to the git forge itself. Skip it for reviewing code you're writing locally before any PR exists (that's the pre-PR review), and for non-review PR chores (merging, labels, descriptions). metadata: vendor: qodo - version: "1.4.6" + version: "1.4.7" recommended: "true" package: "qodo" distribution: "marketplace" instruction_mode: "embedded" arguments: - name: autofix - description: Resolve the recommended fixes directly without asking. Omit to evaluate the findings and let the user pick which to resolve. + description: Optional shorthand for authorizing supported fixes. An explicit fix request or covering implementation authority also permits those fixes without another prompt. optional: true --- @@ -30,9 +30,9 @@ evidence, location, dismissal, or review-run history. Reading alone is a valid use: stop after the read to report where a review stands or what it flagged (e.g. to gate a merge on it being clean at head). To go further, **resolve the open findings in code**, applying your own judgment (the review is a strong second opinion, not -gospel) — by default you evaluate the findings and let the user pick which to apply (pass `autofix` -to apply directly), run once (report + resolve what the user approves) or as a watch loop (resolve → -let Qodo re-review the new commit → repeat until clean). Then **record the outcome** on the findings +gospel). Apply supported fixes when the user has authorized them; otherwise present your assessment +for selection. Run once (report + authorized fixes) or as a watch loop (resolve → +let Qodo re-review the new commit → repeat until clean). When separately authorized, **record the outcome** on the findings you settled — `mark-implemented` for ones you fixed, `dismiss` for ones the user agreed to close without a code change. That is what clears the merge-policy block those findings hold; skip it and the review stays red until a human clicks through the PR. You still never post to the forge @@ -44,7 +44,7 @@ - The Qodo CLI is authenticated and exposes the structured PR-review session tools. - The exact PR URL and its current head SHA can be resolved without scraping review comments. -- Any write to a finding has the user's explicit authority or the skill's explicit `autofix` scope. +- Any finding-status write has explicit user authorization; code-fix authority or `autofix` alone does not cover it. ## Instructions @@ -86,7 +86,7 @@ ``` qodo --version # compatibility probe — run this FIRST -qodo read whoami --json --skill qodo-review-resolver --skill-version 1.4.6 --distribution marketplace --host codex +qodo read whoami --json --skill qodo-review-resolver --skill-version 1.4.7 --distribution marketplace --host codex qodo read pr-review-session findings --pr-url <PR_URL> --json # the review session for a PR qodo read pr-review-session findings --pr-url <PR_URL> --extended --json # details, if advertised by tool help qodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation "..." --json @@ -94,9 +94,10 @@ qodo read tools pr-review-session --json # exact safe tools + flags (offline) ``` -Add `--json` to anything you parse. **Confirm the exact tool names, flags, and read/write status -with `qodo read tools pr-review-session [<tool>] --json`** (renders offline) — the names above -are illustrative, not guaranteed current. +Add `--json` to anything you parse. Inspect reads with +`qodo read tools pr-review-session findings --json`; inspect a write's input schema with +`qodo tools help pr-review-session <tool> --json`. Both are offline discovery, not mutations. +The read-only catalog deliberately excludes writes; absence there does not prove they are unavailable. `unknown command` on `dismiss`/`mark-implemented` after authentication may be a stale local tool catalog — refresh once as described below. If the commands are still absent, the workspace does @@ -110,24 +111,23 @@ administrator. Installers are served from https://get.qodo.ai, but never invent a digest or pipe an installer directly into a shell. -**Sandbox auth diagnostic.** In a sandboxed environment, if `qodo read whoami` fails for any reason -(including `Not logged in`), ask the user to approve one exact read-only retry of `qodo read whoami` -outside the sandbox before recommending login or refreshing tools. Keychain failures can be -reported as generic auth failures, so the sandboxed result alone is not diagnostic. That approval -applies only to this single diagnostic retry: do not reuse it, request persistent approval, or move -later Qodo commands outside the sandbox automatically. If the retry succeeds, continue with normal -per-command permission checks. If it still fails, follow the normal auth troubleshooting below. +**Sandbox auth diagnostic.** Missing credentials can mean inaccessible keychain access. When that +is plausible, request one exact read-only `qodo read whoami` retry through the host's approval +flow before recommending login. Stop on denial; that approval covers no other command. Reuse a +successful check in the same executable/workspace/deployment and execution context; request each +required host approval. Network, TLS, service, and explicit authorization failures retain their +own diagnosis, not a login recommendation or an automatic sandbox bypass. ## Preflight -1. **Auth first.** Run `qodo read whoami`. After the sandbox retry above when applicable, a non-zero - exit → tell the user to run `qodo login`, then stop. Never guess creds. The tool only exists - *after* login, so treat `Not logged in` or `No - tool catalog cached` as "run `qodo login`", and don't retry before they have. - **An `unknown command`/`unknown option` while `whoami` SUCCEEDED is not an auth failure.** Run - `qodo tools --refresh` once and re-check `qodo read tools pr-review-session --json`. If the write command - remains absent, report that this account/workspace currently has read-only review capability; - do not re-login, retry indefinitely, or substitute a forge comment for the structured write. +1. **Auth and catalog.** Run `qodo read whoami` unless a successful check still covers this + execution context. After the sandbox diagnostic when applicable, only explicit missing credentials + call for login: preserve the organization's exact login command/endpoint, never guess or switch + a customer deployment to Cloud. `No tool catalog cached` is not proof of missing credentials; + refresh once with `qodo tools --refresh` and retry the check. Other failures retain their error + and stop this workflow. After identity succeeds, an unknown managed command permits one catalog + refresh and schema recheck. If still absent or `tool_unavailable`, report the missing capability; + do not repeat login or refresh. 2. **Resolve the PR.** Use the PR URL the user gives. If they don't name one and you're inside a git repo, infer the open PR for the current branch and **confirm it with the user before acting**. Never guess a PR URL. @@ -135,8 +135,11 @@ resolve the PR repository from provider metadata and the current checkout repository from its `origin`; normalize both to the full case-insensitive `owner/repo` identity. They must match exactly. A missing/ambiguous origin or mismatch means stop and ask the user to open the correct - checkout — never apply a finding from one repository to another worktree. Repeat this check if - the target PR changes during a watch loop. + checkout — never apply a finding from one repository to another worktree. Use the PR branch + or an isolated worktree for that PR, with local HEAD at the reviewed head (or a verified descendant + produced by this same fix workflow). Merely having the commit in the repository is insufficient. + Inspect local differences and preserve unrelated edits; never reset or switch a dirty worktree + to satisfy this check. Repeat these checks if the target PR changes. ## Fetch the review session @@ -149,7 +152,7 @@ `action_level` (`action_required` > `remediation_recommended` > `informational`), `attribution_status`, `git_sha`, `review_run_id`, `comment_id` / `inline_comment_id`. -`finding_count: 0` with a non-null session = a clean review. +Zero findings supports a clean verdict only for a complete, completed review at the current PR head. ### Extended results for audits and investigation @@ -181,17 +184,19 @@ The `review_session` tells you *whether the findings are real yet and what code they cover* — check it before acting: -- **Is a review still running?** If `status` is not a terminal/`completed` state (e.g. `started` / - in-progress), a review is **mid-flight** — the findings are provisional and will change. Do NOT - resolve them yet; poll `qodo read pr-review-session findings … --json` until `status` is `completed`. +- **Is a review still running?** The API reports a running review as `started`; that is the polling state. For a status-only + request, report that state and return; poll only when waiting is part of the requested task. + `failed`, `aborted`, `skipped`, and `superseded` are non-success terminal states: report them + and stop the loop. An unknown status is not success or permission to poll indefinitely. - **What commit do the findings describe?** `review_session.commit_sha` is the last commit the review included. If it's **behind the PR head**, the findings are **stale** — they don't reflect your latest code. Either the review hasn't run on the new commit yet (wait) or you're looking at an old run. Only trust findings when the session is `completed` AND its `commit_sha` is the commit you care about (the head, in a watch loop). -In short: act only on a **completed review of the current commit**. A running review or a -lagging `commit_sha` means wait, don't fix. +Act only on a **completed review of the current commit**. A running or stale review cannot +authorize finding resolution. In watch mode, respect retry delays, recheck the forge head before +claiming clean, and stop if the review makes no progress rather than polling indefinitely. ## Present the review state @@ -222,12 +227,13 @@ ## Triage -- **Open vs done is `attribution_status`**, and it is NOT a three-way field — it carries the raw - stored value, so matching only `pending` silently drops real work: +- **Open vs done is `attribution_status`.** Classify the returned value, including the + supported representations used by different deployments: - **OPEN — work these:** `pending`, `partial_implementation`, `not_implemented`, - `focus_areas_edited`. The last three are re-attributions of a finding that is still unresolved - (a partial fix is still an open finding). - - **CLOSED — leave these:** `full_implementation`, `dismissed`, `detected_after_merge`, `outdated`. + `focus_areas_edited`. + - **CLOSED — leave these:** `implemented`, `full_implementation`, `dismissed`, + `detected_after_merge`, `outdated`. Report unfamiliar values instead of silently excluding + them from a clean verdict. - `action_level` is **severity**, not open-vs-closed. A closed finding can still be `action_required`. - **Order by `action_level`:** `action_required` first, then `remediation_recommended`; treat @@ -247,7 +253,7 @@ - **Report-only** — "what did the review find?" / "is it clean?" → summarize the findings and their statuses, change no code. -No instruction → default to presenting for approval open `action_required` then +No fix instruction or covering implementation authority → present for approval open `action_required` then `remediation_recommended`, and surface (don't auto-fix) `informational`. When an instruction is ambiguous, state the scope you picked in one line before acting, so the user can redirect. Always report which findings you **skipped** and why (out of scope / dismissed / informational) — never @@ -255,31 +261,31 @@ ## Two modes -Each round follows the present-and-ask gate from **Resolve a finding** — evaluate, present, and let -the user pick which findings to resolve — unless `autofix` is in effect, which lets you apply the -recommended fixes without prompting. Either way, ask before pushing unless told otherwise. +Each round follows **Resolve a finding**: evaluate and apply only fixes covered by existing user +authority (`autofix` or an explicit fix request); otherwise present and ask. Push authority is separate. **Once (default).** Fetch → evaluate every open finding (triage — all four OPEN statuses, not just -`pending`) → present + ask (or apply directly under `autofix`) → resolve the chosen ones in code → -commit/push per the user's workflow → **record the outcome** -(`mark-implemented` for what you fixed; `dismiss`, with the user's explicit go, for what they -agreed to close without a change) → summarize what you resolved and what remains (e.g. skipped / -dismissed / informational). Stop. Don't loop unless asked. Triage covers +`pending`) → present + ask if authority is missing → apply authorized fixes in code → +commit/push only within the user's authorization → summarize fixes and remaining findings. +For local-only fixes, report "awaiting push" and leave finding status unchanged. After a verified +push, prefer the next review's automatic re-attribution; a manual status write additionally needs +explicit authorization and the checks in **Record the outcome**. Stop. Don't loop unless asked. Triage covers **all** open findings, but the picker only *offers* the actionable set — `action_required` then `remediation_recommended` — with `informational` surfaced separately, matching the default scope above; put `informational` in the picker only when the user asks. (Offering isn't selecting: every box starts unticked.) -**Watch until clean** (when the user says "babysit" / "keep going until it's clean"). `autofix` is -what makes this loop autonomous — without it you still present + ask each round. After you resolve +**Watch until clean** (when the user says "babysit" / "keep going until it's clean"). Reuse explicit +fix authority within its scope; monitoring alone does not authorize edits. After you resolve findings and the fix commit is pushed, Qodo re-reviews the *new* commit — so: 1. Note the PR's current head SHA — the commit you just pushed (`git rev-parse HEAD`), or, for a PR you didn't push, read it as forge metadata (`gh pr view <pr> --json headRefOid`). That's a metadata read, not review-comment scraping — it's fine. -2. Poll `qodo read pr-review-session findings … --json` until the review is **`completed` AND its - `commit_sha` equals that head SHA**. Until both hold, the findings are stale or provisional - (a review is still running, or it describes the pre-fix commit) — do not act on them. +2. Follow **Read the session state FIRST** on each read: poll `started` only within the bounded + watch; report non-success terminal or unknown states and stop. A completed older run is stale: + allow a bounded wait for the new head's review to appear. Act only when the review is + **`completed` AND its `commit_sha` equals that head SHA**. 3. When fresh: if any OPEN findings remain (all four statuses — a `partial_implementation` is still open), resolve them and repeat; if none remain, report the review clean and stop. @@ -300,7 +306,12 @@ choice supports dismissal only when the implementation enforces its assumptions. - **Unsure** → identify the evidence or check needed before deciding. -**Present and ask (default).** Use the contextual assessment above for each open, in-scope finding, +**Report-only.** Return the assessment and stop; do not solicit edit approval for an explicit +request to review without changes. + +**Present and ask only when edit authority is missing.** If `autofix`, an explicit fix request, +or covering implementation authority already applies, skip this selection prompt and follow +**Authorized fixes** below. Otherwise use the assessment above for each open, in-scope finding, keeping its `action_level`/`category` and your recommendation, then ask **in a single prompt** which findings to resolve. Use whatever the host gives you: a multi-select if it has one (Claude Code's `AskUserQuestion`, say), otherwise a numbered list and "reply with the numbers to @@ -308,22 +319,19 @@ ones you recommend, but the user must actively choose: this prompt is the last thing standing between a finding and an edit, so a bare Enter must resolve nothing. Resolve only what the user picks (edit as normal, matching the surrounding code); report the rest as skipped with your reason. -Do not edit any code before the user has chosen. +On this missing-authority path, do not edit before the user has chosen. -**Autofix (skip the gate).** Only an **explicit `autofix` token** in the invocation (e.g. -`qodo-review-resolver autofix`) skips the prompt outright. Phrasing that merely sounds like opting -in ("just fix them", "don't ask me") is not enough by itself — reading intent wrong here edits code -the user never approved, which is the exact failure this gate exists to prevent. On inferred intent, -name the exact scope you'd apply and get one confirmation — "Reading that as autofix — resolve the -N findings I recommended?" — never "resolve all N", which reads as the whole set and widens scope on -the very ambiguity this check exists to catch. Either way apply exactly what the evaluation decided -and nothing beyond it (findings are usually right, but you're the engineer in the loop, not a rubber -stamp), and report what you resolved and what you skipped. +**Authorized fixes.** `autofix` or an explicit request such as "fix the action-required findings" +authorizes supported code fixes within that scope; no special token or repeated confirmation is +needed. Existing implementation authority can also cover the correction. State your assessment +before applying it. A status-only request grants no edit authority; ask once if scope is ambiguous. +Neither fix authority nor monitoring authorizes finding-status writes (`dismiss` or +`mark-implemented`) or a push. Report fixes and skipped findings. Commit/push per the user's workflow — ask before pushing unless they've told you to. **`attribution_status` is the intended signal** — a fixed finding is re-attributed to -`full_implementation` by the next review on its own, so after pushing, re-fetch and work only what's +`implemented` or `full_implementation` by the next review on its own, so after pushing, re-fetch and work only what's still open. But it's tooling and can glitch: if a finding stays open after a fix you're confident in, or a status plainly contradicts the code, don't loop re-fixing it — flag the discrepancy to the user and move on. (Resolving converges over rounds; a fix can also surface genuinely new findings, @@ -331,6 +339,9 @@ ## Record the outcome +Require explicit authorization for the specific status write; permission to fix code or push it +does not authorize closing findings. Prefer automatic re-attribution after a pushed fix. + Closing a finding is a **write** — it updates Qodo's review DB, restyles the finding's PR comments, re-renders the review summary, and releases the merge-policy block that finding holds. Two commands, and the distinction between them is the whole point: one says *the code changed*, the other says @@ -344,7 +355,7 @@ - **Batch per PR, one call.** Reconciliation runs once per call, not once per finding — so all the findings you implemented go in one `mark-implemented`, and all the ones sharing a dismissal reason go in one `dismiss`. Up to 100 ids. -- **`mark-implemented` only for code you actually changed and pushed.** It clears the merge gate +- **`mark-implemented` only when explicitly authorized and for code you actually changed and pushed.** It clears the merge gate without a review having verified the fix, so a wrong claim ships an unfixed finding as fixed. If another review round is going to run anyway, prefer letting it re-attribute the fix itself; reach for this when no further round will run before merge, or the gate must clear now. @@ -374,21 +385,20 @@ 4. Evaluate each: *"SQL built via string interpolation"* → real → recommend parameterizing the query in `db/orders.py`. *"Missing timeout on the outbound call"* → the client already sets a default timeout upstream → already satisfied → recommend skipping with that reason. -5. Present both with those recommendations and ask (multi-select) which to resolve — both unticked, the SQL - one marked *recommended*. Apply what the user picks, then report: "Resolved the SQL finding - (parameterized the query in `db/orders.py`). Skipped the timeout one — already set upstream — and 1 - informational (out of scope). Push and I'll re-check, or say 'watch' to loop until the review is clean." - (Had the user said `resolve … autofix`, I'd have applied the recommended fix directly, no prompt.) +5. The explicit request covers the supported action-required fix: parameterize the SQL query and + verify it. Report the timeout as already satisfied and the informational finding as out of scope; + neither is dismissed automatically. Report the local fix separately from the PR's review state. + Push only with separate covering authority, then check the review of the new head. ## Configuration Use `--json`, compare `review_session.commit_sha` with forge head metadata, and stamp the exact -skill/version/distribution provenance on the first Qodo call. Read and write capabilities are +skill/version/distribution provenance on the first authenticated Qodo call after the unadorned version probe. Read and write capabilities are discovered from the installed CLI catalog; rendered forge comments are never the data source. ## Error Handling -Treat null sessions, in-progress or stale commits, missing write capabilities, rate limits, and +Treat null sessions, running reviews (`started`), stale commits, missing write capabilities, rate limits, and tool-loop errors as explicit states. Preserve them in the report and never close a finding merely to make the review appear clean.
Full snapshot data
{
"description": "Read or resolve a pull request's Qodo review with the qodo CLI — fetch structured status, reviewed commit SHA, and findings for ANY PR as JSON, with optional extended details and citation evidence for audits, then optionally resolve open findings and record outcomes, once or until clean. Use this — never `gh`/`curl` scraping of review comments — for \"is the review clean on PR",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 359
},
{
"relative_path": "references/skill-updates.md",
"size_in_bytes": 1685
}
],
"name": "qodo-review-resolver",
"skill_md_contents": "---\nname: qodo-review-resolver\ndescription: Read or resolve a pull request's Qodo review with the qodo CLI — fetch structured status, reviewed commit SHA, and findings for ANY PR as JSON, with optional extended details and citation evidence for audits, then optionally resolve open findings and record outcomes, once or until clean. Use this — never `gh`/`curl` scraping of review comments — for \"is the review clean on PR #N\", \"get Qodo's findings for <pr> as JSON\", \"audit the review evidence\", \"show finding citations\", \"what did Qodo flag\", \"is this review up to date with head\", \"check before merging\", \"resolve my PR review\", \"fix the review findings\", or \"babysit this PR until it's clean\".\ntriggers:\n - \"Check the Qodo findings on this pull request\"\n - \"Audit the citation evidence for these Qodo PR findings\"\n - \"Resolve the open Qodo review findings on this PR\"\nowner: Qodo\nwhen_to_use: When you need to read or act on a pull request's Qodo review — check where it stands, see what it flagged, gate a merge on it being clean at head, or fix the open findings — for any PR, not just your own. It reads the review through qodo's managed tool (structured, git-provider-agnostic), so use it instead of scraping the rendered PR review comments with `gh`/`curl` (lossy, provider-specific, and easy to read stale against the head commit). It resolves findings in local code and then records the outcome on each finding through qodo's own tools (dismiss / mark-implemented, which clear the merge-policy block); it never posts to the git forge itself. Skip it for reviewing code you're writing locally before any PR exists (that's the pre-PR review), and for non-review PR chores (merging, labels, descriptions).\nmetadata:\n vendor: qodo\n version: \"1.4.7\"\n recommended: \"true\"\n package: \"qodo\"\n distribution: \"marketplace\"\n instruction_mode: \"embedded\"\narguments:\n - name: autofix\n description: Optional shorthand for authorizing supported fixes. An explicit fix request or covering implementation authority also permits those fixes without another prompt.\n optional: true\n---\n\n# Read & Resolve Findings\n\n## Description\n\nUse the `qodo` CLI to read a pull request's **review session** — its status, the commit that\nwas reviewed, and every finding with its resolution status — for **any** PR (yours or someone\nelse's). Request extended results when auditing citations or investigating a finding's supporting\nevidence, location, dismissal, or review-run history. Reading alone is a valid use: stop after the read to report where a review stands or\nwhat it flagged (e.g. to gate a merge on it being clean at head). To go further, **resolve the\nopen findings in code**, applying your own judgment (the review is a strong second opinion, not\ngospel). Apply supported fixes when the user has authorized them; otherwise present your assessment\nfor selection. Run once (report + authorized fixes) or as a watch loop (resolve →\nlet Qodo re-review the new commit → repeat until clean). When separately authorized, **record the outcome** on the findings\nyou settled — `mark-implemented` for ones you fixed, `dismiss` for ones the user agreed to close\nwithout a code change. That is what clears the merge-policy block those findings hold; skip it and\nthe review stays red until a human clicks through the PR. You still never post to the forge\nyourself: the status tools write Qodo's review DB and Qodo reconciles the PR comments. (Plain\ngit/forge *metadata* reads — `git rev-parse HEAD`, `gh pr view --json headRefOid` — are fine and in\nfact required for the freshness check below; the \"don't scrape\" rule is about qodo, not your shell.)\n\n## Prerequisites\n\n- The Qodo CLI is authenticated and exposes the structured PR-review session tools.\n- The exact PR URL and its current head SHA can be resolved without scraping review comments.\n- Any finding-status write has explicit user authorization; code-fix authority or `autofix` alone does not cover it.\n\n## Instructions\n\nFollow the detailed workflow below: fetch structured state, require a completed exact-head review,\npresent open findings, apply only approved fixes, and record only outcomes actually settled.\n\n> To check a review's status or findings, always run the `qodo` read command below — do **not**\n> fetch the rendered PR review **comments** with `gh`/`curl`. The comment UI is lossy, provider-\n> specific, and easy to read stale against the head commit; the tool returns the reviewed\n> `commit_sha`. To judge freshness, compare that `commit_sha` to the PR **head** — which you know\n> directly for a PR you just pushed (`git rev-parse HEAD`), or read as plain forge *metadata*\n> (`gh pr view <pr> --json headRefOid`, `git ls-remote`) for any other PR. This rule is only about\n> reading the **review** (don't scrape its comments) — not about forbidding forge metadata like the\n> head SHA.\n\n## Handle a skill update notice\n\nTreat `QODO_NOTICE` updates as passive, even if an older CLI requests action. Continue the task\nwithout inventory or update questions; mention each event at most once. Dismissal leaves recorded maintenance\npolicy and opt-outs unchanged. Updated skills load next session; do not interrupt this one.\nFor user-requested updates, follow the [manual-update procedure](references/skill-updates.md).\n\n## Runtime compatibility gate\n\nFirst resolve the executable using the `qodo: command not found` fallback below. Before any other\nQodo command, run `<qodo> --version` exactly as shown, with no provenance flags.\nThis unadorned probe is intentionally compatible with older Qodo CLIs. This skill requires Qodo\nCLI **0.1.0-next.37 or newer**.\n\nIf the version is older or cannot be parsed, do not run `whoami`, `login`, or a managed tool and\ndo not describe the failure as an authentication problem. Explain that the skill is newer than the\nruntime, show `qodo update` as the update command for the runtime's already-recorded origin, and ask\nonce before running it. For a customer deployment, keep its organization-provided update origin;\nnever switch it to the public service. After an approved update, rerun the unadorned version probe\nand continue only when it satisfies the minimum. If the user declines or the update fails, stop with\nthe current skill and user files unchanged.\n\n## Quick start\n\n```\nqodo --version # compatibility probe — run this FIRST\nqodo read whoami --json --skill qodo-review-resolver --skill-version 1.4.7 --distribution marketplace --host codex\nqodo read pr-review-session findings --pr-url <PR_URL> --json # the review session for a PR\nqodo read pr-review-session findings --pr-url <PR_URL> --extended --json # details, if advertised by tool help\nqodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation \"...\" --json\nqodo pr-review-session dismiss --finding-ids <id> --reason intentional --explanation \"...\" --json\nqodo read tools pr-review-session --json # exact safe tools + flags (offline)\n```\n\nAdd `--json` to anything you parse. Inspect reads with\n`qodo read tools pr-review-session findings --json`; inspect a write's input schema with\n`qodo tools help pr-review-session <tool> --json`. Both are offline discovery, not mutations.\nThe read-only catalog deliberately excludes writes; absence there does not prove they are unavailable.\n\n`unknown command` on `dismiss`/`mark-implemented` after authentication may be a stale local tool\ncatalog — refresh once as described below. If the commands are still absent, the workspace does\nnot currently expose PR-review writes; report that capability boundary instead of looping.\n\n**`qodo: command not found`?** That's PATH, not a missing install: GUI-launched agents (e.g.\nthe Claude Code desktop app) run shells with a minimal PATH. Retry with the absolute path\n`~/.qodo/bin/qodo` (or `$QODO_HOME/bin/qodo` if set) and keep using it for every `qodo`\ncommand here. Only if that file is missing too is qodo actually not installed; tell the\nuser to obtain a checksum-pinned installer command from Qodo or their organization's\nadministrator. Installers are served from https://get.qodo.ai, but never invent a digest\nor pipe an installer directly into a shell.\n\n**Sandbox auth diagnostic.** Missing credentials can mean inaccessible keychain access. When that\nis plausible, request one exact read-only `qodo read whoami` retry through the host's approval\nflow before recommending login. Stop on denial; that approval covers no other command. Reuse a\nsuccessful check in the same executable/workspace/deployment and execution context; request each\nrequired host approval. Network, TLS, service, and explicit authorization failures retain their\nown diagnosis, not a login recommendation or an automatic sandbox bypass.\n\n## Preflight\n\n1. **Auth and catalog.** Run `qodo read whoami` unless a successful check still covers this\n execution context. After the sandbox diagnostic when applicable, only explicit missing credentials\n call for login: preserve the organization's exact login command/endpoint, never guess or switch\n a customer deployment to Cloud. `No tool catalog cached` is not proof of missing credentials;\n refresh once with `qodo tools --refresh` and retry the check. Other failures retain their error\n and stop this workflow. After identity succeeds, an unknown managed command permits one catalog\n refresh and schema recheck. If still absent or `tool_unavailable`, report the missing capability;\n do not repeat login or refresh.\n2. **Resolve the PR.** Use the PR URL the user gives. If they don't name one and you're inside\n a git repo, infer the open PR for the current branch and **confirm it with the user before\n acting**. Never guess a PR URL.\n3. **Bind edits to the checkout.** Report-only reads may target any PR. Before any local fix,\n resolve the PR repository from provider metadata and the current checkout repository from its\n `origin`; normalize both to the full case-insensitive `owner/repo` identity. They must match\n exactly. A missing/ambiguous origin or mismatch means stop and ask the user to open the correct\n checkout — never apply a finding from one repository to another worktree. Use the PR branch\n or an isolated worktree for that PR, with local HEAD at the reviewed head (or a verified descendant\n produced by this same fix workflow). Merely having the commit in the repository is insufficient.\n Inspect local differences and preserve unrelated edits; never reset or switch a dirty worktree\n to satisfy this check. Repeat these checks if the target PR changes.\n\n## Fetch the review session\n\n`qodo read pr-review-session findings --pr-url <PR_URL> --json` returns:\n\n- `review_session` — the latest review run: `status`, `commit_sha` (**the last commit included in\n the review** — the code these findings describe), `started_at`. **`null` = the PR has no review\n yet** — tell the user and stop (nothing to resolve).\n- `findings[]` — every current finding, each with: `title`, `description`, `category`,\n `action_level` (`action_required` > `remediation_recommended` > `informational`),\n `attribution_status`, `git_sha`, `review_run_id`, `comment_id` / `inline_comment_id`.\n\nZero findings supports a clean verdict only for a complete, completed review at the current PR head.\n\n### Extended results for audits and investigation\n\nKeep compact reads for routine status polling. When the user needs supporting evidence or more\ndetail, inspect `qodo read tools pr-review-session findings --json`. Only if the schema declares\nthe `extended` boolean, use `qodo read pr-review-session findings --pr-url <PR_URL> --extended --json`.\nThe tool/API input is `extended: true`; omitted or false keeps the compact response.\nThis reads more stored data; it does not rerun or deepen the review.\n\nExtended results add finding locations and code snippets, dismissal reasons/explanations,\n`review_runs`, and `findings[].evidence` with `explanation` and `citations`. Preserve each\ncitation's source type, source reference, text and source-specific metadata in an audit output.\nCorrelate evidence with that finding's `id`, `git_sha`, `review_run_id` and `review_source`;\ncurrent findings can originate in earlier runs than `review_session`.\n\nNull evidence means unavailable; an empty citations list contains no recorded citations. An\nabsent evidence field can indicate an older backend: report that limitation without claiming\nthe finding has no supporting evidence. If `extended` is absent from the catalog, follow the\nexisting one-refresh recovery and check again; if still absent, report that extended reads are\nunavailable and keep using compact reads. Never send `--extended` to a catalog that lacks it;\ndo not invent an alternative flag or substitute scraped comments.\n\nIf the result has `qar_operation_result_truncated: true`, report an incomplete read, not an\nempty or clean review. Extended results describe current findings and recorded runs, not an\nimmutable history of every finding revision. Apply the freshness checks below before acting.\n\n## Read the session state FIRST (before trusting any finding)\n\nThe `review_session` tells you *whether the findings are real yet and what code they cover* —\ncheck it before acting:\n\n- **Is a review still running?** The API reports a running review as `started`; that is the polling state. For a status-only\n request, report that state and return; poll only when waiting is part of the requested task.\n `failed`, `aborted`, `skipped`, and `superseded` are non-success terminal states: report them\n and stop the loop. An unknown status is not success or permission to poll indefinitely.\n- **What commit do the findings describe?** `review_session.commit_sha` is the last commit the\n review included. If it's **behind the PR head**, the findings are **stale** — they don't reflect\n your latest code. Either the review hasn't run on the new commit yet (wait) or you're looking at\n an old run. Only trust findings when the session is `completed` AND its `commit_sha` is the commit\n you care about (the head, in a watch loop).\n\nAct only on a **completed review of the current commit**. A running or stale review cannot\nauthorize finding resolution. In watch mode, respect retry delays, recheck the forge head before\nclaiming clean, and stop if the review makes no progress rather than polling indefinitely.\n\n## Present the review state\n\nUse natural prose: **outcome → contextual explanation of changes and dispositions → verification\n→ remaining work**. For report-only requests, lead with the current review state and the impact\nof remaining findings. Credit Qodo once for the specific concerns its review surfaced; you own\nthe final assessment and recommended action. No branded headings, emoji banners, slogans,\nfooters, or repeated summary blocks. Use short issue titles or lists when useful.\n\nFor each finding, explain what could happen, under which conditions, and why it matters to the\nuser's intended change. Evaluate it against the code and available coding-session decisions and\nconstraints; retrieve PR context when needed, never invent a missing session. Cite the evidence\nand preserve finding references and reported category/level separately from your recommendation.\nOwn the fix, dismissal, or investigation decision and its rationale. A deliberate choice supports\ndismissal only when the implementation enforces its assumptions. Keep the tone collaborative\nand factual; do not routinely qualify Qodo's capability. Follow the existing scope and approval\ngates for edits and disposition writes; your technical assessment does not grant permission.\n\nName the PR, review status, and reviewed commit from structured state; compare with the forge\nhead before acting. Make stale, running, failed, or missing reviews explicit. Distinguish **code\nchanged**, **disposition recorded**, and **updated code reviewed**. Tests passing or a status\nwrite succeeding does not establish a clean review of the updated commit. Only a completed\nreview at the current head can support that verdict; report remaining findings and missing\nverification honestly. For example: “Addressed [risk] Qodo identified by [change], preserving\n[user decision]. [Verification]. The latest review covers [old SHA]; review of [head SHA] remains\noutstanding.” Use only actual outcomes. In watch mode, report meaningful state changes without\nrepeating the assessment on every poll or status write.\n\n## Triage\n\n- **Open vs done is `attribution_status`.** Classify the returned value, including the\n supported representations used by different deployments:\n - **OPEN — work these:** `pending`, `partial_implementation`, `not_implemented`,\n `focus_areas_edited`.\n - **CLOSED — leave these:** `implemented`, `full_implementation`, `dismissed`,\n `detected_after_merge`, `outdated`. Report unfamiliar values instead of silently excluding\n them from a clean verdict.\n - `action_level` is **severity**, not open-vs-closed. A closed finding can still be\n `action_required`.\n- **Order by `action_level`:** `action_required` first, then `remediation_recommended`; treat\n `informational` as optional and surface it, don't necessarily fix it.\n- Group open findings by file so you edit each file once.\n\n## Honor the user's instruction (optional scope)\n\nIf the user gave an instruction, treat it as a **filter over the open findings** and act only on\nthe matches — don't widen it:\n\n- **By action level** — \"resolve the action-required findings\" → only `action_level == action_required`;\n \"everything actionable\" → `action_required` + `remediation_recommended`.\n- **By category** — \"just the security findings\" → `category == Security` (same for correctness,\n performance, etc.).\n- **By specific finding** — \"fix finding #3\" / \"the SQL-injection one\" → match by `id` or `title`.\n- **Report-only** — \"what did the review find?\" / \"is it clean?\" → summarize the findings and their\n statuses, change no code.\n\nNo fix instruction or covering implementation authority → present for approval open `action_required` then\n`remediation_recommended`, and surface (don't auto-fix) `informational`. When an instruction is\nambiguous, state the scope you picked in one line before acting, so the user can redirect. Always\nreport which findings you **skipped** and why (out of scope / dismissed / informational) — never\nsilently drop one.\n\n## Two modes\n\nEach round follows **Resolve a finding**: evaluate and apply only fixes covered by existing user\nauthority (`autofix` or an explicit fix request); otherwise present and ask. Push authority is separate.\n\n**Once (default).** Fetch → evaluate every open finding (triage — all four OPEN statuses, not just\n`pending`) → present + ask if authority is missing → apply authorized fixes in code →\ncommit/push only within the user's authorization → summarize fixes and remaining findings.\nFor local-only fixes, report \"awaiting push\" and leave finding status unchanged. After a verified\npush, prefer the next review's automatic re-attribution; a manual status write additionally needs\nexplicit authorization and the checks in **Record the outcome**. Stop. Don't loop unless asked. Triage covers\n**all** open findings, but the picker only *offers* the actionable set —\n`action_required` then `remediation_recommended` — with `informational` surfaced separately,\nmatching the default scope above; put `informational` in the picker only when the user asks.\n(Offering isn't selecting: every box starts unticked.)\n\n**Watch until clean** (when the user says \"babysit\" / \"keep going until it's clean\"). Reuse explicit\nfix authority within its scope; monitoring alone does not authorize edits. After you resolve\nfindings and the fix commit is pushed, Qodo re-reviews the *new* commit — so:\n\n1. Note the PR's current head SHA — the commit you just pushed (`git rev-parse HEAD`), or, for a\n PR you didn't push, read it as forge metadata (`gh pr view <pr> --json headRefOid`). That's a\n metadata read, not review-comment scraping — it's fine.\n2. Follow **Read the session state FIRST** on each read: poll `started` only within the bounded\n watch; report non-success terminal or unknown states and stop. A completed older run is stale:\n allow a bounded wait for the new head's review to appear. Act only when the review is\n **`completed` AND its `commit_sha` equals that head SHA**.\n3. When fresh: if any OPEN findings remain (all four statuses — a `partial_implementation` is\n still open), resolve them and repeat; if none remain, report the\n review clean and stop.\n4. Bound it: stop after a few rounds with no progress and hand back to the user rather than\n looping forever.\n\n## Resolve a finding\n\nEvaluate Qodo's findings against the code, PR intent, and available session context. Own the final\ntechnical recommendation and rationale, while following the user's scope and approval below.\n\n**Evaluate each finding** against the actual code and the PR's intent, and form a recommendation:\n\n- **Sound and in scope** → a fix is warranted; note what you'd change (read `title` +\n `description`, locate the code — the `qodo-codebase-wisdom` skill's read tools help when it isn't\n local).\n- **Unsupported or already addressed** → recommend dismissal with code evidence. A deliberate\n choice supports dismissal only when the implementation enforces its assumptions.\n- **Unsure** → identify the evidence or check needed before deciding.\n\n**Report-only.** Return the assessment and stop; do not solicit edit approval for an explicit\nrequest to review without changes.\n\n**Present and ask only when edit authority is missing.** If `autofix`, an explicit fix request,\nor covering implementation authority already applies, skip this selection prompt and follow\n**Authorized fixes** below. Otherwise use the assessment above for each open, in-scope finding,\nkeeping its `action_level`/`category` and your recommendation, then ask **in a single\nprompt** which findings to resolve. Use whatever the host gives you: a multi-select if it has one\n(Claude Code's `AskUserQuestion`, say), otherwise a numbered list and \"reply with the numbers to\nresolve\". One prompt either way — don't ask per finding. **Nothing is pre-selected.** Mark which\nones you recommend, but the user must actively choose: this prompt is the last thing standing\nbetween a finding and an edit, so a bare Enter must resolve nothing. Resolve only what the user\npicks (edit as normal, matching the surrounding code); report the rest as skipped with your reason.\nOn this missing-authority path, do not edit before the user has chosen.\n\n**Authorized fixes.** `autofix` or an explicit request such as \"fix the action-required findings\"\nauthorizes supported code fixes within that scope; no special token or repeated confirmation is\nneeded. Existing implementation authority can also cover the correction. State your assessment\nbefore applying it. A status-only request grants no edit authority; ask once if scope is ambiguous.\nNeither fix authority nor monitoring authorizes finding-status writes (`dismiss` or\n`mark-implemented`) or a push. Report fixes and skipped findings.\n\nCommit/push per the user's workflow — ask before pushing unless they've told you to.\n\n**`attribution_status` is the intended signal** — a fixed finding is re-attributed to\n`implemented` or `full_implementation` by the next review on its own, so after pushing, re-fetch and work only what's\nstill open. But it's tooling and can glitch: if a finding stays open after a fix you're confident\nin, or a status plainly contradicts the code, don't loop re-fixing it — flag the discrepancy to the\nuser and move on. (Resolving converges over rounds; a fix can also surface genuinely new findings,\nwhich the watch loop picks up.)\n\n## Record the outcome\n\nRequire explicit authorization for the specific status write; permission to fix code or push it\ndoes not authorize closing findings. Prefer automatic re-attribution after a pushed fix.\n\nClosing a finding is a **write** — it updates Qodo's review DB, restyles the finding's PR comments,\nre-renders the review summary, and releases the merge-policy block that finding holds. Two commands,\nand the distinction between them is the whole point: one says *the code changed*, the other says\n*the code didn't and here's why*. Never use one to mean the other.\n\n```\nqodo pr-review-session mark-implemented --finding-ids <id>,<id> --explanation \"what you changed\" --json\nqodo pr-review-session dismiss --finding-ids <id>,<id> --reason <reason> --explanation \"why\" --json\n```\n\n- **Batch per PR, one call.** Reconciliation runs once per call, not once per finding — so all the\n findings you implemented go in one `mark-implemented`, and all the ones sharing a dismissal reason\n go in one `dismiss`. Up to 100 ids.\n- **`mark-implemented` only when explicitly authorized and for code you actually changed and pushed.** It clears the merge gate\n without a review having verified the fix, so a wrong claim ships an unfixed finding as fixed. If\n another review round is going to run anyway, prefer letting it re-attribute the fix itself; reach\n for this when no further round will run before merge, or the gate must clear now.\n- **`dismiss` needs the user's explicit go, per finding, every time — `autofix` does NOT cover it.**\n `autofix` is consent to *edit code*, which the next review re-checks; a dismissal closes a finding\n the review still believes in, is visible to the team, and nothing re-opens it. Present what you\n propose to dismiss and why, and dismiss only what the user names.\n- **`--reason`** (required): `false_positive` (the finding is wrong) · `intentional` (the code is\n deliberate and correct) · `deferred` (real, but out of scope for this PR) · `rejected` (understood\n and declined). Always add `--explanation` — a reviewer reads it later without your context.\n- **Read `results` per finding, don't assume the call succeeded as a whole.** It is a 200 even when\n individual ids fail: `not_found` (wrong id or wrong workspace) and `conflict` (already closed, or\n not linked to a PR) are terminal — don't retry them. `reconciled: false` means the DB change\n landed but the PR-side update didn't; re-running the same command is safe and idempotent, and the\n PR self-heals on its next review regardless. `already_dismissed` / `already_implemented` report the\n **stored** reason — a replay never overwrites the original.\n\n## Example\n\n**User: \"Resolve the action-required findings on https://github.com/acme/api/pull/318\"**\n\n1. `qodo read whoami` → logged in.\n2. `qodo read pr-review-session findings --pr-url https://github.com/acme/api/pull/318 --json`\n → `review_session`: `status: completed`, `commit_sha: a1b2c3d` (= the PR head, so findings are current);\n `findings`: 3 open (2 `pending`, 1 `partial_implementation`) — 2 `action_required`, 1 `informational`.\n3. Instruction filters to `action_required` → work those 2; the informational one is out of scope (report it, don't fix).\n4. Evaluate each: *\"SQL built via string interpolation\"* → real → recommend parameterizing the query in\n `db/orders.py`. *\"Missing timeout on the outbound call\"* → the client already sets a default timeout\n upstream → already satisfied → recommend skipping with that reason.\n5. The explicit request covers the supported action-required fix: parameterize the SQL query and\n verify it. Report the timeout as already satisfied and the informational finding as out of scope;\n neither is dismissed automatically. Report the local fix separately from the PR's review state.\n Push only with separate covering authority, then check the review of the new head.\n\n## Configuration\n\nUse `--json`, compare `review_session.commit_sha` with forge head metadata, and stamp the exact\nskill/version/distribution provenance on the first authenticated Qodo call after the unadorned version probe. Read and write capabilities are\ndiscovered from the installed CLI catalog; rendered forge comments are never the data source.\n\n## Error Handling\n\nTreat null sessions, running reviews (`started`), stale commits, missing write capabilities, rate limits, and\ntool-loop errors as explicit states. Preserve them in the report and never close a finding merely\nto make the review appear clean.\n\n## Guardrails\n\n- **Freshness = a completed review of the reviewed commit, not a timestamp.** Findings describe\n `review_session.commit_sha` and are only final once `status` is `completed`. After any push, treat\n them as stale until a `completed` review's `commit_sha` catches up to the PR head — otherwise\n you'll act on a mid-flight review or \"fix\" a commit the findings don't describe.\n- **Never post to the forge yourself.** The only writes you make are `dismiss` /\n `mark-implemented`, which go through Qodo and let it reconcile the PR. Do not call any forge-write\n tool (comments, approvals, labels, description) to \"resolve\" a finding — resolve it in *code*, then\n record the outcome.\n- **You may decline a finding you judge wrong** (with a clear reason). Dismissing it in the system is\n now possible but is the **user's** call, not yours — propose it, name the reason, and act only on\n their explicit go. On a real disagreement the user is the arbiter.\n- **Don't close what you didn't settle.** A finding you skipped for scope stays open — report it as\n skipped rather than dismissing it as `deferred` to make the list look clean.\n- **Don't guess** the PR URL — resolve it first; a `null` session means no review yet.\n- An `MT-TOOL-LOOP` or `MT-RATE-LIMITED` error means stop/back off and change approach, not retry.\n\nAfter authorized changes, report what improved, why each decision was made, what was verified,\nand what still needs attention. Keep local edits, recorded dispositions, and review state distinct.\n"
}SHA-256 of public snapshot: 1b297bd40fd9e3aa38ea722de70ed88026758e5e7d0300ef18800645cbdc71ab