[GH-ISSUE #8214] [Feature] Aggregate retained comparison Evidence without resending full records #6492

Closed
opened 2026-11-01 21:11:37 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

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

Area

MCP or agent integration

Current limitation

find_changed_behavior accepts an array of complete comparison Evidence, but does not accept the exact retained Evidence references supported by compare_functions. A caller aggregating already-retained comparisons must resend each complete record, including repeated provenance and limitations. The MCP input element allowance can reject the aggregate before the tool runs.

Desired outcome and success criteria

Consider letting find_changed_behavior consume exact retained comparison Evidence references alongside complete inline Evidence, resolving and authenticating them at the owning boundary. Preserve source records, exact IDs, provenance, duplicate detection, caller order where relevant, aggregate semantics, bounded admission, and the distinction between static candidates and observed runtime change. Missing, wrong-operation, foreign or damaged references must remain explicit errors; a summary/view must not silently substitute for complete comparison Evidence. Reuse existing Evidence-reference contracts and CLI/bundle behavior as appropriate, rather than adding a provider-specific wrapper.

Expected interaction with targets

Read existing retained Evidence; no target execution or new provider session is required for aggregation.

Verification available so far

I have a prototype or observed results

Verification details (optional)

On source 38433cfb4577b133d7598f9439c6448299cb44eb, macOS arm64, Ghidra 12.1.4, and a self-built unexecuted Mach-O, I obtained three retained function dossiers in one MCP session and used exact references to produce five distinct real compare_functions Evidence records. Sending all five inline to find_changed_behavior returned resource_constraint before execution, with max_input_elements: 1024. An independent recursive member/element count of that particular request was 1,278; the server reports the configured limit, not an exact count. Sending one of those comparison records succeeded and returned two static candidates with runtime behavior unknown. Sending its {kind: "retained-evidence", evidence_id: ...} reference was rejected as invalid Evidence (evidence_integrity_mismatch), consistent with the current input contract. The connection and close remained usable.

This is a small controlled aggregation, not a general maximum number of functions: record shapes vary, and no runtime or performance benchmark was run. Raising REA_MCP_MAX_INPUT_ELEMENTS and restarting is existing recovery; splitting into several independent aggregates does not necessarily produce the same combined result.

References

find_changed_behavior contract, changedBehaviorInputSchema, and related #8172 for a different oversized inline comparison in the Ghidra verifier. #8213 concerns one source comparison's identity result, not input admission.

Originally created by @morluto on GitHub (Oct 30, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8214 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This request does not include credentials, private samples, or sensitive target data. ### Area MCP or agent integration ### Current limitation `find_changed_behavior` accepts an array of complete comparison Evidence, but does not accept the exact retained Evidence references supported by `compare_functions`. A caller aggregating already-retained comparisons must resend each complete record, including repeated provenance and limitations. The MCP input element allowance can reject the aggregate before the tool runs. ### Desired outcome and success criteria Consider letting `find_changed_behavior` consume exact retained comparison Evidence references alongside complete inline Evidence, resolving and authenticating them at the owning boundary. Preserve source records, exact IDs, provenance, duplicate detection, caller order where relevant, aggregate semantics, bounded admission, and the distinction between static candidates and observed runtime change. Missing, wrong-operation, foreign or damaged references must remain explicit errors; a summary/view must not silently substitute for complete comparison Evidence. Reuse existing Evidence-reference contracts and CLI/bundle behavior as appropriate, rather than adding a provider-specific wrapper. ### Expected interaction with targets Read existing retained Evidence; no target execution or new provider session is required for aggregation. ### Verification available so far I have a prototype or observed results ### Verification details (optional) On source `38433cfb4577b133d7598f9439c6448299cb44eb`, macOS arm64, Ghidra 12.1.4, and a self-built unexecuted Mach-O, I obtained three retained function dossiers in one MCP session and used exact references to produce five distinct real `compare_functions` Evidence records. Sending all five inline to `find_changed_behavior` returned `resource_constraint` before execution, with `max_input_elements: 1024`. An independent recursive member/element count of that particular request was 1,278; the server reports the configured limit, not an exact count. Sending one of those comparison records succeeded and returned two static candidates with runtime behavior `unknown`. Sending its `{kind: "retained-evidence", evidence_id: ...}` reference was rejected as invalid Evidence (`evidence_integrity_mismatch`), consistent with the current input contract. The connection and close remained usable. This is a small controlled aggregation, not a general maximum number of functions: record shapes vary, and no runtime or performance benchmark was run. Raising `REA_MCP_MAX_INPUT_ELEMENTS` and restarting is existing recovery; splitting into several independent aggregates does not necessarily produce the same combined result. ### References [`find_changed_behavior` contract](https://github.com/morluto/rea/blob/38433cfb4577b133d7598f9439c6448299cb44eb/src/contracts/sessionToolContracts.ts), [`changedBehaviorInputSchema`](https://github.com/morluto/rea/blob/38433cfb4577b133d7598f9439c6448299cb44eb/src/domain/changedBehavior.ts), and related #8172 for a different oversized inline comparison in the Ghidra verifier. #8213 concerns one source comparison's identity result, not input admission.
bsakaguchi 2026-11-01 21:11:37 +00:00
Author
Owner

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

I tested the current recovery options on five newly generated real Ghidra comparison records. First, sending the complete inline comparison records to a fresh server without importing their Evidence bundle failed with evidence_integrity_mismatch: the server said the selected comparison Evidence ID was not available from the selected source. Complete inline comparison records alone were not sufficient in that context. I then exported the source session's Evidence bundle and imported it into two fresh servers before retrying. This is an authentication/provenance requirement, not a reason to weaken source validation.

With the default 1,024 input-element allowance, all five inline records were rejected at admission (1,278 recursively counted members/elements in this request). Splitting the same ordered comparisons into groups of two and three succeeded. A separate fresh server started with REA_MCP_MAX_INPUT_ELEMENTS=4096 accepted all five after importing the same bundle. The combined run returned behavior_status: unknown, 16 static candidates and no runtime observations; the two partition results returned 2 and 14 static candidates, both unknown. For this all-static sample, the union of per-partition findings, source links and limitations equaled the full result's sets. This checks one sample, not a general merge algorithm or runtime-status equivalence.

A duplicate control demonstrates a semantic caveat for manual partitioning: sending the same comparison once in each of two separate calls succeeded twice, while sending both together returned invalid_request because duplicate comparison Evidence is rejected. A caller that combines partitions must itself preserve global duplicate and aggregate semantics; repeated successful partitions are not automatically one authenticated combined result. The connection was usable after refusals. No target was executed. The raised limit was a temporary test-server setting, not a recommendation to change global configuration.

<!-- gh-comment-id:6535060302 --> @morluto commented on GitHub (Oct 30, 2026): I tested the current recovery options on five newly generated real Ghidra comparison records. First, sending the complete inline comparison records to a **fresh** server without importing their Evidence bundle failed with `evidence_integrity_mismatch`: the server said the selected comparison Evidence ID was not available from the selected source. Complete inline comparison records alone were not sufficient in that context. I then exported the source session's Evidence bundle and imported it into two fresh servers before retrying. This is an authentication/provenance requirement, not a reason to weaken source validation. With the default 1,024 input-element allowance, all five inline records were rejected at admission (1,278 recursively counted members/elements in this request). Splitting the same ordered comparisons into groups of two and three succeeded. A separate fresh server started with `REA_MCP_MAX_INPUT_ELEMENTS=4096` accepted all five after importing the same bundle. The combined run returned `behavior_status: unknown`, 16 static candidates and no runtime observations; the two partition results returned 2 and 14 static candidates, both unknown. For this all-static sample, the union of per-partition findings, source links and limitations equaled the full result's sets. This checks one sample, not a general merge algorithm or runtime-status equivalence. A duplicate control demonstrates a semantic caveat for manual partitioning: sending the same comparison once in each of two separate calls succeeded twice, while sending both together returned `invalid_request` because duplicate comparison Evidence is rejected. A caller that combines partitions must itself preserve global duplicate and aggregate semantics; repeated successful partitions are not automatically one authenticated combined result. The connection was usable after refusals. No target was executed. The raised limit was a temporary test-server setting, not a recommendation to change global configuration.
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:6538798406 --> @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.
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#6492
No description provided.