Skip to content

fix(registry): resolve aliased direct-symbol imports in import_map (#875)#979

Merged
DeusData merged 2 commits into
DeusData:mainfrom
LA-10:fix/875-alias-import-resolution
Jul 9, 2026
Merged

fix(registry): resolve aliased direct-symbol imports in import_map (#875)#979
DeusData merged 2 commits into
DeusData:mainfrom
LA-10:fix/875-alias-import-resolution

Conversation

@LA-10

@LA-10 LA-10 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

trace_path returns no inbound caller for a function called through an import alias (from m import f as g; g()). No CALLS edge is emitted at all.

Root cause (registry.c, resolve_import_map): build_import_map stores key = local_namevalue = the IMPORTS edge's target QN. Plain imports target the Module node (value = module QN); aliased direct-symbol imports target the Function node (value = full symbol QN). The bare-callee branch assumes the former and always appends:

snprintf(candidate, sizeof(candidate), "%s.%s", resolved, prefix);

For _scan_bash that yields ...security_scan.scan_bash._scan_bash matches nothing, edge dropped. Plain imports work because module + "." + name reconstructs the real QN. That asymmetry is why only aliases break, and why resolve_import_map_bare_function (module-valued vals[]) never caught it.

Fix: if resolved is itself a registered symbol, it is the target return it before appending. Cannot regress plain/dotted imports: pass_definitions.c:337 registers only never Module, so module-valued entries can't match. resolve_import_map is shared by the sequential and parallel pipelines, so one change covers both.

Issue #875

Verification

tests/test_registry.c::resolve_import_map_bare_alias — RED on unmodified clone, GREEN with fix. Existing import_map tests stay green.

End-to-end on willow-2.0 (the issue's public repro), trace_path(scan_bash, inbound):

  • Before: _scan_shell_fragment, check_kart_task (both core/kart_task_scan.py)
  • After: adds main (willow/fylgja/events/pre_tool.py) — the production caller

Call-site identity preserved, per the triage note:

src=main  callee=_scan_bash  strategy=import_map  tgt=...security_scan.scan_bash

Checklist

  • Every commit is signed off (git commit -s) — required, CI rejects
    unsigned commits (DCO, see CONTRIBUTING.md)
  • Tests pass locally (make -f Makefile.cbm test)
  • Lint passes (make -f Makefile.cbm lint-ci)
  • New behavior is covered by a test (reproduce-first for bug fixes)

Signed-off-by: LA-10 <lashuha@uwaterloo.com>
@LA-10 LA-10 requested a review from DeusData as a code owner July 9, 2026 11:29
@LA-10

LA-10 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

On where the fix lives, I went with making the resolver handle the value shape build_import_map already produces. The other option would be normalizing at construction instead (store the module QN plus the original leaf name, so the append rule holds for everything). That's arguably cleaner, but it means touching build_import_map in both pass_calls.c and pass_parallel.c and changing the contract at pipeline.h:180. Happy to redo it that way if you'd rather.
Also worth mentioning: while instrumenting resolve_file_calls I noticed these calls only reach the registry because the Python LSP misses them entirely lsp=MISS for _scan_bash/_scan_write/_scan_worst, but lsp=HIT with a correct callee_qn for plain scan_bash. So the LSP isn't tracking import ... as ... bindings. Doesn't overlap with this fix, but happy to file it separately if that's useful.

@DeusData DeusData added the bug Something isn't working label Jul 9, 2026
@DeusData DeusData added this to the 0.9.1-rc milestone Jul 9, 2026
@DeusData DeusData added parsing/quality Graph extraction bugs, false positives, missing edges priority/high Needs near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker. labels Jul 9, 2026
@DeusData

DeusData commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Thanks for digging into the import-map shape. I have triaged this as a 0.9.1-rc bug fix for #875. During review we will compare the local resolver fix with the alternative of normalizing build_import_map, and we should keep the LSP alias miss as a separate follow-up so this PR stays focused.

@DeusData DeusData merged commit a6207c6 into DeusData:main Jul 9, 2026
19 checks passed
@DeusData

DeusData commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Merged — thank you! The asymmetry analysis (module-valued vs symbol-valued import-map entries) was spot-on, the four-line fix lands exactly at the root cause, and the end-to-end verification on the issue's repro repo is the gold standard. Much appreciated.

@LA-10 LA-10 deleted the fix/875-alias-import-resolution branch July 9, 2026 19:26
kcsraju pushed a commit to AsatoCorp/utils-codebase-memory that referenced this pull request Jul 10, 2026
The DeusData#979 direct-hit early return in resolve_import_map fires before
suffix handling, so any imported_symbol.method() call whose base symbol
is itself an indexed node resolved to the base node instead of
base.method — the exact mis-resolution the neighboring comment warns
about. On django this degraded the graph by ~11K edges (CALLS
74,685->72,175, TESTS 38,032->29,236); auth.login => Signal.send became
an edge onto the user_logged_in Variable node.

Take the direct hit only for suffix-less callees — precisely the
aliased direct-symbol import case (DeusData#875) the early return was added
for. Verified on django: CALLS 74,708 (baseline + the 23 genuine DeusData#979
wins), TESTS 38,035; the DeusData#979 bare-alias test stays green.

Reproduce-first: resolve_import_map_alias_with_suffix_hits_method is
RED on the unguarded code (returns the bare symbol QN) and GREEN with
the guard.

Closes DeusData#1000

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working parsing/quality Graph extraction bugs, false positives, missing edges priority/high Needs near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants