[GH-ISSUE #8510] [Bug] Kuna 1.988 stored-pointer references disappear from xrefs and feature traces #6636

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

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

Before submitting

  • I searched open and closed issues for a related report.
  • I removed credentials and private target data.

Area

Native analysis or decompilation

Observed behavior

With Kuna 1.988, REA xrefs drops a relocation-backed pointer reference that the selected Kuna executable returned. trace_feature consequently returns zero references with truncated: false and no residual unknowns for the same target. The xrefs Evidence includes the raw response digest and an examined-row count of zero, but it does not expose or disclose the omitted pointer row. Its general limitation says an empty result does not prove absence.

Reproduction

On macOS arm64, build this owned fixture with clang -arch arm64 -O0 -g0 pointer-only.c -o pointer-only; do not run it.

__attribute__((noinline, used)) int audit_target(int x) { return x + 11; }
int (*volatile audit_func_ptr)(int) = audit_target;
int main(void) { return 0; }

For this build, nm -nm pointer-only reports _audit_target at 0x1000003c0 and _audit_func_ptr at 0x100004000. Addresses are build-specific.

  1. Direct Kuna 1.988 kuna xrefs pointer-only --to 0x1000003c0 --json reports zero instruction xrefs, but data_refs_coverage: "chained-fixups", data_refs_count: 1, and a pointer from 0x100004000 to 0x1000003c0.
  2. On REA #8509 head 7f344af1a, open the same target with Kuna and call xrefs({"address":"0x1000003c0"}): the normalized result is []. trace_feature({"query":"audit_target"}) finds the function but reports references: [], truncated: false, residual_unknowns: [].
  3. Independent dyld_info -fixups pointer-only reports the rebase from 0x100004000 to 0x1000003c0. REA/Ghidra 12.1.4 on the same file reports the pointer address among its xrefs; Ghidra also reports other references.

Both full and compact advertised MCP schema profiles were exercised on Node 24.22.1, macOS arm64. The target SHA-256 22c604d669ebd4e32be8d1f5c820ecbe9f28b1101dcb8da4b399acea355f21a9 was unchanged and the target was never executed. This is one generated static Mach-O, not a completeness or prevalence estimate. Kuna 1.986 on the same fixture also returned no REA references, but its direct result did not provide the new pointer rows.

Expected behavior

Define and preserve the distinction between instruction references and relocation-backed stored pointers. If xrefs includes pointer references, retain the source address and its provenance without treating a stored pointer as an executed instruction. If the existing contract intentionally excludes them, report their omission and coverage explicitly in both direct and composed answers; do not report their absence. Do not equate upstream data_refs_coverage: none with absence of stored pointers.

Impact and scope

An analyst seeking references to a function can miss a provider-observed callback/function-pointer slot. A general empty-result caveat remains, but it does not say that the provider returned a concrete row that REA discarded. No autonomous-agent behavior or runtime pointer use was tested.

REA version

7f344af1aa0a78fd4e331dbbc9c30d38e4cfb796 (#8509); source-derived behavior also exists in its main base.

Runtime and platform

Node 24.22.1, macOS arm64, Kuna 1.988, Ghidra 12.1.4/JDK 21 control.

Target and artifact context

Self-built Mach-O arm64 executable; read-only static analysis, no target execution or mutation.

Interface

MCP

Earliest failure stage

Provider output parsing/projection

Relevant output or evidence

Direct Kuna: xrefs: [], data_refs_count: 1, pointer 0x100004000 → 0x1000003c0, source chained-fixups. REA: xrefs normalized [], raw source examined_rows: 0; trace_feature returned the matched function with no references, no truncation and no residual unknowns. Ghidra and dyld_info independently observed the pointer slot.

Typed outcome or recovery expected

Keep instruction and stored-pointer provenance distinct and preserve their applicable coverage. Test exact target/alias filtering, duplicates, missing versus empty metadata, malformed rows, bounded output, both MCP profiles, composed trace and offline Evidence.

Analysis or suspected cause

Source inspection: xrefsDocument in KunaReferenceFiles.ts parses xrefs but has no data_refs or data_refs_coverage fields; its default object parser strips those members. parseKunaIncomingReferences validates and counts only instruction rows and projects their addresses. The observed omission follows that producer boundary; no runtime instrumentation of the parser was added.

Additional context

Related #8348 concerns loss of kind and owner on instruction rows; #8190 concerns outgoing references. This report is specifically loss of a separately reported relocation-backed incoming pointer. Upstream 1.988 documents pointer rows separately and documents none as not enumerated. Do not infer that a stored pointer proves a runtime call.

cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Follow-up controls

A separate x86-64 static ELF fixture has a slot at 0x202190 containing 0x201159, the address of initially_selected, as confirmed by its ELF load mapping and bytes. Direct Kuna 1.988 reports data_refs_coverage: "none" and no data rows for that target. This is a concrete example of unenumerated pointer coverage, not a claim that Kuna promised to find this statically linked pointer.

An unmerged producer prototype that includes Kuna-reported pointer addresses recovered both an instruction reference and a stored pointer in a mixed Mach-O fixture. However, a trace_feature-only Evidence export retained neither the underlying xrefs observation nor a link to it, leaving its source addresses untyped. The prototype also returned no references and no residual unknown for the ELF control. These are prototype observations, not fixes shipped in #8509; a complete design needs to propagate applicable coverage and retain enough source Evidence for composed answers without treating a stored pointer as an executed call.

ELF and PE relocation controls

An independently built, unexecuted x86-64 ELF shared object has audit_target at 0x1320 and pointer slot 0x33e0; LLVM readobj reports R_X86_64_RELATIVE at the slot with addend 0x1320. Direct Kuna 1.988 reports one pointer in data_refs with data_refs_coverage: dynamic-relocations; on #8509 head 7f344af1a, real Kuna MCP xrefs and trace_feature omit it. REA/Ghidra 12.1.4 reports the corresponding DATA reference at its own rebased coordinates 0x1033e0 -> 0x101320. An unmerged producer experiment recovered 0x33e0, but the resulting trace still lacks a link to the source's pointer-kind observation; it is not a shipped fix. ELF SHA-256 0df5b9c004412594fc976326144f9a8488ae089d91bc70c962c9f23e60f0b75e stayed unchanged.

For a separate x86-64 PE DLL, LLVM reports a DIR64 base relocation at RVA 0x3000; the stored 64-bit value points to audit_target RVA 0x1000. Direct Kuna 1.988 reports that pointer with base-relocations coverage, and REA/Ghidra reports a DATA edge at 0x180003000 -> 0x180001000. REA intentionally refuses the Kuna provider for PE (target_format_unsupported), so this is an upstream-format control, not a claim of an REA/Kuna PE regression. PE SHA-256 73b336bb59c09db4b0a9df052b4a6face8222115f257c119567842998843f92d stayed unchanged. Both fixtures were statically analyzed only. These cases do not establish general relocation or provider completeness.

ELF preemption qualification

A further x86-64 ELF fixture has a default-visible global audit_target and a pointer initialized using a symbol-based R_X86_64_64 audit_target relocation. Direct Kuna 1.988 reports a dynamic-relocations pointer row from 0x33f0 to the local symbol value 0x1340; REA/Kuna currently omits it and REA/Ghidra reports a static DATA reference at rebased coordinates. Under the ELF gABI, default-visible globals can be preempted, so this static row must not be presented as proof of the runtime-resolved target. A paired protected-visibility object uses an R_X86_64_RELATIVE relocation, but current inspect_native_exports drops the default/protected distinction; #8517 and draft #8519 address that separate observed-fact omission. The two fixture hashes were unchanged and no runtime linker or target was run.

Exact-address PLT and slot control

On the previously described default-visible ELF fixture (SHA-256 741f17c72cea92c0316549c9733cdf77c528d890fde6231bdf4cc8ba325aa630), direct Kuna 1.988 xrefs --to at the PLT stub 0x13b0 returns call 0x138e -> 0x13b0 and lists slot 0x3488 as an alias. Querying the slot itself returns the same call row whose actual destination remains 0x13b0; querying the implementation 0x1370 returns a separate data_refs row 0x3488 -> 0x1370. Querying the name groups all three. LLVM identifies the slot as R_X86_64_JUMP_SLOT audit_target; its runtime binding is not established by these static observations.

On #8509 real compact MCP, exact-address xrefs returned [0x138e] for the PLT, [] for the slot, and [] for the implementation. The unmerged pointer prototype returned the same PLT and slot answers and [0x3488] for the implementation. This one control confirms why a fix must filter each row by its actual endpoint, not include every row in Kuna's alias class, while preserving the distinct relocation source and its binding limitation. It does not establish general alias or relocation coverage. The fixture was unexecuted and its digest stayed unchanged.

Indirect-call handoff through a stored slot

A source-built, unexecuted x86-64 ELF has audit_target at 0x1260, a relocation-backed audit_slot at 0x3320 initialized to that function, and one instruction call *audit_slot(%rip) at 0x1266 (LLVM disassembly). Direct Kuna 1.988 reports a pointer row 0x3320 -> 0x1260 and separately a call row 0x1266 -> 0x3320. On #8509 real compact MCP, xrefs of the target is empty while xrefs of the slot returns 0x1266; the unmerged pointer prototype returns the slot for the target, allowing this second query. Its feature trace includes the slot but does not automatically traverse to the caller and does not retain the source pointer kind. Both baseline and prototype Kuna trace_call_path report unknown with indirect-target limitations.

As a separate real Ghidra 12.1.4 control on the same image, rebased inspect_native_instruction(0x101266) reports a READ to slot 0x103320 and a COMPUTED_CALL candidate to target 0x101260; its static call path reaches that candidate. These are provider-derived static observations, not proof of a runtime call or of the slot's value at execution. The two-step Kuna handoff demonstrates the analyst task and why the stored-pointer kind and source Evidence need to remain available; it does not imply the workflow should automatically traverse every pointer or equate the two providers' semantics. The ELF SHA-256 fce58ca524039c732f734251c55378e6bc0ef09d40b1155235dba45933a4af8f stayed unchanged; the target was never executed. One host and fixture, no autonomous-agent or completeness claim.

Unmerged trace source-retention experiment

An exploratory change to the earlier pointer parser retained each xrefs observation consumed by trace_feature as linked Evidence. On the pointer-only Mach-O, a real Kuna 1.988 compact MCP trace alone then exported one linked xrefs record whose raw source rows contained the pointer kind and chained-fixups origin. Importing that bundle into a fresh target-free server retained the trace and linked source identically in both MCP schema profiles. This does not add a typed pointer kind to the inline trace; the caller must follow the source link.

On the separate 100-slot fixture, the previous address-only prototype returned 100 references and 100 independently resolvable owner unknowns, with a 101-record / 316,525-byte exported bundle. This experiment returned the same counts and unknowns with a 102-record / 342,152-byte bundle. These serialized bundle sizes are observations for one fixture, not token counts or performance benchmarks. The real CLI trace also returned a source link; when supplied an existing caller-selected --snapshot, the updated snapshot retained both the trace and linked pointer record. Without a selected snapshot, the CLI output observed here contains the link but no source record inline, and no durable source handoff was established.

This is not a proposed finished fix: it retains every trace xref observation, so many matched targets can increase retained state and response work; capacity, cancellation, failed source publication, duplicate observations and bounded retrieval need design and testing. The data_refs_coverage: none case still needs an explicit composed coverage outcome, and both CLI/MCP call sites currently require coordinated changes. The experiment changes the trace workflow profile revision; it was exercised on one host and selected fixtures, not committed or shipped. All targets were unchanged and unexecuted.

Controlled cancellation during source retention

In the unmerged source-retention experiment, a test-owned Node wrapper forwarded commands to real Kuna 1.988 but paused the second xrefs request on a two-function Mach-O fixture. After the barrier was observed, cancelling the public compact MCP trace_feature call rejected the client request. The first completed xrefs Evidence remained in the session, no completed trace_feature record appeared, binary_session reported the target open with no pending cleanup, and a same-session exact xrefs retry succeeded. The paused wrapper PID was absent in bounded polling; that PID observation alone does not establish process-family identity. The target SHA-256 9db44909124eb1356bd1715882912cd38802bf624e6aa5613b3867816836acdc was unchanged and it was not executed.

An earlier test wrapper used macOS platform shell/sleep, which produced cleanup_incomplete with platform_binary_environment_withheld; the test closed its connection before attempting the prescribed retry, and the test-owned process group was subsequently terminated manually. This is a limitation of that attempted control, not evidence of successful cleanup retry or a natural provider failure. The successful control uses an artificial barrier during active execution; final publication, late cleanup, cancellation timing, and other platforms remain unverified.

Controlled cleanup retry after cancellation

A separate run kept the compact MCP connection open after cancelling at the same second-xref barrier, using a test-owned macOS shell wrapper with a six-second delay. The first close_binary returned cleanup_incomplete with retry_cleanup and withheld-environment diagnostics; binary_session reported cleanup_pending: true. After bounded polling observed the wrapper PID had exited naturally, a second close_binary succeeded and cleanup_pending became false. The Evidence bundle before and after retry was identical: it retained the first completed xrefs observation and had no completed trace. The fixture SHA-256 remained unchanged and the target was not executed.

This exercises the documented retry on one artificial withheld-environment case. PID absence is an observation, not independent proof of process-family identity; this does not establish late-finalization cancellation, all cleanup failures, or other-host behavior. Unlike the earlier aborted shell attempt above, the connection remained open through successful retry and no manual termination was required.

Unmerged coverage propagation control

A further isolated experiment passes a producer-owned stored-pointer coverage gap into the composed trace without setting truncated for an unenumerated category. Real full/compact MCP controls with Kuna 1.988: the static ELF with data_refs_coverage: none still returned no addresses, but now exposed an address-scoped residual unknown; the chained-fixup Mach-O returned its pointer and separately stated that metadata enumeration does not establish all stored pointers. Kuna 1.986 did not report the metadata and the experiment stated that coverage was unreported. Each trace linked its source xrefs Evidence; successful responses validated against the fetched schemas (Ajv 2020, strict and formats disabled). The ELF case also returned the gap through the real CLI. These are unmerged experiments, not shipped behavior.

A second source-built Mach-O with 12 matched functions and no observed references produced 12 separate coverage unknowns and 12 linked xrefs records in the experiment: 25 Evidence records / 68,376 serialized bundle bytes, compared with one record / 4,649 bytes and no unknowns on #8509. The targets are distinct and can have independently resolvable coverage, so merging their unknown identities would be unsafe. Bounded presentation and source retention deserve design work; byte counts are not a token or performance benchmark. On one pointer fixture, a direct xrefs call and the source consumed by the trace had the same Evidence ID within each session. Across fresh sessions the raw-output digests and Evidence IDs differed; direct Kuna controls on identical staged bytes confirmed the serialized binary path changes the exact raw-output hash even when all other parsed fields match. That raw hash is a truthful hash of different producer bytes; whether and how to support semantic deduplication without discarding raw provenance remains open. All artifacts were unchanged and unexecuted.

The experiment has not resolved bounded admission, duplicate/cross-session source identity, finalization cancellation, or the unsnapshotted CLI handoff, and should not be treated as a complete fix.

Source-publication capacity and manual recovery control

In an isolated integration of the unmerged pointer experiment with #8444 head 92adb42521f4ec73048d3f1d82844d2360da9db1 (one workflow-profile conflict resolved for the experiment), real Kuna 1.988 analyzed the 12-function fixture through in-memory production MCP registration with a deliberately injected 21,237-byte retained-representation allowance. In both compact and full profiles, source publication stopped after one source: the resource_constraint response delivered the completed 12-match trace as unretained with source_closure: not-established, and separately delivered the first failed source as unretained. The trace had 12 source links; one was retained and one was in the error response, leaving ten linked sources neither retained nor included in that response. This is a controlled application-boundary capacity fault, not natural exhaustion or a shipped integration.

With the same session and fixture still open, the test saved each retained checkpoint, reset the investigation and re-queried the ten remaining targets; the returned source IDs matched the original links. It manually assembled the completed error-response Evidence and all 12 recovered source records into a valid bundle, then imported it into an unrestricted target-free server in both profiles. All 12 links resolved and the trace retained 12 residual-unknown strings, but the imported Unknown registry had zero entries. Source inspection shows automatic workflow-unknown recording occurs only after successful publication; manual Evidence import does not itself register them. This is a one-session, warm-cache manual control, not an advertised one-command recovery, a guarantee across restarts/cache eviction, or a claim that #8444 promises complete source closure. It exposes a design question for preserving per-target unknown identities and practical bounded handoff after publication failure. The target stayed unchanged and unexecuted.

Related scope-selection discussion for recording recovered unknowns: #8546.

100-target boundedness control

On a separate source-built, unexecuted Mach-O containing 100 matched functions with no observed references, the real compact stdio MCP workflow completed on both #8509 and the unmerged pointer/coverage prototype. The baseline exported one Evidence record (10,815 serialized bytes) and zero registered unknowns; the prototype exported 201 records (100 xrefs sources, 100 separately resolvable, address-specific questions and the trace; 541,474 serialized bytes) and returned 100 coverage questions. The successful response sizes were 22,569 and 56,033 serialized MCP bytes respectively. Both runs used the same binary and Kuna 1.988; its SHA-256 460e69c94aa8cbbdc736458987172086916253f7f62b1637c7b3ab4f3bd06e6c was unchanged.

This demonstrates successful handling at this fixture size and a source-retention/presentation growth tradeoff; it does not establish normal-capacity exhaustion, token cost, a performance benchmark, or a safe upper limit. The questions refer to distinct target addresses and must remain independently resolvable; a smaller presentation must not discard their identities or provenance. Full-profile, larger corpus and recovery behavior were not exercised in this control.

Current-main prototype: 3,000 stored-pointer slots

On REA ce9095d72, I rebased the earlier unmerged pointer/coverage experiment in an isolated temporary worktree (one workflow return-type conflict resolved for the experiment). With real Kuna 1.988 and compact stdio MCP on the same source-built, unexecuted arm64 Mach-O containing 3,000 stored pointer slots to one matched target, the experimental trace_feature returned 3,000 references and 3,001 residual questions: one pointer-coverage question and one unavailable-containment question per slot. Its exported bundle had 3,003 records and 3,001 unknowns (10,062,729 serialized bytes); the successful MCP response serialized to 1,982,305 bytes. Each source address remained distinct. The same workflow on unmodified ce9095d72 returned no references and no questions, with one bundle record (3,898 bytes) and a 7,547-byte MCP response. Both runs used the same unchanged target and fresh temporary caches; no target was executed.

The baseline omits real provider observations and is not a correctness alternative. The prototype retains them but treats every stored-pointer slot as a source requiring a separate containing-procedure lookup, even though Kuna does not offer that operation. Consider a bounded, task-oriented presentation that makes provider-reported pointer observations and per-address identity available without conflating them with instruction owners or discarding independently resolvable questions. These are serialized byte counts for different outputs, not model token counts, equivalent-work performance benchmarks, or evidence of normal-capacity failure; this control covers one fixture, macOS arm64 and one schema profile.

Direct xrefs source record at the MCP response boundary

On the isolated unmerged pointer/coverage prototype based on ce9095d72, I exercised direct xrefs against two source-built arm64 Mach-O fixtures with 20,000 and 24,000 relocation-backed slots for _audit_target, using real Kuna 1.988 and compact stdio MCP on macOS arm64. The targets were not executed. At 20,000 slots, xrefs returned all 20,000 addresses; the SDK-serialized response was 9,965,171 bytes, and exact get_evidence_bundle(detail: records, limit: 1) succeeded at 9,966,345 bytes. At 24,000 slots, xrefs completed but returned resource_constraint at the default 10 MiB response budget with the retained Evidence ID. Summary lookup found that ID; exact record retrieval also exceeded the response budget, and inspect_analysis_view rejected the xrefs parent as unsupported. export_evidence_bundle succeeded, and its 5,572,550-byte file contained all 24,000 addresses and all 24,000 typed pointer rows in the retained xrefs Evidence. The target's SHA-256 was unchanged (3e15b3d7c8ff848d4399d2f9ab27f09269efca437a72706be8070968cb410016).

These are stress fixtures and a non-shipped prototype, not a claim that current main returns pointer rows or that this volume is typical. The SDK serialized sizes include text and structured response forms, not model tokens or independent benchmarks. Export is a working full-data recovery; there is no tested bounded MCP view of this source record. A production fix should consider direct xrefs source-row selection and pagination, not only the composed trace_feature pages in #8585, while preserving the exact parent identity, row kind, distinct entries, target filtering, coverage and complete export. Other profiles, platforms, allocation bounds and cancellation at this size remain unverified.

Paged address recovery experiment

Draft #8591 extends the existing native-observation view to retained xrefs address lists. In fresh target-free full and compact MCP sessions, it paged an exported 24,000-row Evidence record from the unmerged pointer prototype, reconstructing all addresses with their original indices and parent ID. The record's raw typed pointer rows remained in the complete bundle; the pages contain untyped normalized addresses.

In a separate temporary combination of #8591 with that unmerged pointer prototype, real Kuna 1.988 hit the default MCP response budget on the same source-built 24,000-slot Mach-O. Following the returned continuation and subsequent pages recovered all 24,000 addresses in 25 calls; the target SHA-256 3e15b3d7c8ff848d4399d2f9ab27f09269efca437a72706be8070968cb410016 stayed unchanged and it was not executed. This validates one bounded address handoff, not typed-pointer paging or the pointer fix itself. Real Ghidra and current Kuna controls on the smaller pointer-only Mach-O matched their respective unpaged xrefs; current Kuna still omitted the pointer.

Procedure ownership is separate from pointer provenance

On the pointer-only Mach-O above, I compared real Ghidra 12.1.4 and Kuna 1.988 through compact stdio MCP in the unmerged pointer prototype based on ce9095d72. Both traces included the slot 0x100004000 as a reference to 0x1000003c0. Ghidra's resolve_containing_procedure returned found: false, reason: not_in_procedure for that slot. Kuna returned capability_unavailable for the same operation, and the trace preserved status: unavailable with a residual question for that address. dyld_info -fixups independently showed the slot-to-target rebase and nm placed the slot in __DATA,__data; the target hash remained unchanged and it was not executed.

The pointer producer's kind and the provider's ability to establish a containing procedure are distinct facts. Do not translate Kuna's unsupported ownership lookup into Ghidra's not_in_procedure result, or infer that every pointer location lacks executable interpretation. For large pointer sets, the task-oriented design should preserve each slot and its source kind while avoiding thousands of redundant provider-wide capability failures; any omitted ownership lookup must remain explicitly unexamined or unavailable. This is a single controlled fixture, not cross-provider equivalence or runtime-use evidence.

Capability scope needed for shared-workflow recovery

In the same real compact MCP sessions, binary_session(detail: complete) exposed resolve_containing_procedure as unavailable with reason: provider_missing for the selected Kuna route; the selected Ghidra route advertised it available. The workflow's AnalysisOperationPort currently exposes execution, not that route capability fact. At the execution boundary, an undeclared operation and a provider-returned, address-specific inability both use AnalysisCapabilityUnavailableError without a typed scope; its reason is display text, not a safe cache key.

The existing public MCP regression preserves references and explicitly unknown owners without claiming truncation demonstrates the counterexample: one address produces that error while a second resolves successfully. On current d3ab0faf5, all 23 enhancedTools.traceFeatureCoverage.test.ts tests passed. A shared workflow must therefore not treat the first generic failure as proof that every address is unavailable. Consider passing a binding-owned capability observation with its lifetime or introducing an explicit scoped outcome at the producing boundary, then preserving each address's unknown status and the existing cancellation/cleanup behavior. No performance measurement or implementation is claimed here.

The repeated resolve_containing_procedure requests in the prototype are rejected by REA's session capability router before dispatch to the Kuna process; they are not 3,000 Kuna subprocess requests. Source inspection shows the larger retained-state growth arises because trace_feature creates one address-specific residual string per failure and recordWorkflowUnknowns registers each as a distinct unknown. The draft #8585 summary and page views reduce what is delivered per call but do not avoid constructing or retaining those records. A scoped capability outcome alone would not solve that representation problem. Any grouped or lazy representation needs to retain independently addressable per-slot questions and be checked through export/import, resolution, failure and cancellation, rather than dropping distinct unknowns. This identifies code paths, not a CPU or memory profile.

Experimental stored-pointer Evidence pages

An unmerged combination of the pointer producer, #8591 address paging and the typed-source experiment in #8348 adds separate provider-attributed instruction and stored-pointer pages for a linked xrefs source. In real Kuna 1.988 full and compact MCP on the existing unexecuted mixed Mach-O, trace_feature returned the instruction site 0x10000042c and pointer slot 0x100004008. Following its linked source, the instruction page reported the call and owner; the pointer page reported the slot, width 8, target and chained-fixups provenance. Both pages validated against their fetched schemas and survived export/import into fresh target-free sessions. Target SHA-256 9fc02faea0c3723a094c209adbe62a279011df4d508298625bd766fa20ed7c46 remained unchanged. No runtime call or pointer use is inferred.

On the separate static ELF control, direct Kuna reports data_refs_coverage: none. Both real MCP profiles returned a stored-pointer page with zero recorded rows, enumeration.status: not-enumerated and an explicit statement that this does not establish absence. This distinguishes unenumerated pointer coverage from an observed empty list.

On the source-built 24,000-slot Mach-O, direct Kuna reported 24,000 chained-fixup pointers. The experimental byte-limited view reconstructed all 24,000 rows, names, widths and provenance in four pages in compact live MCP and a fresh full-profile offline session; each page validated against the fetched schema. The target SHA-256 3e15b3d7c8ff848d4399d2f9ab27f09269efca437a72706be8070968cb410016 was unchanged. An earlier variant kept both raw pointer rows and the new normalized rows: the full reply exceeded 10 MiB and the bundle after paging was 12,193,915 bytes. Removing the duplicate representation left the same tested normalized rows, a 6,965,767-byte SDK-serialized complete reply and a 6,961,886-byte bundle after paging. These are sizes for one stress fixture, not token, time, CPU or memory benchmarks; original raw output remains represented by its truthful digest, not retained verbatim.

Synthetic public-boundary controls rejected an unrelated operation, mismatched target and source absent from the parent address list, and preserved two distinct recorded pointer observations at the same address across pages. These controls do not prove the real provider emits such collisions. This remains a design prototype: generic raw-result exposure, source ownership and target admission, large-row resource accounting, cross-provider meaning, repeated per-slot unknowns, source-publication failure, cleanup/cancellation and other hosts are not resolved. See #8348 for instruction-page controls and open design constraints.

A follow-up unmerged UX probe adds guidance to trace_feature only when its linked xrefs sources record typed observations. In real Kuna 1.988 full and compact MCP on the same mixed Mach-O, the trace named the instruction-references and stored-pointers native-context facets; following its linked source produced the separately typed call and pointer pages, and both remained accessible after export/import into a fresh target-free session. A real older baseline xrefs record without stored-pointer metadata returned invalid_request saying the observations were not recorded, rather than an empty pointer inventory. This is a scripted public-tool handoff, not an autonomous-agent selection or token-cost experiment. It does not resolve the existing per-reference unknown retention, source-publication, lifecycle or cross-provider design questions.

Kuna 1.989 upgrade control

On combined upgrade PR #8699 head f8f496f8a, real Kuna 1.989 on macOS arm64, direct xrefs --to 0x1000003c0 --json still reported zero instruction rows and one chained-fixups pointer from 0x100004000 to _audit_target. Independent xcrun dyld_info -fixups reported the same rebase. In both compact and full stdio MCP profiles, REA xrefs returned [] with examined_rows: 0; trace_feature returned the matching function and no references with truncated: false and no residual unknowns. REA retained the raw-output digest and the general limitation that an empty xref result does not prove absence, but did not expose the provider-returned pointer. The source-owned target SHA-256 22c604d669ebd4e32be8d1f5c820ecbe9f28b1101dcb8da4b399acea355f21a9 was unchanged and the target was not executed. This confirms the issue on one fixture, not general coverage or real-world frequency; the version bump alone is not a fix.

Typed-source prototype with Kuna 1.989

On the existing unmerged typed-source/pointer paging experiment in /tmp/rea-xrefs-pointer-combined (base ce9095d72 with local experimental edits), real Kuna 1.989 full and compact stdio MCP traced the owned mixed Mach-O. The trace retained a link to the xrefs source; the source's instruction-reference page identified the call at 0x10000042c, and its stored-pointer page separately identified 0x100004008 with width 8 and chained-fixups provenance. The pointer pages were exactly equal as parsed JSON after exporting the Evidence bundle and importing it into a fresh target-free session in each profile. The source-owned target SHA-256 9fc02faea0c3723a094c209adbe62a279011df4d508298625bd766fa20ed7c46 was unchanged and it was not executed.

This is an experimental integration checkout, not a patch in #8699 or a release. The trace still reports unavailable containing-procedure questions for both the instruction and pointer sites, and the resource/accounting, source-publication, coverage, lifecycle and cross-provider questions above remain. The control demonstrates one typed-provenance handoff with the newer release, not general completeness or autonomous-agent selection.

Synthetic overlapping-source trace control

Using the same unmerged typed-source experiment and real Kuna 1.989 behind a temporary test-only wrapper, I changed one returned pointer row's source address to coincide with the returned instruction-call source 0x10000042c. The wrapper deliberately fabricated this overlap; it is not an assertion that Kuna or the artifact reported such a pointer. In both compact and full stdio MCP, trace_feature normalized the address to one reference and reported one unavailable-containment question, while the linked source's separate pages retained both the call row (including Kuna's reported function owner) and the synthetic pointer row. The pointer page survived Evidence export/import exactly as parsed JSON; the original target hash stayed unchanged.

This control rules out a simple rule that skips function ownership merely because an address has a pointer observation: the same normalized address can carry an instruction observation as well. It also shows why the instruction row's provider-reported owner and a separate containment lookup must retain their own provenance; an address-level projection alone cannot select the right interpretation. Resource bounds and independently resolvable unknowns remain open; no proposed production behavior or real-world overlap frequency is implied.

Released Kuna 1.989 and current REA control

On REA main 9ebbe67e, macOS arm64, I rebuilt the pointer-only fixture above as an owned, unexecuted Mach-O (SHA-256 40b175907eb9e8f57e02ce166c99ad810f2a09ee6cfaa2c26b8d1f2b0bb94938). nm placed _audit_target at 0x1000003c0 and _audit_func_ptr at 0x100004000; dyld_info -fixups independently reported a rebase from that slot to the target.

Direct released Kuna 1.989 xrefs --to _audit_target --json returned zero instruction rows and one 8-byte pointer under data_refs, with data_refs_coverage: chained-fixups. Real REA/Kuna stdio MCP returned an empty xrefs array and a trace with no references, truncated: false, and no residual unknowns in both compact and full profiles. Its xrefs Evidence retained the output digest, byte count and zero examined instruction rows, plus a generic warning that an empty result does not prove absence; it did not report the pointer or the producer's pointer-coverage facts. REA/Ghidra 12.1.4 on the same target returned the pointer slot and another source address; the trace classified the pointer slot as outside a procedure. All calls used fetched SDK tool definitions. The target hash remained unchanged.

This confirms the existing omission with the released default Kuna version on one fixture, not general provider completeness or runtime pointer use. The upstream data_refs and instruction xrefs remain separate categories and need separate provenance/coverage; simply relabeling the stored pointer as a call would be incorrect.

Existing native metadata tool control

On REA main 9ebbe67e with the released Kuna 1.989 and the pointer-only Mach-O in the preceding control, I called inspect_native_dispatch_metadata through real stdio MCP in both schema profiles. It reported pointer_fixups coverage complete, with one examined and one decoded chained-fixup format (DYLD_CHAINED_PTR_64_OFFSET), but its result contained neither the pointer slot 0x100004000 nor the target 0x1000003c0. Objective-C classes, Swift declarations, and relative pointers were empty for this fixture. The target hash remained unchanged.

Source inspection shows that the dispatch reader uses the existing fixup decoder to resolve pointer addresses it encounters while reading metadata. This control does not establish general fixup completeness or show that the metadata tool enumerates incoming references; it is not a workaround for this fixture's omitted xref. The existing decoder may be useful in a future design, but the caller's question, coverage, and pointer provenance still need explicit handling.

Ghidra fallback and offline handoff

On main 9ebbe67e with the released Ghidra 12.1.4, I separately requested xrefs and trace_feature for the pointer-only fixture above, exported the session bundle, and imported it into a fresh MCP server with no binary open. Both retained records exactly matched the original results in compact and full profiles. The xrefs result and trace included slot 0x100004000; the trace classified it as outside a procedure. The direct xrefs record's raw_result was null, and the trace had no Evidence links: these outputs preserve the source address but do not themselves identify it as a stored pointer or link the independently requested xrefs record. dyld_info independently established the slot's rebase in the prior control; this handoff alone does not prove pointer kind or runtime use. The fixture remained unexecuted and SHA-256 40b175907eb9e8f57e02ce166c99ad810f2a09ee6cfaa2c26b8d1f2b0bb94938 stayed unchanged. This is one Ghidra fallback control, not general coverage.

Existing typed Ghidra handoff

A follow-up real Ghidra 12.1.4 control on the same fixture called inspect_native_instruction at _audit_target (0x1000003c0) before exporting. In both MCP profiles, its incoming_references reported the slot 0x100004000 as type: DATA, data: true, call: false, with ghidra-reference-manager provenance. The entire instruction Evidence record survived export/import unchanged in a fresh server with no binary open. This is a more informative existing Ghidra workflow than the address-only xrefs/trace results described immediately above. The instruction record does not itself name the Mach-O chained-fixup mechanism; the independently observed dyld_info rebase provides that separate fact. The trace did not link the separately requested instruction record. The fixture was not executed and its SHA-256 remained 40b175907eb9e8f57e02ce166c99ad810f2a09ee6cfaa2c26b8d1f2b0bb94938.

Released Kuna fixture with a call and stored pointer

A separate control used Kuna's public macho_ptrslots_offset_arm64 fixture at v1.989 (local SHA-256 cd5265aed04ecf2f3d125782892ebdf6eb66ea80c3f783fb3f99fe3a74b6f642). Direct Kuna 1.989 xrefs --to _audit_target --json reported one instruction call from 0x1000003e4 and one separate 8-byte stored-pointer row from 0x100004008, with data_refs_coverage: chained-fixups. Real REA/Kuna xrefs in compact and full MCP profiles returned only 0x1000003e4; its raw metadata counted the one instruction row and did not report the pointer row or coverage. Real REA/Ghidra 12.1.4 reported the pointer source as a DATA reference alongside other references. The public fixture was never executed and its digest remained unchanged.

The Kuna v1.989 xrefs implementation describes instruction and stored-pointer rows as separate collections and says data_refs_coverage: none means the image lists no pointer relocations, not that no pointers exist. Preserving that distinction and the coverage source is necessary for an honest task-level result; no runtime call is implied by a stored pointer.

Kuna 1.990 verification branch control

On the REA 1.990 validation branch 187f3d8cc, macOS arm64, a newly built unexecuted arm64 Mach-O had _audit_target at 0x1000003c0 and _audit_func_ptr at 0x100004000; dyld_info -fixups independently reported that slot's rebase to the function. Direct Kuna 1.990 xrefs --to 0x1000003c0 --json returned no instruction rows and one 8-byte pointer row from the slot with data_refs_coverage: chained-fixups. In both compact and full public MCP profiles, REA/Kuna xrefs returned an empty normalized array, counted zero examined instruction rows in the source digest metadata, and omitted the pointer and coverage facts. trace_feature returned the procedure but no references, truncated: false, and no residual unknowns. The target SHA-256 496e188170232c15f1ceeebf33165f060c6a31b46be9571b6f49778ef0e8d910 stayed unchanged. This confirms the issue persists with the proposed verified Kuna release on one fixture; it does not establish a runtime call or provider-wide completeness.

Explicit Ghidra handoff on the 1.990 fixture

In separate compact and full real MCP sessions on the 1.990 validation branch, I requested Kuna xrefs on the preceding pointer-only fixture, explicitly reopened the same target with Ghidra 12.1.4, and called inspect_native_instruction at 0x1000003c0. Ghidra's incoming-reference observation identified 0x100004000 as DATA, data: true, call: false, with ghidra-reference-manager provenance. The complete retained bundle still contained the original empty Kuna xrefs Evidence unchanged after the switch. The fixture hash remained unchanged. This is an explicit provider handoff on one host; the typed Ghidra observation does not itself identify the chained-fixup mechanism or prove runtime use, and the earlier dyld_info observation is separate.

Direction of the stored-pointer question

On the same owned 1.990 pointer fixture, direct Kuna xrefs --from 0x100004000 --json reported one 8-byte chained-fixups pointer from that slot to 0x1000003c0; its instruction coverage explicitly said the slot was non-executable and not decoded. In compact and full public MCP profiles, REA xrefs at the slot returned an empty incoming-reference result; its contract and analysis profile explicitly say it searches to the address, so this is not an incorrect answer to an outgoing query. The same sessions reported inspect_native_data_type unavailable from Kuna. The fixture was not executed and its SHA-256 remained 496e188170232c15f1ceeebf33165f060c6a31b46be9571b6f49778ef0e8d910.

This suggests a separate analyst question—what address does this stored slot refer to?—rather than treating an incoming-only result as an outgoing answer. Consider whether an existing task-level data inspection workflow can answer it with typed provenance and coverage before adding a directional API; this single fixture does not establish that no alternative exists or that a generic --from wrapper is appropriate.

Existing Ghidra slot inspection

For the same fixture, real Ghidra 12.1.4 through both MCP profiles reported a defined 8-byte pointer at 0x100004000 via inspect_native_data_type, but did not report its value or referenced type. inspect_native_instruction classified the slot as data and returned incoming references to the slot, while its outgoing references array was empty. read_bytes returned c003000001000000, explicitly described as initialized Ghidra memory including loader fixups; interpreted as little-endian 64-bit, that is 0x1000003c0. Independently, llvm-objdump --macho --full-contents --section=__data showed the shipped bytes c003000000000000, which differ from the loaded representation. The fixture SHA-256 was unchanged and it was not executed.

This provides a manual, fixture-specific path using type, byte order, and loaded bytes, but those bytes alone should not be reported as an independently established source-file pointer or runtime use. It also illustrates why a candidate workflow should preserve the origin of a decoded pointer and distinguish original artifact bytes from loader-resolved memory. It does not establish behavior for other fixup kinds or pointer formats.

Ghidra reference-manager producer boundary

A separate direct Ghidra 12.1.4 headless import and analysis of that fixture, using a short post-script calling currentProgram.getReferenceManager().getReferencesFrom(toAddr("100004000")), reported a DATA reference from 0x100004000 to 0x1000003c0 with Ghidra source DEFAULT. The temporary project was deleted. This is a Ghidra analysis observation, not proof of the original fixup mechanism or runtime use.

REA's bridge source populates inspect_native_instruction.references from instruction.getReferencesFrom() only in the decoded-instruction branch; defined data takes the non-instruction branch, leaving that array empty. Thus the preceding empty array is a projection limitation for this fixture, not an absence of a Ghidra ReferenceManager observation. The current field is described as outgoing instruction references, so changing its semantics requires a deliberate contract decision: distinguish references from a data code unit, preserve their provider/source metadata, and avoid implying every empty instruction-reference list exhausts data references.

Interior-address control

On the same fixture, direct Ghidra headless getDefinedDataContaining reported that 0x100004001 and 0x100004007 belong to the 8-byte item beginning at 0x100004000; ReferenceManager.getReferencesFrom reported the pointer reference at the start address, but none at either interior address. Through real REA/Ghidra MCP in both profiles, inspect_native_instruction at 0x100004001 reported status: data with empty references, while inspect_native_data_type returned unavailable with the explicit reason that no exact typed-data identity exists there. The target hash remained unchanged.

Any future data-reference workflow must define whether it answers at the exact address or expands to a containing item, and disclose the actual source address if it does the latter. An empty exact-address query at an interior byte is not evidence that its containing data item has no reference. This is one simple pointer item, not a general test of composites or overlapping data.

Direct Kuna kind-filter control

On the owned pointer fixture with Kuna 1.990, xrefs --to 0x1000003c0 --kind pointer --json returned the chained-fixup pointer row; --kind call returned zero pointer rows while still reporting data_refs_coverage: chained-fixups. The unfiltered control above returned the pointer. This is expected filter behavior on one fixture: the coverage label identifies the metadata source, not proof that an empty filtered pointer list exhausts all reference kinds. Any retained or projected filtered observation should keep its selected kind alongside source coverage and avoid converting filter exclusion into absence.

Relocation-source label is not proof that records were read

An additional owned x86-64 ELF control has one R_X86_64_RELATIVE pointer at 0x33c0 to 0x1310. A malformed copy changes only the relocation section's symbol-table link to nonexistent index 999; llvm-readelf reports that the section's symbol table cannot be located. Direct Kuna 1.990 reports dynamic-relocations for both files, but emits one pointer only for the intact file. An unmerged REA pointer-reference prototype returned the intact pointer and an empty xrefs array for the copy in both MCP profiles; both source records retained the same dynamic-relocations label, and the existing generic caveat remained. The files were not executed and their SHA-256 values remained 112844ea2afd19308af073bb78e9ca60e3797c5114d37db4bbe27c50ce4db11b and afb8b300a1a24a5a643850b07aa3dd9037d9565ba504d0276ed04a3a0579ef62.

A provider's metadata-source label must not be promoted to successful or complete coverage. This example is a deliberately malformed input, not a general failure-rate measurement. Upstream report: https://github.com/Noelo-Lab/kuna/issues/1502.

Exact-address pointer and forwarding-alias control

A source-built x86-64 ELF fixture contains an indirect forwarding veneer at 0x13a0, its slot at 0x3460, a stored pointer at 0x3468 to the veneer, and another at 0x3470 to the slot. Direct Kuna 1.990 xrefs --to 0x13a0 reports the slot as an alias and emits both pointer rows. In the local unmerged REA prototype, compact/full MCP xrefs returns only 0x3468 for the selected exact target; its retained raw source keeps both rows and reports two examined rows, one excluded alias row. An earlier prototype counted only instruction rows and would have shown zero examined/excluded; the experimental fix counts both categories. This does not imply the alias-targeting pointer is an exact reference to the veneer. The fixture was not executed and SHA-256 967b95de168d4c41f039449e6e379a05c1e1ded75ce3427b6359a21f22655a83 was unchanged.

The unmerged parser prototype also has production-boundary controls for numeric pointer and unwalked-source addresses above JavaScript's safe-integer range, preserving their exact u64 values; an unreported pointer inventory remains distinct from an explicitly empty one, and incomplete or inconsistent pointer counts are rejected. These use synthetic Kuna-shaped JSON rather than a real large-address binary. The issue's real-provider controls above establish behavior only for their tested addresses and fixtures.

Real full-width address control

An owned, unexecuted x86-64 ELF shared object was linked with image base 0x20000000000000. Its dynamic relocation stores a pointer from 0x200000000033c0 to the odd address 0x20000000001311, one byte into audit_target; llvm-readelf -r -s independently reports the relocation and addend. Direct Kuna 1.990 returned that pointer, including decimal address tokens beyond JavaScript's exact integer range. The unmerged REA prototype's xrefs returned the exact source and retained both addresses and dynamic-relocations provenance without rounding in compact and full MCP profiles. SHA-256 058eee606b8b0c5965cd5f1a7d2fc9b8fa2a48680f8a5577ab7849749668856a was unchanged. This intentionally unusual address tests static parsing and is not a claim the image is runnable.

On the same fixture, prototype trace_feature("audit_target") matched the procedure entry 0x20000000001310 and returned no references because its xrefs query targets that exact entry, not the interior destination 0x20000000001311. The direct interior xrefs query above did find the pointer. The existing exact-address limitation remains; a procedure-body workflow must define its bounds and coverage rather than treating a reference to an interior byte as an entry reference. See #8569 and #8184.

Current draft large-result recovery

Real Kuna 1.990 with draft #8851 411f02d21 returned a complete direct xrefs for an unexecuted 24,000-slot fixture in both schema profiles. A separate 40,000-slot fixture exceeded the MCP response budget in both profiles; the error returned a retained Evidence ID and continuation. Paging the existing native-observation view recovered all 40,000 distinct source addresses, while exact full-record delivery also exceeded the budget. The supplied first-page continuation was exercised in compact mode. Complete export retained all 40,000 typed pointer rows; the exported bundle after paging was 8,683,464 bytes. The address pages do not expose pointer provenance, so at this size those details require export. Both fixture hashes were unchanged: 1abaca97f961d39b4b3b5ec2e7ff5c26872c4952ad0f91cb780a207c8933c50f and a7aa0b539a8da618137ad4a7257ce14622ec0123f1f8f1706d5b5ccb968e0e52. These are controlled stress cases, not prevalence, token, latency or peak-memory measurements.

Normalized linked-source paging probe

A separate unmerged probe moved typed stored-pointer observations from the xrefs raw-result payload into a linked, provider-attributed normalized source Evidence record and used the existing native-observation view to page that record. With real Kuna 1.990 and the 40,000-slot fixture above, both MCP profiles returned all 40,000 pointer rows in 40 pages; a fresh target-free session without Kuna recovered sampled pages after bundle import. The direct xrefs response with its linked source ID fit the MCP limit. After paging, the bundle was 14,246,696 bytes, including 6,161,750 serialized bytes for the typed source and 7,521,945 for the 40 retained page Evidence records. This does not establish token, latency or memory costs, and the target hash stayed unchanged.

This probes a way to expose typed facts without embedding them twice in the parent. It is not integrated: source construction and admission, alias provenance, partial publication, view-byte bounds, cancellation, and the cost of retaining page Evidence need further work. #8851 does not contain this probe.

Linked-source admission and recovery controls

The unmerged typed-source probe was combined locally with #8444 and the current #8851 alias changes. On a real Kuna 1.990 forwarding-alias fixture, both MCP profiles retained the alias name and address and paged two pointer rows with their distinct destinations; only the direct pointer appeared in the exact-address xrefs result.

With a deliberately injected zero-byte retained-representation allowance, a one-pointer fixture returned the typed source and completed xrefs as unretained observations, linked by ID, in both profiles; no records were retained. On the 40,000-pointer fixture, the corresponding error returned both complete observations inline (about 6.7 MB of JSON), with source closure explicitly not established. A 1 MB retained allowance succeeded for the one-pointer control. These limits were injected, not measurements of default operation.

A separate injected zero authentication-headroom control refused publication with resource_constraint and an explicit completed-observation omission in both profiles. Source inspection shows that this experimental producer constructs and hashes the large typed Evidence before that refusal. No actual out-of-memory condition was induced; nevertheless this ordering means the control does not establish safe behavior under genuinely low heap. Admission must precede constructing expanded Evidence, and the session must own the resulting publication and recovery semantics. The typed-source probe is not in #8851. Target hashes were unchanged.

Current draft creates Evidence before authentication admission

This is not limited to the separate typed-paging probe. On draft #8851 head da842598b, a production stdio MCP session with real Kuna 1.990 analyzed the owned 40,000-slot fixture in both profiles. An instrumented InvestigationRecords.recordEvidence boundary received a fully identified xrefs Evidence record containing all 40,000 raw pointer rows before its deliberately injected availableAuthenticationBytes: () => 0 policy refused authentication. Both callers received resource_constraint; no records were retained and the target hash was unchanged. The reported 128,040,224 authentication bytes are the policy's estimate, not measured peak memory. No real OOM was induced.

The session creates createAnalysisExecutionEvidence before calling recordEvidence, while the latter performs the headroom check. A fix needs to admit the borrowed observation and its expanded Evidence representation at the session-owned boundary before construction, and preserve truthful recovery/omission and source links if admission fails. The existing #8444 recovery complements that ordering; it does not by itself prove preconstruction admission. This is a merge-readiness issue for #8851, not an upstream Kuna defect.

Session admission prototype

A separate unmerged integration of #8851 and #8444 constructs a borrowed Evidence envelope from the same observation fields used by commitment and asks the owning session to admit it before creating the session-generated Evidence. With the 40,000-pointer Kuna 1.990 fixture and injected zero authentication headroom, both MCP profiles reported an explicit insufficient-authentication-headroom omission and an instrumented record boundary was never called. This shows the session-generated xrefs Evidence was not committed or passed to the ledger; the provider's parsed result already existed. With normal headroom and injected zero retained capacity, #8444 returned an unretained observation for the small and 40,000-pointer controls; a 1 MB allowance retained the small result in both profiles. The targets were not executed and their hashes were unchanged. check:fast and four focused suites passed (59 tests).

This is an exploratory local change, not part of #8851: it needs a dedicated regression for preconstruction admission, accounting and coverage for providers that already construct sourceEvidence themselves, cancellation/cleanup and broader provider validation. The admission estimator is not a process-memory guarantee, and this injected policy did not induce OOM.

A new isolated public-MCP regression now runs a profiled provider in both schema profiles with injected zero authentication headroom. It checks that the provider completed, that createAnalysisExecutionEvidence and the ledger recorder were not called, and that the error identifies the omitted completed observation. On the unmodified combined baseline both cases fail because Evidence construction was called; with the prototype both pass. The focused suite and an existing batch cleanup control passed (7 tests), and check:fast passed before the final test-only instrumentation adjustment. This does not prove cancellation during this specific admission stage. The Ghidra project-history path can supply source Evidence constructed before session publication, so that separate path is not covered by this prototype; source inspection alone has not established a large-record failure there.

A real Ghidra 12.1.4/JDK 21 stdio MCP control on the admission prototype recovered an address_name result as unretained Evidence under an injected zero retained allowance and retained it under a 100 KB allowance, in both profiles. Separately, an instrumented workflow attached a synthetic source Evidence record to real Ghidra xrefs output: zero retained allowance returned the source and completed trace as linked, unretained Evidence with source closure not established; a 1 MB allowance completed in both profiles. The target was not executed and its SHA-256 (8a0d4927e1d89dc4aca4c87c0c3ba1bac78c99c0d62df37930598f859485dbcc) remained unchanged. These are cross-provider recovery controls, not a real saved-project history test or proof of preconstruction admission for provider-created source records. After the latest regression instrumentation, check:fast passed.

Typed paging, CLI portability and cost

A separate local prototype deferred construction of linked typed-pointer Evidence until the session admitted it. On the real 40,000-pointer Kuna fixture it paged all typed rows in both MCP profiles; zero-headroom controls refused before source recording, and zero retained capacity returned unretained source/primary when the response budget allowed. This source-only shape broke default one-shot xrefs: the CLI returned a link to the closed session without the pointer details. The same general one-shot closure gap also reproduces with an existing Ghidra project; see #8590.

Keeping pointer rows in the primary raw Evidence as well as a linked pageable record restored the real one-shot CLI facts. Both MCP profiles then followed overflow recovery through parent address pages, retained-link discovery and 40 typed pages; the exported bundle after paging was 20,406,827 bytes. At injected zero retained capacity the 40,000-pointer error returned the completed parent with its raw pointer rows but explicitly omitted the separate source at the MCP response limit. On a 24,000-pointer real Kuna task, three alternating runs per variant gave median first/repeated calls of 723/339 ms for the current combined baseline versus 1,044/581 ms with the duplicated pageable index; median full-process elapsed was 2.19/2.78 s. Sampled summed process-family peak RSS was 1,254,400/1,391,568 KiB and sampled CPU lower bounds were 2.87/3.64 s. Raw address and pointer-array hashes agreed. This is a small host-specific comparison; shared RSS pages may be counted twice, token use was not measured, and no target was executed or modified.

The duplicate-index prototype is not in #8851. It imposes substantial measured cost on this fixture, while a source-only shape leaves default CLI evidence incomplete. A shared portable one-shot source handoff or another nonduplicating normalized representation needs design before typed paging is integrated. A single synthetic 6 MB source-name row also exceeded the MCP response budget even at page size 1; the error retained the view and offered export, but this is not a claim about real Kuna name frequency.

Parent raw-row projection feasibility

On the combined #8444/#8851 checkout, the real Kuna 1.990 one-shot CLI returned 40,000 pointer rows in the parent Evidence's raw_result.references.pointers. A standalone JavaScript probe sliced that already-parsed array into 40 pages of 1,000; rejoining them gave the same SHA-256 (4de84cdddc6a1cc69977918fa0a3b4b2ddae86163bfcecbf428e3c1bf92a9711), and page elements referenced the same objects in memory. The parent JSON was 6,722,606 bytes and the first pointer page was 154,013 bytes. The unexecuted target digest remained a7aa0b539a8da618137ad4a7257ce14622ec0123f1f8f1706d5b5ccb968e0e52.

This is a local data-access probe, not an REA view or MCP measurement. It suggests that paging the existing parent could avoid retaining a second source record, but does not settle provider-format ownership, discoverability, byte-bounded pages, page Evidence costs, or offline contract validation. An agent-facing design must preserve the raw values and caveats without silently interpreting Kuna-specific fields in the shared domain.

An unmerged generic raw-array view on the combined checkout retrieved the same 40,000 rows from the parent in 40 real Kuna MCP pages in both schema profiles; an invalid path returned invalid_request. Export after paging was 12,960,646 bytes. Import into a fresh MCP session without Kuna reproduced three sampled pages in both profiles; bundle and target hashes stayed unchanged. check:fast passed. This prototype requires callers to know a raw provider-specific path; its discovery, byte accounting, complete lifecycle, and typed semantics are not established, so it is not proposed for integration.

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8510 ### Before submitting - [x] I searched open and closed issues for a related report. - [x] I removed credentials and private target data. ### Area Native analysis or decompilation ### Observed behavior With Kuna 1.988, REA `xrefs` drops a relocation-backed pointer reference that the selected Kuna executable returned. `trace_feature` consequently returns zero references with `truncated: false` and no residual unknowns for the same target. The xrefs Evidence includes the raw response digest and an examined-row count of zero, but it does not expose or disclose the omitted pointer row. Its general limitation says an empty result does not prove absence. ### Reproduction On macOS arm64, build this owned fixture with `clang -arch arm64 -O0 -g0 pointer-only.c -o pointer-only`; do not run it. ```c __attribute__((noinline, used)) int audit_target(int x) { return x + 11; } int (*volatile audit_func_ptr)(int) = audit_target; int main(void) { return 0; } ``` For this build, `nm -nm pointer-only` reports `_audit_target` at `0x1000003c0` and `_audit_func_ptr` at `0x100004000`. Addresses are build-specific. 1. Direct Kuna 1.988 `kuna xrefs pointer-only --to 0x1000003c0 --json` reports zero instruction `xrefs`, but `data_refs_coverage: "chained-fixups"`, `data_refs_count: 1`, and a pointer from `0x100004000` to `0x1000003c0`. 2. On REA #8509 head `7f344af1a`, open the same target with Kuna and call `xrefs({"address":"0x1000003c0"})`: the normalized result is `[]`. `trace_feature({"query":"audit_target"})` finds the function but reports `references: []`, `truncated: false`, `residual_unknowns: []`. 3. Independent `dyld_info -fixups pointer-only` reports the rebase from `0x100004000` to `0x1000003c0`. REA/Ghidra 12.1.4 on the same file reports the pointer address among its xrefs; Ghidra also reports other references. Both full and compact advertised MCP schema profiles were exercised on Node 24.22.1, macOS arm64. The target SHA-256 `22c604d669ebd4e32be8d1f5c820ecbe9f28b1101dcb8da4b399acea355f21a9` was unchanged and the target was never executed. This is one generated static Mach-O, not a completeness or prevalence estimate. Kuna 1.986 on the same fixture also returned no REA references, but its direct result did not provide the new pointer rows. ### Expected behavior Define and preserve the distinction between instruction references and relocation-backed stored pointers. If `xrefs` includes pointer references, retain the source address and its provenance without treating a stored pointer as an executed instruction. If the existing contract intentionally excludes them, report their omission and coverage explicitly in both direct and composed answers; do not report their absence. Do not equate upstream `data_refs_coverage: none` with absence of stored pointers. ### Impact and scope An analyst seeking references to a function can miss a provider-observed callback/function-pointer slot. A general empty-result caveat remains, but it does not say that the provider returned a concrete row that REA discarded. No autonomous-agent behavior or runtime pointer use was tested. ### REA version `7f344af1aa0a78fd4e331dbbc9c30d38e4cfb796` (#8509); source-derived behavior also exists in its main base. ### Runtime and platform Node 24.22.1, macOS arm64, Kuna 1.988, Ghidra 12.1.4/JDK 21 control. ### Target and artifact context Self-built Mach-O arm64 executable; read-only static analysis, no target execution or mutation. ### Interface MCP ### Earliest failure stage Provider output parsing/projection ### Relevant output or evidence Direct Kuna: `xrefs: []`, `data_refs_count: 1`, pointer `0x100004000 → 0x1000003c0`, source `chained-fixups`. REA: `xrefs` normalized `[]`, raw source `examined_rows: 0`; `trace_feature` returned the matched function with no references, no truncation and no residual unknowns. Ghidra and `dyld_info` independently observed the pointer slot. ### Typed outcome or recovery expected Keep instruction and stored-pointer provenance distinct and preserve their applicable coverage. Test exact target/alias filtering, duplicates, missing versus empty metadata, malformed rows, bounded output, both MCP profiles, composed trace and offline Evidence. ### Analysis or suspected cause Source inspection: `xrefsDocument` in `KunaReferenceFiles.ts` parses `xrefs` but has no `data_refs` or `data_refs_coverage` fields; its default object parser strips those members. `parseKunaIncomingReferences` validates and counts only instruction rows and projects their addresses. The observed omission follows that producer boundary; no runtime instrumentation of the parser was added. ### Additional context Related #8348 concerns loss of kind and owner on instruction rows; #8190 concerns outgoing references. This report is specifically loss of a separately reported relocation-backed incoming pointer. Upstream 1.988 documents pointer rows separately and documents `none` as not enumerated. Do not infer that a stored pointer proves a runtime call. cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 ### Follow-up controls A separate x86-64 static ELF fixture has a slot at `0x202190` containing `0x201159`, the address of `initially_selected`, as confirmed by its ELF load mapping and bytes. Direct Kuna 1.988 reports `data_refs_coverage: "none"` and no data rows for that target. This is a concrete example of unenumerated pointer coverage, not a claim that Kuna promised to find this statically linked pointer. An unmerged producer prototype that includes Kuna-reported pointer addresses recovered both an instruction reference and a stored pointer in a mixed Mach-O fixture. However, a `trace_feature`-only Evidence export retained neither the underlying `xrefs` observation nor a link to it, leaving its source addresses untyped. The prototype also returned no references and no residual unknown for the ELF control. These are prototype observations, not fixes shipped in #8509; a complete design needs to propagate applicable coverage and retain enough source Evidence for composed answers without treating a stored pointer as an executed call. ### ELF and PE relocation controls An independently built, unexecuted x86-64 ELF shared object has `audit_target` at `0x1320` and pointer slot `0x33e0`; LLVM `readobj` reports `R_X86_64_RELATIVE` at the slot with addend `0x1320`. Direct Kuna 1.988 reports one pointer in `data_refs` with `data_refs_coverage: dynamic-relocations`; on #8509 head `7f344af1a`, real Kuna MCP `xrefs` and `trace_feature` omit it. REA/Ghidra 12.1.4 reports the corresponding DATA reference at its own rebased coordinates `0x1033e0 -> 0x101320`. An unmerged producer experiment recovered `0x33e0`, but the resulting trace still lacks a link to the source's pointer-kind observation; it is not a shipped fix. ELF SHA-256 `0df5b9c004412594fc976326144f9a8488ae089d91bc70c962c9f23e60f0b75e` stayed unchanged. For a separate x86-64 PE DLL, LLVM reports a `DIR64` base relocation at RVA `0x3000`; the stored 64-bit value points to `audit_target` RVA `0x1000`. Direct Kuna 1.988 reports that pointer with `base-relocations` coverage, and REA/Ghidra reports a DATA edge at `0x180003000 -> 0x180001000`. REA intentionally refuses the Kuna provider for PE (`target_format_unsupported`), so this is an upstream-format control, not a claim of an REA/Kuna PE regression. PE SHA-256 `73b336bb59c09db4b0a9df052b4a6face8222115f257c119567842998843f92d` stayed unchanged. Both fixtures were statically analyzed only. These cases do not establish general relocation or provider completeness. ### ELF preemption qualification A further x86-64 ELF fixture has a default-visible global `audit_target` and a pointer initialized using a symbol-based `R_X86_64_64 audit_target` relocation. Direct Kuna 1.988 reports a `dynamic-relocations` pointer row from `0x33f0` to the local symbol value `0x1340`; REA/Kuna currently omits it and REA/Ghidra reports a static DATA reference at rebased coordinates. Under the [ELF gABI](https://gabi.xinuos.com/elf.pdf), default-visible globals can be preempted, so this static row must not be presented as proof of the runtime-resolved target. A paired protected-visibility object uses an `R_X86_64_RELATIVE` relocation, but current `inspect_native_exports` drops the default/protected distinction; #8517 and draft #8519 address that separate observed-fact omission. The two fixture hashes were unchanged and no runtime linker or target was run. ### Exact-address PLT and slot control On the previously described default-visible ELF fixture (SHA-256 `741f17c72cea92c0316549c9733cdf77c528d890fde6231bdf4cc8ba325aa630`), direct Kuna 1.988 `xrefs --to` at the PLT stub `0x13b0` returns call `0x138e -> 0x13b0` and lists slot `0x3488` as an alias. Querying the slot itself returns the same call row whose actual destination remains `0x13b0`; querying the implementation `0x1370` returns a separate `data_refs` row `0x3488 -> 0x1370`. Querying the name groups all three. LLVM identifies the slot as `R_X86_64_JUMP_SLOT audit_target`; its runtime binding is not established by these static observations. On #8509 real compact MCP, exact-address `xrefs` returned `[0x138e]` for the PLT, `[]` for the slot, and `[]` for the implementation. The unmerged pointer prototype returned the same PLT and slot answers and `[0x3488]` for the implementation. This one control confirms why a fix must filter each row by its actual endpoint, not include every row in Kuna's alias class, while preserving the distinct relocation source and its binding limitation. It does not establish general alias or relocation coverage. The fixture was unexecuted and its digest stayed unchanged. ### Indirect-call handoff through a stored slot A source-built, unexecuted x86-64 ELF has `audit_target` at `0x1260`, a relocation-backed `audit_slot` at `0x3320` initialized to that function, and one instruction `call *audit_slot(%rip)` at `0x1266` (LLVM disassembly). Direct Kuna 1.988 reports a `pointer` row `0x3320 -> 0x1260` and separately a `call` row `0x1266 -> 0x3320`. On #8509 real compact MCP, `xrefs` of the target is empty while `xrefs` of the slot returns `0x1266`; the unmerged pointer prototype returns the slot for the target, allowing this second query. Its feature trace includes the slot but does not automatically traverse to the caller and does not retain the source pointer kind. Both baseline and prototype Kuna `trace_call_path` report `unknown` with indirect-target limitations. As a separate real Ghidra 12.1.4 control on the same image, rebased `inspect_native_instruction(0x101266)` reports a `READ` to slot `0x103320` and a `COMPUTED_CALL` candidate to target `0x101260`; its static call path reaches that candidate. These are provider-derived static observations, not proof of a runtime call or of the slot's value at execution. The two-step Kuna handoff demonstrates the analyst task and why the stored-pointer kind and source Evidence need to remain available; it does not imply the workflow should automatically traverse every pointer or equate the two providers' semantics. The ELF SHA-256 `fce58ca524039c732f734251c55378e6bc0ef09d40b1155235dba45933a4af8f` stayed unchanged; the target was never executed. One host and fixture, no autonomous-agent or completeness claim. ### Unmerged trace source-retention experiment An exploratory change to the earlier pointer parser retained each `xrefs` observation consumed by `trace_feature` as linked Evidence. On the pointer-only Mach-O, a real Kuna 1.988 compact MCP trace alone then exported one linked `xrefs` record whose raw source rows contained the pointer kind and `chained-fixups` origin. Importing that bundle into a fresh target-free server retained the trace and linked source identically in both MCP schema profiles. This does not add a typed pointer kind to the inline trace; the caller must follow the source link. On the separate 100-slot fixture, the previous address-only prototype returned 100 references and 100 independently resolvable owner unknowns, with a 101-record / 316,525-byte exported bundle. This experiment returned the same counts and unknowns with a 102-record / 342,152-byte bundle. These serialized bundle sizes are observations for one fixture, not token counts or performance benchmarks. The real CLI trace also returned a source link; when supplied an existing caller-selected `--snapshot`, the updated snapshot retained both the trace and linked pointer record. Without a selected snapshot, the CLI output observed here contains the link but no source record inline, and no durable source handoff was established. This is not a proposed finished fix: it retains every trace xref observation, so many matched targets can increase retained state and response work; capacity, cancellation, failed source publication, duplicate observations and bounded retrieval need design and testing. The `data_refs_coverage: none` case still needs an explicit composed coverage outcome, and both CLI/MCP call sites currently require coordinated changes. The experiment changes the trace workflow profile revision; it was exercised on one host and selected fixtures, not committed or shipped. All targets were unchanged and unexecuted. ### Controlled cancellation during source retention In the unmerged source-retention experiment, a test-owned Node wrapper forwarded commands to real Kuna 1.988 but paused the second `xrefs` request on a two-function Mach-O fixture. After the barrier was observed, cancelling the public compact MCP `trace_feature` call rejected the client request. The first completed `xrefs` Evidence remained in the session, no completed `trace_feature` record appeared, `binary_session` reported the target open with no pending cleanup, and a same-session exact xrefs retry succeeded. The paused wrapper PID was absent in bounded polling; that PID observation alone does not establish process-family identity. The target SHA-256 `9db44909124eb1356bd1715882912cd38802bf624e6aa5613b3867816836acdc` was unchanged and it was not executed. An earlier test wrapper used macOS platform shell/sleep, which produced `cleanup_incomplete` with `platform_binary_environment_withheld`; the test closed its connection before attempting the prescribed retry, and the test-owned process group was subsequently terminated manually. This is a limitation of that attempted control, not evidence of successful cleanup retry or a natural provider failure. The successful control uses an artificial barrier during active execution; final publication, late cleanup, cancellation timing, and other platforms remain unverified. ### Controlled cleanup retry after cancellation A separate run kept the compact MCP connection open after cancelling at the same second-xref barrier, using a test-owned macOS shell wrapper with a six-second delay. The first `close_binary` returned `cleanup_incomplete` with `retry_cleanup` and withheld-environment diagnostics; `binary_session` reported `cleanup_pending: true`. After bounded polling observed the wrapper PID had exited naturally, a second `close_binary` succeeded and `cleanup_pending` became false. The Evidence bundle before and after retry was identical: it retained the first completed xrefs observation and had no completed trace. The fixture SHA-256 remained unchanged and the target was not executed. This exercises the documented retry on one artificial withheld-environment case. PID absence is an observation, not independent proof of process-family identity; this does not establish late-finalization cancellation, all cleanup failures, or other-host behavior. Unlike the earlier aborted shell attempt above, the connection remained open through successful retry and no manual termination was required. ### Unmerged coverage propagation control A further isolated experiment passes a producer-owned stored-pointer coverage gap into the composed trace without setting `truncated` for an unenumerated category. Real full/compact MCP controls with Kuna 1.988: the static ELF with `data_refs_coverage: none` still returned no addresses, but now exposed an address-scoped residual unknown; the chained-fixup Mach-O returned its pointer and separately stated that metadata enumeration does not establish all stored pointers. Kuna 1.986 did not report the metadata and the experiment stated that coverage was unreported. Each trace linked its source xrefs Evidence; successful responses validated against the fetched schemas (Ajv 2020, strict and formats disabled). The ELF case also returned the gap through the real CLI. These are unmerged experiments, not shipped behavior. A second source-built Mach-O with 12 matched functions and no observed references produced 12 separate coverage unknowns and 12 linked xrefs records in the experiment: 25 Evidence records / 68,376 serialized bundle bytes, compared with one record / 4,649 bytes and no unknowns on #8509. The targets are distinct and can have independently resolvable coverage, so merging their unknown identities would be unsafe. Bounded presentation and source retention deserve design work; byte counts are not a token or performance benchmark. On one pointer fixture, a direct `xrefs` call and the source consumed by the trace had the same Evidence ID within each session. Across fresh sessions the raw-output digests and Evidence IDs differed; direct Kuna controls on identical staged bytes confirmed the serialized `binary` path changes the exact raw-output hash even when all other parsed fields match. That raw hash is a truthful hash of different producer bytes; whether and how to support semantic deduplication without discarding raw provenance remains open. All artifacts were unchanged and unexecuted. The experiment has not resolved bounded admission, duplicate/cross-session source identity, finalization cancellation, or the unsnapshotted CLI handoff, and should not be treated as a complete fix. ### Source-publication capacity and manual recovery control In an isolated integration of the unmerged pointer experiment with #8444 head `92adb42521f4ec73048d3f1d82844d2360da9db1` (one workflow-profile conflict resolved for the experiment), real Kuna 1.988 analyzed the 12-function fixture through in-memory production MCP registration with a deliberately injected 21,237-byte retained-representation allowance. In both compact and full profiles, source publication stopped after one source: the `resource_constraint` response delivered the completed 12-match trace as unretained with `source_closure: not-established`, and separately delivered the first failed source as unretained. The trace had 12 source links; one was retained and one was in the error response, leaving ten linked sources neither retained nor included in that response. This is a controlled application-boundary capacity fault, not natural exhaustion or a shipped integration. With the same session and fixture still open, the test saved each retained checkpoint, reset the investigation and re-queried the ten remaining targets; the returned source IDs matched the original links. It manually assembled the completed error-response Evidence and all 12 recovered source records into a valid bundle, then imported it into an unrestricted target-free server in both profiles. All 12 links resolved and the trace retained 12 residual-unknown strings, but the imported Unknown registry had zero entries. Source inspection shows automatic workflow-unknown recording occurs only after successful publication; manual Evidence import does not itself register them. This is a one-session, warm-cache manual control, not an advertised one-command recovery, a guarantee across restarts/cache eviction, or a claim that #8444 promises complete source closure. It exposes a design question for preserving per-target unknown identities and practical bounded handoff after publication failure. The target stayed unchanged and unexecuted. Related scope-selection discussion for recording recovered unknowns: #8546. ### 100-target boundedness control On a separate source-built, unexecuted Mach-O containing 100 matched functions with no observed references, the real compact stdio MCP workflow completed on both #8509 and the unmerged pointer/coverage prototype. The baseline exported one Evidence record (10,815 serialized bytes) and zero registered unknowns; the prototype exported 201 records (100 xrefs sources, 100 separately resolvable, address-specific questions and the trace; 541,474 serialized bytes) and returned 100 coverage questions. The successful response sizes were 22,569 and 56,033 serialized MCP bytes respectively. Both runs used the same binary and Kuna 1.988; its SHA-256 `460e69c94aa8cbbdc736458987172086916253f7f62b1637c7b3ab4f3bd06e6c` was unchanged. This demonstrates successful handling at this fixture size and a source-retention/presentation growth tradeoff; it does not establish normal-capacity exhaustion, token cost, a performance benchmark, or a safe upper limit. The questions refer to distinct target addresses and must remain independently resolvable; a smaller presentation must not discard their identities or provenance. Full-profile, larger corpus and recovery behavior were not exercised in this control. ### Current-main prototype: 3,000 stored-pointer slots On REA `ce9095d72`, I rebased the earlier unmerged pointer/coverage experiment in an isolated temporary worktree (one workflow return-type conflict resolved for the experiment). With real Kuna 1.988 and compact stdio MCP on the same source-built, unexecuted arm64 Mach-O containing 3,000 stored pointer slots to one matched target, the experimental `trace_feature` returned 3,000 references and 3,001 residual questions: one pointer-coverage question and one unavailable-containment question per slot. Its exported bundle had 3,003 records and 3,001 unknowns (10,062,729 serialized bytes); the successful MCP response serialized to 1,982,305 bytes. Each source address remained distinct. The same workflow on unmodified `ce9095d72` returned no references and no questions, with one bundle record (3,898 bytes) and a 7,547-byte MCP response. Both runs used the same unchanged target and fresh temporary caches; no target was executed. The baseline omits real provider observations and is not a correctness alternative. The prototype retains them but treats every stored-pointer slot as a source requiring a separate containing-procedure lookup, even though Kuna does not offer that operation. Consider a bounded, task-oriented presentation that makes provider-reported pointer observations and per-address identity available without conflating them with instruction owners or discarding independently resolvable questions. These are serialized byte counts for different outputs, not model token counts, equivalent-work performance benchmarks, or evidence of normal-capacity failure; this control covers one fixture, macOS arm64 and one schema profile. ### Direct xrefs source record at the MCP response boundary On the isolated unmerged pointer/coverage prototype based on `ce9095d72`, I exercised direct `xrefs` against two source-built arm64 Mach-O fixtures with 20,000 and 24,000 relocation-backed slots for `_audit_target`, using real Kuna 1.988 and compact stdio MCP on macOS arm64. The targets were not executed. At 20,000 slots, `xrefs` returned all 20,000 addresses; the SDK-serialized response was 9,965,171 bytes, and exact `get_evidence_bundle(detail: records, limit: 1)` succeeded at 9,966,345 bytes. At 24,000 slots, `xrefs` completed but returned `resource_constraint` at the default 10 MiB response budget with the retained Evidence ID. Summary lookup found that ID; exact record retrieval also exceeded the response budget, and `inspect_analysis_view` rejected the `xrefs` parent as unsupported. `export_evidence_bundle` succeeded, and its 5,572,550-byte file contained all 24,000 addresses and all 24,000 typed pointer rows in the retained xrefs Evidence. The target's SHA-256 was unchanged (`3e15b3d7c8ff848d4399d2f9ab27f09269efca437a72706be8070968cb410016`). These are stress fixtures and a non-shipped prototype, not a claim that current main returns pointer rows or that this volume is typical. The SDK serialized sizes include text and structured response forms, not model tokens or independent benchmarks. Export is a working full-data recovery; there is no tested bounded MCP view of this source record. A production fix should consider direct xrefs source-row selection and pagination, not only the composed `trace_feature` pages in #8585, while preserving the exact parent identity, row kind, distinct entries, target filtering, coverage and complete export. Other profiles, platforms, allocation bounds and cancellation at this size remain unverified. ### Paged address recovery experiment Draft #8591 extends the existing native-observation view to retained `xrefs` address lists. In fresh target-free full and compact MCP sessions, it paged an exported 24,000-row Evidence record from the unmerged pointer prototype, reconstructing all addresses with their original indices and parent ID. The record's raw typed pointer rows remained in the complete bundle; the pages contain untyped normalized addresses. In a separate temporary combination of #8591 with that unmerged pointer prototype, real Kuna 1.988 hit the default MCP response budget on the same source-built 24,000-slot Mach-O. Following the returned continuation and subsequent pages recovered all 24,000 addresses in 25 calls; the target SHA-256 `3e15b3d7c8ff848d4399d2f9ab27f09269efca437a72706be8070968cb410016` stayed unchanged and it was not executed. This validates one bounded address handoff, not typed-pointer paging or the pointer fix itself. Real Ghidra and current Kuna controls on the smaller pointer-only Mach-O matched their respective unpaged xrefs; current Kuna still omitted the pointer. ### Procedure ownership is separate from pointer provenance On the pointer-only Mach-O above, I compared real Ghidra 12.1.4 and Kuna 1.988 through compact stdio MCP in the unmerged pointer prototype based on `ce9095d72`. Both traces included the slot `0x100004000` as a reference to `0x1000003c0`. Ghidra's `resolve_containing_procedure` returned `found: false`, `reason: not_in_procedure` for that slot. Kuna returned `capability_unavailable` for the same operation, and the trace preserved `status: unavailable` with a residual question for that address. `dyld_info -fixups` independently showed the slot-to-target rebase and `nm` placed the slot in `__DATA,__data`; the target hash remained unchanged and it was not executed. The pointer producer's kind and the provider's ability to establish a containing procedure are distinct facts. Do not translate Kuna's unsupported ownership lookup into Ghidra's `not_in_procedure` result, or infer that every pointer location lacks executable interpretation. For large pointer sets, the task-oriented design should preserve each slot and its source kind while avoiding thousands of redundant provider-wide capability failures; any omitted ownership lookup must remain explicitly unexamined or unavailable. This is a single controlled fixture, not cross-provider equivalence or runtime-use evidence. ### Capability scope needed for shared-workflow recovery In the same real compact MCP sessions, `binary_session(detail: complete)` exposed `resolve_containing_procedure` as unavailable with `reason: provider_missing` for the selected Kuna route; the selected Ghidra route advertised it available. The workflow's `AnalysisOperationPort` currently exposes execution, not that route capability fact. At the execution boundary, an undeclared operation and a provider-returned, address-specific inability both use `AnalysisCapabilityUnavailableError` without a typed scope; its reason is display text, not a safe cache key. The existing public MCP regression `preserves references and explicitly unknown owners without claiming truncation` demonstrates the counterexample: one address produces that error while a second resolves successfully. On current `d3ab0faf5`, all 23 `enhancedTools.traceFeatureCoverage.test.ts` tests passed. A shared workflow must therefore not treat the first generic failure as proof that every address is unavailable. Consider passing a binding-owned capability observation with its lifetime or introducing an explicit scoped outcome at the producing boundary, then preserving each address's unknown status and the existing cancellation/cleanup behavior. No performance measurement or implementation is claimed here. The repeated `resolve_containing_procedure` requests in the prototype are rejected by REA's session capability router before dispatch to the Kuna process; they are not 3,000 Kuna subprocess requests. Source inspection shows the larger retained-state growth arises because `trace_feature` creates one address-specific residual string per failure and `recordWorkflowUnknowns` registers each as a distinct unknown. The draft #8585 summary and page views reduce what is delivered per call but do not avoid constructing or retaining those records. A scoped capability outcome alone would not solve that representation problem. Any grouped or lazy representation needs to retain independently addressable per-slot questions and be checked through export/import, resolution, failure and cancellation, rather than dropping distinct unknowns. This identifies code paths, not a CPU or memory profile. ### Experimental stored-pointer Evidence pages An unmerged combination of the pointer producer, #8591 address paging and the typed-source experiment in #8348 adds separate provider-attributed instruction and stored-pointer pages for a linked `xrefs` source. In real Kuna 1.988 full and compact MCP on the existing unexecuted mixed Mach-O, `trace_feature` returned the instruction site `0x10000042c` and pointer slot `0x100004008`. Following its linked source, the instruction page reported the `call` and owner; the pointer page reported the slot, width 8, target and `chained-fixups` provenance. Both pages validated against their fetched schemas and survived export/import into fresh target-free sessions. Target SHA-256 `9fc02faea0c3723a094c209adbe62a279011df4d508298625bd766fa20ed7c46` remained unchanged. No runtime call or pointer use is inferred. On the separate static ELF control, direct Kuna reports `data_refs_coverage: none`. Both real MCP profiles returned a stored-pointer page with zero recorded rows, `enumeration.status: not-enumerated` and an explicit statement that this does not establish absence. This distinguishes unenumerated pointer coverage from an observed empty list. On the source-built 24,000-slot Mach-O, direct Kuna reported 24,000 chained-fixup pointers. The experimental byte-limited view reconstructed all 24,000 rows, names, widths and provenance in four pages in compact live MCP and a fresh full-profile offline session; each page validated against the fetched schema. The target SHA-256 `3e15b3d7c8ff848d4399d2f9ab27f09269efca437a72706be8070968cb410016` was unchanged. An earlier variant kept both raw pointer rows and the new normalized rows: the full reply exceeded 10 MiB and the bundle after paging was 12,193,915 bytes. Removing the duplicate representation left the same tested normalized rows, a 6,965,767-byte SDK-serialized complete reply and a 6,961,886-byte bundle after paging. These are sizes for one stress fixture, not token, time, CPU or memory benchmarks; original raw output remains represented by its truthful digest, not retained verbatim. Synthetic public-boundary controls rejected an unrelated operation, mismatched target and source absent from the parent address list, and preserved two distinct recorded pointer observations at the same address across pages. These controls do not prove the real provider emits such collisions. This remains a design prototype: generic raw-result exposure, source ownership and target admission, large-row resource accounting, cross-provider meaning, repeated per-slot unknowns, source-publication failure, cleanup/cancellation and other hosts are not resolved. See #8348 for instruction-page controls and open design constraints. A follow-up unmerged UX probe adds guidance to `trace_feature` only when its linked xrefs sources record typed observations. In real Kuna 1.988 full and compact MCP on the same mixed Mach-O, the trace named the `instruction-references` and `stored-pointers` native-context facets; following its linked source produced the separately typed call and pointer pages, and both remained accessible after export/import into a fresh target-free session. A real older baseline xrefs record without stored-pointer metadata returned `invalid_request` saying the observations were not recorded, rather than an empty pointer inventory. This is a scripted public-tool handoff, not an autonomous-agent selection or token-cost experiment. It does not resolve the existing per-reference unknown retention, source-publication, lifecycle or cross-provider design questions. ### Kuna 1.989 upgrade control On combined upgrade PR #8699 head `f8f496f8a`, real Kuna 1.989 on macOS arm64, direct `xrefs --to 0x1000003c0 --json` still reported zero instruction rows and one `chained-fixups` pointer from `0x100004000` to `_audit_target`. Independent `xcrun dyld_info -fixups` reported the same rebase. In both compact and full stdio MCP profiles, REA `xrefs` returned `[]` with `examined_rows: 0`; `trace_feature` returned the matching function and no references with `truncated: false` and no residual unknowns. REA retained the raw-output digest and the general limitation that an empty xref result does not prove absence, but did not expose the provider-returned pointer. The source-owned target SHA-256 `22c604d669ebd4e32be8d1f5c820ecbe9f28b1101dcb8da4b399acea355f21a9` was unchanged and the target was not executed. This confirms the issue on one fixture, not general coverage or real-world frequency; the version bump alone is not a fix. ### Typed-source prototype with Kuna 1.989 On the existing unmerged typed-source/pointer paging experiment in `/tmp/rea-xrefs-pointer-combined` (base `ce9095d72` with local experimental edits), real Kuna 1.989 full and compact stdio MCP traced the owned mixed Mach-O. The trace retained a link to the xrefs source; the source's instruction-reference page identified the call at `0x10000042c`, and its stored-pointer page separately identified `0x100004008` with width 8 and `chained-fixups` provenance. The pointer pages were exactly equal as parsed JSON after exporting the Evidence bundle and importing it into a fresh target-free session in each profile. The source-owned target SHA-256 `9fc02faea0c3723a094c209adbe62a279011df4d508298625bd766fa20ed7c46` was unchanged and it was not executed. This is an experimental integration checkout, not a patch in #8699 or a release. The trace still reports unavailable containing-procedure questions for both the instruction and pointer sites, and the resource/accounting, source-publication, coverage, lifecycle and cross-provider questions above remain. The control demonstrates one typed-provenance handoff with the newer release, not general completeness or autonomous-agent selection. ### Synthetic overlapping-source trace control Using the same unmerged typed-source experiment and real Kuna 1.989 behind a temporary test-only wrapper, I changed one returned pointer row's source address to coincide with the returned instruction-call source `0x10000042c`. The wrapper deliberately fabricated this overlap; it is not an assertion that Kuna or the artifact reported such a pointer. In both compact and full stdio MCP, `trace_feature` normalized the address to one reference and reported one unavailable-containment question, while the linked source's separate pages retained both the call row (including Kuna's reported function owner) and the synthetic pointer row. The pointer page survived Evidence export/import exactly as parsed JSON; the original target hash stayed unchanged. This control rules out a simple rule that skips function ownership merely because an address has a pointer observation: the same normalized address can carry an instruction observation as well. It also shows why the instruction row's provider-reported owner and a separate containment lookup must retain their own provenance; an address-level projection alone cannot select the right interpretation. Resource bounds and independently resolvable unknowns remain open; no proposed production behavior or real-world overlap frequency is implied. ### Released Kuna 1.989 and current REA control On REA main `9ebbe67e`, macOS arm64, I rebuilt the pointer-only fixture above as an owned, unexecuted Mach-O (SHA-256 `40b175907eb9e8f57e02ce166c99ad810f2a09ee6cfaa2c26b8d1f2b0bb94938`). `nm` placed `_audit_target` at `0x1000003c0` and `_audit_func_ptr` at `0x100004000`; `dyld_info -fixups` independently reported a rebase from that slot to the target. Direct released Kuna 1.989 `xrefs --to _audit_target --json` returned zero instruction rows and one 8-byte pointer under `data_refs`, with `data_refs_coverage: chained-fixups`. Real REA/Kuna stdio MCP returned an empty `xrefs` array and a trace with no references, `truncated: false`, and no residual unknowns in both compact and full profiles. Its xrefs Evidence retained the output digest, byte count and zero examined instruction rows, plus a generic warning that an empty result does not prove absence; it did not report the pointer or the producer's pointer-coverage facts. REA/Ghidra 12.1.4 on the same target returned the pointer slot and another source address; the trace classified the pointer slot as outside a procedure. All calls used fetched SDK tool definitions. The target hash remained unchanged. This confirms the existing omission with the released default Kuna version on one fixture, not general provider completeness or runtime pointer use. The upstream `data_refs` and instruction `xrefs` remain separate categories and need separate provenance/coverage; simply relabeling the stored pointer as a call would be incorrect. ### Existing native metadata tool control On REA main `9ebbe67e` with the released Kuna 1.989 and the pointer-only Mach-O in the preceding control, I called `inspect_native_dispatch_metadata` through real stdio MCP in both schema profiles. It reported `pointer_fixups` coverage `complete`, with one examined and one decoded chained-fixup format (`DYLD_CHAINED_PTR_64_OFFSET`), but its result contained neither the pointer slot `0x100004000` nor the target `0x1000003c0`. Objective-C classes, Swift declarations, and relative pointers were empty for this fixture. The target hash remained unchanged. Source inspection shows that the dispatch reader uses the existing fixup decoder to resolve pointer addresses it encounters while reading metadata. This control does not establish general fixup completeness or show that the metadata tool enumerates incoming references; it is not a workaround for this fixture's omitted xref. The existing decoder may be useful in a future design, but the caller's question, coverage, and pointer provenance still need explicit handling. ### Ghidra fallback and offline handoff On main `9ebbe67e` with the released Ghidra 12.1.4, I separately requested `xrefs` and `trace_feature` for the pointer-only fixture above, exported the session bundle, and imported it into a fresh MCP server with no binary open. Both retained records exactly matched the original results in compact and full profiles. The xrefs result and trace included slot `0x100004000`; the trace classified it as outside a procedure. The direct xrefs record's `raw_result` was null, and the trace had no Evidence links: these outputs preserve the source address but do not themselves identify it as a stored pointer or link the independently requested xrefs record. `dyld_info` independently established the slot's rebase in the prior control; this handoff alone does not prove pointer kind or runtime use. The fixture remained unexecuted and SHA-256 `40b175907eb9e8f57e02ce166c99ad810f2a09ee6cfaa2c26b8d1f2b0bb94938` stayed unchanged. This is one Ghidra fallback control, not general coverage. ### Existing typed Ghidra handoff A follow-up real Ghidra 12.1.4 control on the same fixture called `inspect_native_instruction` at `_audit_target` (`0x1000003c0`) before exporting. In both MCP profiles, its `incoming_references` reported the slot `0x100004000` as `type: DATA`, `data: true`, `call: false`, with `ghidra-reference-manager` provenance. The entire instruction Evidence record survived export/import unchanged in a fresh server with no binary open. This is a more informative existing Ghidra workflow than the address-only xrefs/trace results described immediately above. The instruction record does not itself name the Mach-O chained-fixup mechanism; the independently observed `dyld_info` rebase provides that separate fact. The trace did not link the separately requested instruction record. The fixture was not executed and its SHA-256 remained `40b175907eb9e8f57e02ce166c99ad810f2a09ee6cfaa2c26b8d1f2b0bb94938`. ### Released Kuna fixture with a call and stored pointer A separate control used Kuna's public [`macho_ptrslots_offset_arm64` fixture at v1.989](https://github.com/Noelo-Lab/kuna/blob/v1.989/decompiler/crates/kuna-analysis/tests/fixtures/macho_ptrslots_offset_arm64) (local SHA-256 `cd5265aed04ecf2f3d125782892ebdf6eb66ea80c3f783fb3f99fe3a74b6f642`). Direct Kuna 1.989 `xrefs --to _audit_target --json` reported one instruction call from `0x1000003e4` and one separate 8-byte stored-pointer row from `0x100004008`, with `data_refs_coverage: chained-fixups`. Real REA/Kuna `xrefs` in compact and full MCP profiles returned only `0x1000003e4`; its raw metadata counted the one instruction row and did not report the pointer row or coverage. Real REA/Ghidra 12.1.4 reported the pointer source as a DATA reference alongside other references. The public fixture was never executed and its digest remained unchanged. The [Kuna v1.989 xrefs implementation](https://github.com/Noelo-Lab/kuna/blob/v1.989/decompiler/crates/kuna-cli/src/xrefs.rs) describes instruction and stored-pointer rows as separate collections and says `data_refs_coverage: none` means the image lists no pointer relocations, not that no pointers exist. Preserving that distinction and the coverage source is necessary for an honest task-level result; no runtime call is implied by a stored pointer. ### Kuna 1.990 verification branch control On the REA 1.990 validation branch `187f3d8cc`, macOS arm64, a newly built unexecuted arm64 Mach-O had `_audit_target` at `0x1000003c0` and `_audit_func_ptr` at `0x100004000`; `dyld_info -fixups` independently reported that slot's rebase to the function. Direct Kuna 1.990 `xrefs --to 0x1000003c0 --json` returned no instruction rows and one 8-byte pointer row from the slot with `data_refs_coverage: chained-fixups`. In both compact and full public MCP profiles, REA/Kuna `xrefs` returned an empty normalized array, counted zero examined instruction rows in the source digest metadata, and omitted the pointer and coverage facts. `trace_feature` returned the procedure but no references, `truncated: false`, and no residual unknowns. The target SHA-256 `496e188170232c15f1ceeebf33165f060c6a31b46be9571b6f49778ef0e8d910` stayed unchanged. This confirms the issue persists with the proposed verified Kuna release on one fixture; it does not establish a runtime call or provider-wide completeness. ### Explicit Ghidra handoff on the 1.990 fixture In separate compact and full real MCP sessions on the 1.990 validation branch, I requested Kuna `xrefs` on the preceding pointer-only fixture, explicitly reopened the same target with Ghidra 12.1.4, and called `inspect_native_instruction` at `0x1000003c0`. Ghidra's incoming-reference observation identified `0x100004000` as `DATA`, `data: true`, `call: false`, with `ghidra-reference-manager` provenance. The complete retained bundle still contained the original empty Kuna xrefs Evidence unchanged after the switch. The fixture hash remained unchanged. This is an explicit provider handoff on one host; the typed Ghidra observation does not itself identify the chained-fixup mechanism or prove runtime use, and the earlier `dyld_info` observation is separate. ### Direction of the stored-pointer question On the same owned 1.990 pointer fixture, direct Kuna `xrefs --from 0x100004000 --json` reported one 8-byte chained-fixups pointer from that slot to `0x1000003c0`; its instruction coverage explicitly said the slot was non-executable and not decoded. In compact and full public MCP profiles, REA `xrefs` at the slot returned an empty incoming-reference result; its contract and analysis profile explicitly say it searches **to** the address, so this is not an incorrect answer to an outgoing query. The same sessions reported `inspect_native_data_type` unavailable from Kuna. The fixture was not executed and its SHA-256 remained `496e188170232c15f1ceeebf33165f060c6a31b46be9571b6f49778ef0e8d910`. This suggests a separate analyst question—what address does this stored slot refer to?—rather than treating an incoming-only result as an outgoing answer. Consider whether an existing task-level data inspection workflow can answer it with typed provenance and coverage before adding a directional API; this single fixture does not establish that no alternative exists or that a generic `--from` wrapper is appropriate. ### Existing Ghidra slot inspection For the same fixture, real Ghidra 12.1.4 through both MCP profiles reported a defined 8-byte `pointer` at `0x100004000` via `inspect_native_data_type`, but did not report its value or referenced type. `inspect_native_instruction` classified the slot as data and returned incoming references to the slot, while its outgoing `references` array was empty. `read_bytes` returned `c003000001000000`, explicitly described as initialized Ghidra memory including loader fixups; interpreted as little-endian 64-bit, that is `0x1000003c0`. Independently, `llvm-objdump --macho --full-contents --section=__data` showed the shipped bytes `c003000000000000`, which differ from the loaded representation. The fixture SHA-256 was unchanged and it was not executed. This provides a manual, fixture-specific path using type, byte order, and loaded bytes, but those bytes alone should not be reported as an independently established source-file pointer or runtime use. It also illustrates why a candidate workflow should preserve the origin of a decoded pointer and distinguish original artifact bytes from loader-resolved memory. It does not establish behavior for other fixup kinds or pointer formats. ### Ghidra reference-manager producer boundary A separate direct Ghidra 12.1.4 headless import and analysis of that fixture, using a short post-script calling `currentProgram.getReferenceManager().getReferencesFrom(toAddr("100004000"))`, reported a `DATA` reference from `0x100004000` to `0x1000003c0` with Ghidra source `DEFAULT`. The temporary project was deleted. This is a Ghidra analysis observation, not proof of the original fixup mechanism or runtime use. REA's bridge source populates `inspect_native_instruction.references` from `instruction.getReferencesFrom()` only in the decoded-instruction branch; defined data takes the non-instruction branch, leaving that array empty. Thus the preceding empty array is a projection limitation for this fixture, not an absence of a Ghidra ReferenceManager observation. The current field is described as outgoing **instruction** references, so changing its semantics requires a deliberate contract decision: distinguish references from a data code unit, preserve their provider/source metadata, and avoid implying every empty instruction-reference list exhausts data references. ### Interior-address control On the same fixture, direct Ghidra headless `getDefinedDataContaining` reported that `0x100004001` and `0x100004007` belong to the 8-byte item beginning at `0x100004000`; `ReferenceManager.getReferencesFrom` reported the pointer reference at the start address, but none at either interior address. Through real REA/Ghidra MCP in both profiles, `inspect_native_instruction` at `0x100004001` reported `status: data` with empty references, while `inspect_native_data_type` returned unavailable with the explicit reason that no **exact** typed-data identity exists there. The target hash remained unchanged. Any future data-reference workflow must define whether it answers at the exact address or expands to a containing item, and disclose the actual source address if it does the latter. An empty exact-address query at an interior byte is not evidence that its containing data item has no reference. This is one simple pointer item, not a general test of composites or overlapping data. ### Direct Kuna kind-filter control On the owned pointer fixture with Kuna 1.990, `xrefs --to 0x1000003c0 --kind pointer --json` returned the chained-fixup pointer row; `--kind call` returned zero pointer rows while still reporting `data_refs_coverage: chained-fixups`. The unfiltered control above returned the pointer. This is expected filter behavior on one fixture: the coverage label identifies the metadata source, not proof that an empty filtered pointer list exhausts all reference kinds. Any retained or projected filtered observation should keep its selected kind alongside source coverage and avoid converting filter exclusion into absence. ### Relocation-source label is not proof that records were read An additional owned x86-64 ELF control has one `R_X86_64_RELATIVE` pointer at `0x33c0` to `0x1310`. A malformed copy changes only the relocation section's symbol-table link to nonexistent index `999`; `llvm-readelf` reports that the section's symbol table cannot be located. Direct Kuna 1.990 reports `dynamic-relocations` for both files, but emits one pointer only for the intact file. An unmerged REA pointer-reference prototype returned the intact pointer and an empty xrefs array for the copy in both MCP profiles; both source records retained the same `dynamic-relocations` label, and the existing generic caveat remained. The files were not executed and their SHA-256 values remained `112844ea2afd19308af073bb78e9ca60e3797c5114d37db4bbe27c50ce4db11b` and `afb8b300a1a24a5a643850b07aa3dd9037d9565ba504d0276ed04a3a0579ef62`. A provider's metadata-source label must not be promoted to successful or complete coverage. This example is a deliberately malformed input, not a general failure-rate measurement. Upstream report: https://github.com/Noelo-Lab/kuna/issues/1502. ### Exact-address pointer and forwarding-alias control A source-built x86-64 ELF fixture contains an indirect forwarding veneer at `0x13a0`, its slot at `0x3460`, a stored pointer at `0x3468` to the veneer, and another at `0x3470` to the slot. Direct Kuna 1.990 `xrefs --to 0x13a0` reports the slot as an alias and emits both pointer rows. In the local unmerged REA prototype, compact/full MCP `xrefs` returns only `0x3468` for the selected exact target; its retained raw source keeps both rows and reports two examined rows, one excluded alias row. An earlier prototype counted only instruction rows and would have shown zero examined/excluded; the experimental fix counts both categories. This does not imply the alias-targeting pointer is an exact reference to the veneer. The fixture was not executed and SHA-256 `967b95de168d4c41f039449e6e379a05c1e1ded75ce3427b6359a21f22655a83` was unchanged. The unmerged parser prototype also has production-boundary controls for numeric pointer and unwalked-source addresses above JavaScript's safe-integer range, preserving their exact u64 values; an unreported pointer inventory remains distinct from an explicitly empty one, and incomplete or inconsistent pointer counts are rejected. These use synthetic Kuna-shaped JSON rather than a real large-address binary. The issue's real-provider controls above establish behavior only for their tested addresses and fixtures. ### Real full-width address control An owned, unexecuted x86-64 ELF shared object was linked with image base `0x20000000000000`. Its dynamic relocation stores a pointer from `0x200000000033c0` to the odd address `0x20000000001311`, one byte into `audit_target`; `llvm-readelf -r -s` independently reports the relocation and addend. Direct Kuna 1.990 returned that pointer, including decimal address tokens beyond JavaScript's exact integer range. The unmerged REA prototype's `xrefs` returned the exact source and retained both addresses and `dynamic-relocations` provenance without rounding in compact and full MCP profiles. SHA-256 `058eee606b8b0c5965cd5f1a7d2fc9b8fa2a48680f8a5577ab7849749668856a` was unchanged. This intentionally unusual address tests static parsing and is not a claim the image is runnable. On the same fixture, prototype `trace_feature("audit_target")` matched the procedure entry `0x20000000001310` and returned no references because its xrefs query targets that exact entry, not the interior destination `0x20000000001311`. The direct interior xrefs query above did find the pointer. The existing exact-address limitation remains; a procedure-body workflow must define its bounds and coverage rather than treating a reference to an interior byte as an entry reference. See #8569 and #8184. ### Current draft large-result recovery Real Kuna 1.990 with draft #8851 `411f02d21` returned a complete direct `xrefs` for an unexecuted 24,000-slot fixture in both schema profiles. A separate 40,000-slot fixture exceeded the MCP response budget in both profiles; the error returned a retained Evidence ID and continuation. Paging the existing native-observation view recovered all 40,000 distinct source addresses, while exact full-record delivery also exceeded the budget. The supplied first-page continuation was exercised in compact mode. Complete export retained all 40,000 typed pointer rows; the exported bundle after paging was 8,683,464 bytes. The address pages do not expose pointer provenance, so at this size those details require export. Both fixture hashes were unchanged: `1abaca97f961d39b4b3b5ec2e7ff5c26872c4952ad0f91cb780a207c8933c50f` and `a7aa0b539a8da618137ad4a7257ce14622ec0123f1f8f1706d5b5ccb968e0e52`. These are controlled stress cases, not prevalence, token, latency or peak-memory measurements. ### Normalized linked-source paging probe A separate unmerged probe moved typed stored-pointer observations from the `xrefs` raw-result payload into a linked, provider-attributed normalized source Evidence record and used the existing native-observation view to page that record. With real Kuna 1.990 and the 40,000-slot fixture above, both MCP profiles returned all 40,000 pointer rows in 40 pages; a fresh target-free session without Kuna recovered sampled pages after bundle import. The direct `xrefs` response with its linked source ID fit the MCP limit. After paging, the bundle was 14,246,696 bytes, including 6,161,750 serialized bytes for the typed source and 7,521,945 for the 40 retained page Evidence records. This does not establish token, latency or memory costs, and the target hash stayed unchanged. This probes a way to expose typed facts without embedding them twice in the parent. It is not integrated: source construction and admission, alias provenance, partial publication, view-byte bounds, cancellation, and the cost of retaining page Evidence need further work. #8851 does not contain this probe. ### Linked-source admission and recovery controls The unmerged typed-source probe was combined locally with #8444 and the current #8851 alias changes. On a real Kuna 1.990 forwarding-alias fixture, both MCP profiles retained the alias name and address and paged two pointer rows with their distinct destinations; only the direct pointer appeared in the exact-address xrefs result. With a deliberately injected zero-byte retained-representation allowance, a one-pointer fixture returned the typed source and completed xrefs as unretained observations, linked by ID, in both profiles; no records were retained. On the 40,000-pointer fixture, the corresponding error returned both complete observations inline (about 6.7 MB of JSON), with source closure explicitly not established. A 1 MB retained allowance succeeded for the one-pointer control. These limits were injected, not measurements of default operation. A separate injected zero authentication-headroom control refused publication with `resource_constraint` and an explicit completed-observation omission in both profiles. Source inspection shows that this experimental producer constructs and hashes the large typed Evidence before that refusal. No actual out-of-memory condition was induced; nevertheless this ordering means the control does not establish safe behavior under genuinely low heap. Admission must precede constructing expanded Evidence, and the session must own the resulting publication and recovery semantics. The typed-source probe is not in #8851. Target hashes were unchanged. ### Current draft creates Evidence before authentication admission This is not limited to the separate typed-paging probe. On draft #8851 head `da842598b`, a production stdio MCP session with real Kuna 1.990 analyzed the owned 40,000-slot fixture in both profiles. An instrumented `InvestigationRecords.recordEvidence` boundary received a fully identified `xrefs` Evidence record containing all 40,000 raw pointer rows before its deliberately injected `availableAuthenticationBytes: () => 0` policy refused authentication. Both callers received `resource_constraint`; no records were retained and the target hash was unchanged. The reported 128,040,224 authentication bytes are the policy's estimate, not measured peak memory. No real OOM was induced. The session creates `createAnalysisExecutionEvidence` before calling `recordEvidence`, while the latter performs the headroom check. A fix needs to admit the borrowed observation and its expanded Evidence representation at the session-owned boundary before construction, and preserve truthful recovery/omission and source links if admission fails. The existing #8444 recovery complements that ordering; it does not by itself prove preconstruction admission. This is a merge-readiness issue for #8851, not an upstream Kuna defect. ### Session admission prototype A separate unmerged integration of #8851 and #8444 constructs a borrowed Evidence envelope from the same observation fields used by commitment and asks the owning session to admit it before creating the session-generated Evidence. With the 40,000-pointer Kuna 1.990 fixture and injected zero authentication headroom, both MCP profiles reported an explicit `insufficient-authentication-headroom` omission and an instrumented record boundary was never called. This shows the session-generated `xrefs` Evidence was not committed or passed to the ledger; the provider's parsed result already existed. With normal headroom and injected zero retained capacity, #8444 returned an unretained observation for the small and 40,000-pointer controls; a 1 MB allowance retained the small result in both profiles. The targets were not executed and their hashes were unchanged. `check:fast` and four focused suites passed (59 tests). This is an exploratory local change, not part of #8851: it needs a dedicated regression for preconstruction admission, accounting and coverage for providers that already construct `sourceEvidence` themselves, cancellation/cleanup and broader provider validation. The admission estimator is not a process-memory guarantee, and this injected policy did not induce OOM. A new isolated public-MCP regression now runs a profiled provider in both schema profiles with injected zero authentication headroom. It checks that the provider completed, that `createAnalysisExecutionEvidence` and the ledger recorder were not called, and that the error identifies the omitted completed observation. On the unmodified combined baseline both cases fail because Evidence construction was called; with the prototype both pass. The focused suite and an existing batch cleanup control passed (7 tests), and `check:fast` passed before the final test-only instrumentation adjustment. This does not prove cancellation during this specific admission stage. The Ghidra project-history path can supply source Evidence constructed before session publication, so that separate path is not covered by this prototype; source inspection alone has not established a large-record failure there. A real Ghidra 12.1.4/JDK 21 stdio MCP control on the admission prototype recovered an `address_name` result as unretained Evidence under an injected zero retained allowance and retained it under a 100 KB allowance, in both profiles. Separately, an instrumented workflow attached a synthetic source Evidence record to real Ghidra `xrefs` output: zero retained allowance returned the source and completed trace as linked, unretained Evidence with source closure not established; a 1 MB allowance completed in both profiles. The target was not executed and its SHA-256 (`8a0d4927e1d89dc4aca4c87c0c3ba1bac78c99c0d62df37930598f859485dbcc`) remained unchanged. These are cross-provider recovery controls, not a real saved-project history test or proof of preconstruction admission for provider-created source records. After the latest regression instrumentation, `check:fast` passed. ### Typed paging, CLI portability and cost A separate local prototype deferred construction of linked typed-pointer Evidence until the session admitted it. On the real 40,000-pointer Kuna fixture it paged all typed rows in both MCP profiles; zero-headroom controls refused before source recording, and zero retained capacity returned unretained source/primary when the response budget allowed. This source-only shape broke default one-shot `xrefs`: the CLI returned a link to the closed session without the pointer details. The same general one-shot closure gap also reproduces with an existing Ghidra project; see #8590. Keeping pointer rows in the primary raw Evidence as well as a linked pageable record restored the real one-shot CLI facts. Both MCP profiles then followed overflow recovery through parent address pages, retained-link discovery and 40 typed pages; the exported bundle after paging was 20,406,827 bytes. At injected zero retained capacity the 40,000-pointer error returned the completed parent with its raw pointer rows but explicitly omitted the separate source at the MCP response limit. On a 24,000-pointer real Kuna task, three alternating runs per variant gave median first/repeated calls of 723/339 ms for the current combined baseline versus 1,044/581 ms with the duplicated pageable index; median full-process elapsed was 2.19/2.78 s. Sampled summed process-family peak RSS was 1,254,400/1,391,568 KiB and sampled CPU lower bounds were 2.87/3.64 s. Raw address and pointer-array hashes agreed. This is a small host-specific comparison; shared RSS pages may be counted twice, token use was not measured, and no target was executed or modified. The duplicate-index prototype is not in #8851. It imposes substantial measured cost on this fixture, while a source-only shape leaves default CLI evidence incomplete. A shared portable one-shot source handoff or another nonduplicating normalized representation needs design before typed paging is integrated. A single synthetic 6 MB source-name row also exceeded the MCP response budget even at page size 1; the error retained the view and offered export, but this is not a claim about real Kuna name frequency. ### Parent raw-row projection feasibility On the combined #8444/#8851 checkout, the real Kuna 1.990 one-shot CLI returned 40,000 pointer rows in the parent Evidence's `raw_result.references.pointers`. A standalone JavaScript probe sliced that already-parsed array into 40 pages of 1,000; rejoining them gave the same SHA-256 (`4de84cdddc6a1cc69977918fa0a3b4b2ddae86163bfcecbf428e3c1bf92a9711`), and page elements referenced the same objects in memory. The parent JSON was 6,722,606 bytes and the first pointer page was 154,013 bytes. The unexecuted target digest remained `a7aa0b539a8da618137ad4a7257ce14622ec0123f1f8f1706d5b5ccb968e0e52`. This is a local data-access probe, not an REA view or MCP measurement. It suggests that paging the existing parent could avoid retaining a second source record, but does not settle provider-format ownership, discoverability, byte-bounded pages, page Evidence costs, or offline contract validation. An agent-facing design must preserve the raw values and caveats without silently interpreting Kuna-specific fields in the shared domain. An unmerged generic raw-array view on the combined checkout retrieved the same 40,000 rows from the parent in 40 real Kuna MCP pages in both schema profiles; an invalid path returned `invalid_request`. Export after paging was 12,960,646 bytes. Import into a fresh MCP session without Kuna reproduced three sampled pages in both profiles; bundle and target hashes stayed unchanged. `check:fast` passed. This prototype requires callers to know a raw provider-specific path; its discovery, byte accounting, complete lifecycle, and typed semantics are not established, so it is not proposed for integration.
Author
Owner

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

Native source-side control

On the same unexecuted mixed Mach-O with Kuna 1.989, xrefs --from 0x10000042c --json reports the call to 0x100000410 and repeats the provider-reported _audit_direct_call owner at 0x100000424. The incoming row already carries that same owner, so this extra source query adds no ownership fact for this call. xrefs --from 0x100004008 --json instead reports the same chained-fixup pointer and explicitly reports its mapped section as non-executable and not decoded; it does not supply a containing-function result. The fixture SHA-256 remained 9fc02faea0c3723a094c209adbe62a279011df4d508298625bd766fa20ed7c46.

These are two source addresses in one fixture, not a general provider guarantee. They suggest preserving the incoming instruction row's already-reported owner as an attributed observation, while keeping pointer location, executable mapping and independently queried function containment distinct. A source-side query per pointer would introduce further provider work and should not be assumed necessary for every trace; no performance measurement or general mapping-to-containment inference is claimed.

<!-- gh-comment-id:6584342551 --> @morluto commented on GitHub (Nov 2, 2026): ### Native source-side control On the same unexecuted mixed Mach-O with Kuna 1.989, `xrefs --from 0x10000042c --json` reports the call to `0x100000410` and repeats the provider-reported `_audit_direct_call` owner at `0x100000424`. The incoming row already carries that same owner, so this extra source query adds no ownership fact for this call. `xrefs --from 0x100004008 --json` instead reports the same chained-fixup pointer and explicitly reports its mapped section as non-executable and not decoded; it does not supply a containing-function result. The fixture SHA-256 remained `9fc02faea0c3723a094c209adbe62a279011df4d508298625bd766fa20ed7c46`. These are two source addresses in one fixture, not a general provider guarantee. They suggest preserving the incoming instruction row's already-reported owner as an attributed observation, while keeping pointer location, executable mapping and independently queried function containment distinct. A source-side query per pointer would introduce further provider work and should not be assumed necessary for every trace; no performance measurement or general mapping-to-containment inference is claimed.
Author
Owner

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

String-search to reference handoff

On owned Mach-O SHA-256 ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d, real Kuna 1.989 compact and full MCP search_strings found REA audit distinctive message at 0x1000004c0. REA xrefs at that address returned []. Direct Kuna xrefs --to 0x1000004c0 --json instead reported one chained-fixup pointer from 0x100004008 to the string; independent dyld_info -fixups reported the same rebase. Real REA/Ghidra 12.1.4 on the same target returned 0x100004008 and 0x1000004ac. The target was not executed and its hash was unchanged.

This reproduces the existing stored-pointer omission in a string-search handoff as well as the function-pointer case, on one fixture. It does not establish why Ghidra reports the additional address, general provider completeness, or runtime use. The proposed search_strings byte-read guidance in #8704 does not fix this underlying omission.

<!-- gh-comment-id:6585264308 --> @morluto commented on GitHub (Nov 2, 2026): ### String-search to reference handoff On owned Mach-O SHA-256 `ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d`, real Kuna 1.989 compact and full MCP `search_strings` found `REA audit distinctive message` at `0x1000004c0`. REA `xrefs` at that address returned `[]`. Direct Kuna `xrefs --to 0x1000004c0 --json` instead reported one chained-fixup pointer from `0x100004008` to the string; independent `dyld_info -fixups` reported the same rebase. Real REA/Ghidra 12.1.4 on the same target returned `0x100004008` and `0x1000004ac`. The target was not executed and its hash was unchanged. This reproduces the existing stored-pointer omission in a string-search handoff as well as the function-pointer case, on one fixture. It does not establish why Ghidra reports the additional address, general provider completeness, or runtime use. The proposed `search_strings` byte-read guidance in #8704 does not fix this underlying omission.
Author
Owner

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

Composed string trace control

Following the preceding string-search control, real REA/Kuna 1.989 trace_feature for REA audit distinctive message in both compact and full stdio MCP found the string but returned references: [], truncated: false, residual_unknowns: [], and no linked Evidence. Its limitations did include the general statement that an empty xref result does not prove absence, but did not disclose that Kuna had returned the specific chained-fixup pointer recorded above. Real REA/Ghidra 12.1.4 traced the same string to the instruction address 0x1000004ac and stored-pointer address 0x100004008; its containing-procedure outcomes differed for those two locations. The fixture hash was unchanged and it was not executed.

This adds a string-target composed-workflow example to the function-target finding already reported here. truncated: false describes the reported result, not proof of exhaustive references; the concern is the undisclosed producer-observed row and lack of its typed source in the composed answer. This one fixture does not establish runtime use or general provider coverage.

<!-- gh-comment-id:6585325785 --> @morluto commented on GitHub (Nov 2, 2026): ### Composed string trace control Following the preceding string-search control, real REA/Kuna 1.989 `trace_feature` for `REA audit distinctive message` in both compact and full stdio MCP found the string but returned `references: []`, `truncated: false`, `residual_unknowns: []`, and no linked Evidence. Its limitations did include the general statement that an empty xref result does not prove absence, but did not disclose that Kuna had returned the specific chained-fixup pointer recorded above. Real REA/Ghidra 12.1.4 traced the same string to the instruction address `0x1000004ac` and stored-pointer address `0x100004008`; its containing-procedure outcomes differed for those two locations. The fixture hash was unchanged and it was not executed. This adds a string-target composed-workflow example to the function-target finding already reported here. `truncated: false` describes the reported result, not proof of exhaustive references; the concern is the undisclosed producer-observed row and lack of its typed source in the composed answer. This one fixture does not establish runtime use or general provider coverage.
Author
Owner

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

Experimental typed handoff for the string trace

In the unmerged pointer/typed-source prototype combined locally with main 75c3cab54 (with one manually resolved KunaSessionClient conflict), real Kuna 1.989 compact and full MCP traced the same string and returned source 0x100004008. Following the linked xrefs Evidence to its stored-pointer page identified _message, width 8 and chained-fixups provenance; enumeration was qualified as metadata-only. Both profiles retained explicit unknowns for other pointers and unavailable containing-procedure resolution. The stored-pointer page was exactly equal as parsed JSON after Evidence export and import into a fresh target-free session. The fixture SHA-256 was unchanged and the target was not run.

The separate instruction-reference page was empty for Kuna; Ghidra's additional instruction result remains a provider-coverage difference. This is a scripted handoff on an experimental integration, not a production fix or autonomous-agent test. Per-source unknown scaling, source publication, lifecycle, cross-provider semantics and resource bounds remain unresolved as described above.

<!-- gh-comment-id:6585347320 --> @morluto commented on GitHub (Nov 2, 2026): ### Experimental typed handoff for the string trace In the unmerged pointer/typed-source prototype combined locally with main `75c3cab54` (with one manually resolved `KunaSessionClient` conflict), real Kuna 1.989 compact and full MCP traced the same string and returned source `0x100004008`. Following the linked xrefs Evidence to its stored-pointer page identified `_message`, width 8 and `chained-fixups` provenance; enumeration was qualified as metadata-only. Both profiles retained explicit unknowns for other pointers and unavailable containing-procedure resolution. The stored-pointer page was exactly equal as parsed JSON after Evidence export and import into a fresh target-free session. The fixture SHA-256 was unchanged and the target was not run. The separate instruction-reference page was empty for Kuna; Ghidra's additional instruction result remains a provider-coverage difference. This is a scripted handoff on an experimental integration, not a production fix or autonomous-agent test. Per-source unknown scaling, source publication, lifecycle, cross-provider semantics and resource bounds remain unresolved as described above.
Author
Owner

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

Controlled source-publication refusal

Using the xrefs source and completed string trace captured from the real Kuna 1.989 prototype run above, I exercised the prototype's actual retainAnalysisResultSources boundary with an injected recorder that deterministically returned a resource_constraint. The source record contained the 0x100004008 pointer and the completed trace contained that reference. The retention function returned the recorder error, with neither partialObservation nor returned sourceEvidence; its projected error likewise did not contain the completed trace or source. The recorder was called once.

This is a controlled application-boundary failure with previously captured real-provider records, not an end-to-end capacity failure, a default-capacity frequency claim, or proof of what a user can recover elsewhere in a live session. The result is consistent with the broader retention problem in #8425: making pointer provenance mandatory needs a deliberate completed-work and source-closure failure contract, rather than returning a trace with an uncommitted link or silently losing the completed observation. Test session publication, multiple source records, cancellation and response-size limits before integration.

<!-- gh-comment-id:6585430645 --> @morluto commented on GitHub (Nov 2, 2026): ### Controlled source-publication refusal Using the xrefs source and completed string trace captured from the real Kuna 1.989 prototype run above, I exercised the prototype's actual `retainAnalysisResultSources` boundary with an injected recorder that deterministically returned a `resource_constraint`. The source record contained the `0x100004008` pointer and the completed trace contained that reference. The retention function returned the recorder error, with neither `partialObservation` nor returned `sourceEvidence`; its projected error likewise did not contain the completed trace or source. The recorder was called once. This is a controlled application-boundary failure with previously captured real-provider records, not an end-to-end capacity failure, a default-capacity frequency claim, or proof of what a user can recover elsewhere in a live session. The result is consistent with the broader retention problem in #8425: making pointer provenance mandatory needs a deliberate completed-work and source-closure failure contract, rather than returning a trace with an uncommitted link or silently losing the completed observation. Test session publication, multiple source records, cancellation and response-size limits before integration.
Author
Owner

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

Real-provider MCP publication refusal

In the same unmerged current-main/pointer integration, I constructed the production BinarySession, Kuna provider and MCP server with an explicitly injected InvestigationRecords representation limit, and wrapped the admitted analysis port only to capture each same-call provider result. With real Kuna 1.989 on the owned string fixture, in both compact and full stdio MCP profiles, the wrapper observed successful xrefs containing 0x100004008. At injected limits of 0, 1,000 and 5,000 bytes, the subsequent public trace_feature call returned resource_constraint for record_evidence, with no partial_observation; the session's Evidence-bundle summary reported zero retained records. At injected 100,000- and 5,000,000-byte limits, the same workflow succeeded, returned the pointer reference and retained the xrefs, trace and two unknown records. The target SHA-256 ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d remained unchanged and it was not executed.

These are controlled session capacities, not a public configuration setting, default-capacity failure or frequency estimate. The wrapper does not alter provider results. This confirms the public handoff failure for this prototype and real fixture, beyond the preceding helper-only control; it does not by itself establish how a partially filled ledger or multi-source failure behaves. Related shared retention work: #8425.

<!-- gh-comment-id:6585529553 --> @morluto commented on GitHub (Nov 2, 2026): ### Real-provider MCP publication refusal In the same unmerged current-main/pointer integration, I constructed the production `BinarySession`, Kuna provider and MCP server with an explicitly injected `InvestigationRecords` representation limit, and wrapped the admitted analysis port only to capture each same-call provider result. With real Kuna 1.989 on the owned string fixture, in both compact and full stdio MCP profiles, the wrapper observed successful `xrefs` containing `0x100004008`. At injected limits of 0, 1,000 and 5,000 bytes, the subsequent public `trace_feature` call returned `resource_constraint` for `record_evidence`, with no `partial_observation`; the session's Evidence-bundle summary reported zero retained records. At injected 100,000- and 5,000,000-byte limits, the same workflow succeeded, returned the pointer reference and retained the xrefs, trace and two unknown records. The target SHA-256 `ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d` remained unchanged and it was not executed. These are controlled session capacities, not a public configuration setting, default-capacity failure or frequency estimate. The wrapper does not alter provider results. This confirms the public handoff failure for this prototype and real fixture, beyond the preceding helper-only control; it does not by itself establish how a partially filled ledger or multi-source failure behaves. Related shared retention work: #8425.
Author
Owner

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

Shared recovery control on the string trace

A separate older integration based on #8444 head 92adb4252 with its existing unmerged pointer-source prototype exercised the same real Kuna 1.989 string trace in full and compact stdio MCP. With production session composition and injected 0-, 1,000- and 5,000-byte retention allowances, the same call's instrumented analysis port observed the pointer before publication. The public capacity error returned the failed xrefs as partial_observation.kind: unretained-evidence and the completed trace as completed_observation.kind: unretained-evidence, with source_closure: not-established; the trace linked the supplied source ID. The session bundle contained zero records. At injected 100,000 and 5,000,000 bytes, the trace succeeded and four records were retained. Target hash stayed unchanged and the target was not executed.

This is a controlled fault and a different, older experimental integration from the current-main test above: its pointer representation and pre-#8699 release policy differ, and it reports 1.989 as unverified. It supports reusing #8444's explicit unretained-completion model, not claiming that #8444 or the pointer prototype is merged or current-main compatible. Multiple-source closure, omitted oversized responses, failure/cancellation and real cleanup remain separate verification requirements; default-capacity exhaustion frequency is unknown.

<!-- gh-comment-id:6585636725 --> @morluto commented on GitHub (Nov 2, 2026): ### Shared recovery control on the string trace A separate older integration based on #8444 head `92adb4252` with its existing unmerged pointer-source prototype exercised the same real Kuna 1.989 string trace in full and compact stdio MCP. With production session composition and injected 0-, 1,000- and 5,000-byte retention allowances, the same call's instrumented analysis port observed the pointer before publication. The public capacity error returned the failed xrefs as `partial_observation.kind: unretained-evidence` and the completed trace as `completed_observation.kind: unretained-evidence`, with `source_closure: not-established`; the trace linked the supplied source ID. The session bundle contained zero records. At injected 100,000 and 5,000,000 bytes, the trace succeeded and four records were retained. Target hash stayed unchanged and the target was not executed. This is a controlled fault and a different, older experimental integration from the current-main test above: its pointer representation and pre-#8699 release policy differ, and it reports 1.989 as unverified. It supports reusing #8444's explicit unretained-completion model, not claiming that #8444 or the pointer prototype is merged or current-main compatible. Multiple-source closure, omitted oversized responses, failure/cancellation and real cleanup remain separate verification requirements; default-capacity exhaustion frequency is unknown.
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#6636
No description provided.