[PR #2634] [MERGED] perf(native): add opt-in Mach-O summary delivery and retained pages #5295

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2634
Author: @kaoru0822-kitauji
Created: 10/13/2026
Status: ✅ Merged
Merged: 10/13/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: perf/macho-summary-detail


📝 Commits (4)

  • 0d98b37 perf(native): add opt-in Mach-O summary delivery and retained pages
  • 5be6342 Merge origin/main into perf/macho-summary-detail
  • 6edba0b fix(mcp): refuse unretainable summary delivery before analysis
  • d190e84 fix(native): keep whole rows in Mach-O architecture and segment pages

📊 Changes

13 files changed (+864 additions, -17 deletions)

View changed files

📝 .agents/skills/reverse-engineer-anything/references/native-and-artifacts.md (+8 -0)
📝 docs/mcp-contracts.md (+15 -2)
📝 src/contracts/analysisViewToolContracts.ts (+2 -2)
📝 src/contracts/native/nativeToolContracts.ts (+10 -2)
📝 src/contracts/toolOutputSchemaGroups.ts (+4 -1)
📝 src/domain/analysisView/analysisView.ts (+28 -1)
➕ src/domain/analysisView/machoView.test.ts (+246 -0)
➕ src/domain/analysisView/machoView.ts (+247 -0)
📝 src/server/createServer.ts (+2 -3)
📝 src/server/registerArtifactTools.ts (+13 -5)
📝 src/server/registerEvidenceTools.ts (+19 -1)
➕ src/server/registerNativeTools.ts (+54 -0)
➕ tests/boundary/mcp/nativeMachoSummaryMcp.test.ts (+216 -0)

📄 Description

Summary

inspect_macho returns every import and export inline, with no way to ask for less. On VS Code's Electron Framework one MCP call returns 2,521,011 bytes of text (827,986 o200k tokens), plus the same JSON again as structuredContent. The 10 MiB default MCP response budget admits this, so it reaches the agent in full. An agent that only wanted the slice, UUID or dependency count still paid for 11,231 exports and 5,129 imports.

This PR adds the opt-in delivery selection that WASM, EVM, managed, Android, Dart AOT and pcap already have. detail: "summary" retains the complete Evidence and returns slice identity plus per-collection counts. inspect_analysis_view kind macho pages the original rows. Omitted or complete detail is unchanged, including its Evidence ID.

Refs #2016, #1065.

Problem and expected behavior

Smallest trigger: open_binary on any large framework, then inspect_macho {}. Expected (the precedent for every other large producer): a first call can ask for a bounded answer, and the complete Evidence stays retained for exact pages.

Change and scope

  • src/domain/analysisView/machoView.ts (new) is the single owner of Mach-O views.
    • Summary: keeps format, selected_architecture, endian, word_size, file_type, flags and uuid. Each of the eight collections becomes {returned, total, exhaustive}. It adds provenance_count and the merged report and collection limitations.
    • kind: "macho" pages: entrypoints, architectures, build_metadata, load_commands, dependencies, imports, exports, segments or provenance. Rows are the original rows. Each page repeats that collection's source_total and source_exhaustive and its own limitations, so exhausting a non-exhaustive collection (nm/dyld_info imports and exports) is never read as absence.
    • Refusals: other view kinds, a malformed retained result, and a subject whose format is not a thin or universal Mach-O (isMachOFormat, following 3c57e1a8b's subject authentication). A missing subject keeps the artifact identity unknown.
  • src/server/registerNativeTools.ts (new) registers the native contracts with the same hooks registerArtifactTools uses for inspect_artifact. detail is stripped before execution, and summary goes through summarizeRetainedAnalysis.
  • registerEvidenceTools gains parametersForEvidence, so delivery detail stays out of Evidence identity. The summary's parent_evidence_id is the same Evidence ID as a complete call, as WASM's delivery already guarantees. Omitted detail still records parameters: {}: /bin/ls gives ev_9e6882ef… on both main and this branch.
  • inspect_macho declares detail as optional (the inspect_artifact form), and its output schema is complete-or-summary. The CLI inspect-macho is unchanged. The portable CLI path is inspect-analysis-view with the complete Evidence inline, which works for kind: "macho" without other changes.
  • Docs: docs/mcp-contracts.md, the skill reference native-and-artifacts.md, and a short addition to the inspect_analysis_view description.

Not included: a default change (complete stays the default), CLI --detail, and any change to the native tools or their caching.

Contribution scope: not applicable. This follows the established opt-in delivery pattern; there's no new target execution, mutation or authority.

Contract and boundary impact

  • Semantic owner and earliest changed stage: machoView.ts (projection of retained inspect_macho Evidence); MCP delivery selection in registerNativeTools.

  • Contribution scope fit and linked maintainer decision: not applicable.

  • CLI and MCP/tool-catalog contract: additive. inspect_macho accepts optional detail and its output is a union with the summary carrier. inspect_analysis_view gains a macho request/result variant. Omitted detail behaves as before.

  • Provider, bridge, target-format, or platform compatibility: none. The native tools receive the same (empty) parameters.

  • Evidence, artifact, provenance, or reconstruction contract: complete Evidence and its ID are unchanged. Summary/page Evidence are derived views linked to the retained parent.

  • Generated metadata, package, or installation impact: the catalog is regenerated at build; docs:check passes.

  • Read existing files or captured data.

Evidence and regression coverage

  • src/domain/analysisView/machoView.test.ts (any platform): summary counts and merged limitations without rows, the non-exhaustive unknown, pages with producer coverage, provenance, an offset past the end, a missing subject, a contradictory subject format, the wrong view kind, and a malformed retained result.
  • tests/boundary/mcp/nativeMachoSummaryMcp.test.ts (darwin, real native tools on a copy of /bin/ls): omitted detail records parameters: {}; summary counts equal the complete result's collections; parent_evidence_id equals the complete call's Evidence ID; paging imports 16 at a time reproduces the complete imports.items exactly; a wrong view kind is refused.

Real-data measurements (macOS, real MCP stdio, this branch)

Target complete text summary text 64-export page
VS Code Electron Framework (195 MB) 2,521,011 B / 827,986 o200k tok 3,339 B / 956 tok 9,847 B / 3,266 tok
Transmission.app executable 111,433 B / 34,063 tok 3,171 B / 911 tok 11,570 B / 3,594 tok
/bin/ls 20,894 B / 6,356 tok 3,002 B / 913 tok 2,311 B / 723 tok

structuredContent carries the same JSON again in each case. Tokens were counted with tiktoken o200k_base (cl100k is within 1%). Timings for the first inspect_macho call in a fresh server:

  • Cold: about 0.55–0.7 s for both complete and summary (the same analysis).
  • Second call in the session: 0.14–0.32 s, because native results are reused.
  • Each view: 6–12 ms.

CPU and peak memory were not measured separately; the analysis is identical and only delivery differs.

Catalog cost: tools/list grows from 676,832 to 680,472 o200k tokens (+3,640, +0.54%). inspect_macho adds 1,042 tokens (input/output schema), and inspect_analysis_view adds 2,598, mostly the typed macho row union (1,593). Typing item loosely, as the older native function view does, would save about 1.2k, but I followed the typed WASM/managed views. One complete call on a mid-size app (34k tokens) outweighs the catalog cost.

Validation performed

  • npm run test:local -- src/domain/analysisView/machoView.test.ts — 4 passed
  • npx vitest run src/contracts src/domain/analysisView src/application/analysisView src/server — 147 passed, 3 skipped
  • npm run test:focused -- nativeMachoSummaryMcp, analysisSummaryDetailMcp, toolSchemaValidity, serverIdentity, analysisViewCli, targetContentProvenance, wasmArtifactMcp, managedArtifactSummaryMcp, nativeProvider, providerBinding — all pass. The one exception is analysisViewMcp "reads successive native source pages directly from a completed-result transport error", which fails identically on unmodified main on this host.
  • npm run check:fast, npm run typecheck, npm run format:check, npm run docs:check, npm run jscpd, npm run verify:architecture-guards — pass
  • Real CLI: inspect-macho on the Electron Framework, then inspect-analysis-view with that Evidence inline for summary, macho/exports and macho/build_metadata; each takes about 0.35 s and returns 2.5–3.3 KB.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Omitted and complete detail keep the same result shape and Evidence ID.
  • Real Hopper/Ghidra, browser, or OS coverage: real macOS native tools (otool, nm, dyld_info, lipo, vtool); the Linux CI runs the domain tests, and the darwin MCP test skips there.
  • Package or release metadata impact: none beyond the regenerated catalog.
  • Security, privacy, process, or containment review: summary/pages read only retained Evidence; no new process, file or network effects.

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

Summary by CodeRabbit

  • New Features
    • Mach-O inspection now offers a summary option with slice identity, collection counts, and coverage information, alongside full results.
    • View Mach-O analysis summaries or page through supported collections, including imports, exports, dependencies, and provenance, using retained inspection results.
    • Results indicate when additional rows may exist beyond those returned. Summary requests are unavailable when the server cannot retain analysis results.
  • Documentation
    • Added guidance for requesting summaries and paging through large Mach-O results.

🔄 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/2634 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/13/2026 **Status:** ✅ Merged **Merged:** 10/13/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `perf/macho-summary-detail` --- ### 📝 Commits (4) - [`0d98b37`](https://github.com/morluto/rea/commit/0d98b3715ba74f3286c2f6eab852f007461c78d4) perf(native): add opt-in Mach-O summary delivery and retained pages - [`5be6342`](https://github.com/morluto/rea/commit/5be63423d89effc1b8a887f251b7b871ffe1377e) Merge origin/main into perf/macho-summary-detail - [`6edba0b`](https://github.com/morluto/rea/commit/6edba0b10e595ed75473246269c28d273b893d8f) fix(mcp): refuse unretainable summary delivery before analysis - [`d190e84`](https://github.com/morluto/rea/commit/d190e84d81ce87d1ab26abd54bc8762f3b1bb2cd) fix(native): keep whole rows in Mach-O architecture and segment pages ### 📊 Changes **13 files changed** (+864 additions, -17 deletions) <details> <summary>View changed files</summary> 📝 `.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md` (+8 -0) 📝 `docs/mcp-contracts.md` (+15 -2) 📝 `src/contracts/analysisViewToolContracts.ts` (+2 -2) 📝 `src/contracts/native/nativeToolContracts.ts` (+10 -2) 📝 `src/contracts/toolOutputSchemaGroups.ts` (+4 -1) 📝 `src/domain/analysisView/analysisView.ts` (+28 -1) ➕ `src/domain/analysisView/machoView.test.ts` (+246 -0) ➕ `src/domain/analysisView/machoView.ts` (+247 -0) 📝 `src/server/createServer.ts` (+2 -3) 📝 `src/server/registerArtifactTools.ts` (+13 -5) 📝 `src/server/registerEvidenceTools.ts` (+19 -1) ➕ `src/server/registerNativeTools.ts` (+54 -0) ➕ `tests/boundary/mcp/nativeMachoSummaryMcp.test.ts` (+216 -0) </details> ### 📄 Description ## Summary `inspect_macho` returns every import and export inline, with no way to ask for less. On VS Code's `Electron Framework` one MCP call returns **2,521,011 bytes of text (827,986 o200k tokens)**, plus the same JSON again as `structuredContent`. The 10 MiB default MCP response budget admits this, so it reaches the agent in full. An agent that only wanted the slice, UUID or dependency count still paid for 11,231 exports and 5,129 imports. This PR adds the opt-in delivery selection that WASM, EVM, managed, Android, Dart AOT and pcap already have. `detail: "summary"` retains the complete Evidence and returns slice identity plus per-collection counts. `inspect_analysis_view` kind `macho` pages the original rows. Omitted or `complete` detail is unchanged, including its Evidence ID. Refs #2016, #1065. ## Problem and expected behavior Smallest trigger: `open_binary` on any large framework, then `inspect_macho {}`. Expected (the precedent for every other large producer): a first call can ask for a bounded answer, and the complete Evidence stays retained for exact pages. ## Change and scope - `src/domain/analysisView/machoView.ts` (new) is the single owner of Mach-O views. - **Summary:** keeps `format`, `selected_architecture`, `endian`, `word_size`, `file_type`, `flags` and `uuid`. Each of the eight collections becomes `{returned, total, exhaustive}`. It adds `provenance_count` and the merged report and collection limitations. - **`kind: "macho"` pages:** `entrypoints`, `architectures`, `build_metadata`, `load_commands`, `dependencies`, `imports`, `exports`, `segments` or `provenance`. Rows are the original rows. Each page repeats that collection's `source_total` and `source_exhaustive` and its own limitations, so exhausting a non-exhaustive collection (nm/dyld_info imports and exports) is never read as absence. - **Refusals:** other view kinds, a malformed retained result, and a subject whose format is not a thin or universal Mach-O (`isMachOFormat`, following 3c57e1a8b's subject authentication). A missing subject keeps the artifact identity unknown. - `src/server/registerNativeTools.ts` (new) registers the native contracts with the same hooks `registerArtifactTools` uses for `inspect_artifact`. `detail` is stripped before execution, and `summary` goes through `summarizeRetainedAnalysis`. - `registerEvidenceTools` gains `parametersForEvidence`, so delivery detail stays out of Evidence identity. The summary's `parent_evidence_id` is the same Evidence ID as a complete call, as WASM's delivery already guarantees. Omitted detail still records `parameters: {}`: `/bin/ls` gives `ev_9e6882ef…` on both main and this branch. - `inspect_macho` declares `detail` as optional (the `inspect_artifact` form), and its output schema is complete-or-summary. The CLI `inspect-macho` is unchanged. The portable CLI path is `inspect-analysis-view` with the complete Evidence inline, which works for `kind: "macho"` without other changes. - Docs: `docs/mcp-contracts.md`, the skill reference `native-and-artifacts.md`, and a short addition to the `inspect_analysis_view` description. Not included: a default change (complete stays the default), CLI `--detail`, and any change to the native tools or their caching. Contribution scope: not applicable. This follows the established opt-in delivery pattern; there's no new target execution, mutation or authority. ## Contract and boundary impact - Semantic owner and earliest changed stage: `machoView.ts` (projection of retained `inspect_macho` Evidence); MCP delivery selection in `registerNativeTools`. - Contribution scope fit and linked maintainer decision: not applicable. - CLI and MCP/tool-catalog contract: additive. `inspect_macho` accepts optional `detail` and its output is a union with the summary carrier. `inspect_analysis_view` gains a `macho` request/result variant. Omitted detail behaves as before. - Provider, bridge, target-format, or platform compatibility: none. The native tools receive the same (empty) parameters. - Evidence, artifact, provenance, or reconstruction contract: complete Evidence and its ID are unchanged. Summary/page Evidence are derived views linked to the retained parent. - Generated metadata, package, or installation impact: the catalog is regenerated at build; `docs:check` passes. - [x] Read existing files or captured data. ## Evidence and regression coverage - `src/domain/analysisView/machoView.test.ts` (any platform): summary counts and merged limitations without rows, the non-exhaustive unknown, pages with producer coverage, provenance, an offset past the end, a missing subject, a contradictory subject format, the wrong view kind, and a malformed retained result. - `tests/boundary/mcp/nativeMachoSummaryMcp.test.ts` (darwin, real native tools on a copy of `/bin/ls`): omitted detail records `parameters: {}`; summary counts equal the complete result's collections; `parent_evidence_id` equals the complete call's Evidence ID; paging imports 16 at a time reproduces the complete `imports.items` exactly; a wrong view kind is refused. ### Real-data measurements (macOS, real MCP stdio, this branch) | Target | complete text | summary text | 64-export page | | --- | --- | --- | --- | | VS Code `Electron Framework` (195 MB) | 2,521,011 B / **827,986** o200k tok | 3,339 B / **956** tok | 9,847 B / 3,266 tok | | `Transmission.app` executable | 111,433 B / 34,063 tok | 3,171 B / 911 tok | 11,570 B / 3,594 tok | | `/bin/ls` | 20,894 B / 6,356 tok | 3,002 B / 913 tok | 2,311 B / 723 tok | `structuredContent` carries the same JSON again in each case. Tokens were counted with tiktoken o200k_base (cl100k is within 1%). Timings for the first `inspect_macho` call in a fresh server: - **Cold:** about 0.55–0.7 s for both complete and summary (the same analysis). - **Second call in the session:** 0.14–0.32 s, because native results are reused. - **Each view:** 6–12 ms. CPU and peak memory were not measured separately; the analysis is identical and only delivery differs. Catalog cost: `tools/list` grows from 676,832 to 680,472 o200k tokens (+3,640, +0.54%). `inspect_macho` adds 1,042 tokens (input/output schema), and `inspect_analysis_view` adds 2,598, mostly the typed `macho` row union (1,593). Typing `item` loosely, as the older native function view does, would save about 1.2k, but I followed the typed WASM/managed views. One complete call on a mid-size app (34k tokens) outweighs the catalog cost. ## Validation performed - `npm run test:local -- src/domain/analysisView/machoView.test.ts` — 4 passed - `npx vitest run src/contracts src/domain/analysisView src/application/analysisView src/server` — 147 passed, 3 skipped - `npm run test:focused --` `nativeMachoSummaryMcp`, `analysisSummaryDetailMcp`, `toolSchemaValidity`, `serverIdentity`, `analysisViewCli`, `targetContentProvenance`, `wasmArtifactMcp`, `managedArtifactSummaryMcp`, `nativeProvider`, `providerBinding` — all pass. The one exception is `analysisViewMcp` "reads successive native source pages directly from a completed-result transport error", which fails identically on unmodified main on this host. - `npm run check:fast`, `npm run typecheck`, `npm run format:check`, `npm run docs:check`, `npm run jscpd`, `npm run verify:architecture-guards` — pass - Real CLI: `inspect-macho` on the Electron Framework, then `inspect-analysis-view` with that Evidence inline for `summary`, `macho/exports` and `macho/build_metadata`; each takes about 0.35 s and returns 2.5–3.3 KB. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Omitted and complete detail keep the same result shape and Evidence ID. - Real Hopper/Ghidra, browser, or OS coverage: real macOS native tools (`otool`, `nm`, `dyld_info`, `lipo`, `vtool`); the Linux CI runs the domain tests, and the darwin MCP test skips there. - Package or release metadata impact: none beyond the regenerated catalog. - Security, privacy, process, or containment review: summary/pages read only retained Evidence; no new process, file or network effects. ## 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. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Mach-O inspection now offers a summary option with slice identity, collection counts, and coverage information, alongside full results. * View Mach-O analysis summaries or page through supported collections, including imports, exports, dependencies, and provenance, using retained inspection results. * Results indicate when additional rows may exist beyond those returned. Summary requests are unavailable when the server cannot retain analysis results. * **Documentation** * Added guidance for requesting summaries and paging through large Mach-O results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:05:31 +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#5295
No description provided.