[GH-ISSUE #5073] [Bug] Mixed native reference kinds discard known typed calls during fallback #3109

Closed
opened 2026-10-31 00:36:45 +00:00 by bsakaguchi · 2 comments
Owner

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

Area

Native analysis or decompilation; Evidence.

Observed behavior

A source-level fixture through readNativeCallRoutes supplies one known typed direct call (0x1004 → procedure 0x2000) and one reference with unavailable kind flags, with global reference_kinds_available:false. When fallback procedure_callees returns 0x4000, the result contains only an inferred provider_call to 0x4000; the observed call site and typed edge to 0x2000 disappear. If callee fallback is unavailable, the function returns an error with no routes despite the earlier known typed call.

Reproduction

Executed the current source helper using pinned Node 24.18/tsx and a controlled analysis port on main 29910d16b98fe4b607a7aa15928789a73614b0b9 plus an operation-name-only native-call-reader edit for #5071. No call-reader control flow has changed. Called readNativeCallRoutes(port,"0x1000") for fallback success and typed capability failure, logging actual results. Both calls execute procedure_references then procedure_callees.

Smallest outputs:

{"fallback":"success","result":{"ok":true,"routes":[{"address":"0x4000","site":"0x1000","relation":"provider_call","resolution":"inferred"}]}}
{"fallback":"failure","result":{"ok":false,"error":"AnalysisCapabilityUnavailableError","unknowns":[]}}

The fixture's missing 0x2000 call had available kind flags marking an observed direct call. No real native engine or UI archive was used.

Expected behavior

Preserve each available typed route and its original site, relation, confidence and producing provider when other references lack kind flags. Preserve fallback observations separately and keep incomplete coverage/failures explicit; an untyped inventory must not replace typed evidence already obtained.

Impact and scope

Observed in the shared application producer. Its NativeUiActionTrace.addDirectCallees consumer has no other source for the lost edge: it expands returned routes on success or emits a generic unresolved call on failure. NOT_ENOUGH_INFO for actual provider occurrence/frequency, cross-host behavior and real artifact reproduction.

Earliest failure stage

Native analysis or reconstruction, before trace projection.

Source-derived cause

src/application/native/NativeCallRoutes.ts returns typed routes only when the global flag is true or all per-reference kind flags are available. Mixed coverage instead falls back wholesale; only unresolved-call observations and limitations are retained. src/application/native/NativeUiActionTrace.ts consumes this all-or-error representation. Review ownership of routes/provenance/partial facts rather than requiring both capabilities or changing discovery to hide the defect.

Searched current open narratives and open/closed titles. #3922 concerns downstream node-bound branches replacing known relation kinds; this loss occurs with adequate node budget, before that branch. #2565's targetless-site retention and #3343's Objective-C receiver join are also distinct. Related discovery issue #5071 does not repair this producer.

Originally created by @morluto on GitHub (Oct 18, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5073 ### Area Native analysis or decompilation; Evidence. ### Observed behavior A source-level fixture through `readNativeCallRoutes` supplies one known typed direct call (`0x1004` → procedure `0x2000`) and one reference with unavailable kind flags, with global `reference_kinds_available:false`. When fallback `procedure_callees` returns `0x4000`, the result contains only an inferred `provider_call` to `0x4000`; the observed call site and typed edge to `0x2000` disappear. If callee fallback is unavailable, the function returns an error with no routes despite the earlier known typed call. ### Reproduction Executed the current source helper using pinned Node 24.18/tsx and a controlled analysis port on main `29910d16b98fe4b607a7aa15928789a73614b0b9` plus an operation-name-only native-call-reader edit for #5071. No call-reader control flow has changed. Called `readNativeCallRoutes(port,"0x1000")` for fallback success and typed capability failure, logging actual results. Both calls execute `procedure_references` then `procedure_callees`. Smallest outputs: ```json {"fallback":"success","result":{"ok":true,"routes":[{"address":"0x4000","site":"0x1000","relation":"provider_call","resolution":"inferred"}]}} {"fallback":"failure","result":{"ok":false,"error":"AnalysisCapabilityUnavailableError","unknowns":[]}} ``` The fixture's missing `0x2000` call had available kind flags marking an observed direct call. No real native engine or UI archive was used. ### Expected behavior Preserve each available typed route and its original site, relation, confidence and producing provider when other references lack kind flags. Preserve fallback observations separately and keep incomplete coverage/failures explicit; an untyped inventory must not replace typed evidence already obtained. ### Impact and scope Observed in the shared application producer. Its `NativeUiActionTrace.addDirectCallees` consumer has no other source for the lost edge: it expands returned routes on success or emits a generic unresolved call on failure. NOT_ENOUGH_INFO for actual provider occurrence/frequency, cross-host behavior and real artifact reproduction. ### Earliest failure stage Native analysis or reconstruction, before trace projection. ### Source-derived cause `src/application/native/NativeCallRoutes.ts` returns typed routes only when the global flag is true or all per-reference kind flags are available. Mixed coverage instead falls back wholesale; only unresolved-call observations and limitations are retained. `src/application/native/NativeUiActionTrace.ts` consumes this all-or-error representation. Review ownership of routes/provenance/partial facts rather than requiring both capabilities or changing discovery to hide the defect. Searched current open narratives and open/closed titles. #3922 concerns downstream node-bound branches replacing known relation kinds; this loss occurs with adequate node budget, before that branch. #2565's targetless-site retention and #3343's Objective-C receiver join are also distinct. Related discovery issue #5071 does not repair this producer.
bsakaguchi 2026-10-31 00:36:45 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@CassieFox23 commented on GitHub (Oct 18, 2026):

TL;DR: I can reproduce this on main 32f0e5120. The typed call to 0x2000 is lost in both fallback cases. The results match the issue. I have a fix, and I can open a PR if its shape suits you.

My test gives readNativeCallRoutes two references. One is a typed direct call, 0x1004 to 0x2000. The other has unavailable kind flags. The global flag is false.

  • Callees fallback returns 0x4000: the only route is the inferred provider_call to 0x4000.
  • Callees fallback raises AnalysisCapabilityUnavailableError: the result is ok:false with no routes.

The test failed 2 of 2 on Node 22.23.1, 24.18.0 and 26.11.1.

A possible fix

I have a fix that passes on all three Node versions. It keeps the typed routes and adds the inferred ones. A typed route wins when both name the same target. When callees are unavailable, it returns the typed routes with a procedure_callees limitation.

It needs one new optional field: a provider on each route. That way the merged list says which provider found each call. One change to flag: with typed routes present, the generic unknown-callees edge goes away. The gap shows as the limitation instead.

Is that the shape you want? If so, I'd like to open a PR for it.

Not run

  • A real native engine or UI archive. The test uses a fixture, as the issue did.
Commands
  • npm ci
  • npm run test:focused -- src/application/native/NativeCallRoutes5073.test.ts (my own test file, not in the repo)
Test setup
  • Box: Nobara 44 (Fedora 44 base), Linux 7.2.9
  • CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads
  • RAM: 32 GB DDR4-3600
  • Node: 22.23.1, 24.18.0, 26.11.1
  • Head: 32f0e5120. The issue used 29910d16b. Since then NativeCallRoutes.ts only gained a constant; no control flow changed.

🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊

<!-- gh-comment-id:6255605611 --> @CassieFox23 commented on GitHub (Oct 18, 2026): **TL;DR:** I can reproduce this on main 32f0e5120. The typed call to `0x2000` is lost in both fallback cases. The results match the issue. I have a fix, and I can open a PR if its shape suits you. My test gives `readNativeCallRoutes` two references. One is a typed direct call, `0x1004` to `0x2000`. The other has unavailable kind flags. The global flag is false. - Callees fallback returns `0x4000`: the only route is the inferred `provider_call` to `0x4000`. - Callees fallback raises `AnalysisCapabilityUnavailableError`: the result is `ok:false` with no routes. The test failed 2 of 2 on Node 22.23.1, 24.18.0 and 26.11.1. ### A possible fix I have a fix that passes on all three Node versions. It keeps the typed routes and adds the inferred ones. A typed route wins when both name the same target. When callees are unavailable, it returns the typed routes with a `procedure_callees` limitation. It needs one new optional field: a `provider` on each route. That way the merged list says which provider found each call. One change to flag: with typed routes present, the generic `unknown-callees` edge goes away. The gap shows as the limitation instead. Is that the shape you want? If so, I'd like to open a PR for it. ### Not run - A real native engine or UI archive. The test uses a fixture, as the issue did. <details> <summary>Commands</summary> - `npm ci` - `npm run test:focused -- src/application/native/NativeCallRoutes5073.test.ts` (my own test file, not in the repo) </details> <details> <summary>Test setup</summary> - Box: Nobara 44 (Fedora 44 base), Linux 7.2.9 - CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads - RAM: 32 GB DDR4-3600 - Node: 22.23.1, 24.18.0, 26.11.1 - Head: 32f0e5120. The issue used 29910d16b. Since then `NativeCallRoutes.ts` only gained a constant; no control flow changed. </details> 🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊
Author
Owner

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

Fixed on main in 65884350f.

The aggregate availability gate discarded individually known calls, and the old success/error shape plus one provider could not represent partial results. The shared reader now returns retained routes, targetless sites and limitations alongside a separate tagged Result outcome. Each route owns its producing provider and call site. Individually unknown kinds remain unknown even when the aggregate flag says available. Fallback adds distinct inferred targets without replacing typed calls or collapsing their separate sites; its failure remains explicit. The consumer emits retained facts before the enumeration-failure marker, while cancellation remains terminal.

Validation: 69 focused cases passed, followed by a final 30-case rerun and the final 9-case public MCP assertion check. The public regressions cover mixed kinds, failed fallback, overlap, cancellation, direct/indirect/provider node omissions and shared-target sites. Before the fixes, the corrected committed-baseline public fixture failed 6/8 cases; the additional identity regression failed with 8 controls passing. Full static/architecture checks, docs, test discovery (1,593 files), hooks and pre-push checks passed. These are controlled providers through the actual SDK/server path; real native-engine behavior remains unverified. Current-head CI runs separately in the background.

Separate follow-up: Hopper also emits call.classification metadata while detailed reference flags are unavailable. This change does not reinterpret those provider-specific classifications as full generic flags; mapping them, especially Objective-C classifications, needs separate provider evidence.

A six-workflow compiled SDK control preserved the complete normalized trace and 207-tool catalog. Separate first-process runs plus two warm repetitions per variant gave baseline→candidate warm medians of 2.234→2.213 seconds elapsed, 2.930→2.900 seconds CPU and 743.4→737.0 MB sampled process-family memory. Full SDK-response estimates were 822,080→822,078 cl100k tokens; catalog and trace responses were identical, and inventory UUID/time/checkout-path values vary. This is not actual model-context usage or a general speedup claim. Mixed/fault paths, real providers and other hosts were not timed.

<!-- gh-comment-id:6256140553 --> @morluto commented on GitHub (Oct 18, 2026): Fixed on main in [65884350f](https://github.com/morluto/rea/commit/65884350ff3373f2adc7337c1945eeb54334693f). The aggregate availability gate discarded individually known calls, and the old success/error shape plus one provider could not represent partial results. The shared reader now returns retained routes, targetless sites and limitations alongside a separate tagged `Result` outcome. Each route owns its producing provider and call site. Individually unknown kinds remain unknown even when the aggregate flag says available. Fallback adds distinct inferred targets without replacing typed calls or collapsing their separate sites; its failure remains explicit. The consumer emits retained facts before the enumeration-failure marker, while cancellation remains terminal. Validation: 69 focused cases passed, followed by a final 30-case rerun and the final 9-case public MCP assertion check. The public regressions cover mixed kinds, failed fallback, overlap, cancellation, direct/indirect/provider node omissions and shared-target sites. Before the fixes, the corrected committed-baseline public fixture failed 6/8 cases; the additional identity regression failed with 8 controls passing. Full static/architecture checks, docs, test discovery (1,593 files), hooks and pre-push checks passed. These are controlled providers through the actual SDK/server path; real native-engine behavior remains unverified. Current-head CI runs separately in the background. Separate follow-up: Hopper also emits `call.classification` metadata while detailed reference flags are unavailable. This change does not reinterpret those provider-specific classifications as full generic flags; mapping them, especially Objective-C classifications, needs separate provider evidence. A six-workflow compiled SDK control preserved the complete normalized trace and 207-tool catalog. Separate first-process runs plus two warm repetitions per variant gave baseline→candidate warm medians of 2.234→2.213 seconds elapsed, 2.930→2.900 seconds CPU and 743.4→737.0 MB sampled process-family memory. Full SDK-response estimates were 822,080→822,078 `cl100k` tokens; catalog and trace responses were identical, and inventory UUID/time/checkout-path values vary. This is not actual model-context usage or a general speedup claim. Mixed/fault paths, real providers and other hosts were not timed.
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#3109
No description provided.