Skip to content

[Bug] Built-in write policies miss Claude Code's MultiEdit / NotebookEdit: "Require Approval for File & Shell Operations" doesn't ask, and "Report-Only (Deny File Writes)" doesn't deny (#51) - #88

Open
jan21deepak wants to merge 1 commit into
mainfrom
cursor/fix-write-policies-multiedit-notebookedit-94da
Open

Conversation

@jan21deepak

@jan21deepak jan21deepak commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Opened automatically by Cursor Forge as a same-repo PR on jan21deepak/omnigent
after the Cloud Agent pushed cursor/fix-write-policies-multiedit-notebookedit-94da (not against an upstream parent).

Fixes #51.

Cursor agent: bc-5139d770-ca59-4d14-89b0-466a087994da


Note

Medium Risk
Touches policy enforcement for file-mutating native tools; the change closes bypass holes rather than loosening rules, with regression tests added.

Overview
Fixes a gap where Claude Code MultiEdit and NotebookEdit could bypass built-in write policies that already covered Write / Edit.

Adds omnigent/policies/native_tools.py with shared CLAUDE_NATIVE_EDIT_TOOLS and claude_native_write_path() (handles path, file_path, and notebook_path). worktree_guard, read_only_os, and ask_on_os_tools now use those helpers so approval prompts, worktree confinement, and report-only denials apply to all four native edit tools. Session routes import the same constant instead of duplicating it locally.

Tests cover NotebookEdit path gating and MultiEdit / NotebookEdit in read_only_os and ask_on_os_tools previews.

Reviewed by Cursor Bugbot for commit 7c37f3a. Bugbot is set up for automated code reviews on this repo. Configure here.

Built-in ask_on_os_tools, read_only_os, and worktree_guard each maintained
their own incomplete Claude Code write-tool name sets. MultiEdit bypassed
approval and NotebookEdit bypassed read-only enforcement; worktree_guard
also missed notebook_path when resolving targets.

Introduce omnigent.policies.native_tools as the single source of truth for
CLAUDE_NATIVE_EDIT_TOOLS and shared path extraction (path/file_path/
notebook_path). Wire all three policies to it and re-export from server
session common constants.

Co-authored-by: jan21deepak <jan21deepak@users.noreply.github.com>
@jan21deepak

Copy link
Copy Markdown
Owner Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Empty path blocks alternate keys
    • claude_native_write_path now skips empty strings so a blank path falls through to file_path/notebook_path, restoring worktree_guard denial of escapes.

Create PR

Or push these changes by commenting:

@cursor push c356d9a2c9
Preview (c356d9a2c9)
diff --git a/omnigent/policies/native_tools.py b/omnigent/policies/native_tools.py
--- a/omnigent/policies/native_tools.py
+++ b/omnigent/policies/native_tools.py
@@ -21,6 +21,8 @@
     """
     for key in _CLAUDE_NATIVE_PATH_KEYS:
         value = args.get(key)
-        if isinstance(value, str):
+        # Skip empty strings so a blank ``path`` falls through to
+        # ``file_path`` / ``notebook_path`` (same as ``or``-chain fallback).
+        if isinstance(value, str) and value:
             return value
     return ""

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 7c37f3a. Configure here.

for key in _CLAUDE_NATIVE_PATH_KEYS:
value = args.get(key)
if isinstance(value, str):
return value

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty path blocks alternate keys

Medium Severity

claude_native_write_path returns the first string value among path, file_path, and notebook_path, including empty strings. That differs from the prior path or file_path logic. When path is "" but file_path or notebook_path holds the real target, worktree_guard treats the call as having no path and ALLOWs instead of validating an escape.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7c37f3a. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants