[GH-ISSUE #1750] fix(hopper): saved databases open without starting the analysis bridge #588

Closed
opened 2026-10-15 18:26:26 +00:00 by bsakaguchi · 2 comments
Owner

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

Summary

REA admits a saved Hopper database as an analysis target, but its macOS database launch does not execute the Python bootstrap on the tested Hopper installation. The database opens normally in Hopper while REA waits for a bridge socket that never appears. Analysis ends with a startup timeout and incomplete cleanup. Importing the original executable succeeds on the same installation, so this is a database-specific integration failure.

Runtime or environment

  • REA package: rea-agents@6.4.0; inspected release source.
  • Runtime: Node.js 26.10.0, macOS 27.0, arm64.
  • Hopper: bundle version 6.1.0-demo, build 42.6295552; embedded API reports 6.1.0. This is a non-stock installation. These observations establish compatibility with this copy only; stock installations and later Hopper versions were not executed.
  • Target: a newly compiled arm64 Mach-O executable and a new .hop database saved from it. The original executable remained byte-identical.
  • Area: Native analysis or decompilation. Interface: CLI and Python bridge. Earliest failure stage: Native analysis or reconstruction.

Steps to reproduce

  1. Use the tested baseline with Hopper Automation access allowed. Create a disposable executable with the following source and command.
work=$(mktemp -d /tmp/rea-hopper-repro.XXXXXX)
cat > "$work/probe.c" <<'C'
#include <stdio.h>
__attribute__((noinline)) int add_three(int x) { return x + 3; }
int main(int argc, char **argv) {
    printf("rea hopper probe: %d\n", add_three(argc));
    return 0;
}
C
xcrun clang -g -O0 "$work/probe.c" -o "$work/probe"
  1. Import that executable into Hopper with the Mach-O AArch64 loader, wait for automatic analysis to complete, and save a new database as $work/probe.hop. Verify that the database exists and can be reopened in Hopper. Close only this disposable document before the REA check.
  2. Run the database analysis and observe Hopper and the command result.
npx -y rea-agents@6.4.0 analyze "$work/probe.hop" --provider hopper --json
  1. For the discriminating control, analyze a separate copy of the original executable with the same command and provider. This control completed successfully locally. The database command may remain alive after emitting its failure because of a separate CLI lifecycle defect; stopping only the owned failed command is sufficient to finish this observation.

Expected behavior

REA's advertised analysis-database route should bind the exact saved Hopper database, start its analysis bridge, and return an overview or other supported database query. Saved annotations and analysis state must come from that database. Reimporting its original executable does not restore this contract. If this Hopper build cannot support the route, REA should identify the specific incompatibility rather than admit the target and wait for a bootstrap the launch route cannot execute.

Actual behavior

One real database analysis attempt opened the saved database in Hopper. The launcher completed with exit code 0, empty stdout and empty stderr. No bridge socket appeared in its newly created runtime directory. After the startup deadline, REA emitted the following meaningful failure fields.

{
  "code": "cleanup_incomplete",
  "message": "REA timed out waiting for Hopper bridge readiness. Hopper may be waiting for a loader or license dialog; inspect its window and the captured launcher outcome before retrying.",
  "primary_error": {
    "code": "provider_timeout",
    "details": {
      "stage": "startup",
      "timeout_ms": 120000,
      "launcher": {
        "exit_code": 0,
        "stdout": { "text": "", "bytes": 0 },
        "stderr": { "text": "", "bytes": 0 }
      },
      "provider_state": "not_started"
    }
  }
}

This is an excerpt of the emitted result, with the nested primary error projected for readability. Hopper displayed the opened database without a loader or license dialog. An executable control returned four segments, three procedures and one string through REA. A separate real stdio session also completed pseudocode, instruction, byte, annotation and bookmark operations on an executable copy.

Evidence

  • Expected source: src/contracts/sessionToolContracts.ts, the open_binary description, admits analysis databases; src/hopper/HopperProvider.ts, inspectTargetSupport, returns supported for database targets. Both are in the release source above.
  • Failure source: The real CLI database attempt emitted the startup timeout excerpt above despite a successful helper exit and an opened HOP. src/hopper/BridgeLauncher.ts, #launchPreparedTarget, passes --analysis -Y <bootstrap> --database <database>. The installed Contents/Resources/Hopper.sdef gives open database only its file parameter, while Python script parameters belong to open executable. Read-only inspection of both helper architecture slices corroborated that the database branch formats only open database and bypasses the executable branch's Python-script append.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Restoration check

Repeat the saved-database workflow on the affected baseline. Store a distinctive analyst label or comment in the disposable HOP before opening it through REA, and confirm that a supported query returns that saved value from the exact database. The database query must complete without waiting for a nonexistent bridge, or return a precise incompatibility outcome if the version cannot be supported. Keep the successful executable control. Preserve the input executable, saved HOP and unrelated Hopper documents during close or failure handling.

Impact

REA cannot analyze saved Hopper databases through this launch route on the tested copy. Reimporting the executable loses the saved document's analysis and annotations, so it is not an equivalent workaround. The result incorrectly suggests loader or licensing setup as the likely next investigation despite the opened database and successful helper outcome. No claim is made about stock Hopper or newer releases.

Triage assessment

  • Impact level: P1
  • Assessment status: provisional
  • Impact basis: A primary admitted native-analysis workflow fails for saved Hopper databases on the tested installation, and executable reimport does not preserve the saved analysis result. P1 is provisional because absence of another practical REA workaround has not been established; stock and later-version behavior is also unverified.
  • Workaround status: unverified
  • Workaround basis: Direct Hopper inspection is available, but no supported REA database workflow preserving saved state was verified. Executable analysis succeeds but does not preserve database-only annotations. Later-version compatibility is unknown.
Originally created by @coygeek on GitHub (Oct 11, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1750 ## Summary REA admits a saved Hopper database as an analysis target, but its macOS database launch does not execute the Python bootstrap on the tested Hopper installation. The database opens normally in Hopper while REA waits for a bridge socket that never appears. Analysis ends with a startup timeout and incomplete cleanup. Importing the original executable succeeds on the same installation, so this is a database-specific integration failure. ## Runtime or environment - REA package: `rea-agents@6.4.0`; inspected [release source](https://github.com/morluto/rea/tree/a56f7bb668ab23fec8d33f7af353ac7ed2fe1895). - Runtime: Node.js `26.10.0`, macOS `27.0`, arm64. - Hopper: bundle version `6.1.0-demo`, build `42.6295552`; embedded API reports `6.1.0`. This is a non-stock installation. These observations establish compatibility with this copy only; stock installations and later Hopper versions were not executed. - Target: a newly compiled arm64 Mach-O executable and a new `.hop` database saved from it. The original executable remained byte-identical. - Area: Native analysis or decompilation. Interface: CLI and Python bridge. Earliest failure stage: Native analysis or reconstruction. ## Steps to reproduce 1. Use the tested baseline with Hopper Automation access allowed. Create a disposable executable with the following source and command. ```sh work=$(mktemp -d /tmp/rea-hopper-repro.XXXXXX) cat > "$work/probe.c" <<'C' #include <stdio.h> __attribute__((noinline)) int add_three(int x) { return x + 3; } int main(int argc, char **argv) { printf("rea hopper probe: %d\n", add_three(argc)); return 0; } C xcrun clang -g -O0 "$work/probe.c" -o "$work/probe" ``` 2. Import that executable into Hopper with the Mach-O AArch64 loader, wait for automatic analysis to complete, and save a new database as `$work/probe.hop`. Verify that the database exists and can be reopened in Hopper. Close only this disposable document before the REA check. 3. Run the database analysis and observe Hopper and the command result. ```sh npx -y rea-agents@6.4.0 analyze "$work/probe.hop" --provider hopper --json ``` 4. For the discriminating control, analyze a separate copy of the original executable with the same command and provider. This control completed successfully locally. The database command may remain alive after emitting its failure because of a separate CLI lifecycle defect; stopping only the owned failed command is sufficient to finish this observation. ## Expected behavior REA's advertised analysis-database route should bind the exact saved Hopper database, start its analysis bridge, and return an overview or other supported database query. Saved annotations and analysis state must come from that database. Reimporting its original executable does not restore this contract. If this Hopper build cannot support the route, REA should identify the specific incompatibility rather than admit the target and wait for a bootstrap the launch route cannot execute. ## Actual behavior One real database analysis attempt opened the saved database in Hopper. The launcher completed with exit code `0`, empty stdout and empty stderr. No bridge socket appeared in its newly created runtime directory. After the startup deadline, REA emitted the following meaningful failure fields. ```json { "code": "cleanup_incomplete", "message": "REA timed out waiting for Hopper bridge readiness. Hopper may be waiting for a loader or license dialog; inspect its window and the captured launcher outcome before retrying.", "primary_error": { "code": "provider_timeout", "details": { "stage": "startup", "timeout_ms": 120000, "launcher": { "exit_code": 0, "stdout": { "text": "", "bytes": 0 }, "stderr": { "text": "", "bytes": 0 } }, "provider_state": "not_started" } } } ``` This is an excerpt of the emitted result, with the nested primary error projected for readability. Hopper displayed the opened database without a loader or license dialog. An executable control returned four segments, three procedures and one string through REA. A separate real stdio session also completed pseudocode, instruction, byte, annotation and bookmark operations on an executable copy. ## Evidence - Expected source: `src/contracts/sessionToolContracts.ts`, the `open_binary` description, admits analysis databases; `src/hopper/HopperProvider.ts`, `inspectTargetSupport`, returns supported for database targets. Both are in the release source above. - Failure source: The real CLI database attempt emitted the startup timeout excerpt above despite a successful helper exit and an opened HOP. `src/hopper/BridgeLauncher.ts`, `#launchPreparedTarget`, passes `--analysis -Y <bootstrap> --database <database>`. The installed `Contents/Resources/Hopper.sdef` gives `open database` only its file parameter, while Python script parameters belong to `open executable`. Read-only inspection of both helper architecture slices corroborated that the database branch formats only `open database` and bypasses the executable branch's Python-script append. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete ## Restoration check Repeat the saved-database workflow on the affected baseline. Store a distinctive analyst label or comment in the disposable HOP before opening it through REA, and confirm that a supported query returns that saved value from the exact database. The database query must complete without waiting for a nonexistent bridge, or return a precise incompatibility outcome if the version cannot be supported. Keep the successful executable control. Preserve the input executable, saved HOP and unrelated Hopper documents during close or failure handling. ## Impact REA cannot analyze saved Hopper databases through this launch route on the tested copy. Reimporting the executable loses the saved document's analysis and annotations, so it is not an equivalent workaround. The result incorrectly suggests loader or licensing setup as the likely next investigation despite the opened database and successful helper outcome. No claim is made about stock Hopper or newer releases. ## Triage assessment - Impact level: P1 - Assessment status: provisional - Impact basis: A primary admitted native-analysis workflow fails for saved Hopper databases on the tested installation, and executable reimport does not preserve the saved analysis result. P1 is provisional because absence of another practical REA workaround has not been established; stock and later-version behavior is also unverified. - Workaround status: unverified - Workaround basis: Direct Hopper inspection is available, but no supported REA database workflow preserving saved state was verified. Executable analysis succeeds but does not preserve database-only annotations. Later-version compatibility is unknown.
bsakaguchi 2026-10-15 18:26:26 +00:00
Author
Owner

@matbrgz commented on GitHub (Oct 12, 2026):

Hopper Bridge Bootstrap Review

When launching Hopper directly against an existing saved database (.hop), Hopper does not execute the document startup Python script arguments in the same sequence as during fresh binary import:

  • Root Cause: Hopper GUI's command-line invocation syntax differs when loading an existing project database compared to headless binary import.
  • Remediation: Verify whether Hopper's CLI accepts -e <script.py> alongside saved database documents or whether the bridge script must be injected via Hopper's user scripts directory. If saved databases cannot reliably bootstrap the socket bridge without manual GUI clicks, the Hopper provider should decline .hop database inputs with an explicit limitation.
<!-- gh-comment-id:6134573556 --> @matbrgz commented on GitHub (Oct 12, 2026): ### Hopper Bridge Bootstrap Review When launching Hopper directly against an existing saved database (`.hop`), Hopper does not execute the document startup Python script arguments in the same sequence as during fresh binary import: - **Root Cause:** Hopper GUI's command-line invocation syntax differs when loading an existing project database compared to headless binary import. - **Remediation:** Verify whether Hopper's CLI accepts `-e <script.py>` alongside saved database documents or whether the bridge script must be injected via Hopper's user scripts directory. If saved databases cannot reliably bootstrap the socket bridge without manual GUI clicks, the Hopper provider should decline `.hop` database inputs with an explicit limitation.
Author
Owner

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

Verified the reported defect is addressed on main by d4bd65c53c.

Root cause and resolution: The body reports a non-stock Hopper installation where .hop opens but bridge bootstrap never starts. Current macOS provider explicitly refuses saved-database targets before launch and explains that no supported bridge launch route exists; this satisfies the report’s fallback acceptance to identify the incompatibility rather than time out.

Validation: src/hopper/HopperProviderDiscovery.test.ts — fails closed for saved Hopper databases on macOS without a bridge launch route asserts unsupported target, database identity and specific incompatibility reason instead of waiting for a bridge timeout.

Evidence: CI run 500e: owner unchanged and assertion passed.

Verification scope: Resolves the issue’s accepted precise-incompatibility outcome; saved-database analysis remains unavailable on macOS.

Current main CI has separate failures under repair; this closure does not claim the complete main workflow is green.

<!-- gh-comment-id:6162527493 --> @morluto commented on GitHub (Oct 14, 2026): Verified the reported defect is addressed on main by d4bd65c53c0254d0195cc7ab8da163dcadfd3b9b. Root cause and resolution: The body reports a non-stock Hopper installation where `.hop` opens but bridge bootstrap never starts. Current macOS provider explicitly refuses saved-database targets before launch and explains that no supported bridge launch route exists; this satisfies the report’s fallback acceptance to identify the incompatibility rather than time out. Validation: `src/hopper/HopperProviderDiscovery.test.ts` — `fails closed for saved Hopper databases on macOS without a bridge launch route` asserts unsupported target, database identity and specific incompatibility reason instead of waiting for a bridge timeout. Evidence: CI run 500e: owner unchanged and assertion passed. Verification scope: Resolves the issue’s accepted precise-incompatibility outcome; saved-database analysis remains unavailable on macOS. Current main CI has separate failures under repair; this closure does not claim the complete main workflow is green.
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#588
No description provided.