Three fixes for a repo that commits a large JS/TS theme/SDK (Metronic under
static/, ~1,600 tracked files):
1. A SECOND "Resolving refs" quadratic that #915 didn't cover. #915 capped
import-name collisions; this caps method-name collisions (init/update/render
re-declared on every widget), which flow through matchMethodCall Strategy 3
and findBestMatch instead. New AMBIGUOUS_NAME_CEILING (default 500, env
CODEGRAPH_AMBIGUOUS_NAME_CEILING): above it the fuzzy strategies decline
rather than score K candidates — no proximity score can pick the one true
target among thousands anyway. Resolving drops from O(K^2) to linear in refs
(e.g. 900-file synthetic: 28.7s -> 3.4s), edge counts unchanged, and the cap
never fires on normal repos (max real method-collision ~40).
2. A new `exclude` array in codegraph.json keeps git-TRACKED paths out of the
index, which .gitignore can't do (enumeration is `git ls-files`). Mirrors the
existing includeIgnored plumbing across the git, sync, and non-git-walk
paths.
3. `index`/`init` now install the #850 liveness + #277 ppid watchdogs (which
were serve-only), so a wedged or orphaned indexer self-terminates instead of
pinning a core. The --liftoff-only relaunch's spawnSync can't forward
signals, so killing the parent shim used to orphan the worker.
Tests: ubiquitous-name ceiling, exclude (incl. tracked-file exclusion on git +
non-git), orphan self-termination (POSIX), and ppid-parser units. Shared the
ppid parsers out of mcp/index.ts into mcp/ppid-watchdog.ts.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On Windows the PPID watchdog could never fire: orphans aren't reparented, so
`process.ppid` stays constant after the parent dies (defeating the ppid-change
check), and the standalone bundle pre-bakes `--liftoff-only`, skipping the
relaunch that sets `CODEGRAPH_HOST_PPID` (defeating the host-liveness check).
With neither signal available, an orphaned proxy / direct server ran forever,
the shared daemon never saw the client disconnect, and its idle timer never
armed — node processes accumulated until CPU saturated.
Add a win32-only signal: poll the original parent's liveness directly, since
ppid is stable there. Gated to Windows so POSIX double-fork cases keep relying
on the ppid-change signal (a dead original parent is not proof of orphaning on
POSIX). The decision is extracted into a pure, unit-tested helper shared by all
three watchdog sites (proxy socket, proxy local-handshake, direct mode).
Validated on a real Windows 11 VM: in the exact bundle scenario (direct mode,
no HOST_PPID) an orphaned server now exits within one watchdog poll via the new
path; the POSIX reparent path is unchanged and its integration test still passes.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>