feat(neo4j)!: schema v2 graph projection; v2 becomes the default schema (3.0.0) - #201
Merged
Merged
Conversation
Adds the canonical schema v2 → Neo4j projection (graph contract 2.0.0), mirroring codeanalyzer-python's vocabulary with J/J_ namespacing: V2GraphProjector (pure Analysis → GraphRows), V2SchemaCatalog, and the L3 CPG overlay (J_HAS_BODY_NODE, J_CFG_NEXT/J_CDG/J_DDG with the _k MERGE discriminant). Per the convergence spec there are no call-site/parameter/ comment nodes: call sites are :JBodyNode rows, parameters flatten to parameters_json, javadoc collapses to docstring. Breaking (3.0.0): - --schema defaults to v2 everywhere; --schema v1 selects the legacy JSON and legacy graph (v1 node/edge statements unchanged). - --emit neo4j at v2 is always full depth (forces L3 + external symbols); -a/--graph-field-depth alongside it exit non-zero. - --emit schema always emits the 2.0.0 catalog; schema.neo4j.json regenerated as the v2 artifact. The wipe/prune traversal spans both generations (J_HAS_UNIT|J_HAS_MODULE + union DESCENDANTS) and sweeps orphaned degree-0 symbols, so a v2 push replaces a same-app v1 graph completely — verified against Neo4j 5: v1 load → v2 load leaves 0 v1 leftovers, reload is idempotent (30223 nodes / 158704 rels unchanged), and graph counts equal the run's analysis.json exact-set for modules/callables/body/cfg/cdg/ddg. Spec: docs/design/specs/2026-08-27-v2-neo4j-projection.md Closes #198
sinha108
approved these changes
Aug 28, 2026
Open
5 tasks
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.
Closes #198. Implements the base relabel + L3 overlay of #182 (L1/L2 families +
J_CFG_NEXT/J_CDG/J_DDG); the L4 SDG overlay (J_PARAM_*/J_SUMMARY, declared-only in the catalog here) remains for after L4. Implements docs/design/specs/2026-08-27-v2-neo4j-projection.md.What
V2GraphProjector— pure(Analysis, appName) → GraphRows, projecting the v2 model onto the 2.0.0 graph vocabulary (python-parity:JSymbolmerge label overJType/JCallable/JExternal;JBodyNodekeyed on the global ordinal replaces call-site nodes;parameters_json/docstringflattening;J_CFG_NEXT/J_CDG/J_DDGoverlay edges with the_kMERGE discriminant).V2SchemaCatalog— declarative 2.0.0 contract, derived uniqueness constraints;--emit schemanow always emits it; repo-rootschema.neo4j.jsonregenerated.RowBuilder/GraphRows/writers gain the optional edge_kdiscriminant (a conditional's true/false CFG pair, one DDG dependence per(var, prov));CypherWriter/BoltWriterMERGE on{_k: row.k}for keyed groups.J_HAS_UNIT|J_HAS_MODULE+ unionDESCENDANTSincl.J_HAS_BODY_NODE) and sweeps orphaned degree-0 symbols (v1's import-materialized bodylessJTypestubs). Bolt diff/prune handles both generations and scopes pruning to the app anchor.Breaking (3.0.0)
--schemadefaults to v2 for json and neo4j;--schema v1selects the legacy shapes (v1 node/edge cypher statements unchanged; the shared DDL/wipe preamble gained the v2 union, required for replacement in both directions).--emit neo4jat v2 is always full depth (forces L3 + external symbols);-a/--graph-field-depthalongside it exit non-zero (keystone depth rule, python Fix Issue 113: call graph is missing edges to implementations of interfaces. Merge to v1.X.X. #119 parity).--emit schemaalways emits the 2.0.0 catalog.python-sdk is shielded by its exact
codeanalyzer-java == "2.4.1"pin; its compat PR (bump + explicit--schema v1) is separate work per the spec's release plan.Verification
CodeAnalyzerIntegrationTest(pre-existing Testcontainers/Docker env failure, identical onmain).V2Neo4jSchemaConformanceTest: every projected label/rel/prop declared; body-node convergence pinned (noJCompilationUnit/JCallSite/JParameter/JCommentrows); keyed overlay edges; wipe coverage.cypher-shellloads clean; v1 load → v2 load leaves 0 v1 leftovers (including the orphaned import stubs); reloading is idempotent (counts unchanged); graph counts equal the same run'sanalysis.jsonexact-set for modules (156), callables (1199), body nodes (18265), cfg (8473), cdg (3031), ddg (5465);J_CALLS/JExternalcounts equal the emitting run's rows exactly (cross-run RTA jitter of ±36 edges exists between separate analyses — pre-existing WALA behavior, not projection loss).JApplication→J_HAS_MODULE→J_DECLARES→J_HAS_METHOD→J_HAS_BODY_NODE→J_RESOLVES_TOreturns resolved callees; CFG edge kinds distribute as expected (fallthrough/true/false/return).