[PR #4754] [MERGED] perf(ghidra): aggregate binary overview at the provider boundary #6388

Closed
opened 2026-10-31 01:14:05 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4754
Author: @N0zoM1z0
Created: 10/17/2026
Status: ✅ Merged
Merged: 10/17/2026
Merged by: @N0zoM1z0

Base: main ← Head: perf/ghidra-overview-4746


📝 Commits (1)

  • 887fdc1 perf(ghidra): aggregate binary overview at the provider boundary

📊 Changes

24 files changed (+406 additions, -52 deletions)

View changed files

📝 bridge/ghidra/ReaGhidraBridge.java (+18 -0)
📝 docs/ghidra-provider.md (+8 -0)
📝 scripts/verify-packaged-ghidra-windows.mjs (+10 -9)
📝 scripts/verify-real-ghidra-address-context.mjs (+14 -0)
📝 scripts/verify-real-ghidra-windows.mjs (+10 -0)
📝 src/application/AnalysisProvider.ts (+3 -0)
➕ src/application/BinaryOverview.test.ts (+61 -0)
📝 src/application/CapabilityInventory.test.ts (+18 -0)
📝 src/application/CapabilityInventory.ts (+5 -0)
📝 src/application/EnhancedTools.ts (+20 -29)
📝 src/domain/hopperValues.ts (+33 -0)
📝 src/ghidra/GhidraInventoryValues.test.ts (+50 -1)
📝 src/ghidra/GhidraInventoryValues.ts (+11 -0)
📝 src/ghidra/GhidraProviderCapabilities.ts (+19 -3)
📝 src/ghidra/GhidraSnapshotCache.test.ts (+26 -2)
📝 tests/boundary/filesystem/directAnalysisSnapshotReplay.test.ts (+14 -0)
📝 tests/boundary/mcp/enhancedTools.01-lists-the-complete-target-open.test.ts (+10 -0)
📝 tests/boundary/mcp/enhancedTools.04-uses-complete-inventories-inline.test.ts (+18 -1)
📝 tests/boundary/mcp/enhancedTools.limitations.test.ts (+10 -1)
📝 tests/boundary/mcp/ghidraEvidenceMcp.test.ts (+4 -0)

...and 4 more files

📄 Description

Summary

Fixes #4746. Ghidra now supplies exact overview counts without sending complete procedure/string inventories to Node just to count them. Repeated overview reads reuse a small target/profile-bound observation. CLI and MCP keep the existing public contract and share the same workflow.

Problem and expected behavior

Six binary_overview calls previously caused six full procedure reads, six full string reads, six segment reads and six document reads. The same task now needs one native aggregate; explicit full-inventory reads remain available. Counts use the existing inventory owners, including external functions and Ghidra-defined strings.

Change and scope

  • Add the internal read_binary_inventory_summary observation, validate its counts/segments at the provider boundary, and reuse existing inventory caches. Its snapshot/Evidence identity is distinct from the derived public binary_overview workflow.
  • Share segment enumeration in Java and overview projection in the domain layer. Providers without the aggregate retain existing composition; malformed results, cancellation and incomplete cleanup do not silently fall back.
  • Keep public provider metadata separate from internal bridge operations and update affected catalog/verifier consumers. Handshake tests assert exact capability membership and cardinality without imposing array order.

Contract and boundary impact

  • Semantic owner: Ghidra inventory caches own counts; shared domain projection owns the overview shape.
  • Scope decision: not applicable; ordinary optimization of existing static reads, with existing Ghidra JVM/script and ephemeral-project authority.
  • CLI/MCP catalog and schemas: unchanged (207 tools; raw catalog SHA256 ff1101a46f1ae5e05b970343e43c665ac12bd490c8a4d7d5ebe8a91013e2b13b in the benchmark).
  • Compatibility: packaged bridge handshake adds one internal operation; public binary_overview {} stays compatible. Complete inventories and defined-string coverage limitations remain accessible.
  • Evidence/cache: preserve raw aggregate Evidence and derived workflow Evidence separately; existing target/profile keys, metadata-edit invalidation, cancellation and snapshot persistence apply.
  • Target selection/cleanup: one imported Program, existing supervised lifecycle and cleanup; target digests checked after real runs.
  • Generated metadata: regenerate ignored product catalog from authored declarations; no generated outputs, binaries or runtime installations committed.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.

The latter two refer to the existing owned Ghidra JVM and trusted analysis scripts. No target execution, injection, executable-byte modification, GUI control or new mutation authority is introduced.

Evidence and regression coverage

Real Linux stdio MCP: source-built tests/conformance/ghidra/inventory.c (31 procedures, 95 defined strings) and system SQLite (4,109 procedures, 2,856 defined strings). Two fresh sessions per implementation/target; complete-list oracles, independently mapped ELF marker bytes, overview facts, catalog hashes and target digests agree. Owned cleanup verified; OOM/oom_kill counters zero.

Recorded performance and context costs

Benchmark baseline: f85a932d71279415dd95cc30083137d1161f83b8 versus this patch before rebase. Linux x86-64, Node 24.18.0, Ghidra 12.1.4, Temurin 21.0.12.1+1; one CPU, 1 GiB JVM heap, 4 GiB family hard limit. Each pair uses the same CPU (15 for pair 1, 14 for pair 2). Fresh REA/JVM sessions; OS caches and host contention are uncontrolled. Task includes discovery, open/import, six overviews, explicit inventory oracles, marker lookup, retained-Evidence check and close.

SQLite, pair 1 / pair 2 Before After
First overview after import, ms 584 / 926 327 / 341
Five warm overviews total, ms 1,555 / 2,464 79 / 125
Whole task wall, s 181.66 / 258.21 183.25 / 172.91
Whole family CPU, s 165.03 / 254.75 181.50 / 170.53
Kernel family peak incl. file cache, MiB 1,405.9 / 1,333.6 1,353.4 / 1,375.9

Fixture warm totals: 515/216 → 111/85 ms; whole wall 109.93/52.46 → 50.03/47.64 s, CPU 80.86/50.87 → 48.72/46.04 s, peak 1,289.6/1,296.2 → 1,299.9/1,285.8 MiB. Counters are observed at payload exit while the guard observer remains alive. Startup variance dominates whole-task differences: only the overview query-phase benefit is established; no stable cold-analysis or memory improvement is claimed.

Offline cl100k_base/tiktoken 0.14.0 estimates over one serialized catalog plus all harness requests/replies, including verification oracles: SQLite 1,901,406 → 1,901,426; fixture 871,507 → 871,613. Catalog alone: 802,821. This includes both text and structured content, not actual model context/usage; prompts, client projection, framing and retries are unmeasured. No token reduction or improved agent investigation outcome is claimed.

SQLite SHA256: 2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8. Fixture SHA256: 7c9c14fab054d2b54670ea99be9f4d3bae56e09d211d9199f5d15571134ac574.

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • Runtime build passed. On rebased commit 887fdc1d62d58f2ae8ed411d49cfc503b6e2282a, npm run test:focused with 17 explicit source/boundary file paths passed: 346 tests, 2 platform skips. These checks cover aggregate validation, fallback/failure paths, source caveats, address representation, snapshot save/import/replay, mutation invalidation, cancellation, capacity and cleanup.
  • node scripts/verify-real-ghidra-address-context.mjs — passed with real Ghidra: CLI/MCP overview parity, count/list agreement, ELF relocation, file-offset round trips, decompilation, unchanged source and complete runtime cleanup.
  • npm exec -- turbo run lint:built format:check knip metadata:check --concurrency=1, npm run docs:check, npm run verify:architecture-guards — passed.
  • Local full npm run check typecheck was guard-stopped at the 3.25 GiB early-stop threshold, before OOM (final kernel counters: OOM=0, oom_kill=0). That local run is incomplete. CI Static checks subsequently passed the full project tsc --noEmit (cache miss), together with the complete static gate.
  • Rebased onto main 4a076f3; all 24 patch files are byte-identical across rebase; the 17-file focused selection passed (346 tests, 2 skips), and real stdio MCP fixture smoke on 887fdc1 passed with matching overview facts, independent ELF bytes and catalog hash. A further real MCP fixture run on CI merge candidate 3e426367a (main 73965f9 plus this PR) also passed, with identical facts, ELF-byte oracle and catalog hash, verified cleanup and zero OOM. Real Windows/macOS coverage remains unverified.

Automated review: Greptile 5/5, no actionable defects on 887fdc1. Codex review could not run because the repository review quota is exhausted; no Codex code finding was received.

  • CI run 39025115925 — all required checks passed, including full-project typecheck, source tests, all five test shards, package/native baseline and packaged Ghidra Java compilation.
  • Merged as ae029fe2f80b171a73df52e57b4a355f32f7c456; after rebuilding that actual merged source tree, the 17-file focused selection passed 377 tests, 2 platform skips, and fresh real Ghidra stdio MCP smoke passed. Overview facts, independent ELF marker bytes, target digest and catalog hash still match the baseline; verified cleanup, OOM=0. The earlier attempt that reused the pre-merge runtime is explicitly excluded from this post-merge evidence and retained locally. Both requested co-authors are present in the squash commit.

Compatibility, safety, and release

No public breaking change or migration. Real-provider coverage is Linux/Ghidra 12.1.4; Windows/macOS real Ghidra and real Hopper/IDA/Kuna were not run. Windows native and packaged verifiers are updated, with actual Windows verification still outside this local evidence. No installer or package-version change.

Author readiness

Human owner: @N0zoM1z0

Declarations are entered by the agent at the human owner's explicit direction. Diff and evidence checks reported here were performed by the agent; this does not assert a separately observed human review.

  • 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 (SQLite: procedure_count: 4109, string_count: 2856; complete segment fields preserved).
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 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/4754 **Author:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Created:** 10/17/2026 **Status:** ✅ Merged **Merged:** 10/17/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `perf/ghidra-overview-4746` --- ### 📝 Commits (1) - [`887fdc1`](https://github.com/morluto/rea/commit/887fdc1d62d58f2ae8ed411d49cfc503b6e2282a) perf(ghidra): aggregate binary overview at the provider boundary ### 📊 Changes **24 files changed** (+406 additions, -52 deletions) <details> <summary>View changed files</summary> 📝 `bridge/ghidra/ReaGhidraBridge.java` (+18 -0) 📝 `docs/ghidra-provider.md` (+8 -0) 📝 `scripts/verify-packaged-ghidra-windows.mjs` (+10 -9) 📝 `scripts/verify-real-ghidra-address-context.mjs` (+14 -0) 📝 `scripts/verify-real-ghidra-windows.mjs` (+10 -0) 📝 `src/application/AnalysisProvider.ts` (+3 -0) ➕ `src/application/BinaryOverview.test.ts` (+61 -0) 📝 `src/application/CapabilityInventory.test.ts` (+18 -0) 📝 `src/application/CapabilityInventory.ts` (+5 -0) 📝 `src/application/EnhancedTools.ts` (+20 -29) 📝 `src/domain/hopperValues.ts` (+33 -0) 📝 `src/ghidra/GhidraInventoryValues.test.ts` (+50 -1) 📝 `src/ghidra/GhidraInventoryValues.ts` (+11 -0) 📝 `src/ghidra/GhidraProviderCapabilities.ts` (+19 -3) 📝 `src/ghidra/GhidraSnapshotCache.test.ts` (+26 -2) 📝 `tests/boundary/filesystem/directAnalysisSnapshotReplay.test.ts` (+14 -0) 📝 `tests/boundary/mcp/enhancedTools.01-lists-the-complete-target-open.test.ts` (+10 -0) 📝 `tests/boundary/mcp/enhancedTools.04-uses-complete-inventories-inline.test.ts` (+18 -1) 📝 `tests/boundary/mcp/enhancedTools.limitations.test.ts` (+10 -1) 📝 `tests/boundary/mcp/ghidraEvidenceMcp.test.ts` (+4 -0) _...and 4 more files_ </details> ### 📄 Description ## Summary Fixes #4746. Ghidra now supplies exact overview counts without sending complete procedure/string inventories to Node just to count them. Repeated overview reads reuse a small target/profile-bound observation. CLI and MCP keep the existing public contract and share the same workflow. ## Problem and expected behavior Six `binary_overview` calls previously caused six full procedure reads, six full string reads, six segment reads and six document reads. The same task now needs one native aggregate; explicit full-inventory reads remain available. Counts use the existing inventory owners, including external functions and Ghidra-defined strings. ## Change and scope - Add the internal `read_binary_inventory_summary` observation, validate its counts/segments at the provider boundary, and reuse existing inventory caches. Its snapshot/Evidence identity is distinct from the derived public `binary_overview` workflow. - Share segment enumeration in Java and overview projection in the domain layer. Providers without the aggregate retain existing composition; malformed results, cancellation and incomplete cleanup do not silently fall back. - Keep public provider metadata separate from internal bridge operations and update affected catalog/verifier consumers. Handshake tests assert exact capability membership and cardinality without imposing array order. ## Contract and boundary impact - Semantic owner: Ghidra inventory caches own counts; shared domain projection owns the overview shape. - Scope decision: not applicable; ordinary optimization of existing static reads, with existing Ghidra JVM/script and ephemeral-project authority. - CLI/MCP catalog and schemas: unchanged (207 tools; raw catalog SHA256 `ff1101a46f1ae5e05b970343e43c665ac12bd490c8a4d7d5ebe8a91013e2b13b` in the benchmark). - Compatibility: packaged bridge handshake adds one internal operation; public `binary_overview {}` stays compatible. Complete inventories and defined-string coverage limitations remain accessible. - Evidence/cache: preserve raw aggregate Evidence and derived workflow Evidence separately; existing target/profile keys, metadata-edit invalidation, cancellation and snapshot persistence apply. - Target selection/cleanup: one imported Program, existing supervised lifecycle and cleanup; target digests checked after real runs. - Generated metadata: regenerate ignored product catalog from authored declarations; no generated outputs, binaries or runtime installations committed. Expected effects: - [x] Read existing files or captured data. - [x] Launch or attach to a process. - [x] Inject instrumentation or run scripts/code. The latter two refer to the existing owned Ghidra JVM and trusted analysis scripts. No target execution, injection, executable-byte modification, GUI control or new mutation authority is introduced. ## Evidence and regression coverage Real Linux stdio MCP: source-built `tests/conformance/ghidra/inventory.c` (31 procedures, 95 defined strings) and system SQLite (4,109 procedures, 2,856 defined strings). Two fresh sessions per implementation/target; complete-list oracles, independently mapped ELF marker bytes, overview facts, catalog hashes and target digests agree. Owned cleanup verified; OOM/oom_kill counters zero. <details> <summary>Recorded performance and context costs</summary> Benchmark baseline: `f85a932d71279415dd95cc30083137d1161f83b8` versus this patch before rebase. Linux x86-64, Node 24.18.0, Ghidra 12.1.4, Temurin 21.0.12.1+1; one CPU, 1 GiB JVM heap, 4 GiB family hard limit. Each pair uses the same CPU (15 for pair 1, 14 for pair 2). Fresh REA/JVM sessions; OS caches and host contention are uncontrolled. Task includes discovery, open/import, six overviews, explicit inventory oracles, marker lookup, retained-Evidence check and close. | SQLite, pair 1 / pair 2 | Before | After | | --- | ---: | ---: | | First overview after import, ms | 584 / 926 | 327 / 341 | | Five warm overviews total, ms | 1,555 / 2,464 | 79 / 125 | | Whole task wall, s | 181.66 / 258.21 | 183.25 / 172.91 | | Whole family CPU, s | 165.03 / 254.75 | 181.50 / 170.53 | | Kernel family peak incl. file cache, MiB | 1,405.9 / 1,333.6 | 1,353.4 / 1,375.9 | Fixture warm totals: 515/216 → 111/85 ms; whole wall 109.93/52.46 → 50.03/47.64 s, CPU 80.86/50.87 → 48.72/46.04 s, peak 1,289.6/1,296.2 → 1,299.9/1,285.8 MiB. Counters are observed at payload exit while the guard observer remains alive. Startup variance dominates whole-task differences: **only the overview query-phase benefit is established; no stable cold-analysis or memory improvement is claimed.** Offline `cl100k_base`/tiktoken 0.14.0 estimates over one serialized catalog plus all harness requests/replies, including verification oracles: SQLite 1,901,406 → 1,901,426; fixture 871,507 → 871,613. Catalog alone: 802,821. This includes both text and structured content, not actual model context/usage; prompts, client projection, framing and retries are unmeasured. **No token reduction or improved agent investigation outcome is claimed.** SQLite SHA256: `2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8`. Fixture SHA256: `7c9c14fab054d2b54670ea99be9f4d3bae56e09d211d9199f5d15571134ac574`. </details> - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - Runtime build passed. On rebased commit `887fdc1d62d58f2ae8ed411d49cfc503b6e2282a`, `npm run test:focused` with 17 explicit source/boundary file paths passed: **346 tests, 2 platform skips**. These checks cover aggregate validation, fallback/failure paths, source caveats, address representation, snapshot save/import/replay, mutation invalidation, cancellation, capacity and cleanup. - `node scripts/verify-real-ghidra-address-context.mjs` — passed with real Ghidra: CLI/MCP overview parity, count/list agreement, ELF relocation, file-offset round trips, decompilation, unchanged source and complete runtime cleanup. - `npm exec -- turbo run lint:built format:check knip metadata:check --concurrency=1`, `npm run docs:check`, `npm run verify:architecture-guards` — passed. - Local full `npm run check` typecheck was guard-stopped at the 3.25 GiB early-stop threshold, before OOM (final kernel counters: OOM=0, oom_kill=0). That local run is incomplete. [CI Static checks](https://github.com/morluto/rea/actions/runs/39025115925/job/117374652143) subsequently passed the full project `tsc --noEmit` (cache miss), together with the complete static gate. - Rebased onto main `4a076f3`; all 24 patch files are byte-identical across rebase; the 17-file focused selection passed (346 tests, 2 skips), and real stdio MCP fixture smoke on `887fdc1` passed with matching overview facts, independent ELF bytes and catalog hash. A further real MCP fixture run on CI merge candidate `3e426367a` (main `73965f9` plus this PR) also passed, with identical facts, ELF-byte oracle and catalog hash, verified cleanup and zero OOM. Real Windows/macOS coverage remains unverified. Automated review: Greptile **5/5**, no actionable defects on `887fdc1`. Codex review could not run because the repository review quota is exhausted; no Codex code finding was received. - [CI run 39025115925](https://github.com/morluto/rea/actions/runs/39025115925) — all required checks passed, including full-project typecheck, source tests, all five test shards, package/native baseline and packaged Ghidra Java compilation. - Merged as `ae029fe2f80b171a73df52e57b4a355f32f7c456`; after rebuilding that actual merged source tree, the 17-file focused selection passed **377 tests, 2 platform skips**, and fresh real Ghidra stdio MCP smoke passed. Overview facts, independent ELF marker bytes, target digest and catalog hash still match the baseline; verified cleanup, OOM=0. The earlier attempt that reused the pre-merge runtime is explicitly excluded from this post-merge evidence and retained locally. Both requested co-authors are present in the squash commit. ## Compatibility, safety, and release No public breaking change or migration. Real-provider coverage is Linux/Ghidra 12.1.4; Windows/macOS real Ghidra and real Hopper/IDA/Kuna were not run. Windows native and packaged verifiers are updated, with actual Windows verification still outside this local evidence. No installer or package-version change. ## Author readiness Human owner: @N0zoM1z0 Declarations are entered by the agent at the human owner's explicit direction. Diff and evidence checks reported here were performed by the agent; this does not assert a separately observed human review. - [x] 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. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output (SQLite: `procedure_count: 4109`, `string_count: 2856`; complete segment fields preserved). - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:14:05 +00:00
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#6388
No description provided.