[GH-ISSUE #8365] [Design] Clarify live metadata across Ghidra byte-search pages #6567

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

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

Before submitting

  • I searched the 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

Should search_bytes continuations explicitly identify that match metadata is live, or bind/qualify pages when an analyst edits function names between requests?

Context and evidence

In real REA/Ghidra stdio MCP, I opened the owned, unexecuted x86-64 raw bytes 90 90 90 90 c3 at entry 0x1000. With {"pattern":"90","start":"0x1000","end":"0x1004","limit":1}, the first page reported the match at 0x1000 in procedure {address:"0x1000",name:"entry"} and returned a cursor. Reusing that cursor without an edit reported the next match at 0x1001 with the same procedure name.

I then explicitly called set_address_name({"address":"0x1000","name":"renamed_entry"}), which succeeded in the ephemeral Ghidra database. Reusing the same first-page cursor succeeded and reported the same second match and function address, now with name renamed_entry. A new first page also reported renamed_entry. The page Evidence records have different IDs but the same target and analysis-profile digest; their limitations did not identify a change between these page observations. The target bytes and hash were unchanged.

I also closed and reopened the same target in the same MCP server after the rename. The session-only rename was discarded, as documented. The original cursor was still accepted and returned the second match with the original entry name and the same profile digest. This establishes the behavior for this fresh-import reopen, not all saved-project cases.

The observed byte addresses and names were correct for their respective requests. This is not a missing-match reproduction or a claim that the current contract promises a frozen snapshot. The usability question is whether an agent combining pages can tell that their attached names were observed in different session states. Export retained all page and rename records; those individual records were not lost.

Expected interaction with targets

Read the caller-selected binary and use the selected Ghidra provider. The test explicitly requested a reversible name edit in REA's ephemeral Ghidra session database; it did not modify or execute the target or write a caller project.

Boundary details (optional)

Keep the exact query, original selected address, provider profile, per-page Evidence and matching semantics. Differentiate byte-search completeness from the freshness of attached metadata. Do not assume a stable or globally unique function name; do not claim an analyst edit changed code bytes. The source project/profile, session-local edit state, and target identity are different concepts.

Options and tradeoffs

Consider a clear live-page limitation, an exposed session analysis revision, invalidating a cursor after relevant edits, or holding an explicit search snapshot. Compare costs and caller workflows; a fresh page after an edit may be useful, and rejecting it is not automatically best. Reuse the existing search and Evidence contract rather than adding an API-shaped duplicate.

Verification available so far

I have a prototype or observed results.

Success criteria and open questions

Exercise an unchanged continuation, a name edit between pages, overlapping matches, reopened sessions, and provider/project changes; preserve correct cursor binding, page coverage, both page Evidence records, and honest metadata freshness. Test whether any future admitted edit can change search bytes or containment before extrapolating beyond this name-only example. No autonomous-agent selection, operating-system breadth, performance, or other provider has been measured.

References

  • search_bytes pagination contract and bridge cursor construction bind target, profile, pattern, mask, bounds and document; source inspection shows no session-edit revision in that binding.
  • Related #8364 concerns contributing Evidence for a different aggregate context workflow; #8232 concerns saved-project bytes and original-file mapping.
  • REA d54a4661da20382ad8456564a08569fdd24131c5, Ghidra 12.1.4 / JDK 21, Node 24.22.1, macOS 26.3 arm64, MCP SDK 2.3.1 with the full advertised output profile. Fixture SHA-256 d7cd210f1b7a30f53b9de1666c99b1fe3963f5f4ebd823ef7131db7f1bafae33.

cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Project change between sessions

A separate control reopened the same target and saved-project path after intentionally renaming a function in a disposable project copy. The prior search_bytes cursor was rejected in both compact and full MCP profiles; starting a fresh search succeeded. This contrasts with the same-session ephemeral rename case above, whose cursor remained accepted. The rejected cursor's recovery text remains tracked by #8366. REA did not modify the target or the edited project during this control; this is one project-edit case, not a general concurrent-edit or metadata-freshness guarantee.

Originally created by @morluto on GitHub (Oct 31, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8365 ### Before submitting - [x] I searched the 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 Should `search_bytes` continuations explicitly identify that match metadata is live, or bind/qualify pages when an analyst edits function names between requests? ### Context and evidence In real REA/Ghidra stdio MCP, I opened the owned, unexecuted x86-64 raw bytes `90 90 90 90 c3` at entry `0x1000`. With `{"pattern":"90","start":"0x1000","end":"0x1004","limit":1}`, the first page reported the match at `0x1000` in procedure `{address:"0x1000",name:"entry"}` and returned a cursor. Reusing that cursor without an edit reported the next match at `0x1001` with the same procedure name. I then explicitly called `set_address_name({"address":"0x1000","name":"renamed_entry"})`, which succeeded in the ephemeral Ghidra database. Reusing the **same first-page cursor** succeeded and reported the same second match and function address, now with name `renamed_entry`. A new first page also reported `renamed_entry`. The page Evidence records have different IDs but the same target and analysis-profile digest; their limitations did not identify a change between these page observations. The target bytes and hash were unchanged. I also closed and reopened the same target in the same MCP server after the rename. The session-only rename was discarded, as documented. The original cursor was still accepted and returned the second match with the original `entry` name and the same profile digest. This establishes the behavior for this fresh-import reopen, not all saved-project cases. The observed byte addresses and names were correct for their respective requests. This is not a missing-match reproduction or a claim that the current contract promises a frozen snapshot. The usability question is whether an agent combining pages can tell that their attached names were observed in different session states. Export retained all page and rename records; those individual records were not lost. ### Expected interaction with targets Read the caller-selected binary and use the selected Ghidra provider. The test explicitly requested a reversible name edit in REA's ephemeral Ghidra session database; it did not modify or execute the target or write a caller project. ### Boundary details (optional) Keep the exact query, original selected address, provider profile, per-page Evidence and matching semantics. Differentiate byte-search completeness from the freshness of attached metadata. Do not assume a stable or globally unique function name; do not claim an analyst edit changed code bytes. The source project/profile, session-local edit state, and target identity are different concepts. ### Options and tradeoffs Consider a clear live-page limitation, an exposed session analysis revision, invalidating a cursor after relevant edits, or holding an explicit search snapshot. Compare costs and caller workflows; a fresh page after an edit may be useful, and rejecting it is not automatically best. Reuse the existing search and Evidence contract rather than adding an API-shaped duplicate. ### Verification available so far I have a prototype or observed results. ### Success criteria and open questions Exercise an unchanged continuation, a name edit between pages, overlapping matches, reopened sessions, and provider/project changes; preserve correct cursor binding, page coverage, both page Evidence records, and honest metadata freshness. Test whether any future admitted edit can change search bytes or containment before extrapolating beyond this name-only example. No autonomous-agent selection, operating-system breadth, performance, or other provider has been measured. ### References - [`search_bytes` pagination contract](https://github.com/morluto/rea/blob/d54a4661da20382ad8456564a08569fdd24131c5/docs/ghidra-provider.md#masked-byte-search) and [bridge cursor construction](https://github.com/morluto/rea/blob/d54a4661da20382ad8456564a08569fdd24131c5/bridge/ghidra/ReaGhidraBridge.java#L804-L826) bind target, profile, pattern, mask, bounds and document; source inspection shows no session-edit revision in that binding. - Related #8364 concerns contributing Evidence for a different aggregate context workflow; #8232 concerns saved-project bytes and original-file mapping. - REA `d54a4661da20382ad8456564a08569fdd24131c5`, Ghidra 12.1.4 / JDK 21, Node 24.22.1, macOS 26.3 arm64, MCP SDK 2.3.1 with the full advertised output profile. Fixture SHA-256 `d7cd210f1b7a30f53b9de1666c99b1fe3963f5f4ebd823ef7131db7f1bafae33`. cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 ### Project change between sessions A separate control reopened the same target and saved-project path after intentionally renaming a function in a disposable project copy. The prior `search_bytes` cursor was rejected in both compact and full MCP profiles; starting a fresh search succeeded. This contrasts with the same-session ephemeral rename case above, whose cursor remained accepted. The rejected cursor's recovery text remains tracked by #8366. REA did not modify the target or the edited project during this control; this is one project-edit case, not a general concurrent-edit or metadata-freshness guarantee.
Author
Owner

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

Identity controls complementing the live-name example: a cursor created with a selected saved project resumed after reopening that same project (including with a different page limit), and was rejected after changing the pattern, switching to a fresh-import profile for the same target, or switching targets under the same fresh profile. Both target hashes and all selected-project regular-file hashes were unchanged, and a subsequent read succeeded after each tested mismatch. The same saved-project success and changed-profile rejection were exercised in CLI as well as MCP.

These checks support retaining the existing target/profile/query binding while discussing session metadata freshness. The mismatch is correctly refused but its recovery is misleading; filed separately as #8366.

<!-- gh-comment-id:6548186832 --> @morluto commented on GitHub (Oct 31, 2026): Identity controls complementing the live-name example: a cursor created with a selected saved project resumed after reopening that same project (including with a different page limit), and was rejected after changing the pattern, switching to a fresh-import profile for the same target, or switching targets under the same fresh profile. Both target hashes and all selected-project regular-file hashes were unchanged, and a subsequent read succeeded after each tested mismatch. The same saved-project success and changed-profile rejection were exercised in CLI as well as MCP. These checks support retaining the existing target/profile/query binding while discussing session metadata freshness. The mismatch is correctly refused but its recovery is misleading; filed separately as #8366.
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#6567
No description provided.