Skip to content

TS/JS new/type references to builtin globals (e.g. Date) collapse onto same-named user symbols → false god node #1726

Description

@2loch-ness6

Summary

TS/JS references to ECMAScript built-in globals (Date, and any other builtin whose casefolded name matches a user symbol) collapse onto a same-named user declaration, producing a huge false "god node". In a real 3,368-file corpus, a module-local, non-exported const DATE in one frontend file accumulated 469 false cross-file references edges (degree 472, betweenness 0.435, bridging ~130 communities) — every new Date() call site in the repo resolved to it.

Call edges are already guarded against this; the type/new-reference path is not.

Root cause

Two things combine:

  1. normalize_id() casefolds (ids.py). The ECMAScript global Date and a user const DATE both normalize to date, so they are indistinguishable to the label/id index.

  2. The reference-resolution path does not consult _LANGUAGE_BUILTIN_GLOBALS. Call edges do — every call-edge site guards on it, e.g.:

    # extract.py:16730
    if callee in _LANGUAGE_BUILTIN_GLOBALS:
        ...  # skip

    But ensure_named_node(name, line) (extract.py:3580, and its 6 sibling closures) has no such guard. When a new Date() / Date reference is walked, it creates a sourceless stub (id: date, label: Date) and draws a references edge (context="call", confidence=EXTRACTED, score 1.0). The corpus-level rewire/dedup step then collapses that stub onto the single real declaration whose norm-id matches — the user's const DATE.

Net: Date ∈ _LANGUAGE_BUILTIN_GLOBALS (so calls are skipped), yet the references/context="call" path still emits edges to a user symbol.

Proposed fix

Guard the reference path the same way call edges are guarded — the natural chokepoint is ensure_named_node: if name in _LANGUAGE_BUILTIN_GLOBALS, do not create a stub/edge (return a sentinel the callers skip, mirroring the existing if target_nid != func_nid skip pattern). Apply consistently to all ensure_named_node closures.

Optionally, as defense in depth, normalize _BUILTIN_NOISE_LABELS membership tests through normalize_id so casefold collisions (DATE vs Date) are still filtered from god-node reporting.

Environment

  • graphifyy 0.9.9
  • Python 3.12.3, Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions