Skip to content

fix(hooks): always set permissionDecision so Claude Code applies rewrites#3020

Closed
Nitjsefnie wants to merge 1 commit into
rtk-ai:developfrom
Nitjsefnie:fix/3018-permission-decision-ask
Closed

fix(hooks): always set permissionDecision so Claude Code applies rewrites#3020
Nitjsefnie wants to merge 1 commit into
rtk-ai:developfrom
Nitjsefnie:fix/3018-permission-decision-ask

Conversation

@Nitjsefnie

Copy link
Copy Markdown

Problem

rtk hook claude emits a hookSpecificOutput containing updatedInput but, on the default "ask" path, omits permissionDecision. Per the Claude Code hooks schema, updatedInput is only applied when permissionDecision is explicitly present, so Claude Code silently executes the original command and the rewrite has no effect.

Root cause

src/hooks/hook_cmd.rs had two paths that build Claude-shaped hookSpecificOutput and they disagreed:

  • The VS Code/Copilot handler (handle_vscode, ~line 153) already mapped AllowRewrite"allow" and AskRewrite"ask" and always emitted permissionDecision.
  • The native Claude Code handler (process_claude_payload, ~line 342) reduced the decision to a bool, only inserting permissionDecision: "allow" when allow == true. On AskRewrite the field was omitted entirely.

AskRewrite is the default verdict for rewritable commands when no explicit allow rule exists, so most Bash commands were rewritten in RTK's output but never actually changed in Claude Code.

Fix

Make process_claude_payload set permissionDecision unconditionally — "allow" for AllowRewrite and "ask" for AskRewrite — matching the existing correct path in handle_vscode.

Schema confirmation

The Claude Code hooks documentation states that for PreToolUse, updatedInput allows modifying tool input parameters, and the example shows it paired with "permissionDecision": "allow". Valid values are "allow", "deny", and "ask". See Claude Code hooks reference — PreToolUse Decision Control.

Regression-test evidence

Added tests covering both rewrite verdicts:

  • test_claude_allow_rewrite_sets_permission_decision_allow
  • test_claude_ask_rewrite_sets_permission_decision_ask

I temporarily reverted the fix while keeping the new tests. The AskRewrite test failed with:

assertion `left == right` failed
  left: Null
 right: "ask"

After restoring the fix, both new tests and the full suite pass.

Gates

  • cargo fmt --all --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test ✅ (2437 unit tests + integration tests)

Closes #3018

Prepared with AI assistance (Kimi K2.7 Code), human-reviewed before submission.

…ites

Claude Code ignores updatedInput when hookSpecificOutput omits permissionDecision.

The native Claude path (process_claude_payload) only inserted permissionDecision: "allow" for AllowRewrite, leaving AskRewrite without the field. AskRewrite is the default verdict, so rewrites were silently discarded.

Mirror the existing correct path in handle_vscode: set permissionDecision to "allow" or "ask" for every rewrite.

Co-Authored-By: Kimi K2.7 Code <noreply@kimi.com>
@CLAassistant

CLAassistant commented Jul 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Nitjsefnie

Copy link
Copy Markdown
Author

Withdrawing this PR — I'm not in a position to sign the CLA, so it can't proceed. The diff stays available on the branch if anyone wants to pick it up. Thanks!

@Nitjsefnie Nitjsefnie closed this Jul 16, 2026
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.

rtk hook claude omits permissionDecision in updatedInput responses, causing Claude Code to silently ignore command rewrites

2 participants