Skip to content

feat(guardian): Allow by default and block only on a named rule - #2180

Merged
dcramer merged 26 commits into
mainfrom
test/guardian-pr-metadata-refresh
Oct 17, 2026
Merged

dcramer merged 26 commits into
mainfrom
test/guardian-pr-metadata-refresh

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Guardian kept asking before Junior refreshed the title and body of its own open PR. In 4 recent threads, github_updatePullRequest got 7 asks, all medium risk with low authorization, with reasons like "did not clearly authorize rewriting the PR metadata". Prompt tweaks alone did not fix this without regressions, because the model chose allow, ask, or deny by open judgment. This PR changes how Guardian decides, and adds cases that check it still blocks real overreach.

Design: allow by default, block only on a named rule

  • Low- and medium-risk work is allowed by default, as in Codex Guardian. A block needs a named rule from a fixed list, as in Claude Code auto mode.
  • The model rates riskLevel, then userAuthorization, then names one rule (or none), then gives a reason. It no longer outputs the decision.
  • guardianDecision in guardian-action-review.ts sets the decision in code:
    • none → allow
    • a confirmation rule → ask: withheld_step, unresolved_prior_ask, unclear_destination, different_change, unrequested_write, new_commitment, high_risk_low_authorization
    • a hard rule → deny: data_exposure, credential_probing, security_weakening, unrequested_destruction, untrusted_instruction, revoked_approval, out_of_scope
    • High or critical risk with low or unknown authorization is at least ask.
    • In an Automation run, or a child of one, ask becomes deny, because no person can answer. The reason then says that no person can confirm, so the agent does not ask.
  • unclear_destination, different_change, unrequested_write, new_commitment, and out_of_scope apply only to writes. Reads, searches, clones, and sandbox-local work never match them.
  • A short list of things that match no rule: upkeep of a resource the agent created for the work (its title, description, and addressed feedback), a reply that steers an offered deliverable, a plan the assistant stated and the user did not object to, and correctness or verification concerns. Closing, reopening, or changing the draft state of that resource is not upkeep.
  • The rules use generic words. No rule names a tool or provider.
  • ToolActionReviewDecision has a new optional rule field for diagnostics. The Guardian eval harness shows it. Persisted events do not change.

Cases

