[PR #1176] [MERGED] fix(session): require an open target for session-bound native and artifact tools #2701

Closed
opened 2026-10-17 21:09:14 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

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

Base: main ← Head: fix/session-availability-active-target


📝 Commits (1)

  • cf77d07 fix(session): require an open target for session-bound native and artifact tools

📊 Changes

3 files changed (+288 additions, -15 deletions)

View changed files

📝 src/application/CapabilityInventory.test.ts (+125 -0)
📝 src/application/CapabilityInventory.ts (+52 -9)
📝 tests/boundary/mcp/serverIdentity.test.ts (+111 -6)

📄 Description

Summary

binary_session is the documented way for an MCP client to choose a callable operation, but it reported native and artifact tools available whenever their provider declared them, whether or not a target was open. In a closed session, inspect_macho, inspect_signature, list_architectures, inspect_artifact, and every other session-bound native/artifact tool were advertised available, and each call failed with target_unavailable. With a ZIP open, inspect_macho stayed available and failed with capability_unavailable.

Fixes #1166

Cause

CapabilityInventory.targetAvailability applied the missing-target check only to the official-proxy and enhanced kinds. The native provider declares its descriptors without regard to the target (they are present and available even with nothing open), so native-provider and artifact-provider tools fell through to "available".

Change (src/application/CapabilityInventory.ts)

  • Closed session: every session-bound kind (official-proxy, enhanced, native-provider, artifact-provider) reports target_required with the open_binary remediation. Tools that take an explicit path keep their current availability: managed inspection and the gated inspect_binary_layout, inspect_recorded_crash, and inspect_evm_interface workflows, which are decided before this check.
  • Wrong target kind: the contracts defined only for a Mach-O executable (inspect_macho, list_architectures, observe_native_calls, observe_native_ui, capture_native_ui_scenario) report target_unsupported unless the open target is a Mach-O executable. This mirrors the provider's own guards (Active artifact is not Mach-O., "requires an active Mach-O executable or app target").
  • Host before target: an unsupported_host descriptor is now reported before target selection, because opening a target cannot fix it. Otherwise a Linux client with nothing open would be told to call open_binary for inspect_macho. Composed (enhanced) operations still decide from their requirements, so inspect_native_dispatch_metadata keeps target_required where another provider could serve it.

tools/list is unchanged; only the binary_session availability entries move.

Real MCP behavior (built main + this branch, macOS arm64, stdio)

State Before After
closed 15 session-bound native/artifact tools available, each call target_unavailable all 15 target_required
ZIP open inspect_macho available, call capability_unavailable inspect_macho, list_architectures, observe_native_*, capture_native_ui_scenario target_unsupported; inspect_signature, inspect_artifact, extract_artifact, demangle_swift stay available and succeed
thin ls-arm64e open all available all available; inspect_macho, inspect_signature, list_architectures, inspect_artifact succeed

Tests

  • src/application/CapabilityInventory.test.ts: closed session reports target_required even when the provider declares the operation; explicit-path tools stay available; Mach-O-only tools are target_unsupported for ZIP and ELF targets and available for Mach-O; unsupported_host wins over target selection except for composed operations. The first and third cases fail on main.
  • tests/boundary/mcp/serverIdentity.test.ts: over a live MCP connection, closed (target_required, and the call returns target_unavailable) → plist open (inspect_macho target_unsupported) → synthetic Mach-O open (available) → closed again. tools/list is identical throughout. Fails on main.

Verification

  • npm run check:fast, npm run jscpd (2.48%), npm run docs:check
  • npm run test:focused -- every test file that calls binary_session (17 files, 108 passed, 1 skipped), plus src/application/CapabilityInventory.test.ts
  • Manual stdio MCP probe of all native/artifact/managed tools in the three states above

Remaining gaps (not changed here)

  • inspect_plist says it accepts "any local plist path", but with no target open an explicit path still fails target_unavailable, so it is now reported target_required, which matches current behavior.
  • Bundle-only artifact operations (decode_interface_builder, inspect_keyed_archive, inspect_asset_catalog, trace_dylib_resolution) remain advertised for any open target and return unsupported_target for, e.g., a ZIP. Reporting that accurately needs target-aware provider descriptors rather than a list in the inventory.
  • list_architectures on a non-Mach-O target fails with execution_failure (a lipo error) rather than a typed refusal; it is now no longer advertised for those targets.

No Hopper/Ghidra verification was needed: the change is limited to session availability metadata.

🤖 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/1176 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/9/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/session-availability-active-target` --- ### 📝 Commits (1) - [`cf77d07`](https://github.com/morluto/rea/commit/cf77d073fc06ab95ce4181c30d68b1346e990b64) fix(session): require an open target for session-bound native and artifact tools ### 📊 Changes **3 files changed** (+288 additions, -15 deletions) <details> <summary>View changed files</summary> 📝 `src/application/CapabilityInventory.test.ts` (+125 -0) 📝 `src/application/CapabilityInventory.ts` (+52 -9) 📝 `tests/boundary/mcp/serverIdentity.test.ts` (+111 -6) </details> ### 📄 Description ## Summary `binary_session` is the documented way for an MCP client to choose a callable operation, but it reported native and artifact tools available whenever their provider declared them, whether or not a target was open. In a closed session, `inspect_macho`, `inspect_signature`, `list_architectures`, `inspect_artifact`, and every other session-bound native/artifact tool were advertised available, and each call failed with `target_unavailable`. With a ZIP open, `inspect_macho` stayed available and failed with `capability_unavailable`. Fixes #1166 ## Cause `CapabilityInventory.targetAvailability` applied the missing-target check only to the `official-proxy` and `enhanced` kinds. The native provider declares its descriptors without regard to the target (they are present and available even with nothing open), so `native-provider` and `artifact-provider` tools fell through to "available". ## Change (`src/application/CapabilityInventory.ts`) - **Closed session:** every session-bound kind (`official-proxy`, `enhanced`, `native-provider`, `artifact-provider`) reports `target_required` with the `open_binary` remediation. Tools that take an explicit path keep their current availability: managed inspection and the gated `inspect_binary_layout`, `inspect_recorded_crash`, and `inspect_evm_interface` workflows, which are decided before this check. - **Wrong target kind:** the contracts defined only for a Mach-O executable (`inspect_macho`, `list_architectures`, `observe_native_calls`, `observe_native_ui`, `capture_native_ui_scenario`) report `target_unsupported` unless the open target is a Mach-O executable. This mirrors the provider's own guards (`Active artifact is not Mach-O.`, "requires an active Mach-O executable or app target"). - **Host before target:** an `unsupported_host` descriptor is now reported before target selection, because opening a target cannot fix it. Otherwise a Linux client with nothing open would be told to call `open_binary` for `inspect_macho`. Composed (`enhanced`) operations still decide from their requirements, so `inspect_native_dispatch_metadata` keeps `target_required` where another provider could serve it. `tools/list` is unchanged; only the `binary_session` availability entries move. ## Real MCP behavior (built `main` + this branch, macOS arm64, stdio) | State | Before | After | |---|---|---| | closed | 15 session-bound native/artifact tools `available`, each call `target_unavailable` | all 15 `target_required` | | ZIP open | `inspect_macho` `available`, call `capability_unavailable` | `inspect_macho`, `list_architectures`, `observe_native_*`, `capture_native_ui_scenario` `target_unsupported`; `inspect_signature`, `inspect_artifact`, `extract_artifact`, `demangle_swift` stay available and succeed | | thin `ls-arm64e` open | all available | all available; `inspect_macho`, `inspect_signature`, `list_architectures`, `inspect_artifact` succeed | ## Tests - `src/application/CapabilityInventory.test.ts`: closed session reports `target_required` even when the provider declares the operation; explicit-path tools stay available; Mach-O-only tools are `target_unsupported` for ZIP and ELF targets and available for Mach-O; `unsupported_host` wins over target selection except for composed operations. The first and third cases fail on `main`. - `tests/boundary/mcp/serverIdentity.test.ts`: over a live MCP connection, closed (`target_required`, and the call returns `target_unavailable`) → plist open (`inspect_macho` `target_unsupported`) → synthetic Mach-O open (available) → closed again. `tools/list` is identical throughout. Fails on `main`. ## Verification - `npm run check:fast`, `npm run jscpd` (2.48%), `npm run docs:check` - `npm run test:focused --` every test file that calls `binary_session` (17 files, 108 passed, 1 skipped), plus `src/application/CapabilityInventory.test.ts` - Manual stdio MCP probe of all native/artifact/managed tools in the three states above ## Remaining gaps (not changed here) - `inspect_plist` says it accepts "any local plist path", but with no target open an explicit path still fails `target_unavailable`, so it is now reported `target_required`, which matches current behavior. - Bundle-only artifact operations (`decode_interface_builder`, `inspect_keyed_archive`, `inspect_asset_catalog`, `trace_dylib_resolution`) remain advertised for any open target and return `unsupported_target` for, e.g., a ZIP. Reporting that accurately needs target-aware provider descriptors rather than a list in the inventory. - `list_architectures` on a non-Mach-O target fails with `execution_failure` (a `lipo` error) rather than a typed refusal; it is now no longer advertised for those targets. No Hopper/Ghidra verification was needed: the change is limited to session availability metadata. 🤖 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>
bsakaguchi 2026-10-17 21:09:14 +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#2701
No description provided.