Repository navigation
feat(review): add pr-review-cli, a review lane on run-claude-cli - #862
Conversation
A reusable workflow that runs the code or security review on the run-claude-cli launcher with the two-job pattern: the role's API key in review-key, its subscription token in review-subscription only on an exact handoff or with no key (REVIEWS_KEY_EXHAUSTED=true skips the key's model call). The model jobs are read-only with Read, Grep, Glob, Skill and Agent under dontAsk, the review plugin from claude-code-plugins' default tip, and the diff and context as files named by the FULL DIFF, REVIEW SCOPE and PR CONTEXT prompt lines. A status job with no model publishes the structured review through the new publish-review action: anchors checked against the diff at the head, HTML comments stripped, a claude-lane footer, the publish gate's credential scan, one COMMENT review, the marker and the completion notice. Summary mode posts nothing and never ends red. pr-review.yml and pr-review-security.yml are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b986353771
ℹ️ 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 status job receives the review as one environment variable, and Linux refuses a string over 128 KiB, so a large valid review could stop the publish step from starting. The schema now caps comments at 25 and bodies at 3,000 characters, and the extract step calls a serialized review over 100,000 bytes incomplete instead of passing it on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 45s —— View job Security review complete
No security issues found in this PR at What I looked at
GitHub Actions hardening concerns (expression injection, trigger safety, permission scoping, pinning) are zizmor's lane; I deferred to it per this skill's instructions and didn't re-check those here. claude-lane-summary: lane=claude-security-review sha=ad522dfbaf61fa0e839384471f2a8725411de27f run=39891824847 |
|
Claude finished @kyle-sexton's task in 3m 38s —— View job Claude code review in progress
|
|
claude-security-review has reviewed this pull request through ad522df; a later push is reviewed from there. |
|
Claude finished @kyle-sexton's task in 6m 21s —— View job Code review —
|
|
claude-review has reviewed this pull request through ad522df; a later push is reviewed from there. |
…contract (#848) Refs: melodic-software/claude-code-account-rotation#259 ## Summary Registers the runner-policy contract for ci-workflows v0.63.0 `pr-review-cli.yml` (`8778094736e414233110f3e0d6d9948628ba77b5`), so claude-code-plugins can move its live security review lane onto it. ## Fix - `policy.json`: a hosted-only contract, `fixedRunsOn: ["ubuntu-24.04"]`, the inputs `lane`, `publish`, `role`, `model-args`, `allowed-bot-sender-ids`, `allowed-author-ids`, `docs-only-paths`, `incremental-review` and `cli-version`, and both reviews-role secrets: `CLAUDE_API_KEY` from `REVIEWS_CLAUDE_API_KEY` (tried first) and `CLAUDE_CODE_OAUTH_TOKEN` from `REVIEWS_CLAUDE_CODE_OAUTH_TOKEN` (after a key handoff). - `README.md`: the v0.63.0 entry. - `runner-policy.test.mjs`: pins the contract; the secret expressions are escaped template literals. Supersedes the key-only #847. ## Verification - `node --test components/runner-policy/runner-policy.test.mjs`: 336 pass, 0 fail. - `node components/runner-policy/runner-policy.mjs --root .`: passed. - This branch's analyzer run against the claude-code-plugins security caller that moves to `pr-review-cli.yml@8778094` with both secrets: passed; the currently synced policy rejects the same caller with `runner-target-contract`. - biome and markdownlint clean on the changed files. ## Related - melodic-software/ci-workflows#862 - #842 (precedent), #847 (closed, key-only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

No related issue: second step of moving the Claude review lanes onto the run-claude-cli launcher (follows #861); claude-code-plugins' shadow and cutover callers consume it.
Summary
The two review lanes run on
claude-code-actionwith one subscription token. This adds a reusable workflow that runs either lane on therun-claude-clilauncher: the funding role's API key first, its subscription token after a credit stop, a 401 or 402, or no key, and nothing after a 403. A summary mode lets a caller run it as a shadow beside the live lanes, posting nothing.pr-review.ymlandpr-review-security.ymlare unchanged.Fix
.github/workflows/pr-review-cli.yml, inputslane: code|securityandpublish: comments|summary, three jobs on the two-job patternintake-triage.ymluses:review-keyruns the key leg;review-subscriptionruns the token leg only on an exacthandoff == 'true'orcredential-present == 'false', onubuntu-24.04, repeating every step. The repository variableREVIEWS_KEY_EXHAUSTED=truemakes the key job report no key without a model call.contents: read,pull-requests: read,cache-mode: none, noid-token, no second secret; tools Read, Grep, Glob, Skill, Agent under--permission-mode dontAskwithSkill(review:<lane skill>)andAgentallowed and Bash disallowed; an init-message permission-mode check; leg limits of 11 and 13 minutes; background tasks off.pull_requestevents only, open, not a draft, head repository equal to the base, no Dependabot as actor or author, bots only by sender id.pr-review.yml, and both lanes now get all three prompt lines (FULL DIFF: ... is in,REVIEW SCOPE: incremental ... That change is in,PR CONTEXT: ... are in). The incremental note points at the FULL DIFF file in place ofgh pr diff, since the model has no shell..lane/plugins/reviewfrom claude-code-plugins' default-branch tip. A head that holds.lanefails.structured-output-fileand its facts from the scanned log, checks shapes and caps, and raises the findings count to the comment and manifest-flag counts..github/actions/publish-review(no model), run by theclaude-review-status/security-reviewstatus job:claude-lane: <lane>to each comment, and withholds everything on a blocking hit from claude-code-plugins'lib/publish-gate.mjs, which it reads at that repository's tip.claude-lane-review-completenotice aspr-review.ymldoes, withaccount=fallbackafter the subscription leg.pr-review-shadowandpr-review-security-shadow. The status job writes a job summary and a scanned JSON artifact (findings, comments, turns, total_cost_usd, models, leg and wall time) named per lane and attempt.actions-expression.cjsevaluatesvarsandsecretspaths. The lane-outcome emitter test lists the two new lane jobs.Verification
node --test .github/scripts/*.test.cjs: 610 pass, 0 fail.pr-review-cli.test.cjs(16) covers: which job holds which secret; read-only model jobs; the gate turning away fork, draft, closed, other-event, Dependabot and unlisted-bot runs; the exact handoff compare; key and subscription steps equal; the exhausted-key variable; the never-red rule forsummary, empty and unknown values (steps continue on error, timeouts add up with headroom); the prompt-line contract; the extract step on a good review and on every gap it checks; and run-claude-cli'sreadConfig/cliArgsaccepting the launcher step's inputs for both lanes.publish-review.test.cjs(13) covers: commentable lines against a hand-numbered patch; the batch rejection; the footer and HTML strip; the post, marker and notice text; the fallback account; the rerun skip; a withheld credential versus a warn-only label; each failure class in comments mode; the skip carry-forward; summary mode never failing or writing across failure inputs and a throwing API; and the shadow report.continue-on-error, and letting summary mode throw, each fail the never-red tests.run-claude-clitests 72 pass;report-lane-outcometests 74 pass. actionlint (only the repository's ignored$/andcache-modemessages), zizmor, biome over.github/scripts, markdownlint, typos and gitleaks: clean.$/references start cleanly in a caller. The first caller's own run is that check.Related
structured-output-file).🤖 Generated with Claude Code