PROBLEM
codeanalyzer-java emits the old schema (Neo4j contract 1.1.0), and its in-flight L3/SDG work (#171/#173) is old-shape (program_graphs/sdg_edges). It is the last L2+ language off canonical schema v2, and the SDK's 2.0.0 GATES on this migration (decision in codellm-devkit/python-sdk#238).
SCOPE BOUNDARY
Pure graph provider — this analyzer emits schema v2 and stops. No SDK work here (that is python-sdk#228); slicing/taint remain SDK-side queries. Golden rule: keep everything that COMPUTES facts (WALA, the resolver, the call-graph builder); replace only what SERIALIZES them.
GOALS (staged lowest-first per the migration playbook; each stage independently validatable)
- L1 emission: the containment tree with
can:// ids, span with byte offsets, whole-file source on the module node (per-callable code retires), structured decorators[] (was flat annotations[]), error_channel[] (was thrown_exceptions[]), single kind per type node (the is_* booleans retire).
- L2 emission: identity-only
call_graph {src,dst,prov,weight} at application scope (rich JGraphEdges retire); callee null->id backfill on call body nodes.
- Neo4j v2 projection: relabel to the v2 node/edge families;
schema.neo4j.json bumps to 2.0.0.
- L3 remap: move
program_graphs.functions[sig].cfg.nodes into body{}; split sdg_edges into cfg/cdg/ddg/summary (intra) + param_in/param_out (application); data_dependence: no-heap|full becomes the ddg prov: ["ssa"] vs ["points-to"] split.
CAVEATS AND KNOWN RISKS
- The WALA L3 remap is the long pole; stages 1-3 land first so the SDK's rc train can validate against Java L1/L2 early.
- Keep the old emitter behind a flag during transition (the compat shim), with a superset check: v2 output contains every old-output fact modulo the sanctioned drops.
- Parity clause: never rename or repurpose shared vocabulary; Java-specific additions are recorded in
.claude/SCHEMA_DECISIONS.md.
DEFINITION OF DONE
- v2 output validates against the SDK cpg models at each emitted max_level; L1 ⊆ L2 ⊆ L3 superset gate holds.
- Neo4j load clean — no dangling edges; conformance test against the bumped
schema.neo4j.json green.
- Major version release cut with the breaking output change in the changelog; python-sdk#228 unblocked.
Part of codellm-devkit/python-sdk#238
PROBLEM
codeanalyzer-java emits the old schema (Neo4j contract 1.1.0), and its in-flight L3/SDG work (#171/#173) is old-shape (
program_graphs/sdg_edges). It is the last L2+ language off canonical schema v2, and the SDK's 2.0.0 GATES on this migration (decision in codellm-devkit/python-sdk#238).SCOPE BOUNDARY
Pure graph provider — this analyzer emits schema v2 and stops. No SDK work here (that is python-sdk#228); slicing/taint remain SDK-side queries. Golden rule: keep everything that COMPUTES facts (WALA, the resolver, the call-graph builder); replace only what SERIALIZES them.
GOALS (staged lowest-first per the migration playbook; each stage independently validatable)
can://ids,spanwith byte offsets, whole-filesourceon the module node (per-callablecoderetires), structureddecorators[](was flatannotations[]),error_channel[](wasthrown_exceptions[]), singlekindper type node (theis_*booleans retire).call_graph{src,dst,prov,weight}at application scope (richJGraphEdgesretire);calleenull->id backfill oncallbody nodes.schema.neo4j.jsonbumps to 2.0.0.program_graphs.functions[sig].cfg.nodesintobody{}; splitsdg_edgesintocfg/cdg/ddg/summary(intra) +param_in/param_out(application);data_dependence: no-heap|fullbecomes theddgprov: ["ssa"]vs["points-to"]split.CAVEATS AND KNOWN RISKS
.claude/SCHEMA_DECISIONS.md.DEFINITION OF DONE
schema.neo4j.jsongreen.Part of codellm-devkit/python-sdk#238