Skip to content

CL-9341: fingerprint hidden-shell declines through the canonical coercion - #1204

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-9341-shell-decline
Sep 29, 2026
Merged

TheGreatAxios merged 2 commits into
mainfrom
cl-9341-shell-decline

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Hidden-shell decline fingerprint: denialFingerprint(rawCall, cwd) = stableRequestId(callForIdentity(rawCall), cwd, ...), so an operator decline suppresses the coerced run_shell retry with the identical reason on the middleware, decide, and reactor paths.

  • denialFingerprint derives from callForIdentity instead of name-only canonicalization; decide() fingerprints the raw call; evaluate() passes the raw call with the deny/timeout-never-cache guard unchanged; resolveSuspended rebuilds its key through the same helper (inline {id:""} form deleted).
  • No tool-aliases change: looksLikeCodexShellArgs already ignores native cwd/timeout, so coercion is idempotent on coerced run_shell (asserted in tests).
  • Audit: stableRequestId has no other callers; remaining canonicalToolName/withCanonicalToolName uses (grant minting, authorize identity cache, classify, grants) are policy/grant concerns, not denial keys — left intact.
  • Tests extend the hiddenShellArgv harness: middleware argv decline suppresses coerced + raw retries, workdir-to-cwd variant, reactor authorizeCall+resolveSuspended path with middleware-identical reason, plain run_shell regression, coercion idempotency.

Note: repo typecheck/build currently fail on origin/main from a stale oauth-core pin (callbackTargetFor missing in the installed github-version package); unrelated to this change.

Fixes CL-9341

…cion

A hidden shell call declined by the operator must suppress its coerced run_shell retry with the identical reason. denialFingerprint now derives the key from callForIdentity(rawCall) instead of a name-only canonicalization, so raw, coerced, and fresh-id retries share one denial entry on the middleware, decide, and reactor paths. resolveSuspended rebuilds its key through the same helper; coercion is idempotent on coerced run_shell because looksLikeCodexShellArgs ignores native cwd/timeout, so tool-aliases needs no change. The workdir case rides inside arguments while the fingerprint cwd stays the session cwd; a suspended request cannot round-trip a coerced cwd (buildRequests keeps only command), so reactor-path workdir declines re-ask fail-safe. No grant/deny policy or wording changes.
@linear-code

linear-code Bot commented Sep 28, 2026

Copy link
Copy Markdown

CL-9341

…ment

Reactor-path declines of workdir-scoped hidden shell record a {command}-keyed denial while same-workdir retries look up a {command, cwd} key, so the retry re-asks fail-safe and only cwd-less retries over-deny fail-closed. Locks both limits with keeper tests; no behavior change.
@TheGreatAxios
TheGreatAxios merged commit 7f2c8f6 into main Sep 29, 2026
13 checks 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