[GH-ISSUE #5131] [Bug] Function references treat generated procedure labels as cross-artifact identity #3154

Closed
opened 2026-10-31 00:37:17 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

  • Searched open and closed issues for related reports.
  • Removed credentials and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

Controlled public compare_functions calls treat generated reference endpoint names as stable identities across different artifacts. Equal sub_..., fcn...., or FUN_... labels can produce references: unchanged; different generated labels can produce changed, even though their address-derived names do not establish cross-artifact identity. A same-artifact coordinate control remains meaningful independently of those labels.

Reproduction

Executed official-SDK MCP calls with canonical analyze_function Evidence fixtures, one outgoing reference per function, complete generic call flags, and different artifact digests. The target procedure name was an address-derived name on both sides. Tested same and differing generated labels. The committed baseline returned unsupported equality/difference rather than unknown. No analysis provider was launched. The public regression was run against isolated source revision 559af3d3ff.

Expected behavior

Generated names are display facts, not stable cross-artifact endpoint identities. Preserve them in source Evidence, keep identity unknown, and let independent known facts still establish contradictions. Within one artifact, exact coordinates can establish identity despite a generated or missing name.

Impact and scope

Observed on controlled admitted Evidence inputs. This can support an unjustified structural comparison verdict. Runtime frequency in real provider output and published-package behavior: NOT_ENOUGH_INFO; those were not measured.

REA version

559af3d3ff

Runtime and platform

Node 24.18.0; macOS arm64; official MCP SDK in-memory transport.

Target and artifact context

Controlled Mach-O function dossier Evidence with distinct source digests; no executable analyzed.

Interface

MCP

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

The existing isAutoName policy excludes address-derived names for function matching. The same module's reference endpoint projection uses every non-null procedure name as identity without this check. The public fixture confirms that the discrepancy reaches compare_functions, rather than being only a hypothetical source path.

Analysis

Source-derived cause: reference normalization conflates a present display name with a stable endpoint identity. Related #4210 covers named-versus-missing endpoint asymmetry. #1947 concerns opaque text dimensions, which are separate from reference identity. The related review also found observed non-unique procedure names require ambiguity preservation; that broader case remains separately identified in the regression suite.

Originally created by @morluto on GitHub (Oct 18, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5131 ### Before submitting - [x] Searched open and closed issues for related reports. - [x] Removed credentials and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior Controlled public `compare_functions` calls treat generated reference endpoint names as stable identities across different artifacts. Equal `sub_...`, `fcn....`, or `FUN_...` labels can produce `references: unchanged`; different generated labels can produce `changed`, even though their address-derived names do not establish cross-artifact identity. A same-artifact coordinate control remains meaningful independently of those labels. ### Reproduction Executed official-SDK MCP calls with canonical `analyze_function` Evidence fixtures, one outgoing reference per function, complete generic call flags, and different artifact digests. The target procedure name was an address-derived name on both sides. Tested same and differing generated labels. The committed baseline returned unsupported equality/difference rather than unknown. No analysis provider was launched. The public regression was run against isolated source revision 559af3d3ff4b0236d468e80788c82d5a85b102da. ### Expected behavior Generated names are display facts, not stable cross-artifact endpoint identities. Preserve them in source Evidence, keep identity unknown, and let independent known facts still establish contradictions. Within one artifact, exact coordinates can establish identity despite a generated or missing name. ### Impact and scope Observed on controlled admitted Evidence inputs. This can support an unjustified structural comparison verdict. Runtime frequency in real provider output and published-package behavior: NOT_ENOUGH_INFO; those were not measured. ### REA version 559af3d3ff4b0236d468e80788c82d5a85b102da ### Runtime and platform Node 24.18.0; macOS arm64; official MCP SDK in-memory transport. ### Target and artifact context Controlled Mach-O function dossier Evidence with distinct source digests; no executable analyzed. ### Interface MCP ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence The existing [isAutoName policy](https://github.com/morluto/rea/blob/559af3d3ff4b0236d468e80788c82d5a85b102da/src/domain/functionComparisonNormalization.ts) excludes address-derived names for function matching. The same module's reference endpoint projection uses every non-null procedure name as identity without this check. The public fixture confirms that the discrepancy reaches `compare_functions`, rather than being only a hypothetical source path. ### Analysis Source-derived cause: reference normalization conflates a present display name with a stable endpoint identity. Related #4210 covers named-versus-missing endpoint asymmetry. #1947 concerns opaque text dimensions, which are separate from reference identity. The related review also found observed non-unique procedure names require ambiguity preservation; that broader case remains separately identified in the regression suite.
bsakaguchi 2026-10-31 00:37:17 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

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

Fixed on main in 92dadf933.

The old projections discarded endpoint uncertainty before comparing rows and erased all reference-kind facts if any row lacked a kind. They also substituted containing procedures for raw same-artifact sites and treated generated/nonunique names as sufficient cross-artifact identity.

A shared reference-fact owner now preserves direction, per-edge kind knowledge, exact same-artifact coordinates and cross-artifact identity uncertainty. Exact compatible pairing retains duplicates and alternatives; a known contradiction proves change only when every pairing contradicts it. The matcher uses a sparse grouped flow graph and iterative walks, replacing quadratic adjacency storage and recursive matching proposed in the existing PR. Native coordinate parsing is shared with call paths; superseded projections were removed. The matching insight from PR #4365 is credited to Henglie in the commit; neither PR #4365 nor #4337 was merged.

Validation executed: 199 focused tests across 11 files, including public MCP comparison/reconstruction, call-path consumers and 15 advertised-schema checks; final expanded public regressions 5/5; independent tiny permutation oracles and 10,000-row dense controls; full static/architecture checks, docs checks (5 conformance tests), discovery and pre-push checks. A clean baseline at 559af3d3f reproduced the public regressions before the fix. Tests use authenticated controlled Evidence; no native engine or binary executed.

Twelve compiled public SDK measurements included discovery and request/reply serialization estimates. Four-row equivalent control repeated-process medians: elapsed 2.154→2.155 s, CPU 2.846→2.867 s, sampled process-family RSS 741→744 MB; request tokens 2,104 unchanged, SDK reply estimate 811,565→811,577 cl100k tokens including the full 207-tool catalog. Catalog hash unchanged. The 1,000-row partial-identity case now correctly returns unknown instead of changed, so its before/after costs are not an equivalent-result speed comparison. No speedup, actual model-context, true cold-cache, adversarial worst-case runtime or real-provider qualification is claimed. Graph storage is linear in distinct row groups; general worst-case flow time remains cubic, applying the general max-flow bound to this linear graph.

The adjacent public consumer scan also reproduced existing #3333 for distinct unresolved reconstruction verifications in one session; that separate registry-identity defect is fixed in 95c8f57aa. Whole-facet unavailable declarations intentionally remain unknown; this change concerns available facets with partial per-row knowledge.

<!-- gh-comment-id:6256664442 --> @morluto commented on GitHub (Oct 18, 2026): Fixed on main in [92dadf933](https://github.com/morluto/rea/commit/92dadf933). The old projections discarded endpoint uncertainty before comparing rows and erased all reference-kind facts if any row lacked a kind. They also substituted containing procedures for raw same-artifact sites and treated generated/nonunique names as sufficient cross-artifact identity. A shared reference-fact owner now preserves direction, per-edge kind knowledge, exact same-artifact coordinates and cross-artifact identity uncertainty. Exact compatible pairing retains duplicates and alternatives; a known contradiction proves change only when every pairing contradicts it. The matcher uses a sparse grouped flow graph and iterative walks, replacing quadratic adjacency storage and recursive matching proposed in the existing PR. Native coordinate parsing is shared with call paths; superseded projections were removed. The matching insight from PR #4365 is credited to Henglie in the commit; neither PR #4365 nor #4337 was merged. Validation executed: 199 focused tests across 11 files, including public MCP comparison/reconstruction, call-path consumers and 15 advertised-schema checks; final expanded public regressions 5/5; independent tiny permutation oracles and 10,000-row dense controls; full static/architecture checks, docs checks (5 conformance tests), discovery and pre-push checks. A clean baseline at 559af3d3f reproduced the public regressions before the fix. Tests use authenticated controlled Evidence; no native engine or binary executed. Twelve compiled public SDK measurements included discovery and request/reply serialization estimates. Four-row equivalent control repeated-process medians: elapsed 2.154→2.155 s, CPU 2.846→2.867 s, sampled process-family RSS 741→744 MB; request tokens 2,104 unchanged, SDK reply estimate 811,565→811,577 cl100k tokens including the full 207-tool catalog. Catalog hash unchanged. The 1,000-row partial-identity case now correctly returns unknown instead of changed, so its before/after costs are not an equivalent-result speed comparison. No speedup, actual model-context, true cold-cache, adversarial worst-case runtime or real-provider qualification is claimed. Graph storage is linear in distinct row groups; general worst-case flow time remains cubic, applying the [general max-flow bound](https://atcoder.github.io/ac-library/production/document_en/maxflow.html) to this linear graph. The adjacent public consumer scan also reproduced existing #3333 for distinct unresolved reconstruction verifications in one session; that separate registry-identity defect is fixed in [95c8f57aa](https://github.com/morluto/rea/commit/95c8f57aa). Whole-facet unavailable declarations intentionally remain unknown; this change concerns available facets with partial per-row knowledge.
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#3154
No description provided.