Skip to content

Attribute --architecture edges by file when symbol names collide - #24

Merged
inth3shadows merged 2 commits into
masterfrom
claude-arch-duplicate-names
Aug 5, 2026
Merged

Attribute --architecture edges by file when symbol names collide#24
inth3shadows merged 2 commits into
masterfrom
claude-arch-duplicate-names

Conversation

@inth3shadows

Copy link
Copy Markdown
Owner

Summary

--architecture probes codegraph callees <name> for every enumerated symbol. That takes a bare name with no file disambiguation — and, measured against the pinned codegraph 1.5.0, it answers with the union of every same-named symbol's callees. So a name collision did not merely attribute an edge to the wrong file; it invented edges that exist in neither. On a purpose-built two-handle fixture, the pre-PR code drew 4 edges where only 2 were real.

TECHNICAL.md and USAGE.md both asserted codeshot had no way to fix this. That was false: codegraph node -f <file> <name> disambiguates a symbol to a file, and its trail line is file-qualified.

  • probeFileEdges re-probes names appearing in more than one file via node -f; everything else keeps the cheaper callees --json route. node -f returns the symbol's full source on every call, so scoping it to the duplicate subset (~2% of symbols on a real ~1,900-node Go index) is what makes it affordable.
  • Counting distinct files rather than symbol occurrences is load-bearing. Two same-named symbols inside one file have no file ambiguity at all — the bare-name union is already exactly right for them — and codegraph answers that case with two concatenated trail blocks, so routing it through the file-qualified probe would silently delete one symbol's edges.
  • The trail is a human-facing summary, not an API. parseNodeCalls falls back to the bare-name probe — which over-reports rather than under-reports, the right way round to fail — on four measured conditions: no trail section (file-mode output, or a changed format); more than one trail section; a trail codegraph truncated with +N more (it caps at 12 entriesmain in this repo has 23 callees and shows 12); or a reported **Location:** outside the requested file (-f is a preference, not a filter: node -f no/such/file.js -- buildDot still answers with render/callgraph.js's buildDot, exit 0).
  • parseCodegraphOutput matches codegraph's not-found message against only the first non-empty line. Under the new json: false path the response embeds indexed source, and this repo's own test file contains that sentence verbatim.

Scope is deliberately partial. A colliding name with >12 callees falls back and keeps the old over-inclusive behavior. USAGE.md says so rather than implying it away.

Still unresolvable: duplicate file basenames (two index.js). unwrapQueryNodes keeps file nodes in the probed set, and node -f answers a file node in file mode. duplicateNameWarning now reports the resolved and unresolved halves separately.

Also folds in a one-line .gitignore fix: .codegraph//.ai/ matched directories only, so the shared-index symlink a worktree layout creates showed as permanently untracked.

Test plan

  • node test/run.js108 passed, 0 failed (was 93 on master).
  • New CLI regression test builds a fixture repo covering both collision kinds and asserts the real edges are present and the fabricated ones absent: a cross-file collision (two handles, must split) and a same-file one (two runs, must not). This repo's own index has zero duplicate names, so the existing self-test could never exercise either path.
  • New unit tests pin each fallback condition: +N morenull, wrong file → null, file-mode output → null, multi-block → null, plus same-file duplicates keeping both edges and source containing the not-found sentence not being misread.
  • Both committed diagrams re-verified against the exact CI guard (--check); unchanged, as expected for a repo with no duplicate names.

The patterns ended in a slash, which git matches against directories only.
In a shared-index worktree layout these paths are symlinks to a sibling
checkout's index, so every worktree showed a permanently untracked
.codegraph entry. Dropping the trailing slash covers both forms.
`codegraph callees <name>` takes a bare name with no file disambiguation,
and answers with the UNION of every same-named symbol's callees. So a
collision did not merely pick the wrong file — it invented edges that
exist in neither. Measured on a two-`handle` fixture: 4 edges drawn, 2
real.

probeFileEdges now re-probes names appearing in more than one FILE with
`codegraph node -f <file> <name>`, the only file-qualified probe codegraph
offers, and reads its trail via parseNodeCalls.

Counting distinct files rather than symbol occurrences is load-bearing:
two same-named symbols inside ONE file have no file ambiguity, the
bare-name union is already exactly right for them, and codegraph answers
that case with two concatenated trail blocks — routing it through the
file-qualified probe would delete one of them.

The trail is a human-facing summary, not an API, so parseNodeCalls falls
back to the bare-name probe (over-reports, never under-reports) on four
measured conditions: no trail section (file-mode output or a changed
format), more than one trail section, a trail truncated with `+N more`
(codegraph caps it at 12 entries — `main` here has 23 callees), or a
reported Location outside the requested file (`-f` is a preference, not a
filter: `-f no/such/file.js -- buildDot` still answers with
render/callgraph.js's buildDot, exit 0).

parseCodegraphOutput now matches the not-found message against only the
first non-empty line: under json:false the response embeds indexed source,
and this repo's own test file contains that sentence verbatim.

Duplicate file basenames remain genuinely unresolvable (node -f answers a
file node in file mode); duplicateNameWarning now reports the resolved and
unresolved halves separately.
@inth3shadows
inth3shadows merged commit 4987e45 into master Aug 5, 2026
5 checks passed
@inth3shadows
inth3shadows deleted the claude-arch-duplicate-names branch August 5, 2026 23:15
@inth3shadows
inth3shadows restored the claude-arch-duplicate-names branch August 6, 2026 02:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant