[PR #5311] fix(setup): register aube's bin shim instead of its versioned store path #6873

Open
opened 2026-11-01 21:43:42 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5311
Author: @yamz8
Created: 10/19/2026
Status: 🔄 Open

Base: main ← Head: fix/aube-bin-shim-registration


📝 Commits (2)

  • d17a259 fix(setup): register aube's bin shim instead of its versioned store path
  • 319bd3c fix(setup): move aube store registrations to the shim and follow links to it

📊 Changes

6 files changed (+334 additions, -5 deletions)

View changed files

📝 docs/installation.md (+5 -2)
📝 src/application/ClientRegistrationIdentity.ts (+4 -0)
📝 src/application/ClientRegistrationStatus.ts (+14 -0)
📝 src/application/SetupHost.ts (+8 -3)
➕ src/process/AubeBinShim.ts (+93 -0)
➕ tests/boundary/filesystem/aubeBinShimRegistration.test.ts (+210 -0)

📄 Description

Summary

Refs #4847. With REA installed through aube (the installer mise's npm backend uses by default), rea setup registers a script inside one version's store, and the next upgrade removes it from under the agents. Setup now registers aube's stable bin shim instead, once the shim's own header proves it runs this exact entrypoint, and registration identity accepts that shim as REA's own. Other install layouts register exactly what they did before.

Problem and expected behavior

aube writes node_modules/.bin/rea as a POSIX shell shim that runs node on ../.mise/rea-agents@<version>/node_modules/rea-agents/scripts/rea.mjs, so process.argv[1] is that versioned script. Through mise, setup registers:

~/.local/share/mise/installs/rea/latest/node_modules/.mise/rea-agents@6.5.0/node_modules/rea-agents/scripts/rea.mjs

After mise up moves latest to 6.7.0, that path no longer exists, while the documented contract is that "Direct registrations follow the installed CLI". The shim at …/installs/rea/latest/node_modules/.bin/rea does follow the install: aube rewrites it for each version.

Change and scope

  • src/process/AubeBinShim.ts owns the one interpretation: it reads at most 512 bytes of a candidate, accepts only a regular file starting with #!/bin/sh and # aube-bin-shim v2 target=<relative path>, and resolves that target from the shim's real directory (as the shim itself does after following links to it) before comparing realpaths with the entrypoint. It opens the file non-blocking, so a registered path naming a FIFO cannot stall classification. An unknown shim format falls back to today's behavior.
  • setupRegistrationCommand (POSIX only) looks for <dir>/.bin/rea beside each node_modules that encloses the entrypoint, keeps the outermost one whose header runs this exact entrypoint, and registers [shim, "mcp"]. Without one, it registers the entrypoint as before.
  • directEntrypointIdentity treats an absolute command as owned when it is such a shim for the current entrypoint, checked only after the exact-path rule has not already owned it, so doctor, status and uninstall recognize the registration; it stays aligned through the existing absolute-launcher rule.
  • registrationAligned reports a direct registration as stale when the running entrypoint has such a shim and the registration is not that shim, so doctor flags registrations written before this fix and setup moves them to the shim.
  • docs/installation.md says aube installs register the shim.

Alternative to #4994, which registers the pinned npx -y rea-agents@<version> mcp command when setup runs from a version-scoped store. That stops the registration from disappearing but no longer follows the installed CLI, and it detects the store from a single name@version path segment (the open Codex finding there). This change keeps a direct registration that follows upgrades, and selects the shim only when the shim's own header names the running entrypoint, so an unrelated rea-agents@x.y.z directory cannot trigger it. Happy to close this in favor of #4994, or to combine them, whichever you prefer.

Not included: pnpm's global bin shims have a different, unversioned format and are untested here; Windows is unchanged. Scope: ordinary fix within existing setup boundaries; maintainer scope decision not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/process/AubeBinShim.ts; setup registration command selection.
  • Contribution scope fit and linked maintainer decision: setup bug fix within existing boundaries; not applicable.
  • CLI and MCP/tool-catalog contract: none.
  • Provider, bridge, target-format, or platform compatibility: POSIX installs through aube change their registered command; npm global, npx/bunx and Windows registrations are unchanged.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: one new runtime module in the package (dist/process/AubeBinShim.js); no generated metadata changes.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

(Setup still writes client configuration as before; this change only selects which path it writes, and reads shim headers.)

Evidence and regression coverage

  • Tests added or updated: tests/boundary/filesystem/aubeBinShimRegistration.test.ts lays versions out the way mise does (one directory per version, latest a symlink) with the shim aube wrote for rea-agents 6.7.0: setup registers the shim, Claude Code status is aligned, and it stays aligned after an upgrade that installs 6.8.0 beside it, repoints latest and deletes 6.7.0; a registered store script is reported stale; a link to the shim is owned; a shim naming another script is not registered and classifies as foreign; an unknown shim format falls back to the entrypoint; a registered FIFO classifies as foreign without blocking.
  • Base reproduction or other evidence: executed. On the base revision, the main test fails because setup registers the versioned script (expected [ …(2) ] to deeply equal [ …(2) ]); the other two tests passed on both revisions. The FIFO test was added afterwards; with the open switched back to a blocking "r", it hangs until killed. The stale-registration and link tests were added in the second commit and fail on the first commit's code.
  • User-visible CLI/MCP output (if applicable): end to end with mise 2026.10.13 in an isolated home: rea 6.5.0 installed as mise's latest with this branch's dist swapped in; rea setup --client codex --yes through mise's shim wrote command = "…/installs/rea/latest/node_modules/.bin/rea"; rea doctor reported codex aligned; mise up rea (6.5.0 → 6.7.0) left that command in place, running it printed 6.7.0, and it answered MCP initialize with serverInfo 6.7.0. The previously registered style of path, …/latest/node_modules/.mise/rea-agents@6.5.0/…/rea.mjs, was gone after the upgrade. On the final code, a Codex entry written that old way reported stale; rea setup moved it to the shim (aligned), which still ran 6.7.0 after mise up; Codex's other server was untouched.
  • Remaining proof gaps: pnpm shims and aube outside mise were not tested; macOS not run. Setup started through a pinned version's directory (installs/rea/6.7.0/...) registers that version's shim, as the user pinned it.

Validation performed

The branch was rebased onto 002e1b68; the one conflict was an import line in ClientRegistrationStatus.ts. On the rebased head (319bd3c9):

  • npm run check:fast — typecheck and lint, 2 tasks successful.
  • npm run test:focused -- tests/boundary/filesystem/aubeBinShimRegistration.test.ts — 6 passed.
  • npm run test:focused -- the 62 test files that reference client registration status/identity, SetupHost, setupRegistrationCommand or uninstall — 1319 passed, 14 skipped.

Before the rebase:

  • npm run test:focused -- tests/boundary/filesystem/aubeBinShimRegistration.test.ts — 6 passed.
  • npm run test:focused -- the 37 test files that reference client registration status/identity, SetupHost, uninstall or setupRegistrationCommand — 710 passed, 2 skipped (Windows-only).
  • npm run check — 6 tasks successful; architecture guards passed; lint warning total unchanged.
  • npm run docs:check — passed.
  • npm run verify:package — setup and uninstall CLI complete, MCP tools and evidence complete.
  • npm pack --dry-run — includes dist/process/AubeBinShim.js.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Existing registrations of the versioned script now show as stale in doctor; rerunning setup under aube moves them to the shim.
  • Real Hopper/Ghidra, browser, or OS coverage: Linux (Arch) only; no provider involved.
  • Package or release metadata impact: one new module; none.
  • Security, privacy, process, or containment review: reads at most 512 bytes of files already named by registrations or adjacent to REA's own entrypoint; opens non-blocking and only reads regular files; ownership needs the shim's target to resolve to the running entrypoint.

Author readiness

Human owner:

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/5311 **Author:** [@yamz8](https://github.com/yamz8) **Created:** 10/19/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/aube-bin-shim-registration` --- ### 📝 Commits (2) - [`d17a259`](https://github.com/morluto/rea/commit/d17a2595a107d55834a739b1851c2dcf089f7dcd) fix(setup): register aube's bin shim instead of its versioned store path - [`319bd3c`](https://github.com/morluto/rea/commit/319bd3c939963cb54d096f6154988e69c2fd8de7) fix(setup): move aube store registrations to the shim and follow links to it ### 📊 Changes **6 files changed** (+334 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `docs/installation.md` (+5 -2) 📝 `src/application/ClientRegistrationIdentity.ts` (+4 -0) 📝 `src/application/ClientRegistrationStatus.ts` (+14 -0) 📝 `src/application/SetupHost.ts` (+8 -3) ➕ `src/process/AubeBinShim.ts` (+93 -0) ➕ `tests/boundary/filesystem/aubeBinShimRegistration.test.ts` (+210 -0) </details> ### 📄 Description ## Summary Refs #4847. With REA installed through aube (the installer mise's npm backend uses by default), `rea setup` registers a script inside one version's store, and the next upgrade removes it from under the agents. Setup now registers aube's stable bin shim instead, once the shim's own header proves it runs this exact entrypoint, and registration identity accepts that shim as REA's own. Other install layouts register exactly what they did before. ## Problem and expected behavior aube writes `node_modules/.bin/rea` as a POSIX shell shim that runs node on `../.mise/rea-agents@<version>/node_modules/rea-agents/scripts/rea.mjs`, so `process.argv[1]` is that versioned script. Through mise, setup registers: ``` ~/.local/share/mise/installs/rea/latest/node_modules/.mise/rea-agents@6.5.0/node_modules/rea-agents/scripts/rea.mjs ``` After `mise up` moves `latest` to 6.7.0, that path no longer exists, while the documented contract is that "Direct registrations follow the installed CLI". The shim at `…/installs/rea/latest/node_modules/.bin/rea` does follow the install: aube rewrites it for each version. ## Change and scope - `src/process/AubeBinShim.ts` owns the one interpretation: it reads at most 512 bytes of a candidate, accepts only a regular file starting with `#!/bin/sh` and `# aube-bin-shim v2 target=<relative path>`, and resolves that target from the shim's real directory (as the shim itself does after following links to it) before comparing realpaths with the entrypoint. It opens the file non-blocking, so a registered path naming a FIFO cannot stall classification. An unknown shim format falls back to today's behavior. - `setupRegistrationCommand` (POSIX only) looks for `<dir>/.bin/rea` beside each `node_modules` that encloses the entrypoint, keeps the outermost one whose header runs this exact entrypoint, and registers `[shim, "mcp"]`. Without one, it registers the entrypoint as before. - `directEntrypointIdentity` treats an absolute command as owned when it is such a shim for the current entrypoint, checked only after the exact-path rule has not already owned it, so doctor, status and uninstall recognize the registration; it stays aligned through the existing absolute-launcher rule. - `registrationAligned` reports a direct registration as `stale` when the running entrypoint has such a shim and the registration is not that shim, so doctor flags registrations written before this fix and setup moves them to the shim. - `docs/installation.md` says aube installs register the shim. Alternative to #4994, which registers the pinned `npx -y rea-agents@<version> mcp` command when setup runs from a version-scoped store. That stops the registration from disappearing but no longer follows the installed CLI, and it detects the store from a single `name@version` path segment (the open Codex finding there). This change keeps a direct registration that follows upgrades, and selects the shim only when the shim's own header names the running entrypoint, so an unrelated `rea-agents@x.y.z` directory cannot trigger it. Happy to close this in favor of #4994, or to combine them, whichever you prefer. Not included: pnpm's global bin shims have a different, unversioned format and are untested here; Windows is unchanged. Scope: ordinary fix within existing setup boundaries; maintainer scope decision not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/process/AubeBinShim.ts`; setup registration command selection. - Contribution scope fit and linked maintainer decision: setup bug fix within existing boundaries; not applicable. - CLI and MCP/tool-catalog contract: none. - Provider, bridge, target-format, or platform compatibility: POSIX installs through aube change their registered command; npm global, npx/bunx and Windows registrations are unchanged. - Evidence, artifact, provenance, or reconstruction contract: none. - Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: one new runtime module in the package (`dist/process/AubeBinShim.js`); no generated metadata changes. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. (Setup still writes client configuration as before; this change only selects which path it writes, and reads shim headers.) ## Evidence and regression coverage - Tests added or updated: `tests/boundary/filesystem/aubeBinShimRegistration.test.ts` lays versions out the way mise does (one directory per version, `latest` a symlink) with the shim aube wrote for rea-agents 6.7.0: setup registers the shim, Claude Code status is aligned, and it stays aligned after an upgrade that installs 6.8.0 beside it, repoints `latest` and deletes 6.7.0; a registered store script is reported stale; a link to the shim is owned; a shim naming another script is not registered and classifies as foreign; an unknown shim format falls back to the entrypoint; a registered FIFO classifies as foreign without blocking. - Base reproduction or other evidence: executed. On the base revision, the main test fails because setup registers the versioned script (`expected [ …(2) ] to deeply equal [ …(2) ]`); the other two tests passed on both revisions. The FIFO test was added afterwards; with the open switched back to a blocking `"r"`, it hangs until killed. The stale-registration and link tests were added in the second commit and fail on the first commit's code. - User-visible CLI/MCP output (if applicable): end to end with mise 2026.10.13 in an isolated home: rea 6.5.0 installed as mise's `latest` with this branch's `dist` swapped in; `rea setup --client codex --yes` through mise's shim wrote `command = "…/installs/rea/latest/node_modules/.bin/rea"`; `rea doctor` reported codex `aligned`; `mise up rea` (6.5.0 → 6.7.0) left that command in place, running it printed `6.7.0`, and it answered MCP `initialize` with `serverInfo` 6.7.0. The previously registered style of path, `…/latest/node_modules/.mise/rea-agents@6.5.0/…/rea.mjs`, was gone after the upgrade. On the final code, a Codex entry written that old way reported `stale`; `rea setup` moved it to the shim (`aligned`), which still ran 6.7.0 after `mise up`; Codex's other server was untouched. - Remaining proof gaps: pnpm shims and aube outside mise were not tested; macOS not run. Setup started through a pinned version's directory (`installs/rea/6.7.0/...`) registers that version's shim, as the user pinned it. ## Validation performed The branch was rebased onto `002e1b68`; the one conflict was an import line in `ClientRegistrationStatus.ts`. On the rebased head (`319bd3c9`): - `npm run check:fast` — typecheck and lint, 2 tasks successful. - `npm run test:focused -- tests/boundary/filesystem/aubeBinShimRegistration.test.ts` — 6 passed. - `npm run test:focused --` the 62 test files that reference client registration status/identity, `SetupHost`, `setupRegistrationCommand` or uninstall — 1319 passed, 14 skipped. Before the rebase: - `npm run test:focused -- tests/boundary/filesystem/aubeBinShimRegistration.test.ts` — 6 passed. - `npm run test:focused --` the 37 test files that reference client registration status/identity, `SetupHost`, uninstall or `setupRegistrationCommand` — 710 passed, 2 skipped (Windows-only). - `npm run check` — 6 tasks successful; architecture guards passed; lint warning total unchanged. - `npm run docs:check` — passed. - `npm run verify:package` — setup and uninstall CLI complete, MCP tools and evidence complete. - `npm pack --dry-run` — includes `dist/process/AubeBinShim.js`. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Existing registrations of the versioned script now show as `stale` in doctor; rerunning setup under aube moves them to the shim. - Real Hopper/Ghidra, browser, or OS coverage: Linux (Arch) only; no provider involved. - Package or release metadata impact: one new module; none. - Security, privacy, process, or containment review: reads at most 512 bytes of files already named by registrations or adjacent to REA's own entrypoint; opens non-blocking and only reads regular files; ownership needs the shim's target to resolve to the running entrypoint. ## Author readiness Human owner: <!-- @GitHub-handle --> - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#6873
No description provided.