feat: restore Agent Shin on safe triggers with staged rollout mechanics - #33011
feat: restore Agent Shin on safe triggers with staged rollout mechanics#33011mateo-berri wants to merge 4 commits into
Conversation
Reintroduces triage_pr_with_llm.yml and review_gate.yml, removed in #30784 because they ran on pull_request_target. Both now run only on workflow_dispatch (plus the review gate's daily schedule sweep), so fork authors cannot fire them and no privileged context is ever exposed to a fork-controlled event. Instant reaction to fork PR events is provided by the agent-shin GitHub App bridge, which dispatches these workflows with the PR number when AGENT_SHIN_ENABLED is true.
Greptile SummaryThis PR restores two Agent Shin workflows (
Confidence Score: 5/5Safe to merge. All destructive paths are gated behind exact-string env-var checks, no pull_request_target trigger exists, and remove_label handles absent labels gracefully. The trigger surface change is the most sensitive part of this PR and was handled correctly: both new workflows use workflow_dispatch (requiring actions:write) with no pull_request_target. The label-pair state machine is idempotent and well-tested. The Greptile gate on reconsider runs before any LLM call, preventing budget abuse. 247 tests cover every new branch. No files require special attention.
|
| Filename | Overview |
|---|---|
| .github/scripts/triage_with_llm.py | Core triage script extended with Greptile-score gate, NOT_READY_LABEL pair reconciliation, lite mode with LITE_NOTICE_MARKER dedup, and linked-issue bypass disabled in reconsider mode. |
| .github/workflows/review_gate.yml | New workflow using workflow_dispatch + daily schedule. SHA-pinned actions, exact-string checks for AGENT_SHIN_ENABLED and AGENT_SHIN_MODE. |
| .github/workflows/triage_pr_with_llm.yml | New workflow using workflow_dispatch only. Requires AGENT_SHIN_ENABLED=true AND DISPATCH_CLOSE=true for the destructive path. |
| .github/workflows/triage_reconsider.yml | Routes open-PR reconsiders to --review-gate instead of --reconsider. Lite mode and policy URL env vars wired in. |
| tests/test_litellm/test_github_review_gate.py | Added label-pair lifecycle tests and full lite-mode branch coverage. |
| tests/test_litellm/test_github_triage_with_llm.py | Added Greptile-gate tests, rewrote linked-issue reconsider test to verify bypass is disabled, added label-pair assertions. |
| tests/test_litellm/test_github_triage_workflows.py | Added static guardrail tests for open-PR reconsider routing and exact-string lite-mode checks. |
Reviews (3): Last reviewed commit: "feat: staged rollout mechanics for Agent..." | Re-trigger Greptile
|
Generated by Claude Code |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Adds the pieces needed for the 3-stage public rollout: - red 'not ready' label paired with 'ready for review'; the review gate reconciles the pair on every run and reconsider flips it on reopen - lite mode (AGENT_SHIN_MODE=lite): the review gate never closes and instead posts a one-time 'closes start in 7 days' notice linking the policy blog post (AGENT_SHIN_POLICY_URL); labels still reconcile - stricter reconsider for closed PRs: requires a Greptile confidence score of at least 4/5 (missing score fails with a comment pointing at @greptileai) and bypasses the linked-issue short-circuit so the QA evidence rubric always applies; a pass reopens and tags ready - reconsider on an OPEN PR now runs the review gate so the label pair flips immediately instead of waiting for the daily sweep - PR rubric tightened: bug fixes need before AND after evidence; command proof from a custom script must include the script source (collapsible section or linked gist) - default triage model bumped to gpt-5.6-luna
|
Generated by Claude Code |
|
🚅 Hi, thanks for the PR! I'm Agent Shin, the automated triage bot for this repository. What's this and why am I getting it? I read the description against our contribution rubric. Here's how it lined up: What you got right:
What's still missing:
If the description isn't updated in the next 24 hours, I'll auto-close this PR. That's not us saying we don't care about the change; we want the open-PR list to mirror what a maintainer can act on right now, so contributors don't get lost in a backlog. A closed PR is a soft "park this for later," not a rejection. Take your time; everything below still works after the close. During the grace period: just update the PR description with the missing pieces. No need to ping me; I'll re-check on the next sweep and skip the auto-close if it now passes. See what counts as QA proof for the full rubric (a linked issue alone isn't enough; it covers context, not proof). If the PR does get auto-closed in 24 hours, you still have easy recovery paths:
Internal BerriAI contributors: this rubric doesn't apply to you; ping a maintainer. (I'm an LLM, so I'm not infallible. If you think I got this wrong, ping a maintainer; they'll override me.) |
Relevant issues
Follow-up to #30784, which removed these two workflows because they ran on
pull_request_target(see also #30433, where they were introduced)Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
zizmor audit of the three Agent Shin workflows at commit 13f3462, confirming the dangerous trigger stays gone:
Workflow files are only dispatchable once they exist on the default branch, so the live end-to-end proof runs after merge. Reviewer steps, all dry-run and side-effect free while
AGENT_SHIN_ENABLEDis unset:gh workflow run "Agent Shin — PR triage" -f pr_number=<open external PR> -f close=falsegh workflow run "Agent Shin — review gate" -f pr_number=<same PR> -f close=false::notice::line confirming dry-run mode and no comment/label/close on the PR itselfAGENT_SHIN_MODE=lite, re-run step 2, and check the step summary showswould-notify-lite(the one-time 7-day notice preview) instead ofwould-closefor a failing PR; unset the variable afterwards@agent-shin reconsideron a bot-closed PR that has no Greptile score and check the run summary showswould-reconsider-needs-greptilepointing the author at@greptileaiType
🚄 Infrastructure
Changes
Restores
triage_pr_with_llm.ymlandreview_gate.yml, which #30784 deleted because they ran onpull_request_target. The bodies are the same as the deleted versions except for the trigger surface and the lines that depended on ittriage_pr_with_llm.ymlnow runs only onworkflow_dispatch.review_gate.ymlruns onworkflow_dispatchplus its original daily 09:30 UTC schedule sweep, which #30784 also deleted and which this PR brings back. Neither workflow can be fired by a fork author:workflow_dispatchrequiresactions:write, so only maintainers and the agent-shin bridge app can trigger them. Thepull_request_target-specific plumbing (EVENT_PR, the force-dry-run branch for automatic PR events, and the conditionalOPENAI_API_KEYexpression keyed on event name) is removed, with the close/dry-run gating onAGENT_SHIN_ENABLEDkept identicalInstant reaction to fork PR events, the one thing
pull_request_targetprovided that these triggers cannot, is restored by a separate Cloudflare Worker (private repo agent-shin). It receives GitHub Apppull_requestwebhooks, verifies the HMAC signature, and dispatches these two workflows with the PR number. It refuses to dispatch unless the repo variableAGENT_SHIN_ENABLEDis exactlytrue, preserving the old guarantee that an external user cannot force paid LLM calls by churning fork PRs while the bot is in dry-run. The bridge's GitHub App carries onlyactions:write,variables:read, andmetadata:read, so the privileged triage logic keeps running exclusively as base-repo code inside ActionsOn top of the restore, this PR adds the mechanics for the staged public rollout:
The review gate now maintains a label pair instead of a single label:
ready for reviewon pass,not readyon fail, reconciled idempotently on every run so the pair always shows the current verdictLite mode: while repo variable
AGENT_SHIN_MODEis the exact stringlite, the review gate never closes anything and instead posts a one-time notice that closes start in 7 days, linking the policy blog post fromAGENT_SHIN_POLICY_URLand deduped via a hidden HTML marker. Labels still reconcile and regression comments quote the 7-day window instead of the 24h grace. Any other value of the variable, including unset, gives full behavior, mirroring the fail-safe exact-string convention used forAGENT_SHIN_ENABLEDReconsider on a closed PR is now held to the full reopen bar: the PR must carry a Greptile confidence score of at least 4/5 (a missing score fails fast, before any LLM spend, with a comment walking the author through
@greptileaiand the QA evidence requirements), and the linked-issue short-circuit is bypassed so the rubric's end-to-end QA evidence check always applies. A pass reopens the PR and swaps the label pair toready for review. Reconsider on an open PR now runs the review gate for that PR, so an author who just fixed their description gets the tag flipped immediately instead of waiting for the daily sweepThe PR rubric is tightened to match the rollout policy: bug-fix proof must show the failure before the change and the fix after, and command-based proof produced by a custom script only counts when the script source is visible in the body (a collapsible section is fine) or a linked gist
The default triage model moves to
gpt-5.6-lunaTests: 247 passing across the Agent Shin suites, including new coverage for the label pair lifecycle, every lite-mode branch (one-time notice, dedup, dry-run, regression wording, never-closes-even-past-grace), the Greptile reconsider gate (missing score, low score, dry-run, PR-only), the linked-issue bypass in reconsider mode, the model default, and static workflow guardrails pinning the exact-string
litecomparison and the open-PR-to-review-gate routingFinal Attestation