Rules can't strictly prevent unauthorized edits; the Agent still modifies files

I’ve explicitly specified in .cursor/rules/*.mdc that certain paths are “accessible but not editable,” for example:

> Accessible but not editable:
>
> * `packages/*.tsx`

(I’ve also tried using packages/**/*.tsx and adding natural language emphasis like “DO NOT EDIT”, but the files still get modified.)

In practice, the Agent still directly edits these files. The rules don’t act as a hard block. It seems like Rules are just soft constraints at the prompt level, which the model can simply ignore.

Is there a better way to enforce stricter constraints?

Hey, thanks for the request. Your diagnosis is correct. Rules from .cursor/rules/*.mdc are guidance level. They get injected into the model context as a strong hint, but they are not a hard runtime block. The model can ignore them, so you can’t reliably prevent editing via rules. Similar discussion with the same conclusion: The agent is ignoring the Rules

But what you want, accessible but not editable, is totally doable, just not via rules, via hard-block mechanisms:

  1. Hooks works in IDE and CLI, this is the best option. Set up a preToolUse hook with matcher Write|Delete that returns permission: "deny" or exit code 2 when the path in tool_input matches a protected glob. Edits get blocked before they run, while reads stay allowed, exactly accessible but not editable. Example hooks.json:
{"hooks": {"preToolUse": [{"matcher": "Write|Delete", "command": "./check-protected-paths.sh"}]}}

Inside the script you check the path and return deny for packages/**/*.tsx. Docs: Hooks | Cursor Docs. Small note: ask for preToolUse is not enforced yet, so use deny.

  1. Cursor CLI only. You can set permissions.deny: ["Write(packages/**/*.tsx)"] in .cursor/cli.json or ~/.cursor/cli-config.json. Deny takes priority over allow. Docs: Permissions | Cursor Docs. Note: the IDE doesn’t read this deny list, so for the IDE use hooks.

For your case, hooks are the most direct path. Let me know if anything doesn’t work.