[GH-ISSUE #8209] [Design] Export a bounded explicit or graph-derived set of native functions #6486

Open
opened 2026-11-01 21:11:32 +00:00 by bsakaguchi · 3 comments
Owner

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

Before submitting

  • I searched open and closed issues and pull requests for a related discussion.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This discussion does not include credentials, private samples, or sensitive target data.

Decision needed

Can an agent export a bounded, explicitly selected set of function pseudocode—such as nodes from an observed call graph—to one resumable directory without one export call per function or accidentally including functions between their addresses?

Context and evidence

A self-built, unexecuted arm64 Mach-O contains task_root -> audit_leaf and an unrelated function whose address lies between them (SHA-256 3f995d931c662a84f2295e8f66b1e3405dfb72acd2cd11e59e80a86d8bb14f91).

  • Direct Kuna 1.986 decompile-all --reachable-from _task_root --json selected the two expected functions on this fixture. This is its static call graph, not runtime reachability or a complete cross-provider result.
  • Real REA MCP get_call_graph with either Ghidra 12.1.4 or Kuna 1.986 returned the root and leaf. batch_decompile on those two observed addresses returned two inline bodies.
  • A single REA decompile_all bounded from the leaf address through the root address wrote three files, including the unrelated function in the middle. This follows the advertised address-range filter.
  • Existing REA behavior can write the desired two-file directory: one decompile_all call with an exact one-address range, then resume: true with the second exact range. I exercised that sequence with both providers; each final manifest contained only the two selected functions. This costs two export calls for this two-node example; no token, latency, or model-success measurement was made.

Expected interaction with targets

Read caller-selected artifacts and existing static analysis; write a new caller-selected output directory using REA's existing owned export lifecycle. Do not execute or modify the target.

Boundary details (optional)

Treat graph edges and its incompleteness as observed provider facts, not proof that all runtime callees were selected. Bind an explicit set or retained graph selection to target, address space, provider/profile and coverage; define behavior for unknown, duplicate, missing, ambiguous, external and failed entries. Preserve caller selection, per-function outcomes, resumable verified files, destination conflicts and cleanup.

Options and tradeoffs

Compare a bounded explicit address set for the existing directory export with accepting a retained graph-derived selection or retaining the current batch-and-resume workflow. A graph selector needs clear depth, direction, traversal/edge coverage and failure semantics. Reuse existing REA workflows and Evidence rather than exposing Kuna's --reachable-from as a provider-specific pass-through. Measure end-to-end calls, tokens and time before claiming an efficiency win.

Verification available so far

I have a prototype or observed results.

Success criteria and open questions

Test noncontiguous selections, unknown and indirect calls, graph truncation, duplicate/invalid addresses, provider/profile mismatch, resume after partial outcomes, caller-owned file conflicts, CLI/MCP parity and resource bounds. The output must identify what was actually selected and what remains unknown.

References

Related: #8200 (typed call-path context), #8181 (empty batch selection), #8191 (cold/warm pseudocode representation). REA source d48e472fa plus unrelated Kuna baseline changes in #8187; macOS arm64.

Originally created by @morluto on GitHub (Oct 30, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8209 ### Before submitting - [x] I searched open and closed issues and pull requests for a related discussion. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This discussion does not include credentials, private samples, or sensitive target data. ### Decision needed Can an agent export a bounded, explicitly selected set of function pseudocode—such as nodes from an observed call graph—to one resumable directory without one export call per function or accidentally including functions between their addresses? ### Context and evidence A self-built, unexecuted arm64 Mach-O contains `task_root -> audit_leaf` and an unrelated function whose address lies between them (SHA-256 `3f995d931c662a84f2295e8f66b1e3405dfb72acd2cd11e59e80a86d8bb14f91`). - Direct Kuna 1.986 `decompile-all --reachable-from _task_root --json` selected the two expected functions on this fixture. This is its static call graph, not runtime reachability or a complete cross-provider result. - Real REA MCP `get_call_graph` with either Ghidra 12.1.4 or Kuna 1.986 returned the root and leaf. `batch_decompile` on those two observed addresses returned two inline bodies. - A single REA `decompile_all` bounded from the leaf address through the root address wrote three files, including the unrelated function in the middle. This follows the advertised address-range filter. - Existing REA behavior can write the desired two-file directory: one `decompile_all` call with an exact one-address range, then `resume: true` with the second exact range. I exercised that sequence with both providers; each final manifest contained only the two selected functions. This costs two export calls for this two-node example; no token, latency, or model-success measurement was made. ### Expected interaction with targets Read caller-selected artifacts and existing static analysis; write a new caller-selected output directory using REA's existing owned export lifecycle. Do not execute or modify the target. ### Boundary details (optional) Treat graph edges and its incompleteness as observed provider facts, not proof that all runtime callees were selected. Bind an explicit set or retained graph selection to target, address space, provider/profile and coverage; define behavior for unknown, duplicate, missing, ambiguous, external and failed entries. Preserve caller selection, per-function outcomes, resumable verified files, destination conflicts and cleanup. ### Options and tradeoffs Compare a bounded explicit address set for the existing directory export with accepting a retained graph-derived selection or retaining the current batch-and-resume workflow. A graph selector needs clear depth, direction, traversal/edge coverage and failure semantics. Reuse existing REA workflows and Evidence rather than exposing Kuna's `--reachable-from` as a provider-specific pass-through. Measure end-to-end calls, tokens and time before claiming an efficiency win. ### Verification available so far I have a prototype or observed results. ### Success criteria and open questions Test noncontiguous selections, unknown and indirect calls, graph truncation, duplicate/invalid addresses, provider/profile mismatch, resume after partial outcomes, caller-owned file conflicts, CLI/MCP parity and resource bounds. The output must identify what was actually selected and what remains unknown. ### References Related: #8200 (typed call-path context), #8181 (empty batch selection), #8191 (cold/warm pseudocode representation). REA source `d48e472fa` plus unrelated Kuna baseline changes in #8187; macOS arm64.
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 for visibility on the Ghidra, Kuna, and REA tool-design investigation.

<!-- gh-comment-id:6538796156 --> @morluto commented on GitHub (Oct 31, 2026): Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 for visibility on the Ghidra, Kuna, and REA tool-design investigation.
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

A bounded-selection control on REA 60149282, real Ghidra 12.1.4 and Kuna 1.986: an owned, unexecuted 20-function Mach-O chain was traced with trace_native_ui_action({action:"_audit_0", max_depth:2, max_nodes:10, max_edges:20}). Both providers returned three function nodes and two edges, with truncated: true, reason native_call_traversal_bound_reached, and partial static-call coverage. This UI-oriented workflow accepts a native seed but is not a generic bounded-call-graph contract (#8236).

For each provider, I explicitly passed the three observed node addresses through batch_decompile and then made three exact-address decompile_all calls, resuming the same directory. All three batch entries succeeded; the index listed exactly those three written addresses. A fourth exact range at 0xdeadbeef returned a successful zero-selection result (selected: 0, written: 0), as a filter operation; it is not proof that the address is a valid or absent function. The exported Evidence bundle retained both the trace and the separate export records, but the export records had no links to the trace. The caller can retain and correlate those separate records; the directory alone does not encode why the three entries were selected or that traversal stopped at depth 2.

A future explicit-set or retained-graph handoff should keep the actual selection separate from graph coverage, invalid/unresolved selectors and runtime reachability. It should not reinterpret a successful zero-match range as successful export of a requested function, nor silently treat a bounded graph as complete. These are one source-owned fixture and two providers, not autonomous-agent or performance measurements. Target hash was unchanged, successful compact SDK output schemas were validated, and no target was executed. A separate index-summary behavior discovered during the resume control is #8351; its per-function body facts remained explicit.

<!-- gh-comment-id:6547081598 --> @morluto commented on GitHub (Oct 31, 2026): A bounded-selection control on REA `60149282`, real Ghidra 12.1.4 and Kuna 1.986: an owned, unexecuted 20-function Mach-O chain was traced with `trace_native_ui_action({action:"_audit_0", max_depth:2, max_nodes:10, max_edges:20})`. Both providers returned three function nodes and two edges, with `truncated: true`, reason `native_call_traversal_bound_reached`, and partial static-call coverage. This UI-oriented workflow accepts a native seed but is not a generic bounded-call-graph contract (#8236). For each provider, I explicitly passed the three observed node addresses through `batch_decompile` and then made three exact-address `decompile_all` calls, resuming the same directory. All three batch entries succeeded; the index listed exactly those three written addresses. A fourth exact range at `0xdeadbeef` returned a successful zero-selection result (`selected: 0`, `written: 0`), as a filter operation; it is not proof that the address is a valid or absent function. The exported Evidence bundle retained both the trace and the separate export records, but the export records had no links to the trace. The caller can retain and correlate those separate records; the directory alone does not encode why the three entries were selected or that traversal stopped at depth 2. A future explicit-set or retained-graph handoff should keep the actual selection separate from graph coverage, invalid/unresolved selectors and runtime reachability. It should not reinterpret a successful zero-match range as successful export of a requested function, nor silently treat a bounded graph as complete. These are one source-owned fixture and two providers, not autonomous-agent or performance measurements. Target hash was unchanged, successful compact SDK output schemas were validated, and no target was executed. A separate index-summary behavior discovered during the resume control is #8351; its per-function body facts remained explicit.
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

A related directory handoff issue surfaced with real Ghidra/Kuna on main d54a4661: #8355. The returned export Evidence retains the inventory's source limitations, but the standalone index does not. For a selected Ghidra project imported without analysis, filtering for _evaluate produced a zero-entry index without the original-analysis-unknown caveat, whereas a fresh import selected that function. For Kuna, the Evidence reported inventory omissions but the directory did not retain that inventory-level fact. Per-function records still retain their own observed caveats when present.

This is not a request to reinterpret a zero-match filter as an error or as proof of absence. A future graph/set handoff should identify both its selection and the source inventory's coverage, including for an empty result, without confusing one resume's selection with accumulated directory history. Details, CLI/MCP controls, offline bundle checks and limits are in #8355.

<!-- gh-comment-id:6547422788 --> @morluto commented on GitHub (Oct 31, 2026): A related directory handoff issue surfaced with real Ghidra/Kuna on main `d54a4661`: #8355. The returned export Evidence retains the inventory's source limitations, but the standalone index does not. For a selected Ghidra project imported without analysis, filtering for `_evaluate` produced a zero-entry index without the original-analysis-unknown caveat, whereas a fresh import selected that function. For Kuna, the Evidence reported inventory omissions but the directory did not retain that inventory-level fact. Per-function records still retain their own observed caveats when present. This is not a request to reinterpret a zero-match filter as an error or as proof of absence. A future graph/set handoff should identify both its selection and the source inventory's coverage, including for an empty result, without confusing one resume's selection with accumulated directory history. Details, CLI/MCP controls, offline bundle checks and limits are in #8355.
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#6486
No description provided.