Skip to content

Conversation

@owenlin0
Copy link
Collaborator

@owenlin0 owenlin0 commented Dec 22, 2025

Summary
This PR makes “ApprovalDecision::AcceptForSession / don’t ask again this session” actually work for apply_patch approvals by caching approvals based on absolute file paths in codex-core, properly wiring it through app-server v2, and exposing the choice in both TUI and TUI2.

  • This brings apply_patch calls to be at feature-parity with general shell commands, which also have a "Yes, and don't ask again" option.
  • This also fixes VSCE's "Allow this session" button to actually work.

While we're at it, also split the app-server v2 protocol's ApprovalDecision enum so execpolicy amendments are only available for command execution approvals.

Key changes

  • Core: per-session patch approval allowlist keyed by absolute file paths
    • Handles multi-file patches and renames/moves by recording both source and destination paths for Update { move_path: Some(...) }.
    • Extend the Approvable trait and ApplyPatchRuntime to work with multiple keys, because an apply_patch tool call can modify multiple files. For a request to be auto-approved, we will need to check that all file paths have been approved previously.
  • App-server v2: honor AcceptForSession for file changes
    • File-change approval responses now map AcceptForSession to ReviewDecision::ApprovedForSession (no longer downgraded to plain Approved).
    • Replace ApprovalDecision with two enums: CommandExecutionApprovalDecision and FileChangeApprovalDecision
  • TUI / TUI2: expose “don’t ask again for these files this session”
    • Patch approval overlays now include a third option (“Yes, and don’t ask again for these files this session (s)”).
    • Snapshot updates for the approval modal.

Tests added/updated

  • Core:
    • Integration test that proves ApprovedForSession on a patch skips the next patch prompt for the same file
  • App-server:
    • v2 integration test verifying FileChangeApprovalDecision::AcceptForSession works properly

User-visible behavior

  • When the user approves a patch “for session”, future patches touching only those previously approved file(s) will no longer prompt gain during that session (both via app-server v2 and TUI/TUI2).

Manual testing
Tested both TUI and TUI2 - see screenshots below.

TUI:
image

TUI2:
image

@owenlin0 owenlin0 force-pushed the owen/fix_allow_this_session_apply_patch branch 4 times, most recently from 5600af9 to 7f9b921 Compare January 5, 2026 22:03
@owenlin0 owenlin0 changed the title fix: implement 'Allow this session' for apply_patch fix: implement 'Allow this session' for apply_patch approvals Jan 5, 2026
@owenlin0 owenlin0 force-pushed the owen/fix_allow_this_session_apply_patch branch 2 times, most recently from dde3e77 to 5e96d2b Compare January 5, 2026 22:38
@owenlin0 owenlin0 marked this pull request as ready for review January 5, 2026 22:55
@owenlin0 owenlin0 requested review from bolinfest and jif-oai and removed request for bolinfest January 5, 2026 23:00
@jif-oai
Copy link
Collaborator

jif-oai commented Jan 6, 2026

@codex review

Copy link
Collaborator

@jif-oai jif-oai left a comment

Choose a reason for hiding this comment

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

It seems to work but it looks a bit like reimplementing what is already partially there. We should be able to re-use the exact same workflow as what exist but with just change the keys we use for approval

Accept,
/// Approve and remember the approval for the session.
AcceptForSession,
Decline,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we really want this? How is it different from Cancel? (in any case, add a docstring please)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

unfortunately they behave differently and both are used by VSCE. added docstrings

decline - does not abort the turn
cancel - aborts

}
}

fn map_file_change_approval_decision(
Copy link
Collaborator

Choose a reason for hiding this comment

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

This logic sounds supper hacky but it was already there so I guess out of scope

@chatgpt-codex-connector
Copy link
Contributor

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@owenlin0 owenlin0 force-pushed the owen/fix_allow_this_session_apply_patch branch 2 times, most recently from 755a8e5 to 39eb1ad Compare January 6, 2026 22:47
@owenlin0 owenlin0 force-pushed the owen/fix_allow_this_session_apply_patch branch from 39eb1ad to fc1c0fd Compare January 6, 2026 23:01
@owenlin0
Copy link
Collaborator Author

owenlin0 commented Jan 6, 2026

@jif-oai Removed the extra store and refactored things a bit so that Approvable / with_cached_approval takes a list of keys instead of a single key. This is because a single apply_patch call can modify multiple files, and we need to make sure all files have been previously approved

@owenlin0
Copy link
Collaborator Author

owenlin0 commented Jan 7, 2026

@codex review

Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f1afe46d0b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Collaborator

@jif-oai jif-oai left a comment

Choose a reason for hiding this comment

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

Ok after the processing of all my comments

} else {
ReviewDecision::Approved
}
if let Some(reason) = retry_reason {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any reason why you extract it from the cache?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

hmm I don't follow - this checks whether there's a retry_reason, which based on codex's explanation happens when the tool orchestrator is trying to retry the command outside of the sandbox (dependent on the right approval policy)

!matches!(policy, AskForApproval::Never)
}

fn exec_approval_requirement(
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we have an assess_patch_safety check prior to triggering the runtime, and it returns a SafetyCheck::AutoApprove / AskUser / Reject value and we now convert AskUser to ExecApprovalRequirement::NeedsApproval to trigger start_approval_async, which will in turn check the cache.

This is needed now since I moved approval checking from core/src/apply_patch.rs to ApplyPatchRuntime::start_approval_async to be more in-line with the shell and unified_exec tools

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added a docstring

@owenlin0 owenlin0 force-pushed the owen/fix_allow_this_session_apply_patch branch from 178a094 to df96740 Compare January 7, 2026 19:25
@owenlin0 owenlin0 enabled auto-merge (squash) January 7, 2026 20:03
@owenlin0 owenlin0 merged commit 66450f0 into main Jan 7, 2026
26 checks passed
@owenlin0 owenlin0 deleted the owen/fix_allow_this_session_apply_patch branch January 7, 2026 20:11
@github-actions github-actions bot locked and limited conversation to collaborators Jan 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants