Skip to content

fix(architecture): stop the CLI probes fabricating and dropping edges - #46

Merged
inth3shadows merged 1 commit into
masterfrom
arch-cli-probe-fixes
Sep 27, 2026
Merged

inth3shadows merged 1 commit into
masterfrom
arch-cli-probe-fixes

Conversation

@inth3shadows

Copy link
Copy Markdown
Owner

Two defects in --architecture's per-symbol CLI probes. They were found by comparing the probes against codegraph's index directly (groundwork for the direct index read, next PR).

  • Import nodes were probed by name. An import statement's node has no callee edges: 0 of 3,659 on codegraph's repo, 0 of 715 on terse. But its text as a name (terse.capture, ../src/mcp/tools) resolves to another symbol and borrows its callees, which fabricates file edges. probeFileEdges now skips import nodes; this also removes thousands of wasted probes on TS repos.
  • fix(architecture): stop a file's import-only callees from adding weight #43's import-only filter dropped real calls. It trusted per-definition edges[], but that list holds ONE edge per callee (whichever codegraph found first). So an imports entry can hide an instantiates/references edge to the same target (codegraph's repo: a test that imports and instantiates ToolHandler lost the edge). The filter is removed from the CLI path: an import-only callee now overcounts its file edge by 1 instead of a real call going missing. TECHNICAL.md Known Limitations is rewritten to match.

Regression tests: both shapes from the real failures (probeSymbolCallees keeps an imported callee whose one listed edge is imports; probeFileEdges never probes an import node).

Local: node test/run.js 188 passed, 0 failed (fork codegraph); --check on docs/architecture.svg is up to date.

Two defects found by comparing --architecture against codegraph's index:

- Import nodes were probed by name. An import statement's node has no
  callee edges (0 of 3,659 on codegraph's repo), but its text as a name
  (terse.capture, ../src/mcp/tools) resolves to another symbol and borrows
  its callees. probeFileEdges now skips them.
- #43's import-only filter trusted per-definition edges[], which lists one
  edge per callee, so an imports entry could hide an instantiates or
  references edge and drop a real call. The filter is removed; an
  import-only callee overcounts its file edge by 1 instead.
@inth3shadows
inth3shadows merged commit 317294b into master Sep 27, 2026
7 checks passed
@inth3shadows
inth3shadows deleted the arch-cli-probe-fixes branch September 27, 2026 11:26
inth3shadows added a commit that referenced this pull request Sep 27, 2026
…obe per symbol (#47)

Roadmap item: make `--architecture` (and `--forbid`) cheap enough to run
on every commit.

**Why:** the scan spent nearly all its time starting one `codegraph
callees` process per symbol: 48.7s on this repo, where codeshot's own
work is ~0.4s.

**What:** on Node 22.5+, `readIndexRows` reads
`<path>/.codegraph/codegraph.db` once via `node:sqlite` (read-only, no
new dependency). It pulls every edge of codegraph's own callee kinds
(`calls/references/imports/instantiates/navigates`, from its
`getCallees`). `fileEdgesFromIndexRows` then derives each definition's
answer using codegraph's own overload grouping (name + file + qualified
name).
- Enumeration stays on the CLI, so the symbol set and `--max-symbols`
are unchanged.
- Falls back to the CLI probes on Node 18/20, when there's no index at
that path, on any read failure, or with `CODESHOT_INDEX_READ=cli`.
- The read sees every edge, so it drops import-only callees exactly (the
CLI's one-edge-per-callee JSON can't; see #46).
- `--limit` caps nothing on this path. On Node 22.5+, fork and npm
codegraph now draw the same weights.

**Proof by equality with the incumbent:** with the import-only rule
switched off, the direct read renders **byte-identical** diagrams to the
CLI probes on: this repo (1 edge), the duplicate-name fixture (7), the
TS fixture (1), terse at 300 symbols (31), and codegraph's own repo at
300 symbols (55). The fork CI test also asserts both paths draw the same
file edges, with index weights ≤ CLI weights.

**Speed:** this repo 48.7s → 1.3s; codegraph's repo, 500 symbols: 2.8s.

Local: `node test/run.js` 191 passed, 0 failed on the fork and 191/0 on
npm 1.6.0. Docs: README, USAGE (speed + troubleshooting), TECHNICAL.md.

Follow-up not in this PR: `--diff` roots can also be import nodes, which
have the same name-probe problem as #46.
inth3shadows added a commit that referenced this pull request Sep 27, 2026
Follow-up from #46/#47.

`matchRootSymbols` excluded `"kind":"file"` nodes but not
`"kind":"import"` ones. So a changed file's import statements became
bold `--diff` roots, and probing an import's text as a name
(`../src/mcp/tools`) can resolve to another symbol and draw its
callers/callees: the same fabrication #46 fixed for `--architecture`.
Import nodes are now excluded too.

Reproduced on a TS repo with a changed `test/t.ts`: before, two roots
(`runTest` and `"../src/mcp/tools"`); after, only `runTest`. The
regression test was written first and failed on the old code.

Local: `node test/run.js` 192 passed, 0 failed (fork codegraph).
TECHNICAL.md updated.
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