[GH-ISSUE #7316] [Bug] Closed-session discovery falsely requires a target for inspect_apk_signature #4346

Open
opened 2026-10-31 00:49:05 +00:00 by bsakaguchi · 0 comments
Owner

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

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

With no target open, binary_session {} puts inspect_apk_signature in a group with available:false, reason:"target_required" and remediation Call open_binary with a supported local target. In that same stdio connection, calling the tool with an absolute path to an unsigned ZIP succeeds. Another status call still reports open:false, cleanup_pending:false and the same false prerequisite. The Python-pyc and SQLite explicit-path tools report available in both status calls.

Reproduction

From the built checkout with locked dependencies, Node and Python 3 already available, run this command. It generates a 126-byte ZIP containing only a text file, isolates server configuration, starts a fresh real stdio session, and removes its temporary files afterward. This exact script was executed successfully; an earlier independent stdio probe reproduced the same mismatch, for two completed sessions total.

node --input-type=module <<'JS'
import { Client } from '@modelcontextprotocol/client';
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';
import { execFileSync } from 'node:child_process';
import { mkdtemp, mkdir, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
const work = await mkdtemp(join(tmpdir(), 'rea-availability-'));
const env = { PATH: process.env.PATH, REA_LOG_LEVEL: 'silent' };
for (const key of ['HOME', 'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_STATE_HOME', 'TMPDIR']) {
  env[key] = join(work, key.toLowerCase());
  await mkdir(env[key]);
}
const fixture = join(work, 'unsigned.zip');
execFileSync('python3', ['-c', "import sys,zipfile; z=zipfile.ZipFile(sys.argv[1],'w'); z.writestr('fixture.txt','hello\\n'); z.close()", fixture], {env});
const client = new Client({name: 'availability-check', version: '1'});
const transport = new StdioClientTransport({command: process.execPath, args: [resolve('scripts/rea.mjs'), 'mcp'], cwd: work, env, stderr: 'pipe'});
const status = async () => {
  const reply = await client.callTool({name: 'binary_session', arguments: {}});
  const s = reply.structuredContent.result;
  return {open: s.open, cleanup_pending: s.cleanup_pending, tools: ['inspect_apk_signature', 'inspect_python_pyc', 'inspect_sqlite_database'].map(name => {
    const g = s.tool_availability.groups.find(g => g.names.includes(name));
    return {name, available: g.available, reason: g.reason, remediation: g.remediation};
  })};
};
try {
  await client.connect(transport);
  console.log('before', JSON.stringify(await status()));
  const reply = await client.callTool({name: 'inspect_apk_signature', arguments: {path: fixture}});
  const result = reply.structuredContent?.normalized_result;
  console.log('inspection', JSON.stringify({isError: reply.isError ?? false, kind: result?.kind, schemes: result?.summary?.schemes, counts: result?.summary?.counts}));
  console.log('after', JSON.stringify(await status()));
} finally {
  await client.close();
  await transport.close();
  await rm(work, {recursive: true, force: true});
}
JS

Expected behavior

Discovery should report inspect_apk_signature callable without an active target when the caller selects a readable supported archive by absolute path. The documented inventory expands each group's availability/reason/remediation onto every named tool. APK signature inspection is documented as an in-process local-file workflow; its actual registered handler reads the selected path without active-target execution.

Impact and scope

The documented operation-selection API returns false readiness and irrelevant recovery guidance for a working static tool. A client following these facts could skip the operation or attempt an unnecessary open_binary; no downstream client decision was measured. Direct MCP invocation succeeds, and the separate inspect-apk-signature CLI control exited 0 on the same unsigned ZIP. Only discovery is shown incorrect; this does not establish a problem with signature decoding or result integrity.

REA version

6.8.0; source revision 3233992733c33dabf2de09d22ee4e6d9409f797a.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1 arm64; real MCP stdio transport with isolated HOME/XDG/TMPDIR. No external analysis engine is needed.

Target and artifact context

No open target. An unsigned, ordinary ZIP containing fixture.txt with hello and a newline; no APK payload, Android execution, device or Java toolchain.

Interface

MCP

Earliest failure stage

Transport or result projection

Relevant output or evidence

Observed before and after the successful direct call, projected onto each selected tool:

open: false
cleanup_pending: false
inspect_apk_signature: available=false, reason=target_required
  remediation: Call open_binary with a supported local target.
inspect_python_pyc: available=true, reason=available, remediation=null
inspect_sqlite_database: available=true, reason=available, remediation=null

The intervening inspect_apk_signature call returned isError:false, normalized_result.kind:"summary", all v1/v2/v3/v3.1 presences false with zero signers, and counts {signers:0,digests:0,lineage:0}. tools/list also advertised the tool with path as its sole required input.

  • Expected source: docs/mcp-contracts.md:610-619 defines per-tool group expansion and callable-operation selection; docs/apk-signature.md:3-14 documents the local in-process workflow; src/server/registerApkSignatureTools.ts:20-36 dispatches directly to the path-based service.
  • Failure source: The two observed stdio sequences above; src/contracts/apkSignature/apkSignatureToolContracts.ts:17 declares an active-target prerequisite, projected by src/application/CapabilityInventory.ts:262-264,405-410,757-762 into the false target_required status.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Typed outcome or recovery expected

Repeating the sequence should report APK inspection available while retaining the successful unsigned summary and open:false afterward. The explicit-path controls should remain available. This is the restoration criterion; no patch was tested.

Analysis or suspected cause

Source-derived: the named APK contract declares requiresActiveTarget:true, but its handler invokes ApkSignatureService.inspect rather than active-target execution. Generic session admission tracks lifecycle transitions and does not itself require an open target. The direct call confirms that the reported prerequisite is absent from execution. This does not imply that all tools accepting paths should be target-free.

Additional context

Related closed reports concern independent debugger discovery (#5447), navigation recovery (#5729) and plist's intentionally retained target prerequisite (#6135); their recorded closures do not cover APK inspection. Open #7310 concerns the opposite mismatch for address context. No exact duplicate was found in live open/closed issue and PR searches. NOT_ENOUGH_INFO: first affected version, last known good version and downstream client occurrence frequency were not established.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Machine-readable discovery marks a callable operation unavailable and supplies an irrelevant prerequisite, impairing the documented operation-selection workflow. Actual downstream agent choices were not measured.
  • Workaround status: available
  • Workaround basis: Directly call inspect_apk_signature with the selected absolute archive path; both fresh stdio sessions returned the unsigned summary while remaining closed. The same fixture also completed through the CLI with exit 0.
Originally created by @coygeek on GitHub (Oct 26, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7316 ### 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 With no target open, `binary_session {}` puts `inspect_apk_signature` in a group with `available:false`, `reason:"target_required"` and remediation `Call open_binary with a supported local target.` In that same stdio connection, calling the tool with an absolute path to an unsigned ZIP succeeds. Another status call still reports `open:false`, `cleanup_pending:false` and the same false prerequisite. The Python-pyc and SQLite explicit-path tools report available in both status calls. ### Reproduction From the built checkout with locked dependencies, Node and Python 3 already available, run this command. It generates a 126-byte ZIP containing only a text file, isolates server configuration, starts a fresh real stdio session, and removes its temporary files afterward. This exact script was executed successfully; an earlier independent stdio probe reproduced the same mismatch, for two completed sessions total. ```sh node --input-type=module <<'JS' import { Client } from '@modelcontextprotocol/client'; import { StdioClientTransport } from '@modelcontextprotocol/client/stdio'; import { execFileSync } from 'node:child_process'; import { mkdtemp, mkdir, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; const work = await mkdtemp(join(tmpdir(), 'rea-availability-')); const env = { PATH: process.env.PATH, REA_LOG_LEVEL: 'silent' }; for (const key of ['HOME', 'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_STATE_HOME', 'TMPDIR']) { env[key] = join(work, key.toLowerCase()); await mkdir(env[key]); } const fixture = join(work, 'unsigned.zip'); execFileSync('python3', ['-c', "import sys,zipfile; z=zipfile.ZipFile(sys.argv[1],'w'); z.writestr('fixture.txt','hello\\n'); z.close()", fixture], {env}); const client = new Client({name: 'availability-check', version: '1'}); const transport = new StdioClientTransport({command: process.execPath, args: [resolve('scripts/rea.mjs'), 'mcp'], cwd: work, env, stderr: 'pipe'}); const status = async () => { const reply = await client.callTool({name: 'binary_session', arguments: {}}); const s = reply.structuredContent.result; return {open: s.open, cleanup_pending: s.cleanup_pending, tools: ['inspect_apk_signature', 'inspect_python_pyc', 'inspect_sqlite_database'].map(name => { const g = s.tool_availability.groups.find(g => g.names.includes(name)); return {name, available: g.available, reason: g.reason, remediation: g.remediation}; })}; }; try { await client.connect(transport); console.log('before', JSON.stringify(await status())); const reply = await client.callTool({name: 'inspect_apk_signature', arguments: {path: fixture}}); const result = reply.structuredContent?.normalized_result; console.log('inspection', JSON.stringify({isError: reply.isError ?? false, kind: result?.kind, schemes: result?.summary?.schemes, counts: result?.summary?.counts})); console.log('after', JSON.stringify(await status())); } finally { await client.close(); await transport.close(); await rm(work, {recursive: true, force: true}); } JS ``` ### Expected behavior Discovery should report `inspect_apk_signature` callable without an active target when the caller selects a readable supported archive by absolute path. The documented inventory expands each group's availability/reason/remediation onto every named tool. APK signature inspection is documented as an in-process local-file workflow; its actual registered handler reads the selected path without active-target execution. ### Impact and scope The documented operation-selection API returns false readiness and irrelevant recovery guidance for a working static tool. A client following these facts could skip the operation or attempt an unnecessary `open_binary`; no downstream client decision was measured. Direct MCP invocation succeeds, and the separate `inspect-apk-signature` CLI control exited 0 on the same unsigned ZIP. Only discovery is shown incorrect; this does not establish a problem with signature decoding or result integrity. ### REA version 6.8.0; source revision `3233992733c33dabf2de09d22ee4e6d9409f797a`. ### Runtime and platform Node.js v24.22.1; macOS 27.0.1 arm64; real MCP stdio transport with isolated HOME/XDG/TMPDIR. No external analysis engine is needed. ### Target and artifact context No open target. An unsigned, ordinary ZIP containing `fixture.txt` with `hello` and a newline; no APK payload, Android execution, device or Java toolchain. ### Interface MCP ### Earliest failure stage Transport or result projection ### Relevant output or evidence Observed before and after the successful direct call, projected onto each selected tool: ```text open: false cleanup_pending: false inspect_apk_signature: available=false, reason=target_required remediation: Call open_binary with a supported local target. inspect_python_pyc: available=true, reason=available, remediation=null inspect_sqlite_database: available=true, reason=available, remediation=null ``` The intervening `inspect_apk_signature` call returned `isError:false`, `normalized_result.kind:"summary"`, all v1/v2/v3/v3.1 presences false with zero signers, and counts `{signers:0,digests:0,lineage:0}`. `tools/list` also advertised the tool with `path` as its sole required input. - Expected source: `docs/mcp-contracts.md:610-619` defines per-tool group expansion and callable-operation selection; `docs/apk-signature.md:3-14` documents the local in-process workflow; `src/server/registerApkSignatureTools.ts:20-36` dispatches directly to the path-based service. - Failure source: The two observed stdio sequences above; `src/contracts/apkSignature/apkSignatureToolContracts.ts:17` declares an active-target prerequisite, projected by `src/application/CapabilityInventory.ts:262-264,405-410,757-762` into the false `target_required` status. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete ### Typed outcome or recovery expected Repeating the sequence should report APK inspection available while retaining the successful unsigned summary and `open:false` afterward. The explicit-path controls should remain available. This is the restoration criterion; no patch was tested. ### Analysis or suspected cause Source-derived: the named APK contract declares `requiresActiveTarget:true`, but its handler invokes `ApkSignatureService.inspect` rather than active-target execution. Generic session admission tracks lifecycle transitions and does not itself require an open target. The direct call confirms that the reported prerequisite is absent from execution. This does not imply that all tools accepting paths should be target-free. ### Additional context Related closed reports concern independent debugger discovery (#5447), navigation recovery (#5729) and plist's intentionally retained target prerequisite (#6135); their recorded closures do not cover APK inspection. Open #7310 concerns the opposite mismatch for address context. No exact duplicate was found in live open/closed issue and PR searches. NOT_ENOUGH_INFO: first affected version, last known good version and downstream client occurrence frequency were not established. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Machine-readable discovery marks a callable operation unavailable and supplies an irrelevant prerequisite, impairing the documented operation-selection workflow. Actual downstream agent choices were not measured. - Workaround status: available - Workaround basis: Directly call inspect_apk_signature with the selected absolute archive path; both fresh stdio sessions returned the unsigned summary while remaining closed. The same fixture also completed through the CLI with exit 0.
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#4346
No description provided.