Add /review-contributor-pr safety prescreen command (#2751)#2752
Merged
Conversation
Read-only prescreen that scans an outside contributor's PR for prompt injection aimed at downstream LLM agents and for unsafe outside code (arbitrary execution, exfiltration, build/install hooks, CI tampering), then emits a SAFE / NEEDS-REVIEW / UNSAFE verdict gating whether other Claude commands should run against the PR. Reuses /review-pr worktree isolation; makes no commits and runs nothing from the PR.
brendancol
commented
May 31, 2026
Contributor
Author
brendancol
left a comment
There was a problem hiding this comment.
PR Review: Add /review-contributor-pr safety prescreen command (#2752)
This PR adds one file, .claude/commands/review-contributor-pr.md, which is a slash-command prompt rather than Python. The library's correctness, backend-parity, and performance checks don't apply, so I scoped this review to the command's own logic: do its bash snippets work, and does it actually catch what it claims to?
Blockers (must fix before merge)
-
.claude/commands/review-contributor-pr.md(the 2a grep, plus the same pattern in 2b and 3f): every recursive grep is piped throughgrep -v '\.claude/worktrees/'to skip nested worktrees. The problem is that the scan root$RCPR_WTis itself always a.claude/worktrees/...path, both when reusing a/rockoutworktree and when the command creates its ownpr-N-prescreenworktree. Sogrep -r ... "$RCPR_WT" | grep -v '\.claude/worktrees/'drops 100% of matches, and the injection and execution scans always come back empty. That produces a false SAFE, the one outcome this command exists to prevent. I checked it: grepping the new file for "ignore previous" through that filter returns 0 lines even though the file contains that exact phrase. Fix: swap thegrep -r ... | grep -vpattern forgit -C "$RCPR_WT" grep -nE 'pattern' -- '*.py' '*.md' .... git grep only searches tracked files, so nested worktrees (untracked) drop out for free and the scan root stops poisoning the filter.
Suggestions (should fix, not blocking)
- Steps 1.5 and 2 read from
git diff origin/<baseRefName>...HEAD, which assumesorigin/<base>is present locally. In a freshly created worktree that usually holds because the object store is shared, but agit -C "$RCPR_WT" fetch origin <baseRefName>before the diff would make the snippet robust when it's run standalone on a stale checkout.
Nits (optional improvements)
- The 2b zero-width grep and the 3f execution grep carry the same
grep -v '\.claude/worktrees/'tail as the Blocker. Folding them into the same git-grep fix keeps the three scans consistent.
What looks good
- The injection-hardening contract at the top is the right call. Saying up front that all PR content is untrusted data, and that imperative text is a finding rather than an instruction, is what a prescreen needs.
- Worktree isolation reuses the proven
/review-prpattern, including the already-in-a-worktree detection, so it composes cleanly when run first inside/rockout. - The
VERDICT:/RECOMMENDATION:header is machine-greppable, which makes the gate usable by downstream automation. - The verdict rubric biases toward the cautious choice and is explicit that SAFE only covers the two threat classes, not correctness.
Checklist
- Bash snippets work as written -- NO: the self-excluding grep filter breaks the core scans (Blocker)
- Worktree isolation pattern matches the proven /review-pr approach
- Command is hardened against the untrusted content it reads
- Verdict output is machine-greppable for gating
- No changes to xrspatial/ source; scope is one command file
- N/A: algorithm/backend/NaN/dask/benchmark checks (no numeric code in this PR)
The recursive scans piped through 'grep -v .claude/worktrees/' to skip nested worktrees, but the scan root $RCPR_WT is itself always under .claude/worktrees/, so the filter dropped every match and the injection and execution scans always returned empty (false SAFE). Replace the 'grep -r ... | grep -v' pattern in the 2a/2b/3f scans with 'git -C $RCPR_WT grep', which searches tracked files only and excludes untracked nested worktrees for free. Also fetch the base ref before the Step 1.5 diff so it works on a stale standalone checkout.
brendancol
commented
May 31, 2026
Contributor
Author
brendancol
left a comment
There was a problem hiding this comment.
Follow-up review: Add /review-contributor-pr safety prescreen command (#2752)
Re-reviewed after commit 2705e7f.
Blockers
- None. The self-excluding
grep -v '.claude/worktrees/'filter is gone. All three scans (2a instruction injection, 2b zero-width, 3f execution) now usegit -C "$RCPR_WT" grep, which searches tracked files only and excludes untracked nested worktrees without a path filter. Verified:git grepfor "ignore previous" now returns the expected lines (it returned 0 before the fix), with zero nested-worktree noise.
Suggestions
- None outstanding. The
git fetch origin <baseRefName>before the Step 1.5 diff was added, so the diff holds up on a standalone stale checkout.
Nits
- None outstanding.
Disposition of the first-pass findings
- Blocker (self-excluding grep filter): fixed.
- Suggestion (fetch base before diff): fixed.
- Nit (2b/2f consistency): fixed as part of the same git-grep change.
Nothing left to iterate on.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2751
Adds
/review-contributor-pr, a read-only safety prescreen for pull requests from outside contributors. It runs first, before/review-pror any/rockoutfollow-up touches the PR, and answers one question: is it safe to let the other Claude commands operate on this PR?eval/exec/subprocess/pickle), network and exfiltration calls, credential/environment access, writes outside the repo, build/install/import-time hooks, and CI/.githubtampering — scoped to what the PR actually changes.VERDICT: SAFE | NEEDS-REVIEW | UNSAFEline plus a recommendation, so the result is greppable as a gate for downstream automation.The command is hardened against the content it reads: an explicit contract at the top states that all PR content is untrusted data, any imperative text found in the PR is a finding to report rather than an instruction to follow, and the run never executes, builds, imports, or fetches anything from the PR. It reuses
/review-pr's worktree isolation and makes no commits.Test plan
.claude/commands/*.mdfiles; verification is by running the command against representative PRs (a clean PR → SAFE, a PR with an injected instruction in a docstring → finding + NEEDS-REVIEW/UNSAFE)./review-prpattern.No changes to
xrspatial/; this adds one command file under.claude/commands/.