Repository navigation
Move Semgrep triage from Claude Code to Pi - #30
Merged
Merged
Conversation
Contributor
Author
|
Picked ulziibay-kernel to review: touched the changed code in |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 75835da. Configure here.
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.

Summary
Moves the Semgrep triage agent in
semgrep.ymlfrom Claude Code (claude -p) to Pi, using the same setup as the other Pi workflows: Node 22,@earendil-works/pi-coding-agent,PI_PREFERRED_MODEL, andANTHROPIC_API_KEY/OPENAI_API_KEY.The agent no longer gets GitHub credentials. It used to run with
--dangerously-skip-permissions, a shell, and the caller'sGITHUB_TOKEN, and post the review itself. Now the work is split by step, the same waypr-risk.ymldoes it:GITHUB_TOKEN):scripts/semgrep_triage.py gathermoves the Semgrep findings from the merge commit Semgrep scanned onto the PR head, usinggit diff -U0between the two, and drops findings on lines only the base branch added. It writes the PR's commentable diff lines and the location and author of every existing inline comment, then checks out the PR head. The agent's files, the line numbers, the diff ranges, and the reviewcommit_idtherefore all refer to the same commit.--tools read,grep,find,ls).--no-approvekeeps.piresources in the PR checkout from loading, and--no-context-fileskeeps the checkout'sAGENTS.mdandCLAUDE.mdout of the instructions. The checkout no longer persists the token in.git/config. Pi's final response is a JSON object withcomments(path, line, body) andomitted.GITHUB_TOKEN):semgrep_triage.py postdrops comments that aren't on a Semgrep finding, fall outside the PR diff, or are on a line that already has a comment. It re-reads existing comments before posting, keeps at most 5, and posts one review.Output contract
The PR output is unchanged and matches what recent triage runs actually posted:
event=COMMENT, with inline comments on the flagged lines andcommit_idset to the PR head SHA.No actionable security findings.scanandtoo-many-findingsjobs, thefindings_countoutput, the inputs, and thesemgrep-resultsartifact are untouched.The prompt's triage rules and comment-body requirements are carried over word for word. Only the
ghinstructions were replaced: the agent now reads the gathered files and returns JSON.Secrets and callers
@mainwithsecrets: inheritand grantcontents: read/pull-requests: write.semgrep.ymldeclares noworkflow_callsecrets, soOPENAI_API_KEYreaches it the same wayANTHROPIC_API_KEYalready does. No caller changes are needed.PI_PREFERRED_MODEL(org variable) and the key for that model's provider (org secret) to be visible to every caller repo. IfPI_PREFERRED_MODELis missing, triage fails withSet the PI_PREFERRED_MODEL organization variableinstead of silently skipping.Rollout note
The triage job fetches the prompt and
scripts/semgrep_triage.pyfrommain, as it already did for the prompt. That means this PR's own self-test can't exercise the new triage path. For a few minutes after merge, raw.githubusercontent.com's cache can serve the old prompt or a 404 for the script. During that window, the triage job fails visibly (::error::or a curl error) and posts nothing. It is not the requiredscan / scancheck.Validation
actionlint(with shellcheck) onsemgrep.ymlandsemgrep-tests.yml: the only remaining note is the existing SC2086 info in the untouchedCount findingsstep.scripts/test_semgrep_triage.py(21 tests, including a real git base/PR/merge fixture where the base branch shifts the PR's lines, also run with a file name that needs literal pathspecs), run in CI by the newsemgrep-tests.yml. It covers diff-line parsing, result parsing, and comment filtering (finding, diff, and existing-comment checks, the 5-comment cap, the omitted count). It also tests the review payload and the credential boundaries: no token in the agent step, read-only tools,--no-approve, a checkout without persisted credentials, model keys only in the agent step, and step order. Mutation checks confirmed that addingGH_TOKENto the agent step, addingbashto its tools, or persisting checkout credentials each make the tests fail. Mutation checks also confirmed that removing the merge-to-head line shift, or posting onGITHUB_SHAinstead of the head, fails the tests. Allscripts/test_*.pysuites pass (62 tests).AGENTS.md, and a.pi/settings.json. Pi (openai/gpt-5.5,--thinking max, the exact flags above) returned valid JSON with one comment on the injection line and skipped the test-file finding.postagainst a stubbedghproduced the expected singleCOMMENTreview.mainas the baseline: no new findings on this branch, so the self-test's triage job will skip.