[GH-ISSUE #5559] [Bug] Doctor reports IDA ready with an unusable headless workspace root #3387

Closed
opened 2026-10-31 00:39:48 +00:00 by bsakaguchi · 0 comments
Owner

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

Before submitting

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

Area

Provider or capability discovery

Observed behavior

rea doctor --provider ida --json reports successful selected IDA readiness when a headless registration's workspaceRoot is a regular file, a missing path, or an existing directory that denies directory creation. An independent verifier observed exit 0, healthy: true, IDA available: true, and passing registration and private_workspace checks for all three cases.

Separate public CLI decompilation runs with a scratch-only fake MCP supervisor failed before idb_open, returning execution_failure and exit 1 with ENOTDIR, ENOENT, and EACCES respectively. Writable-directory and omitted-setting controls completed fake decompilation and cleanup successfully. No real IDA engine was exercised. The doctor's separate environment_healthy field was false because unrelated providers and the installed skill were absent; this report concerns the explicitly selected IDA scope.

Reproduction

From the baseline source checkout with dependencies and the compiled CLI available, the independent verifier ran this script once for each case. It isolates all REA home/config/data/cache/state/temp directories and uses only fake provider files. Doctor does not start the configured provider. Run the permission case as an unprivileged POSIX user; privileged users may bypass the denied-write permissions.

python3 - <<'PY'
import json, os, pathlib, shutil, subprocess, tempfile

root = pathlib.Path(tempfile.mkdtemp(prefix="rea-ida-root-"))
node = shutil.which("node")
env = {"PATH": os.environ["PATH"]}
for variable, directory in {
    "HOME": "home", "XDG_CONFIG_HOME": "config", "XDG_DATA_HOME": "data",
    "XDG_CACHE_HOME": "cache", "XDG_STATE_HOME": "state", "TMPDIR": "temp",
    "IDADIR": "ida", "IDAUSR": "ida-user",
}.items():
    path = root / directory
    path.mkdir()
    env[variable] = str(path)
fake = root / "fake-provider"
fake.write_text("fixture; never executed\n")
fake.chmod(0o700)
env["HOPPER_LAUNCHER_PATH"] = str(fake)
env["REA_LOG_LEVEL"] = "silent"
(root / "file").write_text("fixture")
(root / "read-only").mkdir(mode=0o500)
(root / "writable").mkdir()
for name in ["file", "missing", "read-only", "writable", "default"]:
    registration = {"command": str(fake), "args": [], "mode": "headless"}
    if name != "default":
        registration["workspaceRoot"] = str(root / name)
    config = root / (name + ".json")
    config.write_text(json.dumps(registration))
    result = subprocess.run(
        [node, "scripts/rea.mjs", "doctor", "--provider", "ida", "--json"],
        env={**env, "REA_IDA_MCP_CONFIG": str(config)},
        text=True, capture_output=True, timeout=40,
    )
    (root / (name + "-stdout.json")).write_text(result.stdout)
    (root / (name + "-stderr.txt")).write_text(result.stderr)
    report = json.loads(result.stdout)
    ida = next(p for p in report["providerInspections"] if p["id"] == "ida")
    print(name, "exit", result.returncode, "healthy", report["healthy"],
          "available", ida["available"],
          "checks", [(c["name"], c["ok"]) for c in ida["checks"]])
print("Evidence directory:", root)
PY

Expected behavior

Doctor should fail a local readiness check with actionable workspaceRoot guidance for each unusable parent, report selected-scope healthy: false and IDA available: false, and exit 1 without launching IDA. Existing writable parents and the omitted setting should keep passing.

This expectation follows from docs/ida-provider.md:102, which requires an existing absolute temporary-directory parent on the REA host; docs/ida-provider.md:138, which promises registration validation without starting IDA while deferring runtime compatibility and target binding; and docs/cli.md:514, which defines exit 1 for failed checks in the selected readiness scope. References are at the tested baseline.

Impact and scope

P2: a bounded local configuration error receives a false readiness success, delaying detection until analysis needs its private workspace. All three unusable-parent cases reproduced, alongside two passing controls. Choosing an existing writable parent or omitting workspaceRoot is a verified workaround against the fake supervisor. Real-engine behavior, other platforms, and production frequency were not tested. No data loss or security-boundary crossing was observed; workspace creation failed closed.

REA version

6.7.0; built source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8.

Runtime and platform

Node.js v26.12.0; macOS arm64; unprivileged process with POSIX directory permissions. Fake providers only. NOT_ENOUGH_INFO: the verifier did not record the exact macOS release; no real IDA version applies to this reproduction.

Target and artifact context

Doctor uses disposable registration files and five workspace-root cases. Separate decompilation checks used a local synthetic ELF target and a fake stdio MCP supervisor implementing the modern headless profile. The fake returned int main(void) { return 42; }; no real database or IDA process was used.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

The independent verifier recorded:

workspaceRoot    doctor exit  healthy  IDA available  registration.ok  private_workspace.ok
regular file    0            true     true           true             true
missing path    0            true     true           true             true
directory 0500  0            true     true           true             true
writable dir    0            true     true           true             true
omitted         0            true     true           true             true

The workspace check reported Private workspace authority is available (posix-mkdtemp-owner-only).

Separate node scripts/rea.mjs decompile <generated-target.elf> main --provider ida --json runs completed MCP initialization and tool-catalog validation, then failed before any worker-open call for each bad root. The regular-file, missing-path, and denied-write cases returned ENOTDIR, ENOENT, and EACCES, respectively, with execution_failure and exit 1. Writable and omitted-root controls exited 0; receipts included idb_open, decompile, idb_close, and final idb_list, with owned directories removed normally.

A fresh upstream fetch resolved origin/main to d2a3269d0c1007e16a2f84d44cc0b1503debb2ae. Compared with the tested baseline, IdaConfiguration.ts, IdaDoctor.ts, IdaSessionClient.ts, IdaWorkspace.ts, and docs/ida-provider.md were unchanged. Changes to docs/cli.md concern other commands/output filtering. Current-main applicability is source-inspected; runtime reproduction was at the baseline above.

Typed outcome or recovery expected

Return a failed local readiness check identifying the unusable workspaceRoot, IDA available: false, selected-scope healthy: false, and exit 1. Preserve passing writable/default controls and keep upstream compatibility and target binding explicitly unverified by doctor.

Analysis or suspected cause

Source-derived reasoning: src/ida/IdaConfiguration.ts:11-14 validates only absolute-path syntax. src/ida/IdaDoctor.ts:12-21,50-58 checks platform private-workspace authority without examining the configured parent. src/ida/IdaSessionClient.ts:569-604 reaches workspace allocation after connection and catalog guards; src/ida/IdaWorkspace.ts:44-53 resolves the parent and allocates the private runtime, where the observed filesystem failures arise.

Additional context

Prepared with AI assistance and independently reproduced. Searches included open and closed issues and PRs for ida doctor, workspaceRoot, IdaDoctor, readiness, and workspace symptoms. Merged PR #1481 canonicalizes the workspace path during analysis; it does not validate local readiness in doctor. Issue #5554 concerns a separate Kuna cache-root check.

NOT_ENOUGH_INFO: no last known good version or regression range was established.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5559 ### 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 Provider or capability discovery ### Observed behavior `rea doctor --provider ida --json` reports successful selected IDA readiness when a headless registration's `workspaceRoot` is a regular file, a missing path, or an existing directory that denies directory creation. An independent verifier observed exit 0, `healthy: true`, IDA `available: true`, and passing `registration` and `private_workspace` checks for all three cases. Separate public CLI decompilation runs with a scratch-only fake MCP supervisor failed before `idb_open`, returning `execution_failure` and exit 1 with `ENOTDIR`, `ENOENT`, and `EACCES` respectively. Writable-directory and omitted-setting controls completed fake decompilation and cleanup successfully. No real IDA engine was exercised. The doctor's separate `environment_healthy` field was false because unrelated providers and the installed skill were absent; this report concerns the explicitly selected IDA scope. ### Reproduction From the baseline source checkout with dependencies and the compiled CLI available, the independent verifier ran this script once for each case. It isolates all REA home/config/data/cache/state/temp directories and uses only fake provider files. Doctor does not start the configured provider. Run the permission case as an unprivileged POSIX user; privileged users may bypass the denied-write permissions. ```sh python3 - <<'PY' import json, os, pathlib, shutil, subprocess, tempfile root = pathlib.Path(tempfile.mkdtemp(prefix="rea-ida-root-")) node = shutil.which("node") env = {"PATH": os.environ["PATH"]} for variable, directory in { "HOME": "home", "XDG_CONFIG_HOME": "config", "XDG_DATA_HOME": "data", "XDG_CACHE_HOME": "cache", "XDG_STATE_HOME": "state", "TMPDIR": "temp", "IDADIR": "ida", "IDAUSR": "ida-user", }.items(): path = root / directory path.mkdir() env[variable] = str(path) fake = root / "fake-provider" fake.write_text("fixture; never executed\n") fake.chmod(0o700) env["HOPPER_LAUNCHER_PATH"] = str(fake) env["REA_LOG_LEVEL"] = "silent" (root / "file").write_text("fixture") (root / "read-only").mkdir(mode=0o500) (root / "writable").mkdir() for name in ["file", "missing", "read-only", "writable", "default"]: registration = {"command": str(fake), "args": [], "mode": "headless"} if name != "default": registration["workspaceRoot"] = str(root / name) config = root / (name + ".json") config.write_text(json.dumps(registration)) result = subprocess.run( [node, "scripts/rea.mjs", "doctor", "--provider", "ida", "--json"], env={**env, "REA_IDA_MCP_CONFIG": str(config)}, text=True, capture_output=True, timeout=40, ) (root / (name + "-stdout.json")).write_text(result.stdout) (root / (name + "-stderr.txt")).write_text(result.stderr) report = json.loads(result.stdout) ida = next(p for p in report["providerInspections"] if p["id"] == "ida") print(name, "exit", result.returncode, "healthy", report["healthy"], "available", ida["available"], "checks", [(c["name"], c["ok"]) for c in ida["checks"]]) print("Evidence directory:", root) PY ``` ### Expected behavior Doctor should fail a local readiness check with actionable `workspaceRoot` guidance for each unusable parent, report selected-scope `healthy: false` and IDA `available: false`, and exit 1 without launching IDA. Existing writable parents and the omitted setting should keep passing. This expectation follows from `docs/ida-provider.md:102`, which requires an existing absolute temporary-directory parent on the REA host; `docs/ida-provider.md:138`, which promises registration validation without starting IDA while deferring runtime compatibility and target binding; and `docs/cli.md:514`, which defines exit 1 for failed checks in the selected readiness scope. References are at the tested baseline. ### Impact and scope P2: a bounded local configuration error receives a false readiness success, delaying detection until analysis needs its private workspace. All three unusable-parent cases reproduced, alongside two passing controls. Choosing an existing writable parent or omitting `workspaceRoot` is a verified workaround against the fake supervisor. Real-engine behavior, other platforms, and production frequency were not tested. No data loss or security-boundary crossing was observed; workspace creation failed closed. ### REA version 6.7.0; built source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`. ### Runtime and platform Node.js v26.12.0; macOS arm64; unprivileged process with POSIX directory permissions. Fake providers only. NOT_ENOUGH_INFO: the verifier did not record the exact macOS release; no real IDA version applies to this reproduction. ### Target and artifact context Doctor uses disposable registration files and five workspace-root cases. Separate decompilation checks used a local synthetic ELF target and a fake stdio MCP supervisor implementing the modern headless profile. The fake returned `int main(void) { return 42; }`; no real database or IDA process was used. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence The independent verifier recorded: ```text workspaceRoot doctor exit healthy IDA available registration.ok private_workspace.ok regular file 0 true true true true missing path 0 true true true true directory 0500 0 true true true true writable dir 0 true true true true omitted 0 true true true true ``` The workspace check reported `Private workspace authority is available (posix-mkdtemp-owner-only).` Separate `node scripts/rea.mjs decompile <generated-target.elf> main --provider ida --json` runs completed MCP initialization and tool-catalog validation, then failed before any worker-open call for each bad root. The regular-file, missing-path, and denied-write cases returned `ENOTDIR`, `ENOENT`, and `EACCES`, respectively, with `execution_failure` and exit 1. Writable and omitted-root controls exited 0; receipts included `idb_open`, `decompile`, `idb_close`, and final `idb_list`, with owned directories removed normally. A fresh upstream fetch resolved `origin/main` to `d2a3269d0c1007e16a2f84d44cc0b1503debb2ae`. Compared with the tested baseline, `IdaConfiguration.ts`, `IdaDoctor.ts`, `IdaSessionClient.ts`, `IdaWorkspace.ts`, and `docs/ida-provider.md` were unchanged. Changes to `docs/cli.md` concern other commands/output filtering. Current-main applicability is source-inspected; runtime reproduction was at the baseline above. ### Typed outcome or recovery expected Return a failed local readiness check identifying the unusable `workspaceRoot`, IDA `available: false`, selected-scope `healthy: false`, and exit 1. Preserve passing writable/default controls and keep upstream compatibility and target binding explicitly unverified by doctor. ### Analysis or suspected cause Source-derived reasoning: `src/ida/IdaConfiguration.ts:11-14` validates only absolute-path syntax. `src/ida/IdaDoctor.ts:12-21,50-58` checks platform private-workspace authority without examining the configured parent. `src/ida/IdaSessionClient.ts:569-604` reaches workspace allocation after connection and catalog guards; `src/ida/IdaWorkspace.ts:44-53` resolves the parent and allocates the private runtime, where the observed filesystem failures arise. ### Additional context Prepared with AI assistance and independently reproduced. Searches included open and closed issues and PRs for `ida doctor`, `workspaceRoot`, `IdaDoctor`, readiness, and workspace symptoms. Merged PR #1481 canonicalizes the workspace path during analysis; it does not validate local readiness in doctor. Issue #5554 concerns a separate Kuna cache-root check. NOT_ENOUGH_INFO: no last known good version or regression range was established.
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#3387
No description provided.