Skip to content

feat(codex): add PreToolUse hook support#2033

Open
BEOKS wants to merge 1 commit into
rtk-ai:developfrom
BEOKS:feat/codex-pretooluse-hook
Open

feat(codex): add PreToolUse hook support#2033
BEOKS wants to merge 1 commit into
rtk-ai:developfrom
BEOKS:feat/codex-pretooluse-hook

Conversation

@BEOKS
Copy link
Copy Markdown

@BEOKS BEOKS commented May 22, 2026

Summary

  • add native Codex PreToolUse hook installation and runtime support
  • block denied Codex commands with explicit PreToolUse deny output
  • update docs to reflect Codex hook integration

Testing

  • cargo fmt --all
  • cargo clippy --all-targets
  • cargo test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: BEOKS <lee01042000@gmail.com>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 22, 2026

CLA assistant check
All committers have signed the CLA.

@aeppling aeppling self-assigned this May 22, 2026
@aeppling
Copy link
Copy Markdown
Contributor

aeppling commented May 22, 2026

Hey @BEOKS

Thanks for addressing this, here is a review for this to be valid.

Still open to this and discuss
I'll go further into review once we have found a correct solution for this.

Blocking question: updatedInput rewrite is unverified end-to-end (version-dependent silent failure)

Value of this PR rests on one link in the chain: RTK emits an allow decision carrying the rewritten updatedInput command. RTK emitting the correct payload is verifiable (and the unit tests confirm it), but Codex honoring it is not verified anywhere in this PR, and had issues in the past.

Why there's genuine doubt:

So the behavior is version-dependent: deny is the old, universally-supported primitive, while updatedInput-apply is newer and only stabilized later.

What I'd like to confirm before this can be considered valid:

  • Did you verify it end-to-end on a real Codex binary ; run a raw git status, see it execute as rtk git status, and confirm the entry shows up in rtk gain --history? An empty history after a Codex session would itself be the silent failure.
  • Which codex --version did you confirm the rewrite takes effect on? A short transcript or screenshot would settle it.
  • On a version where it isn't applied, does it silently run the original command (no savings), or error?

Happy to discuss how to handle it; handling falls back when updatedInput isn't honored would be the best options. Open to your take.

In anyway, the RTK context when init should tell to prefix "rtk" with some examples, but we want to aim full transparency at best, so at one point, we hope we will be able to remove totally this context driven RTK rewrite. I do not like and deny and retry approach because it will cost API more tokens and is against our transparency principle.

Design note: Cross-agent permission leakage (Claude's deny rules silently govern Codex)

process_codex_payload calls permissions::check_command(), which (src/hooks/permissions.rs:92–98, 145–155) loads deny/ask/allow rules only from .claude/settings.json / ~/.claude/settings.json

Consequences in a Codex session:

  • A user who has Claude deny rules (e.g. blocked git push in Claude) will have those commands hard-blocked in Codex with "Blocked by RTK permission rule" ; a denial with no rewrite suggestion and no path forward.
  • Ask-classified commands become auto-allowed in Codex (since the rewrite path always sends allow), silently dropping the user's "ask" intent.
  • Pure-Codex users (no .claude/) are unaffected (everything → Default → rewrite), so it hides in testing but bites mixed users if there are.
  • Codex has its own permission model (approval modes, PermissionRequest hooks per the docs). Projecting Claude's config onto it could be error prone

Aware of current state in other integrations

I'm aware that this is also case for other current integrations that can inherit from this, this may become a design issue once most of agent have their permissions system, if you agree with this we could maybe avoid replicating this here as well.

Permissions system

Codex have its own decision system we should use transparently, RTK should not interfer with any usage of CLI and reflect the original behavior at best.

  • Deny side: sources the decision from Claude's .claude/settings.json (wrong config), not Codex rules.
  • Allow/ask side: always sends allow, overriding Codex's approval_policy (suppresses the prompt).
  • Only the OS sandbox survives (can't be bypassed from a hook).

Summary

I have still few things to note here, but let's try solve this first and then we'll move forward :)

Thanks for contributing to RTK !

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.

3 participants