Three sync-convergence checks used `indexAll()` on the synced graph as
the "full re-index" side. Over an existing index that run skips every
file whose content is unchanged, so the edges the sync wrote survive it
and each check compared the synced graph with itself.
They now rebuild the index from an empty database, as `codegraph index`
does (`CodeGraph.recreate` + `indexAll`, the same oracle the CG-33
convergence suite uses):
- sync-import-retry: the imports of the unchanged importer, all 20
languages.
- sync.test.ts "the synced graph matches a full re-index" and "rebinds
the unchanged caller when the symbol moves to another file": every node
and edge by natural key instead of node and edge counts, which a
bidirectional difference can net out of. Both now index twice in the
test body, so they get the 60s bound #1773 gave such tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A sync retried parked failed refs by name_tail (#1240), but an import
names a file, a folder or a namespace, not a symbol, so the lookup never
found one: the tail of `package:app/b.dart` was `dart`, of `inc/db.php`
`php`, of `./req` `/req`. Most languages never parked theirs at all: an
import that named no file reached the importing file's own `import` node
through matchByQualifiedName (its qualified name is the module path) and
resolved there, so `./x` in TS/JS, `import pkg.mod`, `#include "a/b.h"`,
`<stdio.h>`, a C# `using` of an outside namespace, Go module paths and R,
Solidity, Svelte and Vue imports were consumed by an edge to themselves.
A Lua `require` bound the local it is assigned to. The import linked
only once the importer changed, or on a full index.
- resolveOne's target gate drops an `imports` ref's own import statement,
so the ref parks as failed (#2388 did this for Dart alone).
- A Lua / Luau `require` resolves to a module file or nothing.
- An import written as a path is parked under its last segment's stem
(`package:app/b.dart` -> `b`, `./z.js` -> `z`): src/db/reference-tail.ts.
- Sync retries the failed imports an ADDED file can satisfy: by its name,
stem and folder (importPathKeys), as a failed import's tail or whole
name, and by the changed files' namespace / module names as a whole
name (C# `using Foo.Bar`, Java `import com.z.*`). Same per-key ceiling.
- Schema v12: two partial indexes over failed imports, which the planner
needs to avoid reading every failed call that shares a tail; the
migration rewrites the tails of path imports parked by an older version.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>