[GH-ISSUE #8731] [Bug] Bulk decompile failure rows do not associate provider limitations with functions #7527

Open
opened 2026-11-03 06:16:01 +00:00 by bsakaguchi · 0 comments
Owner

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

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

MCP or agent integration

Observed behavior

A completed decompile_all request reports a function failure inline as no_pseudocode / The provider returned null pseudocode for this function. even when the selected provider supplied a more useful reason. The exported index associates that reason with the function. In the observed single-function case, the overall Evidence limitations also include the watchdog text, but the inline failure row does not associate that text with the address. The index provides that per-function association.

Reproduction

On REA main 9ebbe67e05af08b567e215340da993c08dae378f, macOS arm64 and Kuna 1.989, use the controlled mixed-project setup in #8167: a caller-owned wrapper injects KUNA_JOBS_FAULT=stall:0x100000328 only during decompile-project, with a one-second function budget and two workers. After the project completes, call decompile_all selecting the failed _audit_value in a new output directory. The MCP manifest's one failure has code: no_pseudocode and the generic null-result message. Its decompile-index.json record's limitations contain worker stalled past the per-function watchdog (1s); the worker was killed. Resuming the same export retries the function and yields the same split. This occurred in compact and full stdio MCP profiles. The wrapper injects a failure deliberately; no natural timeout or frequency is claimed.

Batch and directory control on the proposed batch change

With #8737 b734bcf51 and the same real Kuna 1.989 injected-stall project, one session in each MCP profile called batch_decompile and then decompile_all for the same address. The batch returned status: unavailable, reason: no_pseudocode and the watchdog limitation on that item. The directory manifest returned code: no_pseudocode with the generic null message, while its index kept the watchdog limitation. The target hash remained unchanged. This is a proposed-branch control of one deliberately injected failure, not evidence of natural timeout frequency. It confirms that the batch change does not by itself solve this directory handoff.

Expected behavior

Make a bounded, actionable distinction between missing pseudocode and a producer-reported reason in the returned failure, or make the index handoff explicit. Preserve the original producer text and index record; do not treat arbitrary general limitations as a proven failure reason. Respect the existing 32-failure and 2,048-byte inline budgets and preserve omitted-count semantics. See docs/tool-design.md for useful inline evidence and truthful limits.

Impact and scope

In this single-function example, an agent can see the watchdog text in the overall Evidence limitations. For per-function association, the index records it alongside the function address; the inline failure row does not. The index path is returned; this is loss of immediate context, not loss of the on-disk detail. One injected failure, one macOS host and one Kuna release were tested; autonomous-agent behavior and other providers are unverified.

REA version

9ebbe67e05af08b567e215340da993c08dae378f

Runtime and platform

Node 24.22.1, macOS arm64, Kuna 1.989 behind the described test wrapper.

Target and artifact context

Self-built, unexecuted thin Mach-O, SHA-256 0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930; its digest remained unchanged.

Interface

MCP

Earliest failure stage

Transport or result projection

Relevant output or evidence

Inline failure: {address:"0x100000328",code:"no_pseudocode",message:"The provider returned null pseudocode for this function."}. The index for the same address contains the explicit watchdog limitation. The overall Evidence limitations also include it, labeled with the procedure_pseudo_code operation but without the function address; the manifest's index_path points to the index.

Analysis or suspected cause

Source-derived: decompileAll.ts preserves decompiled.value.limitations in the journal/index but builds inline failure details through pseudocodeFailure(null), which receives no producer reason. KunaProjectReader.pseudocode distinguishes a project block with error from an inventory entry absent from the code export, but converts both into untyped limitation strings before returning the observation. A consumer cannot reliably promote an arbitrary limitation to the failure cause. If a structured reason is introduced, it needs to survive the provider observation, Evidence, and applicable snapshot replay: AnalysisSnapshotCache.lookup reconstructs observations from persisted fields and adds its own limitation. The documentless pseudocode reads used by this export are not snapshot-replayed. Kuna also marks its capabilities live, so its own pseudocode is not replayed from the generic snapshot cache even with an explicit document. Other provider capabilities may be snapshot-cacheable. A real Kuna 1.989 control in both MCP profiles confirmed that an explicit-document failed pseudocode observation was retained in the snapshot Evidence bundle with the watchdog limitation, while the snapshot had no replay entries; reopening with that snapshot and querying again returned the failure from the persisted Kuna project. The target hash remained unchanged. The failure was deliberately injected as described above. These are design constraints, not an implementation prescription.

Typed outcome or recovery expected

Keep the existing failure code, actual reason and bounded omission accounting distinct. Verify unknown/null and empty bodies, multiple caveats, resume, large failure text and real-provider output; preserve deterministic export and caller-selected data.

Additional context

#8167 asks whether to offer a distinct retry; this issue concerns the existing export's first response and remains relevant even without retry. Related #8260 concerns per-function provenance over resume; #8355 concerns inventory-level limitations. @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Correction: overall Evidence includes the watchdog limitation

An isolated follow-up on main 9ebbe67e called decompile_all directly after open_binary, without a preceding batch call, using the same released Kuna 1.989 and deliberately stalled cached project. In both compact and full MCP profiles, the returned Evidence's top-level limitations included the watchdog text, prefixed with procedure_pseudo_code; the retained decompile_all Evidence contained the same text. The failure row still held the address and generic no_pseudocode message, while the overall limitation did not identify an address. The index recorded both the address and the watchdog limitation. The target SHA-256 remained 0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930.

This corrects the earlier implication that an agent must inspect the index to see the watchdog text in the observed single-function case. Multi-function attribution, limitation aggregation or truncation, and other provider behavior were not tested by this control. The remaining issue is the association of the observation with the failure, not total absence of the text.

Two-function export control

On main 9ebbe67e, I repeated the isolated real Kuna 1.989 export without a name filter in both MCP profiles. Two functions were selected: _audit_value (0x100000328) failed due to the deliberately injected watchdog stall; _main (0x100000340) was written. The inline failure row identified _audit_value but kept the generic no_pseudocode message. The top-level Evidence included the watchdog message attributed to procedure_pseudo_code, without an address. The index associated that limitation with the failed function and not the successfully written function. The target SHA-256 remained 0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930. This verifies one failure and one success, not attribution among multiple failures or general truncation behavior.

Two different failures in one completed project

On main 9ebbe67e, an owned four-function arm64 Mach-O was analyzed with released Kuna 1.989 through a temporary test-only wrapper injecting stall:0x100000328,panic:0x100000340. The resulting completed project had two failed and two successful functions. In both compact and full MCP profiles, decompile_all returned two generic no_pseudocode failure rows. Its overall Evidence limitations included both the watchdog and worker-exit-101 messages, each attributed only to procedure_pseudo_code; their order differed from the failure rows, and neither named an address. The index associated the watchdog text with _first (0x100000328) and the worker-exit text with _second (0x100000340). The other two functions were written. Target SHA-256 60d614e0ba1c93bdada14a044526ba19409f9a75dd2282d57e4f58cab73ece08 stayed unchanged and the target was not run. The failures were deliberately injected, not naturally observed.

An earlier control with only the two injected failures did not produce an accepted project: Kuna exited nonzero because no function bodies were produced, and REA returned a whole-project failure. It is not evidence about a completed directory export.

CLI control and contract constraints

The same completed four-function injected-failure project was used with real rea decompile-all --provider kuna --format json on main 9ebbe67e. The CLI produced two generic failure rows, both unaddressed producer limitations in the overall Evidence, and the correctly associated per-function caveats in decompile-index.json, matching the MCP control. The target SHA-256 remained 60d614e0ba1c93bdada14a044526ba19409f9a75dd2282d57e4f58cab73ece08.

Source-derived design constraint: index record limitations combines and deduplicates caveats from procedure_info and procedure_pseudo_code; they are not all necessarily causes of pseudocode failure. An inline design should not promote an arbitrary caveat to a proven reason. It also needs to honor the existing aggregate 2,048-byte failure-array budget and account explicitly for any omitted row details while preserving function identity and the full index. The existing boundary test exercises oversized caveats and long names; neither that simulated test nor this controlled real-provider fixture measures autonomous-agent outcomes.

Real mixed-panic control of the index-handoff PR

On #8735 head 33f7162723523e09dc4ddaabf692ad8d04d6ae32, real Kuna 1.989 with a deliberately injected single-worker panic produced a completed two-function project on macOS arm64. In both compact and full MCP profiles, decompile_all wrote one function and reported one no_pseudocode failure. The manifest included the new instruction to read index_path; the index associated the worker-exit-101 limitation with the failed 0x100000328 record and not the written 0x100000340 record. Successful responses validated against the advertised schemas.

A resume skipped the verified written function and retried the failed row, but it still read the completed project's failed pseudocode result; it did not launch the separate standalone decompile demonstrated in #8167. The handoff and index association remained present. The fixture SHA-256 0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930 remained unchanged and it was not executed. This is one injected failure and does not establish natural failure frequency, autonomous-agent behavior, or a general standalone-retry mechanism.

CLI cold-versus-warm timing control

On the same #8735 head and injected-panic fixture, a real one-shot CLI decompile-all with a fresh cache wrote both functions before the background project was ready. The index reported each body as a single-function kuna decompile observation lacking whole-program prototypes; there was no failure row. This does not prove what the background export would eventually have produced in that run. Repeating the CLI task with a separate cache already containing the completed mixed-failure project wrote one function and reported the failed address, the index handoff and the correctly associated worker-failure limitation. The target was unchanged and not executed.

This confirms that observed availability can depend on whether the single-function or completed-project route served a request. The exported index preserves the relevant limitations; a future explicit retry should retain both observations and their distinct contexts rather than treat the warm result as proof that the cold result was impossible, or the cold result as proof the project succeeded. One run of each route does not measure their timing or frequency.

Originally created by @morluto on GitHub (Nov 3, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8731 ### 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 MCP or agent integration ### Observed behavior A completed `decompile_all` request reports a function failure inline as `no_pseudocode` / `The provider returned null pseudocode for this function.` even when the selected provider supplied a more useful reason. The exported index associates that reason with the function. In the observed single-function case, the overall Evidence limitations also include the watchdog text, but the inline failure row does not associate that text with the address. The index provides that per-function association. ### Reproduction On REA main `9ebbe67e05af08b567e215340da993c08dae378f`, macOS arm64 and Kuna 1.989, use the controlled mixed-project setup in #8167: a caller-owned wrapper injects `KUNA_JOBS_FAULT=stall:0x100000328` only during `decompile-project`, with a one-second function budget and two workers. After the project completes, call `decompile_all` selecting the failed `_audit_value` in a new output directory. The MCP manifest's one failure has `code: no_pseudocode` and the generic null-result message. Its `decompile-index.json` record's limitations contain `worker stalled past the per-function watchdog (1s); the worker was killed`. Resuming the same export retries the function and yields the same split. This occurred in compact and full stdio MCP profiles. The wrapper injects a failure deliberately; no natural timeout or frequency is claimed. ### Batch and directory control on the proposed batch change With #8737 `b734bcf51` and the same real Kuna 1.989 injected-stall project, one session in each MCP profile called `batch_decompile` and then `decompile_all` for the same address. The batch returned `status: unavailable`, `reason: no_pseudocode` and the watchdog limitation on that item. The directory manifest returned `code: no_pseudocode` with the generic null message, while its index kept the watchdog limitation. The target hash remained unchanged. This is a proposed-branch control of one deliberately injected failure, not evidence of natural timeout frequency. It confirms that the batch change does not by itself solve this directory handoff. ### Expected behavior Make a bounded, actionable distinction between missing pseudocode and a producer-reported reason in the returned failure, or make the index handoff explicit. Preserve the original producer text and index record; do not treat arbitrary general limitations as a proven failure reason. Respect the existing 32-failure and 2,048-byte inline budgets and preserve omitted-count semantics. See `docs/tool-design.md` for useful inline evidence and truthful limits. ### Impact and scope In this single-function example, an agent can see the watchdog text in the overall Evidence limitations. For per-function association, the index records it alongside the function address; the inline failure row does not. The index path is returned; this is loss of immediate context, not loss of the on-disk detail. One injected failure, one macOS host and one Kuna release were tested; autonomous-agent behavior and other providers are unverified. ### REA version `9ebbe67e05af08b567e215340da993c08dae378f` ### Runtime and platform Node 24.22.1, macOS arm64, Kuna 1.989 behind the described test wrapper. ### Target and artifact context Self-built, unexecuted thin Mach-O, SHA-256 `0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930`; its digest remained unchanged. ### Interface MCP ### Earliest failure stage Transport or result projection ### Relevant output or evidence Inline failure: `{address:"0x100000328",code:"no_pseudocode",message:"The provider returned null pseudocode for this function."}`. The index for the same address contains the explicit watchdog limitation. The overall Evidence limitations also include it, labeled with the `procedure_pseudo_code` operation but without the function address; the manifest's `index_path` points to the index. ### Analysis or suspected cause Source-derived: `decompileAll.ts` preserves `decompiled.value.limitations` in the journal/index but builds inline failure details through `pseudocodeFailure(null)`, which receives no producer reason. `KunaProjectReader.pseudocode` distinguishes a project block with `error` from an inventory entry absent from the code export, but converts both into untyped limitation strings before returning the observation. A consumer cannot reliably promote an arbitrary limitation to the failure cause. If a structured reason is introduced, it needs to survive the provider observation, Evidence, and applicable snapshot replay: `AnalysisSnapshotCache.lookup` reconstructs observations from persisted fields and adds its own limitation. The documentless pseudocode reads used by this export are not snapshot-replayed. Kuna also marks its capabilities live, so its own pseudocode is not replayed from the generic snapshot cache even with an explicit document. Other provider capabilities may be snapshot-cacheable. A real Kuna 1.989 control in both MCP profiles confirmed that an explicit-document failed pseudocode observation was retained in the snapshot Evidence bundle with the watchdog limitation, while the snapshot had no replay entries; reopening with that snapshot and querying again returned the failure from the persisted Kuna project. The target hash remained unchanged. The failure was deliberately injected as described above. These are design constraints, not an implementation prescription. ### Typed outcome or recovery expected Keep the existing failure code, actual reason and bounded omission accounting distinct. Verify unknown/null and empty bodies, multiple caveats, resume, large failure text and real-provider output; preserve deterministic export and caller-selected data. ### Additional context #8167 asks whether to offer a distinct retry; this issue concerns the existing export's first response and remains relevant even without retry. Related #8260 concerns per-function provenance over resume; #8355 concerns inventory-level limitations. @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 ### Correction: overall Evidence includes the watchdog limitation An isolated follow-up on main `9ebbe67e` called `decompile_all` directly after `open_binary`, without a preceding batch call, using the same released Kuna 1.989 and deliberately stalled cached project. In both compact and full MCP profiles, the returned Evidence's top-level `limitations` included the watchdog text, prefixed with `procedure_pseudo_code`; the retained `decompile_all` Evidence contained the same text. The failure row still held the address and generic `no_pseudocode` message, while the overall limitation did not identify an address. The index recorded both the address and the watchdog limitation. The target SHA-256 remained `0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930`. This corrects the earlier implication that an agent must inspect the index to see the watchdog text in the observed single-function case. Multi-function attribution, limitation aggregation or truncation, and other provider behavior were not tested by this control. The remaining issue is the association of the observation with the failure, not total absence of the text. ### Two-function export control On main `9ebbe67e`, I repeated the isolated real Kuna 1.989 export without a name filter in both MCP profiles. Two functions were selected: `_audit_value` (`0x100000328`) failed due to the deliberately injected watchdog stall; `_main` (`0x100000340`) was written. The inline failure row identified `_audit_value` but kept the generic `no_pseudocode` message. The top-level Evidence included the watchdog message attributed to `procedure_pseudo_code`, without an address. The index associated that limitation with the failed function and not the successfully written function. The target SHA-256 remained `0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930`. This verifies one failure and one success, not attribution among multiple failures or general truncation behavior. ### Two different failures in one completed project On main `9ebbe67e`, an owned four-function arm64 Mach-O was analyzed with released Kuna 1.989 through a temporary test-only wrapper injecting `stall:0x100000328,panic:0x100000340`. The resulting completed project had two failed and two successful functions. In both compact and full MCP profiles, `decompile_all` returned two generic `no_pseudocode` failure rows. Its overall Evidence limitations included both the watchdog and worker-exit-101 messages, each attributed only to `procedure_pseudo_code`; their order differed from the failure rows, and neither named an address. The index associated the watchdog text with `_first` (`0x100000328`) and the worker-exit text with `_second` (`0x100000340`). The other two functions were written. Target SHA-256 `60d614e0ba1c93bdada14a044526ba19409f9a75dd2282d57e4f58cab73ece08` stayed unchanged and the target was not run. The failures were deliberately injected, not naturally observed. An earlier control with only the two injected failures did not produce an accepted project: Kuna exited nonzero because no function bodies were produced, and REA returned a whole-project failure. It is not evidence about a completed directory export. ### CLI control and contract constraints The same completed four-function injected-failure project was used with real `rea decompile-all --provider kuna --format json` on main `9ebbe67e`. The CLI produced two generic failure rows, both unaddressed producer limitations in the overall Evidence, and the correctly associated per-function caveats in `decompile-index.json`, matching the MCP control. The target SHA-256 remained `60d614e0ba1c93bdada14a044526ba19409f9a75dd2282d57e4f58cab73ece08`. Source-derived design constraint: index record `limitations` combines and deduplicates caveats from `procedure_info` and `procedure_pseudo_code`; they are not all necessarily causes of pseudocode failure. An inline design should not promote an arbitrary caveat to a proven reason. It also needs to honor the existing aggregate 2,048-byte failure-array budget and account explicitly for any omitted row details while preserving function identity and the full index. The existing boundary test exercises oversized caveats and long names; neither that simulated test nor this controlled real-provider fixture measures autonomous-agent outcomes. ### Real mixed-panic control of the index-handoff PR On #8735 head `33f7162723523e09dc4ddaabf692ad8d04d6ae32`, real Kuna 1.989 with a deliberately injected single-worker panic produced a completed two-function project on macOS arm64. In both compact and full MCP profiles, `decompile_all` wrote one function and reported one `no_pseudocode` failure. The manifest included the new instruction to read `index_path`; the index associated the worker-exit-101 limitation with the failed `0x100000328` record and not the written `0x100000340` record. Successful responses validated against the advertised schemas. A resume skipped the verified written function and retried the failed row, but it still read the completed project's failed pseudocode result; it did not launch the separate standalone decompile demonstrated in #8167. The handoff and index association remained present. The fixture SHA-256 `0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930` remained unchanged and it was not executed. This is one injected failure and does not establish natural failure frequency, autonomous-agent behavior, or a general standalone-retry mechanism. ### CLI cold-versus-warm timing control On the same #8735 head and injected-panic fixture, a real one-shot CLI `decompile-all` with a fresh cache wrote both functions before the background project was ready. The index reported each body as a single-function `kuna decompile` observation lacking whole-program prototypes; there was no failure row. This does not prove what the background export would eventually have produced in that run. Repeating the CLI task with a separate cache already containing the completed mixed-failure project wrote one function and reported the failed address, the index handoff and the correctly associated worker-failure limitation. The target was unchanged and not executed. This confirms that observed availability can depend on whether the single-function or completed-project route served a request. The exported index preserves the relevant limitations; a future explicit retry should retain both observations and their distinct contexts rather than treat the warm result as proof that the cold result was impossible, or the cold result as proof the project succeeded. One run of each route does not measure their timing or frequency.
bsakaguchi changed title from [GH-ISSUE #8731] [Bug] Bulk decompile hides provider failure reason in the index to [GH-ISSUE #8731] [Bug] Bulk decompile failure rows do not associate provider limitations with functions 2026-11-03 07:17:02 +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#7527
No description provided.