[GH-ISSUE #4895] [Bug] Unresolved launcher aliases are classified as foreign registrations #3038

Closed
opened 2026-10-31 00:35:16 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

  • Searched related open/closed issues and open PRs.
  • No credentials or private target data included.

Area

Setup, packaging, or upgrade

Observed behavior

Executed the built classifyClientRegistrationCommand at 01cdbbdc5 against owned temporary files on macOS. A registration through a dangling symlink returned foreign; a confirmed different script also returned foreign. The first case has unresolved identity, not evidence of a different target.

Reproduction

Create current.mjs, a different foreign.mjs, and broken -> removed-release.mjs in an owned temporary directory. Call classifyClientRegistrationCommand([broken, "mcp"], current) using the built module. Observed foreign, expected unknown. Control [foreign, "mcp"] correctly returns foreign. Fixture directory was removed afterward. One executed classifier reproduction; public doctor behavior is source-derived here, not yet reproduced.

Expected behavior

Preserve unresolved identity as unknown, following repository ownership guidance. Keep positively established aliases owned and confirmed different entrypoints foreign. Positive ownership guards must continue to fail closed.

Impact and scope

Source-derived: ClientRegistrationStatus reports the unresolved command stale rather than unknown, and setup/maintenance/uninstall consume the same boolean ownership interpretation. No destructive removal was observed; the existing positive ownership predicate returns false in both cases. Runtime frequency and native Windows/Linux effects are NOT_ENOUGH_INFO. Related #4847 concerns stable launchers across upgrades; this identity defect is separate and does not itself solve that report.

REA version

6.5.0, source 01cdbbdc55.

Runtime and platform

Node24.18.0, macOS arm64; no provider required.

Target and artifact context

Owned temporary launcher files/symlinks; no reverse-engineering target.

Interface

Package or setup

Earliest failure stage

Setup or provider admission

Relevant output or evidence

dangling alias: foreign (expected unknown); confirmed different script: foreign.
Boolean producer catches realpath failures as false; the classifier then maps false to foreign. The identity owner also repeats command-shape interpretation in its boolean and three-state entry points.

Typed outcome or recovery expected

Keep the identity tag unknown after failed resolution, retain the original configured command, provide uncertainty-specific diagnostic guidance, and preserve positive ownership checks for mutation/maintenance admission.

Additional context

Proposed regressions: dangling registered alias, unresolvable current alias, cyclic aliases, known different files, known alias equivalence, direct and node-script registration forms, and actual client-registration inspection. No integration change has been made yet.

Originally created by @morluto on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4895 ### Before submitting - [x] Searched related open/closed issues and open PRs. - [x] No credentials or private target data included. ### Area Setup, packaging, or upgrade ### Observed behavior Executed the built `classifyClientRegistrationCommand` at 01cdbbdc5 against owned temporary files on macOS. A registration through a dangling symlink returned `foreign`; a confirmed different script also returned `foreign`. The first case has unresolved identity, not evidence of a different target. ### Reproduction Create `current.mjs`, a different `foreign.mjs`, and `broken -> removed-release.mjs` in an owned temporary directory. Call `classifyClientRegistrationCommand([broken, "mcp"], current)` using the built module. Observed `foreign`, expected `unknown`. Control `[foreign, "mcp"]` correctly returns `foreign`. Fixture directory was removed afterward. One executed classifier reproduction; public doctor behavior is source-derived here, not yet reproduced. ### Expected behavior Preserve unresolved identity as `unknown`, following [repository ownership guidance](https://github.com/morluto/rea/blob/01cdbbdc556262c47d04a5b3391dd9c17946d3fc/AGENTS.md). Keep positively established aliases owned and confirmed different entrypoints foreign. Positive ownership guards must continue to fail closed. ### Impact and scope Source-derived: `ClientRegistrationStatus` reports the unresolved command stale rather than unknown, and setup/maintenance/uninstall consume the same boolean ownership interpretation. No destructive removal was observed; the existing positive ownership predicate returns false in both cases. Runtime frequency and native Windows/Linux effects are NOT_ENOUGH_INFO. Related #4847 concerns stable launchers across upgrades; this identity defect is separate and does not itself solve that report. ### REA version 6.5.0, source 01cdbbdc556262c47d04a5b3391dd9c17946d3fc. ### Runtime and platform Node24.18.0, macOS arm64; no provider required. ### Target and artifact context Owned temporary launcher files/symlinks; no reverse-engineering target. ### Interface Package or setup ### Earliest failure stage Setup or provider admission ### Relevant output or evidence `dangling alias: foreign (expected unknown)`; `confirmed different script: foreign`. [Boolean producer](https://github.com/morluto/rea/blob/01cdbbdc556262c47d04a5b3391dd9c17946d3fc/src/application/ClientRegistrationIdentity.ts#L120) catches realpath failures as false; the classifier then maps false to foreign. The identity owner also repeats command-shape interpretation in its boolean and three-state entry points. ### Typed outcome or recovery expected Keep the identity tag unknown after failed resolution, retain the original configured command, provide uncertainty-specific diagnostic guidance, and preserve positive ownership checks for mutation/maintenance admission. ### Additional context Proposed regressions: dangling registered alias, unresolvable current alias, cyclic aliases, known different files, known alias equivalence, direct and node-script registration forms, and actual client-registration inspection. No integration change has been made yet.
bsakaguchi 2026-10-31 00:35:16 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@xu91102 commented on GitHub (Oct 17, 2026):

I independently reproduced this on exact current main 01cdbbdc556262c47d04a5b3391dd9c17946d3fc using physical, owned macOS files and symlinks, then the compiled public CLI with isolated Cursor configuration. No REA source changes had been made at that reproduction checkpoint.

The classifier returns foreign for four unresolved cases: a dangling direct launcher, a cyclic direct launcher, an unresolved current launcher, and a Node-wrapped dangling script. The positive mutation-ownership predicate remains false for all four. Controls correctly identify two confirmed different scripts as foreign and three exact/equivalent launchers as owned.

The actual public rea doctor --client cursor --json reports the dangling registration as stale, whereas the documented uncertainty contract requires unknown. Its existing-different-file control reports stale and its proven symlink-alias control reports aligned. All three original config byte hashes remain unchanged. No destructive removal was observed.

I read the actual #4803 merged production change and #1732 current production diff; alias recognition and registration-field preservation do not repair this unresolved-identity outcome. The latest 4895 PR lookup is empty. The local investigation keeps the three-state interpretation at the shared identity owner and derives the positive ownership predicate from it, preserving fail-closed mutation admission and proven foreign/owned controls. No upstream PR has been created.

Executed on macOS arm64/Node24.18.0 only. This is not native Windows/Linux qualification, a running Cursor/agent/model test, a provider-session test, an observed data-loss scenario or a performance claim.

Update: the fresh duplicate check now finds #4899 by @behalnihal at head 76f61f099ae8cb725d7aa557a13db33ad7459c64. I read its complete four-file diff: it fixes this same producing identity owner and derives the positive predicate from the classifier. It is currently OPEN, not merged; I have not executed its head or certified all of its coverage.

My local experiment now passes the nine physical identity controls and all three public doctor controls. The focused suite has 126 distinct passing checks across seven files, with a further five README checks; static/docs/discovery and the existing package verifier also passed. These are my local frozen-baseline results, not upstream CI or evidence for somebody else's head. The old nonexistent-path fixture and function-size lint failures are retained in my records.

I have stopped delivery and preserved the five-file experiment uncommitted and read-only. No commit, fork feature push, upstream PR, merge or attribution is claimed. Additional runtime-alias/recovery controls will not be repackaged as another contribution for this same root.

Final source readback: maintainer commit 19329e43bb38ca9d64512d801b25abcb188d2512 independently fixes this root and closed #4895 at 22:18:48Z. I read its complete changed production diff; it also separates native symlink traversal from Node script normalization (#4896). I have not run this new main, so my earlier local checks do not certify that broader merged behavior and I do not claim the maintainer-reported checks as my own. My unpublished experiment has no commit/PR or authorship credit. The local frozen patch received separate Standards/Spec PASS reviews, but remains read-only HOLD; that is not a delivered contribution.

<!-- gh-comment-id:6241973334 --> @xu91102 commented on GitHub (Oct 17, 2026): I independently reproduced this on exact current main `01cdbbdc556262c47d04a5b3391dd9c17946d3fc` using physical, owned macOS files and symlinks, then the compiled public CLI with isolated Cursor configuration. No REA source changes had been made at that reproduction checkpoint. The classifier returns `foreign` for four unresolved cases: a dangling direct launcher, a cyclic direct launcher, an unresolved current launcher, and a Node-wrapped dangling script. The positive mutation-ownership predicate remains false for all four. Controls correctly identify two confirmed different scripts as foreign and three exact/equivalent launchers as owned. The actual public `rea doctor --client cursor --json` reports the dangling registration as `stale`, whereas the documented uncertainty contract requires `unknown`. Its existing-different-file control reports `stale` and its proven symlink-alias control reports `aligned`. All three original config byte hashes remain unchanged. No destructive removal was observed. I read the actual #4803 merged production change and #1732 current production diff; alias recognition and registration-field preservation do not repair this unresolved-identity outcome. The latest 4895 PR lookup is empty. The local investigation keeps the three-state interpretation at the shared identity owner and derives the positive ownership predicate from it, preserving fail-closed mutation admission and proven foreign/owned controls. No upstream PR has been created. Executed on macOS arm64/Node24.18.0 only. This is not native Windows/Linux qualification, a running Cursor/agent/model test, a provider-session test, an observed data-loss scenario or a performance claim. Update: the fresh duplicate check now finds #4899 by @behalnihal at head `76f61f099ae8cb725d7aa557a13db33ad7459c64`. I read its complete four-file diff: it fixes this same producing identity owner and derives the positive predicate from the classifier. It is currently OPEN, not merged; I have not executed its head or certified all of its coverage. My local experiment now passes the nine physical identity controls and all three public doctor controls. The focused suite has 126 distinct passing checks across seven files, with a further five README checks; static/docs/discovery and the existing package verifier also passed. These are my local frozen-baseline results, not upstream CI or evidence for somebody else's head. The old nonexistent-path fixture and function-size lint failures are retained in my records. I have stopped delivery and preserved the five-file experiment uncommitted and read-only. No commit, fork feature push, upstream PR, merge or attribution is claimed. Additional runtime-alias/recovery controls will not be repackaged as another contribution for this same root. Final source readback: maintainer commit `19329e43bb38ca9d64512d801b25abcb188d2512` independently fixes this root and closed #4895 at 22:18:48Z. I read its complete changed production diff; it also separates native symlink traversal from Node script normalization (#4896). I have not run this new main, so my earlier local checks do not certify that broader merged behavior and I do not claim the maintainer-reported checks as my own. My unpublished experiment has no commit/PR or authorship credit. The local frozen patch received separate Standards/Spec PASS reviews, but remains read-only HOLD; that is not a delivered contribution.
Author
Owner

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

Fixed in 19329e43bb on main.

Registration identity now has one owner across doctor, maintenance and uninstall. Failed launcher resolution remains unknown. Native filesystem traversal is separate from Node script-argument normalization; ambiguous direct launchers remain unknown and cannot authorize removal. The duplicate boolean ownership parser was removed.

Validation: 183 focused tests passed, 2 Windows cases skipped; check:fast, docs:check and the pre-push gate passed. All five new public regressions fail on the baseline; two existing valid-alias controls pass there. One isolated baseline regression actually removed a foreign fixture registration; the fix preserves its exact bytes. An additional authored Node-shebang control confirmed divergent launch semantics on macOS arm64 / Node 24.18.0. Two source reviews found no remaining blocker.

No native Windows/Linux or real mise upgrade was exercised. The separate stable mise launcher request remains open in #4847.

<!-- gh-comment-id:6242120039 --> @morluto commented on GitHub (Oct 17, 2026): Fixed in 19329e43bb38ca9d64512d801b25abcb188d2512 on main. Registration identity now has one owner across doctor, maintenance and uninstall. Failed launcher resolution remains unknown. Native filesystem traversal is separate from Node script-argument normalization; ambiguous direct launchers remain unknown and cannot authorize removal. The duplicate boolean ownership parser was removed. Validation: 183 focused tests passed, 2 Windows cases skipped; check:fast, docs:check and the pre-push gate passed. All five new public regressions fail on the baseline; two existing valid-alias controls pass there. One isolated baseline regression actually removed a foreign fixture registration; the fix preserves its exact bytes. An additional authored Node-shebang control confirmed divergent launch semantics on macOS arm64 / Node 24.18.0. Two source reviews found no remaining blocker. No native Windows/Linux or real mise upgrade was exercised. The separate stable mise launcher request remains open in #4847.
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#3038
No description provided.