Skip to content

fix(permissions): stop writing global-only keys into a Cursor project config - #2623

Merged
dyoshikawa merged 3 commits into
mainfrom
resolve-issue-2399-cursor-project-scope-permissions
Aug 7, 2026
Merged

fix(permissions): stop writing global-only keys into a Cursor project config#2623
dyoshikawa merged 3 commits into
mainfrom
resolve-issue-2399-cursor-project-scope-permissions

Conversation

@dyoshikawa

Copy link
Copy Markdown
Owner

fromRulesyncPermissions built one identical object regardless of scope - getSettablePaths switched only the filename. It stamped version: 1 and editor.vimMode unconditionally and merged the cursor override's approvalMode/sandbox into the top level.

Cursor documents the opposite: "Only permissions can be configured at the project level. All other CLI settings must be set globally." So a cursor.approvalMode authored without --global landed in a .cursor/cli.json that Cursor ignores, and the setting silently never took effect - the failure was invisible, since the file looked correct.

Changes

  • Project scope contributes only the permissions key. Global behavior is unchanged.
  • Global-only override keys in project scope are skipped with a warning that names each one and points at --global. The check is over all override keys, not a hardcoded approvalMode/sandbox pair, since the override is a looseObject and any future cli.json key authored there has the same problem.
  • Existing project-file content still passes through untouched - including a version an earlier Rulesync stamped there. Rulesync cannot tell a key it wrote from one you wrote, so deleting it would be destructive; the docs say so explicitly.
  • The scope-specific merge moved into a helper to stay under the oxlint complexity limit.

Note on the test changes

Five existing tests asserted version, editor.vimMode, approvalMode and sandbox landing in a project config - the behavior being removed. They are re-scoped to global: true, where those assertions are still exactly right, rather than deleted. New project-scope coverage: version/editor absent, the override keys skipped, the warning naming both keys and --global, and a negative test that nothing is warned when the override has no global-only keys.

Verified locally with the permissions e2e spec.

Part of #2399

The issue's BUGBOT.md and permissions.json checks items are design-gated and untouched.

🤖 Generated with Claude Code

… config

fromRulesyncPermissions built one identical object for both scopes: it
stamped version and editor.vimMode unconditionally and merged the cursor
override's approvalMode and sandbox into the top level, while only the
filename varied. Cursor documents the opposite - only permissions can be
configured at the project level, all other CLI settings must be set
globally - so a cursor.approvalMode authored without --global landed in a
file Cursor ignores, and the setting silently never took effect.

Project scope now contributes only permissions and warns for each
global-only override key, naming it and pointing at --global. Existing
project-file content still passes through untouched, including a version
an earlier version stamped, since rulesync cannot tell its own key from a
hand-written one.

The scope-specific merge moves into a helper to stay under the
complexity limit.
…rning

Re-scoping left two tests asserting behavior their scope no longer runs:
the version and editor.vimMode preservation checks passed on a plain
spread, so the managed merge went untested. They now target the global
file, a project counterpart covers the pass-through, and the duplicated
version-stamping test is dropped.

The warning no longer names version, editor or permissions. rulesync
re-applies its managed value over those in global scope too, so telling
the user --global would help was a false promise.

The editor narrowing moves into the global branch, where editor is
actually managed; in project scope it warned about ignoring a value that
was in fact passed straight through.

Also record that the configuration reference marks version required
without scoping it to a file, and that import stays scope-blind on
purpose so a project config carrying these keys does not lose them.
…he value

The non-object editor branch had no coverage either before or after the
extraction, so nothing stopped the project-scope false warning from
coming back.
@dyoshikawa
dyoshikawa merged commit b91f16d into main Aug 7, 2026
9 checks passed
@dyoshikawa
dyoshikawa deleted the resolve-issue-2399-cursor-project-scope-permissions branch August 7, 2026 17:35
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.

2 participants