[GH-ISSUE #8350] [Bug] Successful batch decompiles lose per-item provider provenance #6557

Open
opened 2026-11-01 21:12:13 +00:00 by bsakaguchi · 4 comments
Owner

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

Before submitting

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

Area

Native analysis or decompilation

Observed behavior

A successful batch_decompile item does not retain which provider observation produced its pseudocode or that observation's item-specific limitations. If Kuna's background export becomes ready during a batch, repeated selections can legitimately receive different answers; the batch-level caveat does not identify which occurrence used the single-function result.

Reproduction

On REA 60149282fcfc05ac32fbc94434c107710120da6f, macOS arm64, and real Kuna 1.986, I used a self-built, unexecuted Mach-O where 0x100004000 is the writable data symbol global_count but Kuna includes it in its function inventory (#8168). An owned wrapper synchronized the real provider commands: it held decompile-project until the first single-function decompile finished and delayed a later single-function call to allow the project export to complete. This is test scheduling instrumentation, not a normal release configuration or evidence of natural frequency.

A real MCP call selected ["0x100004000", "0x100000430", "0x100004000"]. It returned ordered ok, ok, error; both repeated items had the same resolved address. The first contained single-function pseudocode with an UndefinedInstructionException warning; the final item returned null-pseudocode capability_unavailable and an item-level caveat that the completed project had no body for that entry. A subsequent individual call confirmed raw_result.source.kind: project-export, state: ready, and null for the entry. The first item had no source or own limitations. The batch Evidence carried a single-function/whole-program-prototype caveat at the aggregate level, but raw_result was null and evidence_links empty.

I observed this sequence in two compact-schema runs and one full-schema run, each with a fresh isolated cache and the scheduling wrapper. Successful responses passed the SDK validator after fetching the advertised catalog. A batch-only Evidence bundle contained just the batch record; export and import into a fresh target-free server preserved that record exactly. The fixture SHA-256 ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d was unchanged. The wrapper identifies itself as version 1.986; REA's verified_release is a version match and does not authenticate the wrapper bytes.

Expected behavior

Retain an actionable association between each successful item occurrence and its producer observation or its relevant limitations, including an explicit unknown when source identity is unavailable. Preserve ordered duplicates and the actual differing observations. Decide whether compact item provenance, retained source Evidence links, or another bounded workflow best supports this task; do not imply all providers use the same source or silently replace results.

Impact and scope

An agent can see the aggregate caveat and both outputs, but cannot determine from the batch alone which successful item came from the single-function path. This is an evidence association gap, not a claim that the repeated outputs must be identical or that the first item was executable code. The first pseudocode's warning is itself present. No autonomous-agent behavior, naturally occurring timing frequency, other provider, or behavior of all mixed batches was measured.

REA version

60149282fcfc05ac32fbc94434c107710120da6f

Runtime and platform

Node 24.22.1; macOS arm64; Kuna 1.986 behind an owned scheduling wrapper; TypeScript MCP SDK 2.3.1.

Target and artifact context

Owned arm64 Mach-O; static analysis only; no target execution or mutation.

Interface

MCP

Earliest failure stage

Transport or result projection

Relevant output or evidence

items[0]: status: ok, same resolved address, pseudocode with UndefinedInstructionException, no item limitations or source. items[2]: status: error, provider returned null pseudocode, with its own no-body caveat. Batch limitations separately include the single-function caveat; the successful item and aggregate Evidence have no link to the source observation. Counts: total: 3, succeeded: 2, failed: 1. The later individual null Evidence records a ready project-export source.

Typed outcome or recovery expected

Preserve provider source/limitations for each occurrence or an inspectable retained reference, with bounded output and honest unknowns. Keep existing failed-item caveats, input order, duplicates, partial errors and successful pseudocode.

Analysis or suspected cause

Source inspection: EnhancedTools.#batchPseudocode retains observed.value.limitations on the null-pseudocode branch, but its successful branch returns only selector, procedure, status and pseudocode. The composed workflow aggregates provider limitations and does not retain per-item source Evidence in this case. Any solution should address the observation owner rather than parse the caveat text.

Additional context

Related #8226 fixed missing per-item failure caveats; this report concerns successful-item provenance in a batch crossing a provider-state transition. #8168 tracks the separate function-inventory misclassification, #8191 representation changes, and #8260 per-file producer provenance in directory exports. Last known good: NOT_ENOUGH_INFO. Test real single/project paths, duplicate selectors, successful neighbors and failures, offline Evidence, SDK schemas, and cancellation or partial-result boundaries before changing the contract.

Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0.

File-offset mapping control

A separate real Ghidra 12.1.4 control makes the successful-item provenance gap concrete for coordinates. A batch_decompile item for file-offset:0x430 succeeded while its preliminary procedure lookup was unknown; the individual decompile reported file offset 1072 mapped to procedure address 0x100000430. The unmodified batch did not retain that producer selection. See #8178 for the selector semantics and the batch-only versus separately requested observation controls.

I exercised the earlier unmerged source-Evidence prototype on the same fixture, using its existing isolated checkout based on 60149282fcfc05ac32fbc94434c107710120da6f: the successful item included a source Evidence ID, and a batch-only export contained the linked source record with the exact mapping. It survived import into a fresh target-free MCP server, with source pseudocode equal to the batch item. The source record's inspect_analysis_view summary returned unsupported_target, so I retrieved it from the complete bundle; the prototype does not yet provide a focused mapping view. The target and bundle hashes were unchanged, and no target was executed. Node 24.22.1, macOS arm64, Ghidra 12.1.4/JDK 21, compact stdio SDK schema validation. One fixture and an older unmerged prototype do not establish current-main behavior or agent usability.

This supports retaining the exact producing observation rather than reconstructing a mapping from the failed lookup, but does not make that prototype integration-ready. As noted in the prior prototype evidence, ownership without a recorder, bounded retention/duplication, cancellation, and snapshot source identity need resolution. Do not convert the batch's separate lookup failure into a successful analysis-address lookup or infer broader coordinate equivalence.

On current main 60c0cf977, I repeated the separately requested real Ghidra pseudocode observation and offline bundle import. A summary filtered by its exact Evidence ID returned one complete-record receipt but did not include the offset mapping; inspect_analysis_view with native-observation returned unsupported_target for procedure_pseudo_code. The complete bundle retained the mapping. This also happened with the older source-Evidence prototype, so source linking and a focused way to inspect that source are separate concerns. The target and bundle hashes were unchanged; compact stdio MCP on one fixture and host, no target execution or agent trial. Documentation clarification: #8480. This is related to #5032; no new runtime capability is claimed.

Current public-workflow control

On REA #8485 head 01757d8ec (its changes concern session release guidance), macOS arm64, Ghidra 12.1.4/JDK 21 and real stdio MCP, I repeated batch_decompile(["file-offset:0x430"]) with the full and compact advertised SDK schemas. In both profiles the item succeeded while its separate procedure lookup was unknown; the batch had no Evidence links and a complete bundle at that point held only the batch record. A subsequent separate procedure_pseudo_code call returned the same text and explicitly mapped file offset 1072 to 0x100000430; the bundle then held two records. The separately requested observation is not the batch's retained source, and matching text alone does not establish that it was the same provider observation. The source-owned target stayed unexecuted and its SHA-256 was unchanged. This is one selector and target; it does not resolve resource-capacity, snapshot, cancellation or retained-source ownership questions for a fix.

Inline observation experiment

An unmerged, disposable prototype based on main 293db94dd placed each completed provider observation's selector, provider, analysis profile, raw result, locations and limitations alongside its batch pseudocode, without creating a second complete Evidence record. In real Ghidra 12.1.4 stdio MCP, the full and compact advertised schemas accepted the item and its source included the exact file-offset:0x430 to 0x100000430 mapping. A batch-only bundle contained one record; after import into a target-free server the entire batch, including that mapping, matched exactly. The static target and bundle hashes were unchanged.

On real Kuna 1.986, a deliberately gated launcher made the first two pseudocode items come from single-function runs and the third from the completed project export. The inline observations recorded those respective sources and per-item limitations, with compact SDK schema validation and an unchanged, unexecuted fixture. This is controlled scheduling, not an estimate of natural frequency.

This is not a proposed final contract or integration-ready implementation. The prototype's provider-subject shape initially failed SDK output validation; its temporary broad JSON schema is not an acceptable typed contract. Profile and limitation data are repeated per item; payload cost has not been measured. Source-record links, subject normalization, capacity and cancellation behavior, CLI, and snapshot interactions remain to be designed and verified. The experiment shows that retaining the decisive mapping and source inline is a possible alternative to duplicating each entire pseudocode record; it does not establish that either approach is best.

A further real-Ghidra snapshot control saved the experimental batch with one workflow entry and one Evidence record, reopened the same target and snapshot, and repeated the MCP batch. Both observations contained the same inline file-offset mapping, but their nested lookup diagnostics had different Ghidra run IDs and the second result lacked a snapshot-replay limitation: this was a fresh provider observation, not proof of workflow replay. The target and snapshot hashes were unchanged. On this fixture the raw JSON encoding of one inline source object was 3,572 bytes, including 1,660 bytes of profile and 1,037 bytes of limitations, while the selected pseudocode was 203 bytes. Those are serialized sizes for one observation, not a token, time, CPU or memory benchmark. Repeating the whole profile and common caveats per item is a material design concern; consider shared, explicitly associated observations while preserving item-specific facts and avoiding invented source identities. No direct batch-decompile command appeared in the current CLI catalog; no CLI batch parity is claimed.

Shared-context experiment

A second unmerged prototype groups equal provider/profile/subject/limitations observations once per batch and associates each completed item with its group index, while retaining its own provider selector, raw result and locations. On the real Kuna 1.986 gated three-item control, the two single-function results used one group and the project-export result a second; the item-level raw results still named their respective source. Compact SDK schema validation succeeded and the target hash was unchanged. On real Ghidra 12.1.4, full and compact schemas accepted the file-offset control; a batch-only bundle retained the exact mapping after target-free import.

For the two separate controlled Kuna runs, JSON encoding of only these prototype source fields was 6,579 bytes with repeated inline contexts versus 4,899 bytes with two shared contexts; each had three items. The launchers used different temporary paths, so the sizes are illustrative, not an equivalent-workflow token, latency, CPU or memory comparison. The indirection also adds an agent-facing lookup and the prototype does not yet validate group-index references, settle source-record closure or cancellation/capacity semantics, or cover arbitrary provider subjects and all failure paths. It is not integration-ready. Compare this with a simpler shared provider profile plus per-item caveats, and evaluate the complete agent task rather than serialized bytes alone.

Source ownership and context-reference controls

Using the shared-context prototype with production MCP registration and a simulated provider, a source-free batch returned its inline mapping without an Evidence recorder and did not invent a retained source ID. When the simulated provider supplied a separate source Evidence record, the existing no-recorder boundary refused the call; with a recorder it retained that source and linked it both to the parent and the associated item. This validates those controlled ownership cases, not a real-provider or capacity/cancellation run. The existing loss of a completed workflow on source-publication refusal is separately tracked in #8425.

A temporary canonical-schema check rejects a batch whose item points past the context array. A negative control without that check accepted the same malformed item. In the tested full and compact MCP profiles, the SDK's advertised JSON Schema still accepted the malformed index because it did not carry the cross-field refinement. Any shared-context design must therefore enforce this relationship at the owning boundary and explain it to consumers; advertised schema validation alone is insufficient. The experimental code and tests remain unmerged.

Capacity and cancellation controls

With production MCP registration, a simulated provider, an artificial zero-byte Evidence ledger, and the shared-context prototype, the provider completed its pseudocode call in both controls. With no upstream source record, recording the completed batch_decompile Evidence failed; with an upstream source record, recording that source failed first. Both returned a typed capacity error without the completed batch, and neither retained an Evidence record. The same controls passed against unmodified main 293db94dd, so this loss is not introduced by the prototype. This extends the scenario discussed in #8425; the zero allowance is fault injection, not a production-frequency claim.

A separate gated simulated-provider MCP control cancelled while the second of two pseudocode calls was active, after the first had completed. The client request rejected, the provider observed cancellation, and the ledger contained no batch record. The same control passed on unmodified main. This does not establish real-provider cancellation behavior or a requirement to publish an incomplete batch; #4276 tracks cancellation recovery. Any new item-provenance contract should define whether partial completed items are intentionally recoverable rather than implying they were retained.

A subsequent real-provider control used Kuna 1.986, macOS arm64 and compact stdio MCP on the existing source-owned Rust fixture. A caller-owned scheduling launcher held the project export until the first single-function decompile finished with exit status 0, and signalled when the second single-function process started; the client then cancelled the batch. Against both main 293db94dd and the shared-context experiment, the SDK request rejected, a later complete Evidence bundle contained zero records, binary_session remained usable and close_binary succeeded. The target digest remained unchanged and the target was not executed. This is controlled process timing and one provider/fixture, not a natural-frequency estimate or a claim that cancelled batches must publish partial results.

Integration with source-publication recovery

A disposable, unmerged integration combined the shared-context experiment with #8444 head e619141b9. Production MCP boundary controls showed that when source retention fails after batch completion, the error contains the unretained source and the completed batch, whose item retains its context association and exact source link; source closure is explicitly not-established. The existing cleanup-retry and response-limit controls passed on the combination.

Real Ghidra 12.1.4 full/compact stdio MCP retained the file-offset mapping; real Kuna 1.986 compact stdio with gated scheduling retained two single-function observations and a project-export observation in their respective contexts. Both static targets were unchanged. These runs do not establish untested providers or agent usability. The combination is not a PR or an integration-ready design: subject/provider-profile cross-validation, reliable advertised context-reference semantics, payload cost, and broader lifecycle/format coverage remain.

Context validation and description control

A later unmerged prototype describes the zero-based item-to-context association, preserves the exact selector passed to the pseudocode operation, and omits the redundant operation name from each item. It reuses Evidence's canonical provider/profile consistency check. With a simulated production MCP registration, the canonical contract rejected both an out-of-range context index and a context with a mismatched provider/profile; the advertised SDK JSON schemas accepted these deliberately corrupted cross-field cases in both full and compact profiles. Correct real Ghidra 12.1.4 full/compact and gated Kuna 1.986 compact outputs still passed the fetched SDK schemas, with the mapping/source distinctions intact and fixture hashes unchanged. This is a prototype and one-host control, not a remedy for other clients or a proof of agent comprehension. Cross-field validation remains the producer's responsibility and the item/context relationship must be explicit in the contract.

Context deduplication controls

The shared-context prototype currently clones and JSON-serializes each context before grouping. A controlled direct-port batch with ten observations alternating two semantically identical valid profiles produced two contexts solely because their parameter keys had different insertion order; their canonical profile digests were equal. This is redundant representation, not a claim about a measured end-to-end performance regression.

An in-memory MCP negative control supplied one valid profile followed by changed parameters with the same claimed digest. The existing whole-context grouping kept the second context visible and canonical output validation rejected its invalid digest. An intentionally unsafe digest-only grouping merged the profiles and the call incorrectly succeeded, hiding the invalid profile. The experimental optimization was reverted. Any more efficient grouping must validate the complete candidate before treating its digest as identity, preserve distinct provider/subject/limitation facts, and account for representation expansion before allocation. These are synthetic provider controls, not a claim about a real provider producing malformed profiles.

Synthetic admission control

On Node 24 with a 128-MiB old-space limit, an in-memory MCP control supplied 48 successful short pseudocode results, each with a distinct synthetic 512-KiB raw provider value. Current main e5e0dc554 returned and retained the batch while discarding those raw values. The unmerged inline-provenance prototype completed all 48 provider calls, then failed ledger authentication with a typed memory-headroom constraint and no completed result; combining it with #8444 did not change that admission stage. At 256 MiB, the prototype retained its result but the full reply exceeded the 10-MiB transport budget. This is deliberately large synthetic metadata, not a measured Kuna/Ghidra behavior or frequency.

An immutable-Evidence experiment changed the constrained case to a ledger-capacity refusal with an explicit omitted unretained observation, but still could not deliver the completed batch; that experiment was reverted. A producer design should account for retained raw metadata and representation expansion before allocation, and preserve useful partial results with explicit omissions when complete retention or delivery cannot be established. Item paging is a separate retrieval question in #8498.

Real Ghidra file-offset envelope duplication

On the unmerged batch-source prototype, real Ghidra 12.1.4 returned an 8,992-character pseudocode result for an owned arm64 function selected by file offset. The raw function envelope's value was exactly the same text; its separate selection preserved the file offset and mapped/procedure addresses. In the proposed paged item view, requesting raw detail returned that entire pseudocode again even when the pseudocode page limit was 50 UTF-16 units. On this one fixture the JSON raw envelope was 9,203 UTF-8 bytes and its limitations and selection without value were 103 bytes. The target digest was unchanged; these are fixture-specific byte counts, not token or performance measurements.

Source inspection shows the Ghidra adapter owns a strict function envelope and supplies it as the raw result when the selection is present. A direct object control reconstructed this specimen's exact envelope from its non-value fields and the identical preserved pseudocode. A producer-owned, explicitly reconstructable representation may avoid duplication, but the shared batch workflow should not guess arbitrary raw schemas, discard evidence, or silently change direct-call raw Evidence. No compact representation has been implemented or validated.

Heap-only admission is insufficient

An unmerged experiment attempted to retain raw source details while live V8 headroom allowed, explicitly marking per-item raw omissions otherwise. Repeating the same synthetic 48-item constrained-heap control five times produced four retained batches with readable omitted-source pages and one separate Evidence-ledger capacity refusal with no retained batch. An earlier repetition also hit authentication headroom. The ledger owns a representation allowance that is separate from the live heap estimate, so this heuristic does not establish a safe reservation or reliable recovery. It was removed; no fixed margin is proposed. Real Kuna/Ghidra small-fixture controls had no omissions, but do not establish safety for larger observations. Consider an owner-authorized accounting/admission contract and explicitly distinguish unavailable raw facts from retained source records.

Naturally mixed parallel batch

On PR #8694 head 96294d70c, real Kuna 1.988 on macOS arm64, a cold batch_decompile of all 25 inventory entries of an owned 2 MiB arm64 Mach-O (SHA-256 8698771cccb98f77e1282b76267c96f6699d86fee548e14c4afef6dd3d571517) with REA_KUNA_JOBS=2 returned 22 successful and three failed items in each of compact and full stdio MCP schema profiles. In both runs, the aggregate Evidence contained both the single-function and parallel project-export limitations, indicating both kinds of provider observation occurred during the batch. Successful items carried address, procedure, status and pseudocode, but no per-item source or limitation; a batch-only Evidence export retained one batch record with no source record. No scheduling wrapper was used.

In a separate repeat, I called procedure_pseudo_code for each successful item after the batch. Each later call identified the completed project export, and all 22 returned text equal to the corresponding batch text on this fixture. Text equality does not establish which source produced an earlier item; the provider observations are source-distinct even where their text happens to match. This is one small synthetic fixture, not a prevalence or behavioral-correctness claim. The target was read, not executed, and its digest was unchanged.

This also qualifies PR #8694: aggregate caveats become visible but cannot associate either caveat with a particular successful item when a batch crosses the cold-to-warm transition. Preserve the ordered occurrence and source association without treating a shared cache key as the output's content identity. The compact representation, retention budget and compatibility questions above still apply.

Directory export alternative

On PR #8694 head 96294d70c, real Kuna 1.988 and the same owned arm64 Mach-O, I ran a cold decompile_all with jobs=2, limit=5, then resumed for five more functions. In both MCP profiles, the resulting decompile-index.json associated the single-function caveat with three written functions and the parallel-project caveat with seven, with no overlap. Each resumed first-run record matched its earlier parsed JSON and its file's SHA-256 still matched the index; the resume reported five skipped and five newly written. The two runs used separate cache roots and no scheduling wrapper. This is a practical file-writing alternative for preserving per-function caveats when an export directory is appropriate; it does not itself identify the exact producer project (see #8260) or establish general behavior for other targets. Target digest remained unchanged and the target was not executed.

Completed standalone batch after project failure

On main 9ebbe67e, real Kuna 1.989 compact and full MCP sessions with the deliberately failed two-function project in #8744 returned two successful batch_decompile items using standalone fallback. The top-level batch Evidence included the single-function and project-failure caveats, but neither successful item carried per-item limitations. A same-session directory export recorded those caveats against each function in its index. The owned target SHA-256 0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930 remained unchanged. This tests a uniform fallback batch, not mixed source modes or autonomous-agent use; the fault was deliberately injected.

Released 1.989 batch-only retention after project failure

In a fresh main 9ebbe67e session with the controlled all-worker project failure from #8744, I called batch_decompile directly after the failing assembly request, without separately requesting individual pseudocode. In each compact and full stdio MCP profile, both batch items succeeded through standalone fallback. get_evidence_bundle returned exactly one retained record, the batch; its raw_result was null, it had no Evidence links, and neither successful item had a source or item-level limitations. The record's overall limitations included the single-function and project-failure caveats. Thus the retained batch offers no source record to inspect for the individual occurrences in this control. The target SHA-256 stayed 0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930. The project failures were deliberately injected; this is a uniform-source example, not a mixed-source frequency claim or an Evidence export/import test.

Originally created by @morluto on GitHub (Oct 31, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8350 ### 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 Native analysis or decompilation ### Observed behavior A successful `batch_decompile` item does not retain which provider observation produced its pseudocode or that observation's item-specific limitations. If Kuna's background export becomes ready during a batch, repeated selections can legitimately receive different answers; the batch-level caveat does not identify which occurrence used the single-function result. ### Reproduction On REA `60149282fcfc05ac32fbc94434c107710120da6f`, macOS arm64, and real Kuna 1.986, I used a self-built, unexecuted Mach-O where `0x100004000` is the writable data symbol `global_count` but Kuna includes it in its function inventory (#8168). An owned wrapper synchronized the real provider commands: it held `decompile-project` until the first single-function `decompile` finished and delayed a later single-function call to allow the project export to complete. This is test scheduling instrumentation, not a normal release configuration or evidence of natural frequency. A real MCP call selected `["0x100004000", "0x100000430", "0x100004000"]`. It returned ordered `ok`, `ok`, `error`; both repeated items had the same resolved address. The first contained single-function pseudocode with an `UndefinedInstructionException` warning; the final item returned null-pseudocode `capability_unavailable` and an item-level caveat that the completed project had no body for that entry. A subsequent individual call confirmed `raw_result.source.kind: project-export`, `state: ready`, and null for the entry. The first item had no source or own limitations. The batch Evidence carried a single-function/whole-program-prototype caveat at the aggregate level, but `raw_result` was null and `evidence_links` empty. I observed this sequence in two compact-schema runs and one full-schema run, each with a fresh isolated cache and the scheduling wrapper. Successful responses passed the SDK validator after fetching the advertised catalog. A batch-only Evidence bundle contained just the batch record; export and import into a fresh target-free server preserved that record exactly. The fixture SHA-256 `ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d` was unchanged. The wrapper identifies itself as version 1.986; REA's `verified_release` is a version match and does not authenticate the wrapper bytes. ### Expected behavior Retain an actionable association between each successful item occurrence and its producer observation or its relevant limitations, including an explicit unknown when source identity is unavailable. Preserve ordered duplicates and the actual differing observations. Decide whether compact item provenance, retained source Evidence links, or another bounded workflow best supports this task; do not imply all providers use the same source or silently replace results. ### Impact and scope An agent can see the aggregate caveat and both outputs, but cannot determine from the batch alone which successful item came from the single-function path. This is an evidence association gap, not a claim that the repeated outputs must be identical or that the first item was executable code. The first pseudocode's warning is itself present. No autonomous-agent behavior, naturally occurring timing frequency, other provider, or behavior of all mixed batches was measured. ### REA version `60149282fcfc05ac32fbc94434c107710120da6f` ### Runtime and platform Node 24.22.1; macOS arm64; Kuna 1.986 behind an owned scheduling wrapper; TypeScript MCP SDK 2.3.1. ### Target and artifact context Owned arm64 Mach-O; static analysis only; no target execution or mutation. ### Interface MCP ### Earliest failure stage Transport or result projection ### Relevant output or evidence `items[0]`: `status: ok`, same resolved address, pseudocode with `UndefinedInstructionException`, no item `limitations` or source. `items[2]`: `status: error`, `provider returned null pseudocode`, with its own no-body caveat. Batch limitations separately include the single-function caveat; the successful item and aggregate Evidence have no link to the source observation. Counts: `total: 3`, `succeeded: 2`, `failed: 1`. The later individual null Evidence records a ready project-export source. ### Typed outcome or recovery expected Preserve provider source/limitations for each occurrence or an inspectable retained reference, with bounded output and honest unknowns. Keep existing failed-item caveats, input order, duplicates, partial errors and successful pseudocode. ### Analysis or suspected cause Source inspection: `EnhancedTools.#batchPseudocode` retains `observed.value.limitations` on the null-pseudocode branch, but its successful branch returns only selector, procedure, status and pseudocode. The composed workflow aggregates provider limitations and does not retain per-item source Evidence in this case. Any solution should address the observation owner rather than parse the caveat text. ### Additional context Related #8226 fixed missing per-item **failure** caveats; this report concerns successful-item provenance in a batch crossing a provider-state transition. #8168 tracks the separate function-inventory misclassification, #8191 representation changes, and #8260 per-file producer provenance in directory exports. Last known good: NOT_ENOUGH_INFO. Test real single/project paths, duplicate selectors, successful neighbors and failures, offline Evidence, SDK schemas, and cancellation or partial-result boundaries before changing the contract. Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0. ### File-offset mapping control A separate real Ghidra 12.1.4 control makes the successful-item provenance gap concrete for coordinates. A `batch_decompile` item for `file-offset:0x430` succeeded while its preliminary procedure lookup was unknown; the individual decompile reported file offset 1072 mapped to procedure address `0x100000430`. The unmodified batch did not retain that producer selection. See #8178 for the selector semantics and the batch-only versus separately requested observation controls. I exercised the earlier **unmerged source-Evidence prototype** on the same fixture, using its existing isolated checkout based on `60149282fcfc05ac32fbc94434c107710120da6f`: the successful item included a source Evidence ID, and a batch-only export contained the linked source record with the exact mapping. It survived import into a fresh target-free MCP server, with source pseudocode equal to the batch item. The source record's `inspect_analysis_view` summary returned `unsupported_target`, so I retrieved it from the complete bundle; the prototype does not yet provide a focused mapping view. The target and bundle hashes were unchanged, and no target was executed. Node 24.22.1, macOS arm64, Ghidra 12.1.4/JDK 21, compact stdio SDK schema validation. One fixture and an older unmerged prototype do not establish current-main behavior or agent usability. This supports retaining the exact producing observation rather than reconstructing a mapping from the failed lookup, but does not make that prototype integration-ready. As noted in the prior prototype evidence, ownership without a recorder, bounded retention/duplication, cancellation, and snapshot source identity need resolution. Do not convert the batch's separate lookup failure into a successful analysis-address lookup or infer broader coordinate equivalence. On current main `60c0cf977`, I repeated the separately requested real Ghidra pseudocode observation and offline bundle import. A summary filtered by its exact Evidence ID returned one complete-record receipt but did not include the offset mapping; `inspect_analysis_view` with `native-observation` returned `unsupported_target` for `procedure_pseudo_code`. The complete bundle retained the mapping. This also happened with the older source-Evidence prototype, so source linking and a focused way to inspect that source are separate concerns. The target and bundle hashes were unchanged; compact stdio MCP on one fixture and host, no target execution or agent trial. Documentation clarification: #8480. This is related to #5032; no new runtime capability is claimed. ### Current public-workflow control On REA #8485 head `01757d8ec` (its changes concern session release guidance), macOS arm64, Ghidra 12.1.4/JDK 21 and real stdio MCP, I repeated `batch_decompile(["file-offset:0x430"])` with the full and compact advertised SDK schemas. In both profiles the item succeeded while its separate procedure lookup was unknown; the batch had no Evidence links and a complete bundle at that point held only the batch record. A subsequent separate `procedure_pseudo_code` call returned the same text and explicitly mapped file offset 1072 to `0x100000430`; the bundle then held two records. The separately requested observation is not the batch's retained source, and matching text alone does not establish that it was the same provider observation. The source-owned target stayed unexecuted and its SHA-256 was unchanged. This is one selector and target; it does not resolve resource-capacity, snapshot, cancellation or retained-source ownership questions for a fix. ### Inline observation experiment An unmerged, disposable prototype based on main `293db94dd` placed each completed provider observation's selector, provider, analysis profile, raw result, locations and limitations alongside its batch pseudocode, without creating a second complete Evidence record. In real Ghidra 12.1.4 stdio MCP, the full and compact advertised schemas accepted the item and its source included the exact `file-offset:0x430` to `0x100000430` mapping. A batch-only bundle contained one record; after import into a target-free server the entire batch, including that mapping, matched exactly. The static target and bundle hashes were unchanged. On real Kuna 1.986, a deliberately gated launcher made the first two pseudocode items come from single-function runs and the third from the completed project export. The inline observations recorded those respective sources and per-item limitations, with compact SDK schema validation and an unchanged, unexecuted fixture. This is controlled scheduling, not an estimate of natural frequency. This is not a proposed final contract or integration-ready implementation. The prototype's provider-subject shape initially failed SDK output validation; its temporary broad JSON schema is not an acceptable typed contract. Profile and limitation data are repeated per item; payload cost has not been measured. Source-record links, subject normalization, capacity and cancellation behavior, CLI, and snapshot interactions remain to be designed and verified. The experiment shows that retaining the decisive mapping and source inline is a possible alternative to duplicating each entire pseudocode record; it does not establish that either approach is best. A further real-Ghidra snapshot control saved the experimental batch with one workflow entry and one Evidence record, reopened the same target and snapshot, and repeated the MCP batch. Both observations contained the same inline file-offset mapping, but their nested lookup diagnostics had different Ghidra run IDs and the second result lacked a snapshot-replay limitation: this was a fresh provider observation, not proof of workflow replay. The target and snapshot hashes were unchanged. On this fixture the raw JSON encoding of one inline source object was 3,572 bytes, including 1,660 bytes of profile and 1,037 bytes of limitations, while the selected pseudocode was 203 bytes. Those are serialized sizes for one observation, not a token, time, CPU or memory benchmark. Repeating the whole profile and common caveats per item is a material design concern; consider shared, explicitly associated observations while preserving item-specific facts and avoiding invented source identities. No direct `batch-decompile` command appeared in the current CLI catalog; no CLI batch parity is claimed. ### Shared-context experiment A second unmerged prototype groups equal provider/profile/subject/limitations observations once per batch and associates each completed item with its group index, while retaining its own provider selector, raw result and locations. On the real Kuna 1.986 gated three-item control, the two single-function results used one group and the project-export result a second; the item-level raw results still named their respective source. Compact SDK schema validation succeeded and the target hash was unchanged. On real Ghidra 12.1.4, full and compact schemas accepted the file-offset control; a batch-only bundle retained the exact mapping after target-free import. For the two separate controlled Kuna runs, JSON encoding of only these prototype source fields was 6,579 bytes with repeated inline contexts versus 4,899 bytes with two shared contexts; each had three items. The launchers used different temporary paths, so the sizes are illustrative, not an equivalent-workflow token, latency, CPU or memory comparison. The indirection also adds an agent-facing lookup and the prototype does not yet validate group-index references, settle source-record closure or cancellation/capacity semantics, or cover arbitrary provider subjects and all failure paths. It is not integration-ready. Compare this with a simpler shared provider profile plus per-item caveats, and evaluate the complete agent task rather than serialized bytes alone. ### Source ownership and context-reference controls Using the shared-context prototype with production MCP registration and a simulated provider, a source-free batch returned its inline mapping without an Evidence recorder and did not invent a retained source ID. When the simulated provider supplied a separate source Evidence record, the existing no-recorder boundary refused the call; with a recorder it retained that source and linked it both to the parent and the associated item. This validates those controlled ownership cases, not a real-provider or capacity/cancellation run. The existing loss of a completed workflow on source-publication refusal is separately tracked in #8425. A temporary canonical-schema check rejects a batch whose item points past the context array. A negative control without that check accepted the same malformed item. In the tested full and compact MCP profiles, the SDK's advertised JSON Schema still accepted the malformed index because it did not carry the cross-field refinement. Any shared-context design must therefore enforce this relationship at the owning boundary and explain it to consumers; advertised schema validation alone is insufficient. The experimental code and tests remain unmerged. ### Capacity and cancellation controls With production MCP registration, a simulated provider, an artificial zero-byte Evidence ledger, and the shared-context prototype, the provider completed its pseudocode call in both controls. With no upstream source record, recording the completed `batch_decompile` Evidence failed; with an upstream source record, recording that source failed first. Both returned a typed capacity error without the completed batch, and neither retained an Evidence record. The same controls passed against unmodified main `293db94dd`, so this loss is not introduced by the prototype. This extends the scenario discussed in #8425; the zero allowance is fault injection, not a production-frequency claim. A separate gated simulated-provider MCP control cancelled while the second of two pseudocode calls was active, after the first had completed. The client request rejected, the provider observed cancellation, and the ledger contained no batch record. The same control passed on unmodified main. This does not establish real-provider cancellation behavior or a requirement to publish an incomplete batch; #4276 tracks cancellation recovery. Any new item-provenance contract should define whether partial completed items are intentionally recoverable rather than implying they were retained. A subsequent real-provider control used Kuna 1.986, macOS arm64 and compact stdio MCP on the existing source-owned Rust fixture. A caller-owned scheduling launcher held the project export until the first single-function decompile finished with exit status 0, and signalled when the second single-function process started; the client then cancelled the batch. Against both main `293db94dd` and the shared-context experiment, the SDK request rejected, a later complete Evidence bundle contained zero records, `binary_session` remained usable and `close_binary` succeeded. The target digest remained unchanged and the target was not executed. This is controlled process timing and one provider/fixture, not a natural-frequency estimate or a claim that cancelled batches must publish partial results. ### Integration with source-publication recovery A disposable, unmerged integration combined the shared-context experiment with #8444 head `e619141b9`. Production MCP boundary controls showed that when source retention fails after batch completion, the error contains the unretained source and the completed batch, whose item retains its context association and exact source link; source closure is explicitly `not-established`. The existing cleanup-retry and response-limit controls passed on the combination. Real Ghidra 12.1.4 full/compact stdio MCP retained the file-offset mapping; real Kuna 1.986 compact stdio with gated scheduling retained two single-function observations and a project-export observation in their respective contexts. Both static targets were unchanged. These runs do not establish untested providers or agent usability. The combination is not a PR or an integration-ready design: subject/provider-profile cross-validation, reliable advertised context-reference semantics, payload cost, and broader lifecycle/format coverage remain. ### Context validation and description control A later unmerged prototype describes the zero-based item-to-context association, preserves the exact selector passed to the pseudocode operation, and omits the redundant operation name from each item. It reuses Evidence's canonical provider/profile consistency check. With a simulated production MCP registration, the canonical contract rejected both an out-of-range context index and a context with a mismatched provider/profile; the advertised SDK JSON schemas accepted these deliberately corrupted cross-field cases in both full and compact profiles. Correct real Ghidra 12.1.4 full/compact and gated Kuna 1.986 compact outputs still passed the fetched SDK schemas, with the mapping/source distinctions intact and fixture hashes unchanged. This is a prototype and one-host control, not a remedy for other clients or a proof of agent comprehension. Cross-field validation remains the producer's responsibility and the item/context relationship must be explicit in the contract. ### Context deduplication controls The shared-context prototype currently clones and JSON-serializes each context before grouping. A controlled direct-port batch with ten observations alternating two semantically identical valid profiles produced two contexts solely because their parameter keys had different insertion order; their canonical profile digests were equal. This is redundant representation, not a claim about a measured end-to-end performance regression. An in-memory MCP negative control supplied one valid profile followed by changed parameters with the same claimed digest. The existing whole-context grouping kept the second context visible and canonical output validation rejected its invalid digest. An intentionally unsafe digest-only grouping merged the profiles and the call incorrectly succeeded, hiding the invalid profile. The experimental optimization was reverted. Any more efficient grouping must validate the complete candidate before treating its digest as identity, preserve distinct provider/subject/limitation facts, and account for representation expansion before allocation. These are synthetic provider controls, not a claim about a real provider producing malformed profiles. ### Synthetic admission control On Node 24 with a 128-MiB old-space limit, an in-memory MCP control supplied 48 successful short pseudocode results, each with a distinct synthetic 512-KiB raw provider value. Current main `e5e0dc554` returned and retained the batch while discarding those raw values. The unmerged inline-provenance prototype completed all 48 provider calls, then failed ledger authentication with a typed memory-headroom constraint and no completed result; combining it with #8444 did not change that admission stage. At 256 MiB, the prototype retained its result but the full reply exceeded the 10-MiB transport budget. This is deliberately large synthetic metadata, not a measured Kuna/Ghidra behavior or frequency. An immutable-Evidence experiment changed the constrained case to a ledger-capacity refusal with an explicit omitted unretained observation, but still could not deliver the completed batch; that experiment was reverted. A producer design should account for retained raw metadata and representation expansion before allocation, and preserve useful partial results with explicit omissions when complete retention or delivery cannot be established. Item paging is a separate retrieval question in #8498. ### Real Ghidra file-offset envelope duplication On the unmerged batch-source prototype, real Ghidra 12.1.4 returned an 8,992-character pseudocode result for an owned arm64 function selected by file offset. The raw function envelope's `value` was exactly the same text; its separate `selection` preserved the file offset and mapped/procedure addresses. In the proposed paged item view, requesting raw detail returned that entire pseudocode again even when the pseudocode page limit was 50 UTF-16 units. On this one fixture the JSON raw envelope was 9,203 UTF-8 bytes and its `limitations` and `selection` without `value` were 103 bytes. The target digest was unchanged; these are fixture-specific byte counts, not token or performance measurements. Source inspection shows the Ghidra adapter owns a strict function envelope and supplies it as the raw result when the selection is present. A direct object control reconstructed this specimen's exact envelope from its non-value fields and the identical preserved pseudocode. A producer-owned, explicitly reconstructable representation may avoid duplication, but the shared batch workflow should not guess arbitrary raw schemas, discard evidence, or silently change direct-call raw Evidence. No compact representation has been implemented or validated. ### Heap-only admission is insufficient An unmerged experiment attempted to retain raw source details while live V8 headroom allowed, explicitly marking per-item raw omissions otherwise. Repeating the same synthetic 48-item constrained-heap control five times produced four retained batches with readable omitted-source pages and one separate Evidence-ledger capacity refusal with no retained batch. An earlier repetition also hit authentication headroom. The ledger owns a representation allowance that is separate from the live heap estimate, so this heuristic does not establish a safe reservation or reliable recovery. It was removed; no fixed margin is proposed. Real Kuna/Ghidra small-fixture controls had no omissions, but do not establish safety for larger observations. Consider an owner-authorized accounting/admission contract and explicitly distinguish unavailable raw facts from retained source records. ### Naturally mixed parallel batch On PR #8694 head `96294d70c`, real Kuna 1.988 on macOS arm64, a cold `batch_decompile` of all 25 inventory entries of an owned 2 MiB arm64 Mach-O (SHA-256 `8698771cccb98f77e1282b76267c96f6699d86fee548e14c4afef6dd3d571517`) with `REA_KUNA_JOBS=2` returned 22 successful and three failed items in each of compact and full stdio MCP schema profiles. In both runs, the aggregate Evidence contained both the single-function and parallel project-export limitations, indicating both kinds of provider observation occurred during the batch. Successful items carried address, procedure, status and pseudocode, but no per-item source or limitation; a batch-only Evidence export retained one batch record with no source record. No scheduling wrapper was used. In a separate repeat, I called `procedure_pseudo_code` for each successful item after the batch. Each later call identified the completed project export, and all 22 returned text equal to the corresponding batch text on this fixture. Text equality does not establish which source produced an earlier item; the provider observations are source-distinct even where their text happens to match. This is one small synthetic fixture, not a prevalence or behavioral-correctness claim. The target was read, not executed, and its digest was unchanged. This also qualifies PR #8694: aggregate caveats become visible but cannot associate either caveat with a particular successful item when a batch crosses the cold-to-warm transition. Preserve the ordered occurrence and source association without treating a shared cache key as the output's content identity. The compact representation, retention budget and compatibility questions above still apply. ### Directory export alternative On PR #8694 head `96294d70c`, real Kuna 1.988 and the same owned arm64 Mach-O, I ran a cold `decompile_all` with `jobs=2`, `limit=5`, then resumed for five more functions. In both MCP profiles, the resulting `decompile-index.json` associated the single-function caveat with three written functions and the parallel-project caveat with seven, with no overlap. Each resumed first-run record matched its earlier parsed JSON and its file's SHA-256 still matched the index; the resume reported five skipped and five newly written. The two runs used separate cache roots and no scheduling wrapper. This is a practical file-writing alternative for preserving per-function caveats when an export directory is appropriate; it does not itself identify the exact producer project (see #8260) or establish general behavior for other targets. Target digest remained unchanged and the target was not executed. ### Completed standalone batch after project failure On main `9ebbe67e`, real Kuna 1.989 compact and full MCP sessions with the deliberately failed two-function project in #8744 returned two successful `batch_decompile` items using standalone fallback. The top-level batch Evidence included the single-function and project-failure caveats, but neither successful item carried per-item limitations. A same-session directory export recorded those caveats against each function in its index. The owned target SHA-256 `0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930` remained unchanged. This tests a uniform fallback batch, not mixed source modes or autonomous-agent use; the fault was deliberately injected. ### Released 1.989 batch-only retention after project failure In a fresh main `9ebbe67e` session with the controlled all-worker project failure from #8744, I called `batch_decompile` directly after the failing assembly request, without separately requesting individual pseudocode. In each compact and full stdio MCP profile, both batch items succeeded through standalone fallback. `get_evidence_bundle` returned exactly one retained record, the batch; its `raw_result` was null, it had no Evidence links, and neither successful item had a source or item-level limitations. The record's overall limitations included the single-function and project-failure caveats. Thus the retained batch offers no source record to inspect for the individual occurrences in this control. The target SHA-256 stayed `0e0ecf82c96e4918ee2ca1287dc25513d8fd13d5ab7fa5b98db00ad342f03930`. The project failures were deliberately injected; this is a uniform-source example, not a mixed-source frequency claim or an Evidence export/import test.
Author
Owner

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

Ordinary function with two successful representations in one batch

A separate small, self-built no_std Rust arm64 Mach-O exercises actual code functions, rather than the data-symbol control above. It contains _audit_compute, _audit_adjust, a Rust-mangled marker function and an explicitly retained RUST_BACKTRACE string; the marker and string are part of the test fixture. With real Kuna 1.986 behind the same owned scheduling wrapper, batch_decompile(["_audit_compute", "_audit_adjust", "_audit_compute"]) returned three ok items. Both _audit_compute selections resolved to 0x320, but the first body used Rust-like unsafe fn syntax and the third used C-like int ... syntax. Neither successful item had its own source or limitations; the batch's aggregate caveat mentioned the single-function path.

Direct unwrapped kuna decompile ... _audit_compute --json reported rust-language and its code exactly matched the first item. An individual REA call after the batch recorded project-export / ready and exactly matched the third. The controlled wrapper logged the first single decompile completing before the project was released, and delayed the middle call; this schedules the transition, so it is not a natural frequency measurement. A second independently created cache reproduced the same Rust-like/C-like sequence, and the complete batch record survived bundle export and fresh target-free import exactly.

As a separate provider control, real REA/Ghidra 12.1.4 returned three successes for the same selectors, with equal first and third pseudocode and a real instruction listing for _audit_compute. Neither provider output establishes runtime behavior or equivalence between representations. SDK compact output schemas were fetched before the calls; the fixture SHA-256 cbaf9827225864c7357b0fe74f52eb491aca503abc86af7f863cab0d4bf9cb80 and offline bundle digest remained unchanged, and the target was not executed.

This illustrates why successful-item source and representation matter without suggesting that duplicates must be deduplicated, that repeated results must always agree, or that a batch should wait for a project automatically. The independently relevant language/extension discussion remains #8191.

<!-- gh-comment-id:6546939745 --> @morluto commented on GitHub (Oct 31, 2026): ### Ordinary function with two successful representations in one batch A separate small, self-built `no_std` Rust arm64 Mach-O exercises actual code functions, rather than the data-symbol control above. It contains `_audit_compute`, `_audit_adjust`, a Rust-mangled marker function and an explicitly retained `RUST_BACKTRACE` string; the marker and string are part of the test fixture. With real Kuna 1.986 behind the same owned scheduling wrapper, `batch_decompile(["_audit_compute", "_audit_adjust", "_audit_compute"])` returned three `ok` items. Both `_audit_compute` selections resolved to `0x320`, but the first body used Rust-like `unsafe fn` syntax and the third used C-like `int ...` syntax. Neither successful item had its own source or limitations; the batch's aggregate caveat mentioned the single-function path. Direct unwrapped `kuna decompile ... _audit_compute --json` reported `rust-language` and its code exactly matched the first item. An individual REA call after the batch recorded `project-export` / `ready` and exactly matched the third. The controlled wrapper logged the first single decompile completing before the project was released, and delayed the middle call; this schedules the transition, so it is not a natural frequency measurement. A second independently created cache reproduced the same Rust-like/C-like sequence, and the complete batch record survived bundle export and fresh target-free import exactly. As a separate provider control, real REA/Ghidra 12.1.4 returned three successes for the same selectors, with equal first and third pseudocode and a real instruction listing for `_audit_compute`. Neither provider output establishes runtime behavior or equivalence between representations. SDK compact output schemas were fetched before the calls; the fixture SHA-256 `cbaf9827225864c7357b0fe74f52eb491aca503abc86af7f863cab0d4bf9cb80` and offline bundle digest remained unchanged, and the target was not executed. This illustrates why successful-item source and representation matter without suggesting that duplicates must be deduplicated, that repeated results must always agree, or that a batch should wait for a project automatically. The independently relevant language/extension discussion remains #8191.
Author
Owner

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

Isolated generic caveat-association experiments

I tested two unmerged exploratory changes on REA 60149282, in a detached worktree, using the Rust code and mixed-failure fixtures above. Both consume the shared provider observation's limitations; neither parses Kuna prose or adds a Kuna-specific wrapper.

  • Inline: attach the complete distinct observation limitations to each successful item. The two early Rust-like items carried the single-function caveat; the later C-like item did not. The successful body and selector fields were unchanged. This does not prove the third item's exact source merely from the absence of that caveat.
  • Indexed: retain unique successful-item caveat strings once in a batch-level table and put indices on each successful item. Expanding those indices reproduced the inline caveat lists exactly in the tested Kuna and Ghidra runs. The existing failed-item caveats remained on the failed item in a separate mixed-result control. A batch-only bundle exported and imported into a fresh server with its record exactly equal. Both compact and full advertised SDK output schemas accepted the real Kuna control; the real Ghidra control used compact. Target and bundle digests stayed unchanged.

This only addresses caveat association. It does not preserve the exact source Evidence, structured representation/language, or provider export identity; it also has no distinct-caveat/byte budget or index-consistency invariant yet. The table representation needs an explicit contract for empty and unknown caveats, deduplication scope, error items, pagination, authenticated Evidence closure, and compatibility with older clients before it could be considered for integration. Existing inputs/outputs and cancellation behavior require further verification.

For scale context only, I tokenized JSON.stringify(normalized_result) for the same three-item outputs with o200k_base; the underlying item results were identical after removing the extra fields:

Provider Current Inline Indexed
Kuna 1,080 bytes / 386 tokens 2,857 / 726 1,830 / 556
Ghidra 950 bytes / 334 tokens 4,106 / 910 2,102 / 587

These are serialized-result token estimates for two tiny fixtures, not whole-task, host-prompt, latency or memory measurements. The indexed form adds a lookup for the agent; its catalog/schema and retrieval costs were not included. Larger batches, distinct caveats and real clients remain unmeasured.

Compatibility control: two existing MCP boundary test files on the indexed experiment had 19 passing tests and 2 failing exact-result assertions because of the newly added fields (item_caveats and/or indices). This does not establish that current SDK clients fail—the tested SDK calls validated—but it demonstrates why shape and migration decisions need review. The experiment is not a proposed final patch; no production or user-worktree files were changed.

<!-- gh-comment-id:6546987385 --> @morluto commented on GitHub (Oct 31, 2026): ### Isolated generic caveat-association experiments I tested two unmerged exploratory changes on REA `60149282`, in a detached worktree, using the Rust code and mixed-failure fixtures above. Both consume the shared provider observation's limitations; neither parses Kuna prose or adds a Kuna-specific wrapper. - **Inline:** attach the complete distinct observation limitations to each successful item. The two early Rust-like items carried the single-function caveat; the later C-like item did not. The successful body and selector fields were unchanged. This does **not** prove the third item's exact source merely from the absence of that caveat. - **Indexed:** retain unique successful-item caveat strings once in a batch-level table and put indices on each successful item. Expanding those indices reproduced the inline caveat lists exactly in the tested Kuna and Ghidra runs. The existing failed-item caveats remained on the failed item in a separate mixed-result control. A batch-only bundle exported and imported into a fresh server with its record exactly equal. Both compact and full advertised SDK output schemas accepted the real Kuna control; the real Ghidra control used compact. Target and bundle digests stayed unchanged. This only addresses caveat association. It does **not** preserve the exact source Evidence, structured representation/language, or provider export identity; it also has no distinct-caveat/byte budget or index-consistency invariant yet. The table representation needs an explicit contract for empty and unknown caveats, deduplication scope, error items, pagination, authenticated Evidence closure, and compatibility with older clients before it could be considered for integration. Existing inputs/outputs and cancellation behavior require further verification. For scale context only, I tokenized `JSON.stringify(normalized_result)` for the same three-item outputs with `o200k_base`; the underlying item results were identical after removing the extra fields: | Provider | Current | Inline | Indexed | | --- | ---: | ---: | ---: | | Kuna | 1,080 bytes / 386 tokens | 2,857 / 726 | 1,830 / 556 | | Ghidra | 950 bytes / 334 tokens | 4,106 / 910 | 2,102 / 587 | These are serialized-result token estimates for two tiny fixtures, not whole-task, host-prompt, latency or memory measurements. The indexed form adds a lookup for the agent; its catalog/schema and retrieval costs were not included. Larger batches, distinct caveats and real clients remain unmeasured. Compatibility control: two existing MCP boundary test files on the indexed experiment had 19 passing tests and 2 failing exact-result assertions because of the newly added fields (`item_caveats` and/or indices). This does not establish that current SDK clients fail—the tested SDK calls validated—but it demonstrates why shape and migration decisions need review. The experiment is not a proposed final patch; no production or user-worktree files were changed.
Author
Owner

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

Source-Evidence prototype and ownership limits

I tested a second, unmerged experiment in a detached REA 60149282 worktree. It creates a procedure_pseudo_code source Evidence record for each completed batch observation when one is not already retained, links it from the composed batch, and attaches the source ID to that item. This is generic observation plumbing; it does not interpret Kuna's raw source fields. It is intentionally exploratory, not an integration-ready proposal.

On the scheduled real-Kuna Rust fixture, the first and third successful _audit_compute items pointed to different retained records: the first recorded single-function, the third project-export. Each source's pseudocode exactly matched its item, and all three item source IDs appeared in the batch links. A fresh target-free server imported the batch bundle and recovered all three source records from the complete bundle. A real Ghidra control reused the same source ID for the two equal repeated _audit_compute observations. The mixed Kuna no-body control retained the failure caveat and linked its null observation. Successful real-Kuna MCP calls passed both advertised full and compact SDK schemas; Ghidra was checked with compact. The target digest was unchanged; the Kuna source bundle digest was unchanged during offline replay.

There are substantial unresolved costs and failure modes:

  • The current session owner deliberately avoids retaining documentless pseudocode source records because this can duplicate large bodies. In this three-item example, normalized batch JSON grew from 1,080 to 1,353 bytes (386 to 521 estimated o200k_base tokens), while the exported bundle grew from 4,415 bytes / one record to 13,247 bytes / four records, including 605 pseudocode characters repeated in source records. These are two small serialized examples, not peak-memory, latency, full-task or model-prompt measurements.
  • After import, an exact-ID bundle summary found each source but did not expose its raw source kind. A filtered complete-bundle request returned invalid_request, and inspect_analysis_view on a pseudocode record returned unsupported_target. The unfiltered complete bundle did contain the source data. Thus an ID alone is not yet an efficient agent handoff; this extends the selective historical-Evidence question in #8307.
  • With a test-only wrapper holding the second single decompile, I cancelled the batch after the first single decompile completed and the second began. The SDK call was cancelled; after settling, the session's complete Evidence bundle had zero records. This prototype collects its new sources only when the batch returns, so it did not retain that earlier observation on this controlled cancellation. It needs an explicit ownership/completion design before claiming cancellation safety.
  • The focused two-file MCP suite produced 17 passes and 4 failures. A separate simulated fixed adapter without an Evidence recorder returned capability_unavailable with the existing “requires an explicit retention owner” explanation. Adding source records unconditionally therefore changes behavior for adapter registrations that cannot retain them; an applicable fallback or explicit contract decision is needed. The suite's two Ghidra routing tests passed. Snapshot replay identity, error/partial-source closure, bounds, full client compatibility and final-cleanup cancellation remain unverified.

The evidence points toward designing source retention and retrieval and ownership together, rather than simply adding IDs or retaining every body. The earlier indexed-caveat experiment has a different tradeoff: it preserves a bounded association only if a budget is designed, but cannot establish exact producer identity. No production or user-worktree files were changed.

<!-- gh-comment-id:6547039866 --> @morluto commented on GitHub (Oct 31, 2026): ### Source-Evidence prototype and ownership limits I tested a second, unmerged experiment in a detached REA `60149282` worktree. It creates a `procedure_pseudo_code` source Evidence record for each completed batch observation when one is not already retained, links it from the composed batch, and attaches the source ID to that item. This is generic observation plumbing; it does not interpret Kuna's raw source fields. It is intentionally exploratory, not an integration-ready proposal. On the scheduled real-Kuna Rust fixture, the first and third successful `_audit_compute` items pointed to different retained records: the first recorded `single-function`, the third `project-export`. Each source's pseudocode exactly matched its item, and all three item source IDs appeared in the batch links. A fresh target-free server imported the batch bundle and recovered all three source records from the complete bundle. A real Ghidra control reused the same source ID for the two equal repeated `_audit_compute` observations. The mixed Kuna no-body control retained the failure caveat and linked its null observation. Successful real-Kuna MCP calls passed both advertised full and compact SDK schemas; Ghidra was checked with compact. The target digest was unchanged; the Kuna source bundle digest was unchanged during offline replay. There are substantial unresolved costs and failure modes: - The current session owner deliberately avoids retaining documentless pseudocode source records because this can duplicate large bodies. In this three-item example, normalized batch JSON grew from 1,080 to 1,353 bytes (386 to 521 estimated `o200k_base` tokens), while the exported bundle grew from 4,415 bytes / one record to 13,247 bytes / four records, including 605 pseudocode characters repeated in source records. These are two small serialized examples, not peak-memory, latency, full-task or model-prompt measurements. - After import, an exact-ID bundle **summary** found each source but did not expose its raw source kind. A filtered complete-bundle request returned `invalid_request`, and `inspect_analysis_view` on a pseudocode record returned `unsupported_target`. The unfiltered complete bundle did contain the source data. Thus an ID alone is not yet an efficient agent handoff; this extends the selective historical-Evidence question in #8307. - With a test-only wrapper holding the second single decompile, I cancelled the batch after the first single decompile completed and the second began. The SDK call was cancelled; after settling, the session's complete Evidence bundle had zero records. This prototype collects its new sources only when the batch returns, so it did not retain that earlier observation on this controlled cancellation. It needs an explicit ownership/completion design before claiming cancellation safety. - The focused two-file MCP suite produced 17 passes and 4 failures. A separate simulated fixed adapter without an Evidence recorder returned `capability_unavailable` with the existing “requires an explicit retention owner” explanation. Adding source records unconditionally therefore changes behavior for adapter registrations that cannot retain them; an applicable fallback or explicit contract decision is needed. The suite's two Ghidra routing tests passed. Snapshot replay identity, error/partial-source closure, bounds, full client compatibility and final-cleanup cancellation remain unverified. The evidence points toward designing source retention **and retrieval and ownership together**, rather than simply adding IDs or retaining every body. The earlier indexed-caveat experiment has a different tradeoff: it preserves a bounded association only if a budget is designed, but cannot establish exact producer identity. No production or user-worktree files were changed.
Author
Owner

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

A separate #8352 investigation shows why successful-item attribution affects a possible recovery design. In an isolated unmerged experiment allowing explicitly selected, unclassified addresses, a real Kuna cold batch contained one statically called code address and one known data address. Both items reported success; the batch-level limitations retained two different section/classification caveats, but neither successful item associated itself with its own caveat. Individually querying each address returned its specific caveat. After the project export completed, both batch items instead returned no-body errors with item-level limitations.

The producer delay was deliberately controlled; this does not measure natural frequency. Details, source provenance, offline Evidence checks, and substantial reasons the experiment is not production-ready are at https://github.com/morluto/rea/issues/8352#issuecomment-6547382727. This is an interaction between the existing batch issue and an exploratory route, not a claim that current main allows these rejected data-region addresses.

<!-- gh-comment-id:6547384220 --> @morluto commented on GitHub (Oct 31, 2026): A separate #8352 investigation shows why successful-item attribution affects a possible recovery design. In an isolated **unmerged** experiment allowing explicitly selected, unclassified addresses, a real Kuna cold batch contained one statically called code address and one known data address. Both items reported success; the batch-level limitations retained two different section/classification caveats, but neither successful item associated itself with its own caveat. Individually querying each address returned its specific caveat. After the project export completed, both batch items instead returned no-body errors with item-level limitations. The producer delay was deliberately controlled; this does not measure natural frequency. Details, source provenance, offline Evidence checks, and substantial reasons the experiment is not production-ready are at https://github.com/morluto/rea/issues/8352#issuecomment-6547382727. This is an interaction between the existing batch issue and an exploratory route, not a claim that current main allows these rejected data-region addresses.
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#6557
No description provided.