Give every symbol a real identity and kill the zombie nodes for good - #31
Merged
Merged
Conversation
Symbol identity is no longer a line number in disguise. Every Function, Class, Interface, Variable, Type, and Component now carries an opaque sym:v1 id hashed from its label, normalized path, lexical scope chain, declared name, and disambiguator, with length-prefixed encoding so no name or path can collide. Line numbers become mutable properties: editing a file no longer changes what a symbol IS. Scope is part of identity: members carry their owner chain, nested declarations their lexical chain, overloads a signature hash (class method overload declarations are now extracted at all, with calls binding to the one runtime implementation), declaration-merged forms share one id, and true duplicates fall back to a bounded ordinal. The pipeline builds a project symbol catalog and resolves every edge to endpoint ids before writing; unresolved edges are dropped, never guessed. The graph merges by id, sweeps stale ids from changed files even when inbound edges pin them, notices deleted files by set-difference, and deletes projects by ownership stamp instead of reachability, so force reindex genuinely resets. Ids flow unchanged through search (including the no-embedding text fallback), references, file relationships, embeddings, and the dashboard, which no longer synthesizes ids at all. Legacy idless knowledge entities are backfilled on write and tolerated on read. The proof the whole campaign was building toward now passes: shift a function with inbound CALLS and IMPORTS_SYMBOL edges down the file, reindex incrementally, and it is still one node with the same id, a new line number, and both edges intact. Two adversarial review rounds drove out six defects before merge, four of them integration seams between individually verified components. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
The remote FalkorDB client rejects undefined parameter values; the embedded driver tolerated them, which hid the gap from local testing. Entities seeded without canonical ids now get them derived at the write boundary, and a regression test drives all six legacy symbol shapes through the real params path asserting no undefined survives at any depth. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The strict embedding update was right; the fixtures were still passing the legacy name-and-path shape while discarding the canonical ids their own upserts had produced. Production never hits this path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…opping every row The vector Cypher never returned node.id, and the strict candidate mapper skipped rows without one, so remote search returned zero hits on a fully indexed graph. The projection now includes the id, the row mapping throws a diagnostic error on a missing or malformed id instead of silently filtering, and a Linux temp-directory prefix in one test is made portable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
Batch five: the node-identity redesign, the root cause behind zombie findings in sixteen consecutive adversarial review rounds. Symbols were keyed on name, file, and line number, so any edit that shifted a line created a duplicate node while cross-file edges pinned the stale one forever, surviving even force reindex.
The new identity
Every symbol carries an opaque sym:v1 id: SHA-256 over a length-prefixed canonical tuple of label, normalized path, lexical scope chain, declared name, and disambiguator. Scope is part of identity (owner chains for members, signature hashes for overloads, one id for declaration-merged forms, bounded ordinals as last resort). Line numbers are mutable properties. A fixed-vector test locks the exact bytes-to-hash contract.
What changed everywhere
The kill-shot test
Index two files with cross-file CALLS and IMPORTS_SYMBOL edges, insert lines above the target, reindex incrementally: one node, same id, moved startLine, both edges intact. Force reindex: zero prior-generation survivors, verified by the acceptance queries.
Review process
A scout produced the design work map (three candidates; scope-qualified opaque identity chosen); four implementation groups worked a frozen contract; an integration wave caught a silently skipped seam and a phantom index label; two adversarial rounds found six more defects (deleted files invisible to incremental indexing, overload collapse, fallback rows without ids, legacy Entity crashes, calls binding to every overload, File rows rejected by the converter), four of them integration seams between individually verified components. All fixed red-first and re-verified against the reviewers' own reproductions.
Verification
pnpm turbo build 21/21, test 36/36, typecheck 20/20, release:check green. Core 264 tests, plugin-typescript 116, graph 107 plus 53 lite-integration.
Ledger
🤖 Generated with Claude Code