[GH-ISSUE #8506] [Bug] Capability discovery replaces provider recovery actions with failure descriptions #6631

Closed
opened 2026-11-01 21:12:49 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @morluto on GitHub (Nov 1, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8506

Originally assigned to: @kaoru0822-kitauji on GitHub.

Before submitting

  • Searched open and closed issues for related reports.
  • Removed credentials, private paths, and sensitive target data.

Area

Provider or capability discovery

Observed behavior

Capability discovery loses provider-owned recovery instructions and returns the failure description in its remediation field instead. Confirmed cases are JEB discovery timeouts, ADB/Apktool execute-permission failures, and an unreadable IDA registration.

JEB creates an actionable timeout recovery naming REA_JEB_MCP_TIMEOUT_MS and restart/reconnect requirements, but inspectAvailability() drops it. ADB and Apktool retain their repair instructions in diagnostics.remediation, but the shared inventory ignores those instructions and uses the failure description instead.

Reproduction

Executed against source 3842809c371a59609f576a9db8f9c492a3f071e6:

  1. Create the production JebMcpDeadline(1, undefined, "discovery"), let its real timer expire, and obtain its failure with deadline.failure("jeb_mcp_catalog", deadline.signal.reason). Dispose the deadline.
  2. Inject a JebMcpConnection whose listTools rejects with that exact failure. This isolates result propagation; no JEB engine or network timeout is simulated as a real runtime observation.
  3. Call JebProvider.inspectAvailability() and pass its result to buildCapabilityInventory({open:false, capabilities:[]}, {jebAnalysisAvailability}).
  4. Compare the original error's projection with the inspect_jeb_client inventory entry.

For ADB and Apktool, also created a temporary regular file with mode 0600 and selected it through REA_ADB_PATH / REA_APKTOOL_COMMAND. Called each real provider's inspectAvailability() and passed the result into buildCapabilityInventory. The file could not execute; no ADB device, server, or APK was contacted. Closed both providers and removed the temporary directory.

For IDA, selected a nonexistent registration using production parseConfig, called IdaProvider.inspectReadinessSnapshot(), and projected the returned capabilities through providerCapabilitySets and buildCapabilityInventory. Used a controlled open-target status only to exercise the final inventory projection; no target or IDA connection was opened. A connection factory that would throw if invoked was never called. The provider's configuration_remediation survived in diagnostics, but its launch-environment instructions did not reach the inventory entry for analyze_function.

Expected behavior

Preserve the provider-owned recovery through availability and capability output. A remediation field should tell the caller how to change the relevant deadline, rather than repeat the failure. Retain the original timeout category and budget where the availability contract permits it; keep caller cancellation distinct.

Impact and scope

Reproduced JEB through the production deadline and inventory with an injected MCP connection, ADB/Apktool through real permission-denied readiness probes, and IDA through a missing-file readiness check and controlled status projection. Agents lose instructions the producers already supplied. IDA's final description still says to provide readable JSON, but loses where to change the configuration for the running REA process. No live JEB/IDA server, public CLI/MCP process, connected Android device or APK decoding was exercised; occurrence frequency on those paths is unknown.

REA version

Source 3842809c371a59609f576a9db8f9c492a3f071e6.

Runtime and platform

Node 24.22.1, Darwin arm64. No JEB/ADB/Apktool installation was required for these boundary reproductions.

Target and artifact context

Catalog and client readiness only; no JEB project, Android device, or APK opened.

Interface

Other: shared provider/capability result used by CLI/MCP.

Earliest failure stage

Transport or result projection

Relevant output or evidence

Case Provider-owned recovery Capability inventory remediation
JEB discovery timeout Increase REA_JEB_MCP_TIMEOUT_MS, restart/reconnect and allow client headroom Repeats that catalog discovery reached its deadline
ADB EACCES Check file type and execute permission for REA_ADB_PATH, or select an executable ADB binary Repeats that execution of the selected binary was denied
Apktool execute-permission failure Check file type and execute permission for REA_APKTOOL_COMMAND, or select an executable launcher Repeats that execution of the selected launcher was denied
IDA unreadable registration Correct REA_IDA_MCP_CONFIG in the environment starting REA, including the MCP client's registration, then rerun Reports invalid configuration and asks for readable JSON, omitting the launch-environment instructions

Temporary file paths are omitted here. The ADB/Apktool recovery strings remained present in the availability diagnostics before inventory projection.

The original projectAnalysisError(failure) includes:

{
  "code": "provider_timeout",
  "remediation": {
    "action": "Increase REA_JEB_MCP_TIMEOUT_MS in REA's launch environment ... and restart and reconnect REA to apply it. ..."
  }
}

The capability entry instead includes:

{
  "name": "inspect_jeb_client",
  "available": false,
  "reason": "provider_unavailable",
  "remediation": "This request reached REA's configured JEB catalog discovery deadline of 1 ms (deadlineExpired)."
}

The setting name is absent from the final entry. Ellipses above shorten only the original action for readability; the complete action also names the accepted range, default, tools/call scope and outer-client deadline.

Analysis or suspected cause

JebMcpDeadline.ts owns the timeout and recovery. JebProvider.ts catches AnalysisError but retains only projected.message and raw diagnostics. CapabilityInventory.ts then uses observation.reason as remediation.

The sibling cases show several projections of one weak contract: JEB drops error-owned recovery during availability projection; generic ownerProbeAvailability uses only observation.reason, ignoring recovery retained by ADB/Apktool. IDA retains configuration_remediation in diagnostics but emits unavailable capability descriptors with the failure description only. ADB and Apktool create their recovery facts in their configuration owners.

Give the shared availability contract a clear owner for recovery and make consumers reuse it. Avoid rebuilding provider-specific advice in the inventory or fixing each symptom with another string parser. Regressions should cover the final inventory result for these distinct producer outcomes, while preserving cancellation and cleanup distinctions.

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8506 Originally assigned to: @kaoru0822-kitauji on GitHub. ### Before submitting - [x] Searched open and closed issues for related reports. - [x] Removed credentials, private paths, and sensitive target data. ### Area Provider or capability discovery ### Observed behavior Capability discovery loses provider-owned recovery instructions and returns the failure description in its `remediation` field instead. Confirmed cases are JEB discovery timeouts, ADB/Apktool execute-permission failures, and an unreadable IDA registration. JEB creates an actionable timeout recovery naming `REA_JEB_MCP_TIMEOUT_MS` and restart/reconnect requirements, but `inspectAvailability()` drops it. ADB and Apktool retain their repair instructions in `diagnostics.remediation`, but the shared inventory ignores those instructions and uses the failure description instead. ### Reproduction Executed against source `3842809c371a59609f576a9db8f9c492a3f071e6`: 1. Create the production `JebMcpDeadline(1, undefined, "discovery")`, let its real timer expire, and obtain its failure with `deadline.failure("jeb_mcp_catalog", deadline.signal.reason)`. Dispose the deadline. 2. Inject a `JebMcpConnection` whose `listTools` rejects with that exact failure. This isolates result propagation; no JEB engine or network timeout is simulated as a real runtime observation. 3. Call `JebProvider.inspectAvailability()` and pass its result to `buildCapabilityInventory({open:false, capabilities:[]}, {jebAnalysisAvailability})`. 4. Compare the original error's projection with the `inspect_jeb_client` inventory entry. For ADB and Apktool, also created a temporary regular file with mode `0600` and selected it through `REA_ADB_PATH` / `REA_APKTOOL_COMMAND`. Called each real provider's `inspectAvailability()` and passed the result into `buildCapabilityInventory`. The file could not execute; no ADB device, server, or APK was contacted. Closed both providers and removed the temporary directory. For IDA, selected a nonexistent registration using production `parseConfig`, called `IdaProvider.inspectReadinessSnapshot()`, and projected the returned capabilities through `providerCapabilitySets` and `buildCapabilityInventory`. Used a controlled open-target status only to exercise the final inventory projection; no target or IDA connection was opened. A connection factory that would throw if invoked was never called. The provider's `configuration_remediation` survived in diagnostics, but its launch-environment instructions did not reach the inventory entry for `analyze_function`. ### Expected behavior Preserve the provider-owned recovery through availability and capability output. A `remediation` field should tell the caller how to change the relevant deadline, rather than repeat the failure. Retain the original timeout category and budget where the availability contract permits it; keep caller cancellation distinct. ### Impact and scope Reproduced JEB through the production deadline and inventory with an injected MCP connection, ADB/Apktool through real permission-denied readiness probes, and IDA through a missing-file readiness check and controlled status projection. Agents lose instructions the producers already supplied. IDA's final description still says to provide readable JSON, but loses where to change the configuration for the running REA process. No live JEB/IDA server, public CLI/MCP process, connected Android device or APK decoding was exercised; occurrence frequency on those paths is unknown. ### REA version Source `3842809c371a59609f576a9db8f9c492a3f071e6`. ### Runtime and platform Node 24.22.1, Darwin arm64. No JEB/ADB/Apktool installation was required for these boundary reproductions. ### Target and artifact context Catalog and client readiness only; no JEB project, Android device, or APK opened. ### Interface Other: shared provider/capability result used by CLI/MCP. ### Earliest failure stage Transport or result projection ### Relevant output or evidence | Case | Provider-owned recovery | Capability inventory remediation | | --- | --- | --- | | JEB discovery timeout | Increase `REA_JEB_MCP_TIMEOUT_MS`, restart/reconnect and allow client headroom | Repeats that catalog discovery reached its deadline | | ADB `EACCES` | Check file type and execute permission for `REA_ADB_PATH`, or select an executable ADB binary | Repeats that execution of the selected binary was denied | | Apktool execute-permission failure | Check file type and execute permission for `REA_APKTOOL_COMMAND`, or select an executable launcher | Repeats that execution of the selected launcher was denied | | IDA unreadable registration | Correct `REA_IDA_MCP_CONFIG` in the environment starting REA, including the MCP client's registration, then rerun | Reports invalid configuration and asks for readable JSON, omitting the launch-environment instructions | Temporary file paths are omitted here. The ADB/Apktool recovery strings remained present in the availability diagnostics before inventory projection. The original `projectAnalysisError(failure)` includes: ```json { "code": "provider_timeout", "remediation": { "action": "Increase REA_JEB_MCP_TIMEOUT_MS in REA's launch environment ... and restart and reconnect REA to apply it. ..." } } ``` The capability entry instead includes: ```json { "name": "inspect_jeb_client", "available": false, "reason": "provider_unavailable", "remediation": "This request reached REA's configured JEB catalog discovery deadline of 1 ms (deadlineExpired)." } ``` The setting name is absent from the final entry. Ellipses above shorten only the original action for readability; the complete action also names the accepted range, default, tools/call scope and outer-client deadline. ### Analysis or suspected cause [`JebMcpDeadline.ts`](https://github.com/morluto/rea/blob/3842809c371a59609f576a9db8f9c492a3f071e6/src/jeb/JebMcpDeadline.ts) owns the timeout and recovery. [`JebProvider.ts`](https://github.com/morluto/rea/blob/3842809c371a59609f576a9db8f9c492a3f071e6/src/jeb/JebProvider.ts) catches `AnalysisError` but retains only `projected.message` and raw diagnostics. [`CapabilityInventory.ts`](https://github.com/morluto/rea/blob/3842809c371a59609f576a9db8f9c492a3f071e6/src/application/CapabilityInventory.ts) then uses `observation.reason` as remediation. The sibling cases show several projections of one weak contract: JEB drops error-owned recovery during availability projection; generic `ownerProbeAvailability` uses only `observation.reason`, ignoring recovery retained by ADB/Apktool. IDA retains `configuration_remediation` in diagnostics but emits unavailable capability descriptors with the failure description only. ADB and Apktool create their recovery facts in their configuration owners. Give the shared availability contract a clear owner for recovery and make consumers reuse it. Avoid rebuilding provider-specific advice in the inventory or fixing each symptom with another string parser. Regressions should cover the final inventory result for these distinct producer outcomes, while preserving cancellation and cleanup distinctions.
bsakaguchi 2026-11-01 21:12:49 +00:00
  • closed this issue
  • added the
    bug
    triage
    labels
Author
Owner

@morluto commented on GitHub (Nov 1, 2026):

Confirmed another sibling instance on main bafe3784cd6fd3f46dd472a913e97f08f4d7427f: Kuna configuration recovery is preserved by doctor but lost by capability discovery. This belongs to the same producer-to-discovery contract problem.

Ran readKunaConfiguration, KunaProvider.inspectAvailability(), providerCapabilitySets, and buildCapabilityInventory for each of:

  • REA_KUNA_JOBS=33
  • REA_KUNA_TIMEOUT_MS=0
  • REA_KUNA_CACHE_DIR=relative

Each environment also selected an absolute, deliberately nonexistent /audit/not-invoked/kuna. Configuration validation rejected the setting before executable probing. For the final inventory projection only, supplied controlled open:true, executable/ELF status; no target was opened.

The jobs case gives this comparison:

Boundary Recovery text
Configuration owner Correct REA_KUNA_JOBS to meet the reported constraint, or unset it to use its default. Restart REA after changing the environment.
Final analyze_function inventory REA_KUNA_JOBS must be an integer from 1 to 32; received 33.
inspectKunaProvider doctor control Same complete recovery as the owner

The timeout and cache cases lose the same unset/default/restart guidance. Unlike the EVM raw-code case (#8508), the constraint remains readable here; the missing content is the owner's specific repair action.

Source: readKunaConfiguration returns a separate remediation. KunaProvider.inspectAvailability forwards only its reason and discards the action. capabilities() then propagates that reduced description. The doctor installation path retains the complete action following #5834, so this does not reopen that fixed doctor defect.

Executed once per case with Node 24.22.1 on Darwin arm64. Provider-owned resources and doctor inspection scopes were closed. No Kuna process, binary analysis, public CLI/MCP server, or actual post-restart repair was exercised. Proposed coverage: carry the same configuration-owner action through final capability output, with the fixed doctor path as a comparison.

<!-- gh-comment-id:6558573822 --> @morluto commented on GitHub (Nov 1, 2026): Confirmed another sibling instance on main `bafe3784cd6fd3f46dd472a913e97f08f4d7427f`: **Kuna configuration recovery is preserved by doctor but lost by capability discovery.** This belongs to the same producer-to-discovery contract problem. Ran `readKunaConfiguration`, `KunaProvider.inspectAvailability()`, `providerCapabilitySets`, and `buildCapabilityInventory` for each of: - `REA_KUNA_JOBS=33` - `REA_KUNA_TIMEOUT_MS=0` - `REA_KUNA_CACHE_DIR=relative` Each environment also selected an absolute, deliberately nonexistent `/audit/not-invoked/kuna`. Configuration validation rejected the setting before executable probing. For the final inventory projection only, supplied controlled `open:true`, executable/ELF status; no target was opened. The jobs case gives this comparison: | Boundary | Recovery text | | --- | --- | | Configuration owner | `Correct REA_KUNA_JOBS to meet the reported constraint, or unset it to use its default. Restart REA after changing the environment.` | | Final `analyze_function` inventory | `REA_KUNA_JOBS must be an integer from 1 to 32; received 33.` | | `inspectKunaProvider` doctor control | Same complete recovery as the owner | The timeout and cache cases lose the same unset/default/restart guidance. Unlike the EVM raw-code case (#8508), the constraint remains readable here; the missing content is the owner's specific repair action. Source: [`readKunaConfiguration`](https://github.com/morluto/rea/blob/bafe3784cd6fd3f46dd472a913e97f08f4d7427f/src/kuna/KunaConfiguration.ts#L79) returns a separate `remediation`. [`KunaProvider.inspectAvailability`](https://github.com/morluto/rea/blob/bafe3784cd6fd3f46dd472a913e97f08f4d7427f/src/kuna/KunaProvider.ts#L125) forwards only its `reason` and discards the action. `capabilities()` then propagates that reduced description. The doctor installation path retains the complete action following #5834, so this does **not** reopen that fixed doctor defect. Executed once per case with Node 24.22.1 on Darwin arm64. Provider-owned resources and doctor inspection scopes were closed. No Kuna process, binary analysis, public CLI/MCP server, or actual post-restart repair was exercised. Proposed coverage: carry the same configuration-owner action through final capability output, with the fixed doctor path as a comparison.
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#6631
No description provided.