Skip to content

Re-evaluate the pending approval queue when a grant widens - #288

Merged
TheGreatAxios merged 6 commits into
mainfrom
cl-4863-apply-new-permission-grants-to-already-queued-approval
Aug 4, 2026
Merged

Re-evaluate the pending approval queue when a grant widens#288
TheGreatAxios merged 6 commits into
mainfrom
cl-4863-apply-new-permission-grants-to-already-queued-approval

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • A scope-widening grant (session, project, or global) now re-evaluates the pending approval queue and drains any already-queued permission requests it covers, instead of leaving them to re-prompt one at a time
  • Project-scoped grants carry the minting repo's cwd so they only drain requests from that repo; cross-repo requests still prompt
  • Provider-model grants only drain requests matching the active model, mirroring evaluate()'s own matching rules

Verification

  • bun run typecheck && bun run build && bun test — full suite passes (3570/3570)
  • New coverage: src/tui/hooks/use-gates.test.ts (session/project/global/provider-model reconciliation, including the cross-repo negative case) and src/permission/permission.test.ts (grant cwd tagging)

Closes CL-4863

@linear-code

linear-code Bot commented Aug 1, 2026

Copy link
Copy Markdown

CL-4863

@TheGreatAxios
TheGreatAxios force-pushed the cl-4863-apply-new-permission-grants-to-already-queued-approval branch 2 times, most recently from 8e4814e to 8f07cd0 Compare August 2, 2026 04:49
A scope-widening grant (session, project, or global) now drains any
already-queued permission requests it covers instead of leaving them to
re-prompt one at a time. Project-scoped grants carry the minting repo's
cwd so they only drain requests from that repo; cross-repo requests still
prompt. Provider-model grants only drain requests matching the active
model, matching evaluate()'s own matching rules.
A queued shell request could auto-drain from a newly minted grant even
when it referenced a secret path or a restricted target, because
reconciliation only matched the grant pattern and skipped the guards
evaluate() enforces first. Requests like a queued .env read now stay
queued and prompt normally when a broader grant is minted.
Extracts the secret-path, restricted-path, and shell-authz-block guards
evaluate() runs before consulting any grant into one predicate,
preGrantGuardReason, called from both evaluate() and
isRequestCoveredByGrant. Previously isRequestCoveredByGrant only checked
the secret-path and restricted-path guards, not the shell-authz block
reason; that omission was not independently exploitable (evaluate()
already denies a block-reason command before it is ever queued, so a
queued request has always already cleared it), but folding it into the
shared predicate means a future guard only has to be added once and
both call sites stay in sync automatically.

Also fixes an ordering bug in evaluate() itself: the exact-full-command
grant shortcut ran before the block-reason check, so a stored grant for
a hard-denied multi-segment command (e.g. a pipe to a shell) could skip
the deny path entirely. Reordered so the block-reason check always runs
first.
The gate builds its path restriction once from the session cwd, but
reconciliation rebuilt one from the request's cwd. A sub-agent request
carries its own worktree, so a relative path that escapes that worktree
resolved inside a known root and read as unrestricted, letting a broad
grant drain a request the gate had already ruled restricted. The gate
now hands the coverage predicate to onGrant so the anchor cannot differ.
@TheGreatAxios
TheGreatAxios force-pushed the cl-4863-apply-new-permission-grants-to-already-queued-approval branch from 8f07cd0 to 66631b5 Compare August 4, 2026 00:12
…aths

Positive case: a provider-model grant drains when the active model matches.
Restricted-path coverage uses an absolute path so the path-restriction
fixture actually fires.
@TheGreatAxios
TheGreatAxios marked this pull request as ready for review August 4, 2026 02:58
@TheGreatAxios
TheGreatAxios merged commit 143bad1 into main Aug 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant