[GH-ISSUE #5441] [Bug] Setup rewrites aligned Cursor registration when switching equivalent launcher paths #3302

Closed
opened 2026-10-31 00:38:57 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5441

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Setup, packaging, or upgrade

Observed behavior

Alternating setup --client cursor --skill=false --json --yes between an absolute symlink to REA and its real script rewrites Cursor's registered command back and forth, although doctor reports the existing registration aligned before each rewrite. Only the command string changes in the parsed registration. The writes change configuration bytes and modification time and create recovery backups.

This report was prepared with AI assistance and independently reproduced through the built CLI. The observations below come from that independent verification.

Reproduction

Run from an already-built checkout at the revision below on a POSIX system with symlink support. The independent verifier ran this isolated sequence with skill installation disabled and no provider installation requested:

REPO="$PWD"
CASE_DIR=$(mktemp -d)
export HOME="$CASE_DIR/home" NO_COLOR=1
export XDG_CONFIG_HOME="$CASE_DIR/xdg-config" XDG_DATA_HOME="$CASE_DIR/xdg-data"
export XDG_CACHE_HOME="$CASE_DIR/xdg-cache" XDG_STATE_HOME="$CASE_DIR/xdg-state"
unset npm_command DSH_HOME DSH_AGENTS_HOME
mkdir -p "$HOME" "$XDG_CONFIG_HOME" "$XDG_DATA_HOME" "$XDG_CACHE_HOME" "$XDG_STATE_HOME" "$CASE_DIR/bin"
ln -s "$REPO/scripts/rea.mjs" "$CASE_DIR/bin/rea"
cd "$CASE_DIR"

node "$CASE_DIR/bin/rea" setup --client cursor --skill=false --json --yes
node "$REPO/scripts/rea.mjs" doctor --client cursor --skill=false --json
node "$REPO/scripts/rea.mjs" setup --client cursor --skill=false --json --yes
node "$CASE_DIR/bin/rea" doctor --client cursor --skill=false --json
node "$CASE_DIR/bin/rea" setup --client cursor --skill=false --json --yes

Inspect $HOME/.cursor/mcp.json after each setup. Initial setup stores the symlink. The next setup replaces it with the real script; the final setup restores the symlink. Both doctors report alignment. The verifier also recorded SHA-256, nanosecond modification times and backup listings around these commands.

Repeating the final setup through the same symlink was a no-op. As a discriminating control, changing only the stored command to /bin/sh and running setup through the real script correctly planned and applied an update. Each setup/doctor invocation exited 0.

Expected behavior

Equivalent invocations should converge to a stable registration, return no unnecessary configuration actions, preserve configuration bytes and modification time, and create no additional backups. A genuinely different executable must still require an update.

Source-derived contract: AGENTS.md:11 requires additive, idempotent configuration changes. src/application/ClientRegistrationIdentity.ts:118-132 recognizes same-file launcher identity through realpath, and tests/acceptance/setup/launcherAliasesCli.test.ts:9-60 covers supported symlink launcher spellings in diagnostics. All source references in this report refer to the revision below.

Impact and scope

Observed impact is redundant configuration writes and backup artifacts when switching between two equivalent absolute launcher paths. The first rewrite created the ordinary backup and the second created one content-addressed recovery backup. This report does not claim unlimited backup growth; source inspection shows matching backup contents are reused.

Impact assessment: P3. No client outage or data loss was established. The tested scope is Cursor on macOS with a direct symlink and its target. Other operating systems and arbitrary executable wrapper shims were not tested. The verified workaround is to keep invoking setup through the same launcher spelling, which preserved bytes, modification time and the backup listing.

REA version

6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8.

Runtime and platform

Node v26.12.0; macOS arm64. No Hopper or Ghidra provider was required or started.

Target and artifact context

An isolated Cursor JSON MCP registration in a disposable home and XDG directories. No reverse-engineering target or analysis database was involved.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

The independently recorded real-script doctor reported registration:cursor healthy and registration state aligned. The following real-script setup returned status: "ready", a configure_client:cursor action with operation: "update", and clients.cursor.status: "configured". The stored command changed to the real script, and both its content hash and modification time changed.

Doctor through the symlink also reported alignment. Setup through that symlink planned another update, restored the original command and content hash, changed the modification time and created one recovery backup. Parsed before/after comparisons established that both rewrites changed only the command. Repeating the same launcher spelling returned plannedActions: [] and preserved bytes, modification time and the file listing.

Typed outcome or recovery expected

After an equivalent registration is established, return plannedActions: [] for either launcher spelling, preserve the stored document, and continue reporting alignment. Retain the update behavior for a genuinely different executable.

Analysis or suspected cause

Source-derived reasoning: src/application/SetupHost.ts:69-79 selects the invoking script's lexical path. src/application/SetupClientConfiguration.ts:567-605 and :703-713 compare desired and stored registration values using exact equality, so the alternate path selects an update. The write path at :193-211 uses the same comparison before persistence. This differs from the same-file identity used by doctor.

Additional context

Related #3906 concerned equivalent aliases becoming stale to doctor and foreign to uninstall. This report concerns unnecessary setup mutation while doctor already reports alignment. #4847 concerns version-manager launchers breaking across upgrades; no upgrade is involved here.

The upstream check found only e84468c0b touching the cited files after the tested baseline. Its Windows environment-identity changes do not alter this launcher comparison. No client or production MCP server was started, so client execution success was not tested.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5441 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Setup, packaging, or upgrade ### Observed behavior Alternating `setup --client cursor --skill=false --json --yes` between an absolute symlink to REA and its real script rewrites Cursor's registered command back and forth, although doctor reports the existing registration `aligned` before each rewrite. Only the command string changes in the parsed registration. The writes change configuration bytes and modification time and create recovery backups. This report was prepared with AI assistance and independently reproduced through the built CLI. The observations below come from that independent verification. ### Reproduction Run from an already-built checkout at the revision below on a POSIX system with symlink support. The independent verifier ran this isolated sequence with skill installation disabled and no provider installation requested: ```sh REPO="$PWD" CASE_DIR=$(mktemp -d) export HOME="$CASE_DIR/home" NO_COLOR=1 export XDG_CONFIG_HOME="$CASE_DIR/xdg-config" XDG_DATA_HOME="$CASE_DIR/xdg-data" export XDG_CACHE_HOME="$CASE_DIR/xdg-cache" XDG_STATE_HOME="$CASE_DIR/xdg-state" unset npm_command DSH_HOME DSH_AGENTS_HOME mkdir -p "$HOME" "$XDG_CONFIG_HOME" "$XDG_DATA_HOME" "$XDG_CACHE_HOME" "$XDG_STATE_HOME" "$CASE_DIR/bin" ln -s "$REPO/scripts/rea.mjs" "$CASE_DIR/bin/rea" cd "$CASE_DIR" node "$CASE_DIR/bin/rea" setup --client cursor --skill=false --json --yes node "$REPO/scripts/rea.mjs" doctor --client cursor --skill=false --json node "$REPO/scripts/rea.mjs" setup --client cursor --skill=false --json --yes node "$CASE_DIR/bin/rea" doctor --client cursor --skill=false --json node "$CASE_DIR/bin/rea" setup --client cursor --skill=false --json --yes ``` Inspect `$HOME/.cursor/mcp.json` after each setup. Initial setup stores the symlink. The next setup replaces it with the real script; the final setup restores the symlink. Both doctors report alignment. The verifier also recorded SHA-256, nanosecond modification times and backup listings around these commands. Repeating the final setup through the same symlink was a no-op. As a discriminating control, changing only the stored command to `/bin/sh` and running setup through the real script correctly planned and applied an update. Each setup/doctor invocation exited 0. ### Expected behavior Equivalent invocations should converge to a stable registration, return no unnecessary configuration actions, preserve configuration bytes and modification time, and create no additional backups. A genuinely different executable must still require an update. Source-derived contract: `AGENTS.md:11` requires additive, idempotent configuration changes. `src/application/ClientRegistrationIdentity.ts:118-132` recognizes same-file launcher identity through realpath, and `tests/acceptance/setup/launcherAliasesCli.test.ts:9-60` covers supported symlink launcher spellings in diagnostics. All source references in this report refer to the revision below. ### Impact and scope Observed impact is redundant configuration writes and backup artifacts when switching between two equivalent absolute launcher paths. The first rewrite created the ordinary backup and the second created one content-addressed recovery backup. This report does not claim unlimited backup growth; source inspection shows matching backup contents are reused. Impact assessment: P3. No client outage or data loss was established. The tested scope is Cursor on macOS with a direct symlink and its target. Other operating systems and arbitrary executable wrapper shims were not tested. The verified workaround is to keep invoking setup through the same launcher spelling, which preserved bytes, modification time and the backup listing. ### REA version 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`. ### Runtime and platform Node v26.12.0; macOS arm64. No Hopper or Ghidra provider was required or started. ### Target and artifact context An isolated Cursor JSON MCP registration in a disposable home and XDG directories. No reverse-engineering target or analysis database was involved. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence The independently recorded real-script doctor reported `registration:cursor` healthy and registration state `aligned`. The following real-script setup returned `status: "ready"`, a `configure_client:cursor` action with `operation: "update"`, and `clients.cursor.status: "configured"`. The stored command changed to the real script, and both its content hash and modification time changed. Doctor through the symlink also reported alignment. Setup through that symlink planned another update, restored the original command and content hash, changed the modification time and created one recovery backup. Parsed before/after comparisons established that both rewrites changed only the command. Repeating the same launcher spelling returned `plannedActions: []` and preserved bytes, modification time and the file listing. ### Typed outcome or recovery expected After an equivalent registration is established, return `plannedActions: []` for either launcher spelling, preserve the stored document, and continue reporting alignment. Retain the update behavior for a genuinely different executable. ### Analysis or suspected cause Source-derived reasoning: `src/application/SetupHost.ts:69-79` selects the invoking script's lexical path. `src/application/SetupClientConfiguration.ts:567-605` and `:703-713` compare desired and stored registration values using exact equality, so the alternate path selects an update. The write path at `:193-211` uses the same comparison before persistence. This differs from the same-file identity used by doctor. ### Additional context Related #3906 concerned equivalent aliases becoming stale to doctor and foreign to uninstall. This report concerns unnecessary setup mutation while doctor already reports alignment. #4847 concerns version-manager launchers breaking across upgrades; no upgrade is involved here. The upstream check found only `e84468c0b` touching the cited files after the tested baseline. Its Windows environment-identity changes do not alter this launcher comparison. No client or production MCP server was started, so client execution success was not tested.
Author
Owner

@morluto commented on GitHub (Oct 23, 2026):

Fixed on main in github.com/morluto/rea@adafef2c9e. Registration identity proves equivalent direct launcher files and preserves the caller spelling for an aligned configuration.

Validation: tests/boundary/filesystem/setupConfig.test.ts passed in the retained audit receipt. Real symlink alias stays byte-identical with no backup/write; distinct-file refresh preserves the exact original backup.

Scope: Controlled local filesystem tests; no installed Cursor process or Windows alias behavior claimed.

<!-- gh-comment-id:6376020886 --> @morluto commented on GitHub (Oct 23, 2026): Fixed on main in https://github.com/morluto/rea/commit/adafef2c9ea17075dd1c849ac285bd9f79274df0. Registration identity proves equivalent direct launcher files and preserves the caller spelling for an aligned configuration. Validation: `tests/boundary/filesystem/setupConfig.test.ts` passed in the retained audit receipt. Real symlink alias stays byte-identical with no backup/write; distinct-file refresh preserves the exact original backup. Scope: Controlled local filesystem tests; no installed Cursor process or Windows alias behavior claimed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3302
No description provided.