Skip to content

Unresolvable calls are bound to any same-named symbol (Jest describe, RxJS take) and trace_path exposes no confidence/strategy #1355

Description

@artaommahe

Version

codebase-memory-mcp 0.9.1-rc.1

Platform

macOS (Apple Silicon)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

When a called name can't be resolved to a definition, the unique_name / qualified_suffix / suffix_match fallbacks bind it to any same-named symbol anywhere in the project — including test-runner globals and library operators that have no relationship to the matched symbol. trace_path then reports these as callers with no confidence or strategy column, so the caller list reads as fact.

Minimal case: a Jest/Jasmine describe('...', () => {}) block in a .spec.ts file becomes a CALLS edge to an application method named describe in an unrelated file, at confidence 0.75.

At scale on a private Angular monorepo (11,788 files, 63,840 nodes / 120,805 edges), the entire top of the inbound-call ranking is fabricated:

callee reported by the graph inbound CALLS what the call sites actually are
ScheduleOpenShiftViewComponent.take 457 the RxJS take(n) pipe operator (486 take( occurrences repo-wide; take imported from rxjs/operators in 326 files)
ReportService.describe 377 the Jest describe() global (794 spec files)
ReportApi.describe 275 same
PersonalScheduleComponent.date 264 see below
PermissionDirective.permission 207 unrelated permission references

Filtering on confidence does not rescue it: with WHERE r.confidence >= 0.9, the top callee is still PersonalScheduleComponent.date with 250 inbound edges.

Two of those recorded "call sites" are not calls at all. I opened the source and verified both:

  • An @Input() set date(date: string | Date) { ... } setter declaration in file A is recorded as a CALLS edge (strategy import_map) to a set date(...) setter in unrelated file B. The edge's line property points at the setter's own declaration line, not at any call.
  • lazySelect(getTimesheet(this.timesheet.id)) — where this.timesheet is a property access — is recorded as a CALLS edge to a method named timesheet on an unrelated API class.

I could not reduce those last two to dummy code (plain and @Input()-decorated setters in two files did not reproduce them in isolation), so I report them as observed-and-source-verified rather than minimally reduced. The test-global case reduces cleanly and is in the repro repo.

Expected, in rough priority order:

  1. Prefer no edge over a guessed one when the callee is unresolvable — especially for known test-runner and library globals.
  2. Never emit a CALLS edge for a setter declaration or a property access.
  3. Surface strategy and confidence in trace_path output (a column, or a --min-confidence filter). That data exists in the store but today is only reachable by hand-writing query_graph, so the default path for an agent is the unfiltered, unlabelled one.

Reproduction

Public repro repo: https://github.com/artaommahe/codebase-memory-mcp-rc-repros — see Case B.

git clone https://github.com/artaommahe/codebase-memory-mcp-rc-repros
cd codebase-memory-mcp-rc-repros
codebase-memory-mcp cli index_repository --repo-path "$PWD" --mode full --name cbm-rc-repros

codebase-memory-mcp cli query_graph --project cbm-rc-repros \
  --query "MATCH (a)-[r:CALLS]->(b) RETURN a.file_path AS caller, b.qualified_name AS callee, r.strategy AS s, r.confidence AS c, r.line AS line LIMIT 10"

src/app/report.spec.ts contains only Jest describe/it/expect globals. src/app/report.service.ts defines an unrelated method named describe. Observed (row 2 of 5):

  src/app/report.spec.ts cbm-rc-repros.src.app.report.service.ReportService.describe unique_name "0.75" "9"

Line 9 is the describe('another suite', ...) block in the spec file. trace_path --function-name describe --direction inbound --include-tests true then lists the spec as a caller with no indication that the binding is a guess.

Project scale (if relevant)

Aggregate figures are from a private Angular monorepo: 11,788 files, 63,840 nodes / 120,805 edges, --mode full, 10,175 .ts files, 794 .spec.ts files. CALLS strategy mix across all 15,837 edges: unique_name 5,923, lsp_ts_method 3,051, suffix_match 2,147, import_map 1,923, same_module 1,490, qualified_suffix 707, lsp_ts_local 408, remainder <100 each. Roughly 5,500 edges carry confidence below 0.5. The linked repro is self-contained dummy code.

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Posted by Claude Code on behalf of @artaommahe

Metadata

Metadata

Assignees

No one assigned

    Labels

    editor/integrationEditor compatibility and CLI integrationparsing/qualityGraph extraction bugs, false positives, missing edgeswindowsWindows-specific issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions