fix(review): restore the code-review marketplace plugin as a real surface - #1431
Conversation
…face Closes #1402. v0.15.1 and v0.15.2 reduced the plugin's enumeration of PR-review surfaces to two — the bundled `/code-review` command and the managed Code Review GitHub App service — and presented that enumeration as complete, stating that no installable `code-review` marketplace plugin exists. It does. Re-verified this session: `anthropics/claude-plugins-official`'s `marketplace.json` lists `code-review` (`./plugins/code-review`, category `productivity`) alongside `pr-review-toolkit`, and <https://code.claude.com/docs/en/code-review> confirms the bundled command's and the managed service's behavior as the current text describes them. ## Changes - `quality-gate/context/pr.md` — Boundary covers all three surfaces; the mutation gate again covers the plugin's comment-posting PR mode. - `fanout/SKILL.md` — orchestrator roster back to three plugins; the Boundary heading no longer asserts the two-surface framing. - `fanout/context/findings-normalization.md` — `code-review` parse contract restored, which returns the only referent to the Stage-1 "surfaces emitting no severity → DERIVE" rule. - `README.md` — `code-review` back in the optional-orchestrator roster. - `fanout/evals/evals.json` — `pr-comment-gate-opt-in` covers the plugin's PR mode alongside the other two mutating surfaces. - `CHANGELOG.md` + `plugin.json` — v0.15.3. The prior entries are corrected forward by the new one, not rewritten. The corrections those two versions got right are unchanged: bare `/code-review <target>` stays ungated, the managed service stays described as built-in/managed, and `codex` stays in the README roster. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
|
Warning Automated review did not complete — this is an infrastructure failure, not a review verdict. Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."
Re-running the job, or pushing a new commit, will retry the review. |
|
Warning Automated security review did not complete — this is an infrastructure failure, not a review verdict. Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."
Re-running the job, or pushing a new commit, will retry the review. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0df7fc3a71
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The plugin takes a PR as its only target and its final step comments the surviving findings back onto that PR; it has no session-returning mode. "Its PR mode" and "when the branch has an open PR" both implied an alternative that does not exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a0e842dcd0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A PR is its only target, so `run-everything` step 3's "invoke every installed optional orchestrator" would dispatch it on an ordinary local branch as a surface that cannot produce findings. The roster entry now carries an applicability gate alongside the mutation gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8dd5d7f164
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…n-code-review-marketplace-claim
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
The plugin posts its findings to the PR rather than returning them, so an opted-in dispatch yields nothing for normalization to read and the restored table row had no input. The roster entry and the parse contract now name the retrieval step that supplies it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 2s —— View job I'll analyze this and get back to you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 442167a4c4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Line numbers from LLM reviewers drift — treat inferred lines as approximate and keep dedup noise-tolerant. | ||
|
|
||
| **Not in this table:** the bundled `/code-review` command and the managed Code Review GitHub App service (SKILL.md "Boundary — built-in/managed surfaces, not marketplace plugins"). The managed service posts its findings to the PR rather than returning them to normalize; bare `/code-review` is report-only, but is itself a multi-agent review of the same diff whose output has no documented schema to parse. Neither is dispatched as a fan-out leaf here. | ||
| **One row's raw text is not returned to the session:** the `code-review` plugin ends by posting its surviving findings as a PR comment, so the dispatch itself yields no parsable output. After an opted-in dispatch, fetch that comment (`gh pr view <n> --json comments --jq '.comments[-1].body'`, matching the plugin's `### Code review` heading) and feed the body to Stage 0 as this surface's raw text. Skip the retrieval and the row has no input — then the surface is not normalized and belongs in `## Surfaces` as a skip, not silently absent from the report. |
There was a problem hiding this comment.
Select the plugin comment rather than the latest comment
When another bot or reviewer comments after the opted-in plugin run but before normalization, .comments[-1].body returns that unrelated comment; despite the prose mentioning the ### Code review heading, the expression performs no heading, author, or timestamp filtering. Stage 0 can therefore normalize arbitrary PR discussion as code-review findings and corrupt the persisted report, so select the matching comment created by this invocation instead.
Useful? React with 👍 / 👎.
…patch window (#2077) ## Summary Discharges review thread `PRRT_kwDOTCGFQM6Tzl-v` (PR #1431) on `plugins/review/skills/fanout/context/findings-normalization.md:21`. Stage 0 retrieved the `code-review` plugin's PR comment with `gh pr view <n> --json comments --jq '.comments[-1].body'`. The prose named the plugin's `### Code review` heading, but the expression applied no heading, author, or timestamp filter — so any bot or reviewer commenting between the dispatch and the fetch was normalized as `code-review` findings and written into the persisted report. Retrieval is now an **ID-set difference**. `SKILL.md` records the PR's comment IDs before dispatching; the fetch selects the heading-bearing comment whose ID is new — the comment that did not exist before this invocation, which is what the finding asked for. A `length == 1` guard refuses to guess: zero new heading-bearing comments (the dispatch produced none) and two or more (a genuinely ambiguous window) both yield empty output, documented as a `## Surfaces` skip. ### Why not a timestamp window An earlier revision of this branch used heading + a `createdAt` cutoff. Three review threads on this PR showed that shape could not hold, and all three are fixed here rather than argued with: - **Identity, not time.** A cutoff narrows *when* a comment arrived but never establishes *who* wrote it. A third party quoting the `### Code review` heading mid-dispatch still won the match — the exact interleaving the change set out to close. An ID-set difference has no such gap. - **The snapshot has to live in the dispatching step.** `SKILL.md` Step 1 dispatches and Step 2 only *then* opens `context/findings-normalization.md`, so a "capture this before dispatching" instruction sitting in the normalization context could never have run in time — it would have recorded the plugin's own comment as the cutoff and skipped every opted-in run. The snapshot moved to `SKILL.md`'s `code-review` bullet. - **Shell state does not cross a tool-call boundary.** The cutoff was carried in `$since` between two code blocks separated by a dispatch, i.e. a separate tool call with a fresh shell. It is now recorded as a value and spliced into the retrieval as a literal. ## Verification `id` and `createdAt` are both real fields of `gh pr view --json comments`, confirmed live against this repository: ```text ["author","authorAssociation","body","createdAt","id","includesCreatedEdit", "isMinimized","minimizedReason","reactionGroups","url","viewerDidAuthor"] ``` Pre-fix control, run with real `jq` on one fixture — a pre-dispatch snapshot of `["IC_1","IC_2"]`, then a post-dispatch payload holding a stale `### Code review` comment, this run's `### Code review` comment, and an interleaved bot comment posted after it: | Expression | Result | | --- | --- | | `.comments[-1].body` (pre-fix, on `origin/main`) | `interleaved bot comment posted during the window` — the defect | | ID-set difference (this branch) | `### Code review … THIS RUN findings` | Same fixture, both trees, different results. Further cases exercised on that fixture: | Case | Result | | --- | --- | | A second new comment quoting the heading | empty — refuses to guess | | Dispatch produced no comment | empty — skip | | Empty snapshot, one heading match present | that comment's body | Gates green from the worktree root against `origin/main`: `check-changed-skills.sh`, `check-changelog-parity.sh` (`--check`, `--check-bump`, `--check-order`), `check-skill-portability.sh`, `check-shell-portability.sh`, `check-contract-clause-coverage.py`, `check-contract-slice-prune.sh` (`--check`, `--check-diff`), and `markdownlint-cli2` over `plugins/review/**/*.md` (27 files, 0 errors). `SKILL.md` is 121 lines and `findings-normalization.md` 74 — both well under the 500-line cap. ## Related N/A No linked issue --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
reviewplugin's three-surface framing after#1326/#1351shipped a falsetwo-surface premise (that no installable
code-reviewmarketplace plugin exists).anthropics/claude-plugins-official'smarketplace.jsonlistscode-reviewalongsidepr-review-toolkit;plugins/code-review/commands/code-review.mddefines/code-review:code-review. Re-verified live this session.pr.md,README.md,fanout/SKILL.md,fanout/context/findings-normalization.md,fanout/evals/evals.json, andCHANGELOG.md(0.15.3 entry). The two behavioral corrections the0.15.1/0.15.2entries got right (bare/code-reviewstays ungated; the managed App staysdescribed as built-in/managed) are preserved unchanged. History is corrected forward — the prior
false CHANGELOG entries are left as written, with a new entry explaining what was wrong and why.
plugins/code-review/commands/code-review.mdtakes a PR as its only target and its final step is"use the
ghbash command to comment back on the pull request with the result"(
allowed-toolsgrantsBash(gh pr comment:*)); there is no mode that returns findings to thesession instead.
Test plan
plugins/review/tests/standards-binding.test.sh— 8/8 pass, run against this branch.markdownlint-cli2 'plugins/review/**/*.md'— 27 files, 0 issues.fanout/evals/evals.jsonparses.origin/mainbefore opening this PR.Closes #1402
Related
quality-gate/context/pr.mdand
README.mdfanout/SKILL.mdandfanout/context/findings-normalization.md; this PR reverses both🤖 Generated with Claude Code