[PR #4417] feat(call-path): trace multiple goals and report backward roots #6228

Open
opened 2026-10-31 01:12:51 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4417
Author: @ogutdgn
Created: 10/16/2026
Status: 🔄 Open

Base: main ← Head: feat/4247-call-path-goals


📝 Commits (10+)

  • 611ca88 feat(call-path): trace multiple goals and report backward roots
  • d529e03 fix(call-path): keep verifier fixture calls direct on ELF
  • 5bff9dd fix(call-path): integrate upstream traversal modes
  • e2333ab fix(call-path): complete verifier cleanup after failures
  • b1855de Merge branch 'main' into feat/4247-call-path-goals
  • 5d993a8 fix(call-path): preserve goals across upstream refactors
  • 08ff2cf chore(call-path): restore unrelated upstream imports
  • b1331c5 chore(call-path): merge upstream CI repairs
  • 4c3e777 fix(ci): remove unused hex-region type alias
  • 1d44d12 chore(call-path): resolve upstream metadata conflict

📊 Changes

14 files changed (+1014 additions, -43 deletions)

View changed files

📝 docs/mcp-contracts.md (+26 -0)
📝 docs/testing.md (+10 -0)
📝 package.json (+1 -0)
➕ scripts/verify-call-path-goals.mjs (+254 -0)
📝 src/application/CallPathTracing.ts (+37 -3)
📝 src/application/EnhancedToolSelectorOrigin.test.ts (+33 -30)
📝 src/contracts/enhancedInputs.ts (+20 -8)
📝 src/contracts/enhancedToolContracts.ts (+1 -1)
📝 src/contracts/toolContractExamples.ts (+5 -1)
📝 src/contracts/toolOutputSchemaGroups.ts (+8 -0)
➕ tests/boundary/mcp/enhancedTools.multiGoalCallPaths.test.ts (+233 -0)
➕ tests/boundary/mcp/enhancedTools.multiGoalEdges.test.ts (+226 -0)
➕ tests/boundary/process/callPathGoalsVerifier.test.ts (+142 -0)
➕ tests/conformance/native/call-path-goals.c (+18 -0)

📄 Description

Summary

Checking several candidate callers currently repeats trace_call_path traversal and requires deriving roots manually. Accept goals to return a status and shortest path for each candidate in one traversal, plus confirmed backward roots. Fixes #4247.

Problem and expected behavior

For a backward search from a sink, return which selected functions reach it through observed calls. Missing relationship information must leave unreached goals unknown; a root requires a complete, empty caller read.

Change and scope

Reuse the application-layer breadth-first search for an exhaustive batch. Preserve upstream parent-link traversal and reconstruct paths only for requested goals. Preserve single-goal early stopping and existing fields; reject simultaneous goal and goals. Update contracts, examples, documentation, and verification. Runtime reachability and automatic entry-point/export discovery are outside this feature. The verifier hides internal fixture symbols while explicitly exporting its two candidate entry points, avoiding ELF PLT indirection. Documentation explains that roots belong to the observed graph and that stubs and bodies may remain separate.

Contract and boundary impact

  • Semantic owner and earliest changed stage: canonical input validation and CallPathTracing.
  • Contribution scope fit and linked maintainer decision: extends existing static relationship reads; no new provider or target execution/mutation capability requiring an advance decision.
  • CLI and MCP/tool-catalog contract: optional goals; additive goal_results and roots. Batch legacy top-level fields are neutral; individual answers are in goal_results. No new dedicated CLI command.
  • Provider, bridge, target-format, or platform compatibility: existing caller/callee ports; no adapter changes.
  • Evidence, artifact, provenance, or reconstruction contract: retain supplied selectors in parameters, canonical output addresses, requested goal order/duplicates, failures, coverage and indirect-call limitations.
  • Target selection, authority, upstream behavior, and cleanup: existing selected document and provider-owned helper/project lifecycle. The verifier uses upstream withVerifierCleanup to attempt session, client, transport, observation, and fixture cleanup independently, retaining primary and cleanup errors; no target binary execution or byte modification.
  • Generated metadata, package, or installation impact: regenerate/check ignored catalogs; add a verifier npm command. No dependency, installation, or release-version changes.

Expected effects inherit existing analysis providers: helper processes/scripts and temporary analysis files; no new target authority.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

The checked script/file effects refer to existing provider bridge scripts and temporary analysis projects, not target instrumentation or target modification.

Evidence and regression coverage

  • Tests added or updated: shortest paths, roots, complete/partial/missing/failed reads, aliases/duplicates, cycles, malformed selections, cancellation, and legacy behavior. A compiled C fixture exercises real providers through stdio MCP. Eight subprocess failure-injection cases run the actual verifier entrypoint with controlled dependencies, covering analysis, session close/check, client/transport close, snapshot/lineage checks, and fixture-removal failures.

  • Base reproduction: compiled baseline rejects goals as an unrecognized key. Current upstream still lacks batch goals; its shared direction schema and traversal mapping are preserved by this change.

  • User-visible result: a backward search from sink returns export A as reached through [sink, helper2, helper1, exportA], unrelated export B as not_reached with complete direct-call coverage, and export A as a root only after its complete empty caller read.

  • Remaining proof gaps: current merged revision checked on macOS arm64 with real Ghidra and Hopper. No fresh Linux, Windows, IDA or full-suite run. Hopper reports unknown relationship completeness, so it cannot confirm roots.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

Against upstream 1da304b28, using Node 24.22.1 / npm 11.16.0 on macOS arm64:

  • npm run test:focused -- <31 files below> — 431 tests passed, including multi-goal tracing, cancellation-reason identity, schemas, lifecycle regressions and upstream Hopper caller reconciliation.
  • node scripts/verify-call-path-goals.mjs ghidra and node scripts/verify-call-path-goals.mjs hopper — passed, including requested paths, selectors, single/self goals, process cleanup and fixture removal. Ghidra confirms roots; Hopper retains unknown coverage and empty roots.
  • node scripts/verify-real-hopper-callers.mjs — passed, including reverse caller observations and progress/cancellation/retry checks.
  • npm run check — failed at Knip on duplicate exports MAX_PROVIDER_STARTUP_TIMEOUT_MS|MAXIMUM_HOPPER_CALLER_SCAN_BUDGET_MS in src/domain/analysisResourceLimits.ts. The exact same finding occurs in CI for the upstream base; this file is unchanged by the PR.
  • npm run check:fast, npm run verify:architecture-guards, npm run knip:production, npm run lint:typed, npm run docs:check and npm run mcp-catalog:check:built — passed; existing lint advisories remain.
  • git diff --check — passed. Fresh hosted CI is pending after this update.

Resolved the metadata conflict by retaining upstream's complete file: upstream independently removed the unused alias, so that file is no longer in this PR's diff. The cancellation-reason fix remains intact. No fresh Linux, Windows, IDA or full-suite local run is claimed.

Focused test selection
tests/boundary/mcp/enhancedTools.multiGoalCallPaths.test.ts
tests/boundary/mcp/enhancedTools.multiGoalEdges.test.ts
tests/boundary/mcp/enhancedTools.callPathsAndBatches.test.ts
src/application/EnhancedToolSelectorOrigin.test.ts
src/application/CallPathTracing.test.ts
tests/composition/callPathGraphOracle.test.ts
tests/composition/callPathParserOperation.test.ts
tests/boundary/mcp/callPathSearchExtentMcp.test.ts
tests/boundary/mcp/enhancedTools.traceFeatureCoverage.test.ts
src/domain/native/nativeInvestigationGraph.test.ts
tests/boundary/mcp/nativeUiAvailability.test.ts
tests/boundary/mcp/toolSchemaValidity.test.ts
tests/boundary/mcp/outputSchemaProfile.test.ts
tests/boundary/mcp/compactInputSchemaMcp.test.ts
tests/conformance/contracts/mcpInputSchemaProfile.test.ts
tests/boundary/mcp/callRelationshipAvailability.test.ts
src/application/CapabilityInventory.test.ts
tests/boundary/process/callPathGoalsVerifier.test.ts
tests/boundary/process/verifierCleanup.test.ts
tests/composition/analysis-sessions/providerBinding.test.ts
src/domain/apple/appleApplication.test.ts
src/windows/WindowsNativeLoader.test.ts
tests/boundary/process/processCaptureLifecycle.test.ts
tests/boundary/process/processCleanupRetryOwnership.test.ts
tests/boundary/filesystem/ciPrHealth.test.ts
tests/boundary/filesystem/clientConfigurationBom.test.ts
tests/boundary/filesystem/clientRegistrationRefresh.test.ts
src/hopper/HopperCallerReconciliation.test.ts
src/hopper/HopperProvider.test.ts
tests/boundary/providers/hopper/hopperCallerReconciliation.test.ts
src/domain/callPath.test.ts

Earlier ELF x86-64 verification on 5bff9dd38 used Ghidra on macOS; it was not rerun for this merge. A prior controlled injected-graph comparison produced identical answers with 4 versus 7 relationship reads; no native-engine speedup or token savings are claimed.

Compatibility, safety, and release

  • Breaking changes or migration steps: none; single-goal behavior remains. Exhaustive batches can cost more than one early-stop request.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS arm64, Ghidra 12.1.4/JDK 21 and Hopper 6.6.0 demo; ELF x86-64 fixture checked on the preceding revision with Ghidra on macOS. No browser changes.
  • Package or release metadata impact: additive tool contract and verifier command; no version bump.
  • Security, privacy, process, or containment review: existing read-only target analysis; roots are not guaranteed entry points, and indirect calls can remain unresolved.

Author readiness

Human owner: @ogutdgn

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

Maintainer blocker verification

The open helper finding cites morluto/preference, a different repository. REA has no publicInputStrictObject helper or that referenced policy; its canonical public contracts use Zod strict objects. The named trace_call_path contract therefore follows REA's owning representation without importing another project's wrapper. No code change is warranted for that finding. On Node 24.18.0/npm 11.16.0, npm run test:local -- src/domain/callPath.test.ts tests/composition/callPathParserOperation.test.ts passed 30 tests. Existing real-provider verification and graph-size/cardinality limitations remain as documented above; this pass did not rerun providers.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4417 **Author:** [@ogutdgn](https://github.com/ogutdgn) **Created:** 10/16/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/4247-call-path-goals` --- ### 📝 Commits (10+) - [`611ca88`](https://github.com/morluto/rea/commit/611ca8842c030bcdd25187a48a7f7e0a2a573913) feat(call-path): trace multiple goals and report backward roots - [`d529e03`](https://github.com/morluto/rea/commit/d529e03b10e886f50f34d5d4f98b3e2a3de213c0) fix(call-path): keep verifier fixture calls direct on ELF - [`5bff9dd`](https://github.com/morluto/rea/commit/5bff9dd38401a6d33703e79bf5914b4552ff2541) fix(call-path): integrate upstream traversal modes - [`e2333ab`](https://github.com/morluto/rea/commit/e2333ab6a325d90d2f46c3ff748587ec48f1dd3f) fix(call-path): complete verifier cleanup after failures - [`b1855de`](https://github.com/morluto/rea/commit/b1855deae6c825400720248fa98406e785bbdc16) Merge branch 'main' into feat/4247-call-path-goals - [`5d993a8`](https://github.com/morluto/rea/commit/5d993a8f3b85f49d6a88d8ce9c4bd14e589ea9af) fix(call-path): preserve goals across upstream refactors - [`08ff2cf`](https://github.com/morluto/rea/commit/08ff2cf61b18a3a9e11bbf473fe1e3feb3d92318) chore(call-path): restore unrelated upstream imports - [`b1331c5`](https://github.com/morluto/rea/commit/b1331c5d03a11594ed819e76279c39b1d859c5b8) chore(call-path): merge upstream CI repairs - [`4c3e777`](https://github.com/morluto/rea/commit/4c3e777280fdba599c2262cde80f1d788de17987) fix(ci): remove unused hex-region type alias - [`1d44d12`](https://github.com/morluto/rea/commit/1d44d12807deda350328416f6afc10107d34625d) chore(call-path): resolve upstream metadata conflict ### 📊 Changes **14 files changed** (+1014 additions, -43 deletions) <details> <summary>View changed files</summary> 📝 `docs/mcp-contracts.md` (+26 -0) 📝 `docs/testing.md` (+10 -0) 📝 `package.json` (+1 -0) ➕ `scripts/verify-call-path-goals.mjs` (+254 -0) 📝 `src/application/CallPathTracing.ts` (+37 -3) 📝 `src/application/EnhancedToolSelectorOrigin.test.ts` (+33 -30) 📝 `src/contracts/enhancedInputs.ts` (+20 -8) 📝 `src/contracts/enhancedToolContracts.ts` (+1 -1) 📝 `src/contracts/toolContractExamples.ts` (+5 -1) 📝 `src/contracts/toolOutputSchemaGroups.ts` (+8 -0) ➕ `tests/boundary/mcp/enhancedTools.multiGoalCallPaths.test.ts` (+233 -0) ➕ `tests/boundary/mcp/enhancedTools.multiGoalEdges.test.ts` (+226 -0) ➕ `tests/boundary/process/callPathGoalsVerifier.test.ts` (+142 -0) ➕ `tests/conformance/native/call-path-goals.c` (+18 -0) </details> ### 📄 Description ## Summary Checking several candidate callers currently repeats `trace_call_path` traversal and requires deriving roots manually. Accept `goals` to return a status and shortest path for each candidate in one traversal, plus confirmed backward roots. Fixes #4247. ## Problem and expected behavior For a backward search from a sink, return which selected functions reach it through observed calls. Missing relationship information must leave unreached goals `unknown`; a root requires a complete, empty caller read. ## Change and scope Reuse the application-layer breadth-first search for an exhaustive batch. Preserve upstream parent-link traversal and reconstruct paths only for requested goals. Preserve single-`goal` early stopping and existing fields; reject simultaneous `goal` and `goals`. Update contracts, examples, documentation, and verification. Runtime reachability and automatic entry-point/export discovery are outside this feature. The verifier hides internal fixture symbols while explicitly exporting its two candidate entry points, avoiding ELF PLT indirection. Documentation explains that roots belong to the observed graph and that stubs and bodies may remain separate. ## Contract and boundary impact - Semantic owner and earliest changed stage: canonical input validation and `CallPathTracing`. - Contribution scope fit and linked maintainer decision: extends existing static relationship reads; no new provider or target execution/mutation capability requiring an advance decision. - CLI and MCP/tool-catalog contract: optional `goals`; additive `goal_results` and `roots`. Batch legacy top-level fields are neutral; individual answers are in `goal_results`. No new dedicated CLI command. - Provider, bridge, target-format, or platform compatibility: existing caller/callee ports; no adapter changes. - Evidence, artifact, provenance, or reconstruction contract: retain supplied selectors in parameters, canonical output addresses, requested goal order/duplicates, failures, coverage and indirect-call limitations. - Target selection, authority, upstream behavior, and cleanup: existing selected document and provider-owned helper/project lifecycle. The verifier uses upstream `withVerifierCleanup` to attempt session, client, transport, observation, and fixture cleanup independently, retaining primary and cleanup errors; no target binary execution or byte modification. - Generated metadata, package, or installation impact: regenerate/check ignored catalogs; add a verifier npm command. No dependency, installation, or release-version changes. Expected effects inherit existing analysis providers: helper processes/scripts and temporary analysis files; no new target authority. - [x] Read existing files or captured data. - [x] Launch or attach to a process. - [x] Inject instrumentation or run scripts/code. - [x] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. The checked script/file effects refer to existing provider bridge scripts and temporary analysis projects, not target instrumentation or target modification. ## Evidence and regression coverage - Tests added or updated: shortest paths, roots, complete/partial/missing/failed reads, aliases/duplicates, cycles, malformed selections, cancellation, and legacy behavior. A compiled C fixture exercises real providers through stdio MCP. Eight subprocess failure-injection cases run the actual verifier entrypoint with controlled dependencies, covering analysis, session close/check, client/transport close, snapshot/lineage checks, and fixture-removal failures. - Base reproduction: compiled baseline rejects `goals` as an unrecognized key. Current upstream still lacks batch goals; its shared direction schema and traversal mapping are preserved by this change. - User-visible result: a backward search from `sink` returns export A as `reached` through `[sink, helper2, helper1, exportA]`, unrelated export B as `not_reached` with complete direct-call coverage, and export A as a root only after its complete empty caller read. - Remaining proof gaps: current merged revision checked on macOS arm64 with real Ghidra and Hopper. No fresh Linux, Windows, IDA or full-suite run. Hopper reports unknown relationship completeness, so it cannot confirm roots. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Against upstream `1da304b28`, using Node 24.22.1 / npm 11.16.0 on macOS arm64: - `npm run test:focused -- <31 files below>` — **431 tests passed**, including multi-goal tracing, cancellation-reason identity, schemas, lifecycle regressions and upstream Hopper caller reconciliation. - `node scripts/verify-call-path-goals.mjs ghidra` and `node scripts/verify-call-path-goals.mjs hopper` — **passed**, including requested paths, selectors, single/self goals, process cleanup and fixture removal. Ghidra confirms roots; Hopper retains unknown coverage and empty roots. - `node scripts/verify-real-hopper-callers.mjs` — **passed**, including reverse caller observations and progress/cancellation/retry checks. - `npm run check` — **failed at Knip** on duplicate exports `MAX_PROVIDER_STARTUP_TIMEOUT_MS|MAXIMUM_HOPPER_CALLER_SCAN_BUDGET_MS` in `src/domain/analysisResourceLimits.ts`. The exact same finding occurs in [CI for the upstream base](https://github.com/morluto/rea/actions/runs/40940269684/job/123681643355); this file is unchanged by the PR. - `npm run check:fast`, `npm run verify:architecture-guards`, `npm run knip:production`, `npm run lint:typed`, `npm run docs:check` and `npm run mcp-catalog:check:built` — **passed**; existing lint advisories remain. - `git diff --check` — **passed**. Fresh hosted CI is pending after this update. Resolved the metadata conflict by retaining upstream's complete file: upstream independently removed the unused alias, so that file is no longer in this PR's diff. The cancellation-reason fix remains intact. No fresh Linux, Windows, IDA or full-suite local run is claimed. <details> <summary>Focused test selection</summary> ```text tests/boundary/mcp/enhancedTools.multiGoalCallPaths.test.ts tests/boundary/mcp/enhancedTools.multiGoalEdges.test.ts tests/boundary/mcp/enhancedTools.callPathsAndBatches.test.ts src/application/EnhancedToolSelectorOrigin.test.ts src/application/CallPathTracing.test.ts tests/composition/callPathGraphOracle.test.ts tests/composition/callPathParserOperation.test.ts tests/boundary/mcp/callPathSearchExtentMcp.test.ts tests/boundary/mcp/enhancedTools.traceFeatureCoverage.test.ts src/domain/native/nativeInvestigationGraph.test.ts tests/boundary/mcp/nativeUiAvailability.test.ts tests/boundary/mcp/toolSchemaValidity.test.ts tests/boundary/mcp/outputSchemaProfile.test.ts tests/boundary/mcp/compactInputSchemaMcp.test.ts tests/conformance/contracts/mcpInputSchemaProfile.test.ts tests/boundary/mcp/callRelationshipAvailability.test.ts src/application/CapabilityInventory.test.ts tests/boundary/process/callPathGoalsVerifier.test.ts tests/boundary/process/verifierCleanup.test.ts tests/composition/analysis-sessions/providerBinding.test.ts src/domain/apple/appleApplication.test.ts src/windows/WindowsNativeLoader.test.ts tests/boundary/process/processCaptureLifecycle.test.ts tests/boundary/process/processCleanupRetryOwnership.test.ts tests/boundary/filesystem/ciPrHealth.test.ts tests/boundary/filesystem/clientConfigurationBom.test.ts tests/boundary/filesystem/clientRegistrationRefresh.test.ts src/hopper/HopperCallerReconciliation.test.ts src/hopper/HopperProvider.test.ts tests/boundary/providers/hopper/hopperCallerReconciliation.test.ts src/domain/callPath.test.ts ``` </details> Earlier ELF x86-64 verification on `5bff9dd38` used Ghidra on macOS; it was not rerun for this merge. A prior controlled injected-graph comparison produced identical answers with 4 versus 7 relationship reads; no native-engine speedup or token savings are claimed. ## Compatibility, safety, and release - Breaking changes or migration steps: none; single-goal behavior remains. Exhaustive batches can cost more than one early-stop request. - Real Hopper/Ghidra, browser, or OS coverage: macOS arm64, Ghidra 12.1.4/JDK 21 and Hopper 6.6.0 demo; ELF x86-64 fixture checked on the preceding revision with Ghidra on macOS. No browser changes. - Package or release metadata impact: additive tool contract and verifier command; no version bump. - Security, privacy, process, or containment review: existing read-only target analysis; roots are not guaranteed entry points, and indirect calls can remain unresolved. ## Author readiness Human owner: @ogutdgn - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. <!-- maintainer-blocker-review --> ### Maintainer blocker verification The open helper finding cites `morluto/preference`, a different repository. REA has no `publicInputStrictObject` helper or that referenced policy; its canonical public contracts use Zod strict objects. The named `trace_call_path` contract therefore follows REA's owning representation without importing another project's wrapper. No code change is warranted for that finding. On Node 24.18.0/npm 11.16.0, `npm run test:local -- src/domain/callPath.test.ts tests/composition/callPathParserOperation.test.ts` passed 30 tests. Existing real-provider verification and graph-size/cardinality limitations remain as documented above; this pass did not rerun providers. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#6228
No description provided.