Skip to content

docs: correct the codegraph mechanism — it was inferred, not checked - #64

Merged
inth3shadows merged 1 commit into
mainfrom
fix/codegraph-mechanism-correction
Aug 6, 2026
Merged

docs: correct the codegraph mechanism — it was inferred, not checked#64
inth3shadows merged 1 commit into
mainfrom
fix/codegraph-mechanism-correction

Conversation

@inth3shadows

Copy link
Copy Markdown
Owner

Update 5 (merged an hour ago in #59) gave the wrong cause for the stray-ancestor-index behaviour. This corrects it, and records the upstream status of both codegraph findings now that they have been checked.

What was wrong

codegraph 1.5.0's root detection wants a .git directory, so from any worktree it walks up past the repo

resolveProjectPath and findNearestCodeGraphRoot do not consult .git at all. They look only for an initialized .codegraph, with no repo boundary to stop at:

function resolveProjectPath(pathArg?: string): string {
  const absolutePath = path.resolve(pathArg || process.cwd());
  if (isInitialized(absolutePath)) return absolutePath;
  // Walk up to find nearest parent with CodeGraph initialized
  while (current !== root) { ...; if (isInitialized(current)) { /* use ancestor */ } }

I inferred .git from the symptom — it happened in a worktree — and never checked the source.

How it was falsified

Reproduced with no git repository anywhere:

1. initialize ONLY the parent
   parent/.codegraph exists : yes
   child/.codegraph exists  : no
2. ask codegraph to index the CHILD, by explicit path
   ●  4 nodes, 2 edges in 363ms
   └  Done
3. child/.codegraph created : NO  <-- the request was silently ignored
   'codegraph status' from the child reports:
     Project: /tmp/.../reproindex/parent

The worktree layout is an aggravating condition, not the cause: sibling worktrees are never initialized themselves, so the walk escapes the repo on the first index in a fresh one. Any un-indexed subdirectory does it.

The practical guidance was unaffected — init for a first index, never index — which is the uncomfortable part. It was right for the wrong reason, the exact failure mode this document names everywhere else: a correct answer whose stated justification does not survive being checked. Verified against upstream tip d6d1728, which is the installed 1.5.0, so this describes current code rather than whatever version happened to be lying around.

Reported upstream: colbymchenry/codegraph#1524.

The other finding was already reported

The aliased-module call-resolution bug is not new — upstream issue #899, with open PR #1453 carrying a fix. Its diagnosis matches the measured table exactly: the submodule lookup joins the import source with imp.localName, which under an alias names no module, and localName coincides with exportedName only when the import is unaliased.

I confirmed it on that PR with a five-file minimal repro — the PR's own description says it "reproduces in real trees but not in minimal repros", which turns out to be true only at the calls level; the file→file imports half reproduces in five files. Two modules identical apart from the alias:

plain.py   --imports--> ledger.py  (from . import ledger)      : 1
aliased.py --imports--> db.py      (from . import db as dbmod) : 0

Nothing to do here but wait and re-measure. The registry declaration in journeys/testgraph.json stands until then.

Verification before filing

Since a tracker search proves nothing about fix-state:

  • fetched upstream; local checkout is at the live tip d6d1728 (v1.5.0 = installed)
  • pulled all 618 issues and 881 PRs locally and grepped, rather than trusting gh search
  • body-searched with a control query to prove the API was not fail-opening (control hit #578; resolveProjectPath genuinely empty)
  • diffed all 25 open PRs touching src/bin/codegraph.ts / src/directory.ts — 4 only add calls to the resolver, none modifies it

That last check is the one that mattered: it is what separates "nobody has reported it" from "a fix is already in flight", and it is the check that found #1453 for the other bug.

Verification

251 tests, unchanged by this diff (documentation only).

Update 5 claimed codegraph's root detection "wants a `.git` directory", and that
the bare-worktree layout — where a worktree's `.git` is a file — was therefore
the cause of the stray ancestor index. That was inferred from the symptom (it
happened in a worktree) and never checked against the source.

`resolveProjectPath` and `findNearestCodeGraphRoot` do not consult `.git` at all.
They look only for an initialized `.codegraph`, with no repo boundary to stop at.
`index <path>` discards its argument whenever that path is not itself
initialized, walks up to the filesystem root, and rebuilds the first initialized
ANCESTOR — printing an ordinary `Done` and never naming what it indexed.

Falsified by reproducing it with no git repository anywhere: initialize a parent,
run `codegraph index .` from an un-indexed child, and it reports success while
creating no index in the child and rebuilding the parent's. The worktree layout
is an aggravating condition, not the cause — sibling worktrees are never
initialized themselves, so the walk escapes the repo on the first `index` in a
fresh one. Any un-indexed subdirectory does it.

The practical guidance (`init`, not `index`) was right for the wrong reason,
which is the failure mode this document names everywhere else: a correct answer
whose stated justification does not survive being checked. Verified against
upstream tip d6d1728 = the installed 1.5.0, so this describes current code rather
than a version I happened to have.

Reported upstream as colbymchenry/codegraph#1524.

Also records that the OTHER codegraph finding — no call resolution through an
aliased module binding — was already known upstream: issue #899, open PR #1453,
whose diagnosis matches the measured table exactly (the submodule lookup joins
the import source with `imp.localName`, which under an alias names no module).
Confirmed on that PR with a five-file minimal repro. Checked before filing: all
618 issues and 881 PRs pulled and grepped locally, body search validated against
a control query, and every open PR touching the resolver diffed — 4 add calls to
it, none modifies it.

251 tests, unchanged by this diff.
@inth3shadows
inth3shadows merged commit a5997f4 into main Aug 6, 2026
1 check passed
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