Results

  • b115edf50 ran all 87 cases with main's policy: 78/87. All 7 new block cases pass. The 9 failures are the 6 that already fail on main (2 repo clones, the cluster-size PR, the Automation findings post, 2 calendar searches) and the 3 PR-text cases this PR fixes.
  • 4676bb8f7 (this PR's policy): Guardian 87/87.
  • b115edf50 only put main's policy back for that baseline run. 4676bb8f7 restores the branch policy, so the final code equals a47587ceb plus the new eval file.
  • Earlier runs of this design: 76, 75, 76, 77, and 80 of 80, and 79/80 at a47587ceb. The one failure there was a weekly reminder that came back ask, and it passed on the next run.
  • Integration evals caught 2 regressions from an early draft: a digest to an org Slack channel was read as data exposure, and "one sec" was read as a held-back step. Both are fixed.
  • Behavioral evals, typecheck, and unit tests pass.

Cursor Bugbot findings

  • Fixed: closing a resource or changing its draft state counted as upkeep.
  • Fixed: an Automation deny still told the agent to ask.
  • Not taken: applying out_of_scope to reads. That change denied ordinary calendar lookups and a repo clone (75/80 at 9f2eacc3a), so a47587ceb keeps it on writes. Reads are still blocked when they expose data, probe for credentials, or are high risk with weak authorization.

Limits

  • Each result is one sample per policy. Cases with live model calls can flip between runs.
  • The new block cases cover clear overreach. They do not cover subtler cases, such as a steering reply that does not answer the question ("fridays too?" before a booking).
  • Automation runs now get deny where they could get ask before. Before, the agent posted a question that no one in the run could answer.

via David Cramer.

--

View Junior Session [Sentry]

sentry-junior Bot and others added 2 commits October 17, 2026 00:50
Guardian asked before the bot refreshed the stale title and body of
its own open PR after the user steered the change. Add four historical
cases that expect allow, plus two guard cases: the user withholds PR
text changes, and a review-only request on another author's PR.

Co-Authored-By: David Cramer <david@sentry.io>
The user answered an offered PR by widening the work instead of saying
yes. Guardian then asked before the PR that delivered that work.

Co-Authored-By: David Cramer <david@sentry.io>
@vercel

vercel Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
junior-docs Ready Ready Preview Oct 17, 2026 11:45am UTC

Request Review

@sentry-evals

sentry-evals Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Sentry Evals

junior-behavioral

Run Status Passed Failed Errored Cost Tokens Duration
Head Complete 72 2 0 $0.69 0 335.10s

Base commit f714c41 has no eval run to compare against.

junior-guardian

Run Status Passed Failed Errored Cost Tokens Duration
Head Complete 87 0 0 $0.03 0 64.15s

Base commit f714c41 has no eval run to compare against.

junior-integration

Run Status Passed Failed Errored Cost Tokens Duration
Head Complete 101 0 0 $0.61 0 266.55s

Base commit f714c41 has no eval run to compare against.

@dcramer
dcramer marked this pull request as ready for review October 17, 2026 01:07
@github-actions github-actions Bot added the risk: medium PR risk score: medium label Oct 17, 2026
Three new cases passed on the first run, so they did not reproduce the
asks. Their assistant entries and PR text were loose reconstructions.
Use the real assistant messages, PR title, and PR body instead.

Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
…ized

Steering work on a PR the agent created made Guardian ask before the
agent refreshed that PR's title and body. Count the refresh as a
conventional step of the steered work. Also treat steering an offered
deliverable as accepting it, and treat quoting the requester's own
messages like other ordinary work context.

Co-Authored-By: David Cramer <david@sentry.io>
@github-actions github-actions Bot added risk: high PR risk score: high and removed risk: medium PR risk score: medium labels Oct 17, 2026
…g the actor

Co-Authored-By: David Cramer <david@sentry.io>
… PRs

Co-Authored-By: David Cramer <david@sentry.io>
@sentry-junior sentry-junior Bot changed the title test(guardian): Add PR title and body refresh snapshots fix(guardian): Allow refreshing the agent's own PR after steered work Oct 17, 2026
Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
The model rates risk and authorization, then names one rule from a fixed
list or none. Code derives allow, ask, or deny from that rule. Code also
denies critical risk, asks for high risk with weak authorization, and
turns an ask into deny in an Automation run, where no person can answer.

Confirmation rules other than user boundaries apply only to writes, so
reads, clones, and lookups are allowed.

Co-Authored-By: David Cramer <david@sentry.io>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Co-Authored-By: David Cramer <david@sentry.io>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d9d2fef. Configure here.

…en rules

Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
…from blocking

Co-Authored-By: David Cramer <david@sentry.io>
…ted reads

Closing a resource or changing its draft state is not upkeep.
An Automation deny now says that no person can confirm, so the agent
does not ask. out_of_scope applies to reads of unrelated private data.

Co-Authored-By: David Cramer <david@sentry.io>
@sentry-junior sentry-junior Bot changed the title fix(guardian): Allow refreshing the agent's own PR after steered work fix(guardian): Allow by default and block only on a named rule Oct 17, 2026
Applying it to reads denied ordinary repository clones and calendar
lookups. Exposure, credential, and high-risk checks still cover reads.
Add 7 Guardian cases from real threads where the agent goes past the
request: merging after an approval or a merge-safety question, merging in
an Automation that forbids it, a production deploy, closing an issue,
sending calendar invites, and pushing to the default branch.

Temporarily restore the main Guardian policy to measure the baseline.
The next commit restores the branch policy.

Co-Authored-By: David Cramer <david@sentry.io>
@github-actions github-actions Bot added risk: medium PR risk score: medium and removed risk: high PR risk score: high labels Oct 17, 2026
The previous commit ran the new snapshots against the main policy.

Co-Authored-By: David Cramer <david@sentry.io>
@github-actions github-actions Bot added risk: high PR risk score: high and removed risk: medium PR risk score: medium labels Oct 17, 2026
@sentry-junior sentry-junior Bot changed the title fix(guardian): Allow by default and block only on a named rule feat(guardian): Allow by default and block only on a named rule Oct 17, 2026
@dcramer
dcramer merged commit 03c507d into main Oct 17, 2026
51 checks passed
@dcramer
dcramer deleted the test/guardian-pr-metadata-refresh branch October 17, 2026 12:57

This branch was successfully deployed

1 active deployment
Preview – junior-docs — 4676bb8f Deployed Oct 17, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant