The same repository indexed with results parked on disk produced a
DIFFERENT graph than one indexed in memory. Measured on the php corpus,
same binary, reproducible 3/3 each way: 16,561 nodes / 57,182 edges in
memory against 16,562 / 59,379 while spilling. Not jitter, and not
one-directional -- 1,458 CALLS pairs appeared only under spill and 840
only without it. Present on main, so it ships in v0.11.0 today, and it
bites exactly the large-repo users who need spilling.
Cause: pass_parallel built the namespace map -- what `use` / `using` /
package imports resolve against -- from the in-memory result cache, where
a PARKED result is NULL. Every spilled file therefore contributed no
namespace, and a file missing from that map does not fail to resolve, it
resolves through the looser fallback. That is why edge counts moved in
both directions instead of simply dropping.
The fix keeps each parked file's namespace IN MEMORY while its result is
on disk (one short string per file, nothing against the result it
replaces), and builds the map from names so the memory and disk paths
agree. Non-spill runs take the identical code path and are unchanged.
Across ten languages and four memory settings (default, 2 GB, 700 MB,
forced spill), php/java/csharp/kotlin now produce identical graphs where
they differed by up to 40,341 edges before.
The existing spill-parity contract in test_parallel passed throughout,
because its fixture is Go+Java and the compact parity harness omits the
pass that builds the map -- neither reaches the namespace path. The new
test runs the real pipeline over more than MIN_FILES_FOR_PARALLEL
namespaced PHP files, with and without spilling, and fails without this
fix.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>