[GH-ISSUE #8454] [Design] Discover missing Evidence links without full record transfer #6610

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

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

Originally assigned to: @kaoru0822-kitauji on GitHub.

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 an agent be able to discover which direct Evidence links are missing from the selected session or bundle without transferring complete source records or first attempting a downstream analysis?

Context and evidence

On main e18594b24754ab95ebd119311cc32a1d1ad6fa13, I used an internally constructed canonical bundle containing a previously captured real Ghidra 12.1.4 function dossier but omitting its linked project-health Evidence. The disposable selected project had synthetic historical metadata. No provider or target was started during the offline checks.

In fresh public stdio MCP sessions (full and compact profiles):

  1. import_evidence_bundle succeeded with imported: 1; get_evidence_bundle summary reported one complete-record and zero Unknown revisions. This correctly describes record retention, not source closure.
  2. The summary did not list that record's evidence_links or whether they were present. The complete bundle output did expose the missing source ID, so an agent can transfer the complete record and compare IDs itself.
  3. build_call_path with the retained dossier returned a typed missing-reference error naming the absent source and reference_scope: "retained-closure". Exporting and reimporting the one-record session preserved the same missing link and the same refusal.
  4. Importing a separate canonical bundle for the captured source made the same zero-hop call-path request succeed. A summary filtered to the dossier still returned one matching record while reporting two total retained records: the source was present but intentionally outside the selected rows.
  5. As a positive control, a previously captured Kuna 1.986 dossier with no Evidence links imported in a separate fresh session and its zero-hop path succeeded in both profiles.

These are observed results for one dossier and a deliberately incomplete bundle; no claim is made that a normal exporter produced it, that unknown_revisions: 0 means sources are complete, or that an agent was actually confused. Existing documentation states that complete-record describes the stored record. Large records can make the complete-output alternative expensive or exceed transport limits.

Expected interaction with targets

Read existing Evidence and bundle files; no provider restart, target execution, mutation, or automatic acquisition.

Boundary details

Distinguish a complete record from link membership and from semantic analysis coverage. Missing means absent from the selected session or file, not nonexistent globally. Do not assert transitive closure unless it was actually traversed; preserve external references, missing records and omitted pages explicitly. Filters must not make retained-but-unselected sources look absent.

Options and tradeoffs

Consider a bounded, caller-selected link or closure inspection on the existing Evidence discovery workflow, including direct missing IDs and pagination. Another option is a summary qualification that points to a separate bounded check. Keep complete Evidence available and avoid rejecting deliberately partial canonical bundles or eagerly traversing large graphs on every import without a task need.

Verification available so far

I have a prototype or observed results.

Success criteria and open questions

Exercise complete, missing, filtered and multi-record cases through public CLI/MCP where supported; confirm that importing a missing source changes the membership result without changing the original Evidence ID. Establish the right scope for external links and what a bounded traversal can actually conclude. Evidence IDs commit to their links; no authenticated cyclic example has been observed, so a synthetic cycle should not be treated as a prerequisite without a concrete valid construction.

References

Related: #8427 (recovering unretained records), #8282 (a producer's missing cached trace sources), and #8433 (inline view parent ownership). This report concerns discovering link membership for already imported records and bundles, including ones intentionally assembled from partial evidence.

cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8454 Originally assigned to: @kaoru0822-kitauji on GitHub. ### 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 an agent be able to discover which direct Evidence links are missing from the selected session or bundle without transferring complete source records or first attempting a downstream analysis? ### Context and evidence On main `e18594b24754ab95ebd119311cc32a1d1ad6fa13`, I used an internally constructed canonical bundle containing a previously captured real Ghidra 12.1.4 function dossier but omitting its linked project-health Evidence. The disposable selected project had synthetic historical metadata. No provider or target was started during the offline checks. In fresh public stdio MCP sessions (full and compact profiles): 1. `import_evidence_bundle` succeeded with `imported: 1`; `get_evidence_bundle` summary reported one `complete-record` and zero Unknown revisions. This correctly describes record retention, not source closure. 2. The summary did not list that record's `evidence_links` or whether they were present. The complete bundle output did expose the missing source ID, so an agent can transfer the complete record and compare IDs itself. 3. `build_call_path` with the retained dossier returned a typed missing-reference error naming the absent source and `reference_scope: "retained-closure"`. Exporting and reimporting the one-record session preserved the same missing link and the same refusal. 4. Importing a separate canonical bundle for the captured source made the same zero-hop call-path request succeed. A summary filtered to the dossier still returned one matching record while reporting two total retained records: the source was present but intentionally outside the selected rows. 5. As a positive control, a previously captured Kuna 1.986 dossier with no Evidence links imported in a separate fresh session and its zero-hop path succeeded in both profiles. These are observed results for one dossier and a deliberately incomplete bundle; no claim is made that a normal exporter produced it, that `unknown_revisions: 0` means sources are complete, or that an agent was actually confused. Existing documentation states that `complete-record` describes the stored record. Large records can make the complete-output alternative expensive or exceed transport limits. ### Expected interaction with targets Read existing Evidence and bundle files; no provider restart, target execution, mutation, or automatic acquisition. ### Boundary details Distinguish a complete record from link membership and from semantic analysis coverage. Missing means absent from the selected session or file, not nonexistent globally. Do not assert transitive closure unless it was actually traversed; preserve external references, missing records and omitted pages explicitly. Filters must not make retained-but-unselected sources look absent. ### Options and tradeoffs Consider a bounded, caller-selected link or closure inspection on the existing Evidence discovery workflow, including direct missing IDs and pagination. Another option is a summary qualification that points to a separate bounded check. Keep complete Evidence available and avoid rejecting deliberately partial canonical bundles or eagerly traversing large graphs on every import without a task need. ### Verification available so far I have a prototype or observed results. ### Success criteria and open questions Exercise complete, missing, filtered and multi-record cases through public CLI/MCP where supported; confirm that importing a missing source changes the membership result without changing the original Evidence ID. Establish the right scope for external links and what a bounded traversal can actually conclude. Evidence IDs commit to their links; no authenticated cyclic example has been observed, so a synthetic cycle should not be treated as a prerequisite without a concrete valid construction. ### References Related: #8427 (recovering unretained records), #8282 (a producer's missing cached trace sources), and #8433 (inline view parent ownership). This report concerns discovering link membership for already imported records and bundles, including ones intentionally assembled from partial evidence. cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0
Author
Owner

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

A two-source control further defines the existing workflow. I synthesized a new authenticated function dossier using the captured Ghidra result and linked it to two independently generated synthetic source records; this is not a record emitted by Ghidra. On main in public stdio MCP, both schema profiles returned one missing source from build_call_path. After importing that source, the same call returned the other missing source; after importing both, the path succeeded. An agent can alternatively read the full dossier's evidence_links and inspect membership itself, so this is not a claim that repeated calls are the only route.

Source-derived: resolveInvestigationEvidenceClosure is already the owner for the transitive closure used by this workflow, but currently returns on the first missing record. A discovery design should assess reusing or refactoring that owner rather than building a second interpretation of links; the current fail-fast contract alone is not a paged inventory of all missing links.

The record's semantic ID commits to evidence_links; no valid cyclic example was created or observed. The design's primary checks are multiple missing sources, filtered membership, bounded output, and correct source-scope reporting. No provider was started and no target was executed for this control.

A separate synthetic chain shows why direct membership must not be labeled transitive closure. A dossier (using the captured Ghidra result) linked to a synthetic middle record that was present; that record linked to a synthetic leaf that was absent. On main, build_call_path identified the missing leaf in full and compact stdio profiles; importing the leaf made the same path succeed. This is a controlled graph, not a provider-generated source chain or a claim that direct-link inspection itself is incorrect.

<!-- gh-comment-id:6555216717 --> @morluto commented on GitHub (Nov 1, 2026): A two-source control further defines the existing workflow. I synthesized a new authenticated function dossier using the captured Ghidra result and linked it to two independently generated synthetic source records; this is not a record emitted by Ghidra. On main in public stdio MCP, both schema profiles returned one missing source from `build_call_path`. After importing that source, the same call returned the other missing source; after importing both, the path succeeded. An agent can alternatively read the full dossier's `evidence_links` and inspect membership itself, so this is not a claim that repeated calls are the only route. Source-derived: [`resolveInvestigationEvidenceClosure`](https://github.com/morluto/rea/blob/e18594b24754ab95ebd119311cc32a1d1ad6fa13/src/application/investigation/InvestigationEvidence.ts#L8-L39) is already the owner for the transitive closure used by this workflow, but currently returns on the first missing record. A discovery design should assess reusing or refactoring that owner rather than building a second interpretation of links; the current fail-fast contract alone is not a paged inventory of all missing links. The record's semantic ID commits to `evidence_links`; no valid cyclic example was created or observed. The design's primary checks are multiple missing sources, filtered membership, bounded output, and correct source-scope reporting. No provider was started and no target was executed for this control. A separate synthetic chain shows why direct membership must not be labeled transitive closure. A dossier (using the captured Ghidra result) linked to a synthetic middle record that was present; that record linked to a synthetic leaf that was absent. On main, `build_call_path` identified the missing leaf in full and compact stdio profiles; importing the leaf made the same path succeed. This is a controlled graph, not a provider-generated source chain or a claim that direct-link inspection itself is incorrect.
bsakaguchi 2026-11-03 00:30:02 +00:00
Author
Owner

@kaoru0822-kitauji commented on GitHub (Nov 2, 2026):

Proposal, on the existing Evidence discovery workflow (get_evidence_bundle and CLI inspect-evidence-bundle, one shared implementation). I'm starting on this now; objections welcome.

detail: "links" reads link membership without transferring any record payload:

  • filters select the starting records. Membership is always checked against every record in the selected session or file, so a filtered-out source is retained, not missing.
  • traversal: "direct" (default) reads only the selected records' own evidence_links. traversal: "retained-closure" also follows retained links, the same walk build_call_path performs, and reports retained_closure: "complete" | "incomplete". A direct result makes no closure claim.
  • Rows are {evidence_id, linked_evidence_id, status} in canonical order, paged with offset and limit. status defaults to missing; counts for retained and missing links are always reported.
  • missing means absent from this session or file, not nonexistent, and it says nothing about analysis coverage.

detail: "summary" gains two counters over the matching records, direct_links and missing_direct_links, so the check is discoverable. retention: "complete-record" keeps its meaning.

No eager work: import does not traverse, deliberately partial canonical bundles stay valid, and nothing starts a provider.

Verification: complete, missing, filtered and multi-record cases through public MCP and CLI, including that importing the missing source flips membership without changing the original Evidence ID, and that the reported missing agrees with the refusal from build_call_path.

<!-- gh-comment-id:6570190807 --> @kaoru0822-kitauji commented on GitHub (Nov 2, 2026): Proposal, on the existing Evidence discovery workflow (`get_evidence_bundle` and CLI `inspect-evidence-bundle`, one shared implementation). I'm starting on this now; objections welcome. **`detail: "links"`** reads link membership without transferring any record payload: - `filters` select the starting records. Membership is always checked against every record in the selected session or file, so a filtered-out source is `retained`, not `missing`. - `traversal: "direct"` (default) reads only the selected records' own `evidence_links`. `traversal: "retained-closure"` also follows retained links, the same walk `build_call_path` performs, and reports `retained_closure: "complete" | "incomplete"`. A direct result makes no closure claim. - Rows are `{evidence_id, linked_evidence_id, status}` in canonical order, paged with `offset` and `limit`. `status` defaults to `missing`; counts for retained and missing links are always reported. - `missing` means absent from this session or file, not nonexistent, and it says nothing about analysis coverage. **`detail: "summary"`** gains two counters over the matching records, `direct_links` and `missing_direct_links`, so the check is discoverable. `retention: "complete-record"` keeps its meaning. **No eager work:** import does not traverse, deliberately partial canonical bundles stay valid, and nothing starts a provider. **Verification:** complete, missing, filtered and multi-record cases through public MCP and CLI, including that importing the missing source flips membership without changing the original Evidence ID, and that the reported `missing` agrees with the refusal from `build_call_path`.
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#6610
No description provided.