You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
python-sdk models the schema four times, once per language (cldk/models/{java,python,typescript,c}). All three analyzers now emit canonical v2 — codeanalyzer-python 1.4.0, codeanalyzer-typescript 1.2.0, codeanalyzer-java 3.0.1 — while the SDK pins 0.3.1 / 0.4.3 and bundles the 2.4.1 JAR, so it is the last consumer still parsing v1.
The spine is common to all three: id / kind / span, source once on the module node, named-map containment, a body{} map keyed by ordinal id, split cfg / cdg / ddg / summary lists on the callable, and identity-only edges at application scope. That agreement is what gets modelled once.
Scope boundary
The shared model layer and the Python leg that validates it — they land together, because a spine designed with no consumer is a spine designed against the spec rather than against a real payload. TypeScript is leg 2 (#307), Java is leg 3 (#310), the query layer is leg 4 (#311).
Does not collapse the per-language facades (PythonAnalysis / JavaAnalysis / TypeScriptAnalysis / CAnalysis) into one — explicitly out of scope for the parent epic. Does not change what any analyzer emits.
Per-language subclasses narrow the container maps by redeclaring them and add typed extras — no generics, no untyped extra="allow" dicts (spec D2)
No language model package redefines a spine field
Python leg: pin codeanalyzer-python==1.4.0, subclasses, view layer, Neo4j backend, facade — pin bump and model migration in the same PR, since v1 models cannot parse v2 output and vice versa
The Java blocker. The earlier body said the SDK "cannot move to identity-only edges while its producer emits rich ones", and marked the Java half blocked on Migrate to canonical schema v2: can:// ids, statement-level CPG, identity-only edges codeanalyzer-java#179. codeanalyzer-java 3.0.1 emits JCallEdge{src, dst, prov, weight}, JIdEdge{src, dst} and a canonical body map. JGraphEdges and _CALLABLES_LOOKUP_TABLE survive only in the SDK's own v1 models — SDK-side legacy retirement, not an upstream dependency.
"Invisible to users until the pins move off the 0.x line." True when written; the pin bump is now part of leg 1 rather than a follow-up, so nothing about this work is deferred behind a separate pin-moving issue.
"May need promotion to its own epic." Epic fixing caller method #35 keeps coordinating (spec D5). Per-leg work items are filed at pickup.
Removing _CALLABLES_LOOKUP_TABLE is behavioural, not a refactor: today a miss silently fabricates a callable with is_implicit=True and -1 sentinels rather than failing, so consumers may depend on edges resolving to synthetic nodes. That lands in leg 3 (python-sdk: Java models → schema v2 (two-layer views) #310), not here.
Four of the nine registered divergences are parity-clause breaches on the Python side (config_reads_unresolved vs config_reads, base_classes vs base_types/interfaces, attributes vs fields, and v1 line fields retained alongside span). The SDK absorbs them; each is a line item COBOL support #36 can retire.
Definition of done
cldk/models/cpg/ exists and no language model package redefines a spine field.
The Python facade loads codeanalyzer-python 1.4.0 output, and every public accessor's name, signature and return type is unchanged — proven by the existing Python facade tests running unmodified.
Both projections agree: analysis.json and the Python Neo4j backend return the same facts for the same run.
Parent: codellm-devkit/.github#35 · Spec:
docs/design/specs/2026-09-03-python-sdk-canonical-v2.md(#318)Problem
python-sdkmodels the schema four times, once per language (cldk/models/{java,python,typescript,c}). All three analyzers now emit canonical v2 —codeanalyzer-python1.4.0,codeanalyzer-typescript1.2.0,codeanalyzer-java3.0.1 — while the SDK pins 0.3.1 / 0.4.3 and bundles the 2.4.1 JAR, so it is the last consumer still parsing v1.The spine is common to all three:
id/kind/span,sourceonce on the module node, named-map containment, abody{}map keyed by ordinal id, splitcfg/cdg/ddg/summarylists on the callable, and identity-only edges at application scope. That agreement is what gets modelled once.Scope boundary
The shared model layer and the Python leg that validates it — they land together, because a spine designed with no consumer is a spine designed against the spec rather than against a real payload. TypeScript is leg 2 (#307), Java is leg 3 (#310), the query layer is leg 4 (#311).
Does not collapse the per-language facades (
PythonAnalysis/JavaAnalysis/TypeScriptAnalysis/CAnalysis) into one — explicitly out of scope for the parent epic. Does not change what any analyzer emits.Goals
cldk/models/cpg/defines the spine once: envelope (Analysis,AnalyzerInfo), containers (Application,Module,Type,Callable), leaves (BodyNode,Field,Parameter,Decorator,Import,Comment,Span), edges (CallEdge,CfgEdge,CdgEdge,DdgEdge,IdEdge), and the repository-artifact layerextra="allow"dicts (spec D2)codeanalyzer-python==1.4.0, subclasses, view layer, Neo4j backend, facade — pin bump and model migration in the same PR, since v1 models cannot parse v2 output and vice versaPyCallableOverviewprojection pattern (#180/feat(python): bulk/projected accessors for the Python facade (#180) #181) generalises into the view layer, which is where API stability is bought:.codeand.call_sitesbecome computed views overbody/source2.0.0-rc.1; closes Incorporate codeanalyzer-python v1.2.0 #315, Incorporate codeanalyzer-python v1.3.0 #316, Incorporate codeanalyzer-python v1.4.0 #317, and Python get_method_bodies lacks the None-code omission filter (twin of the TS #298 rule) #301Withdrawn from the previous revision
codeanalyzer-java3.0.1 emitsJCallEdge{src, dst, prov, weight},JIdEdge{src, dst}and a canonicalbodymap.JGraphEdgesand_CALLABLES_LOOKUP_TABLEsurvive only in the SDK's own v1 models — SDK-side legacy retirement, not an upstream dependency.Caveats and known risks
codeanalyzer-schemaholds only a README. The SDK models what the three analyzers actually emit and records every divergence rather than blocking (spec D1) — which means today's divergence is absorbed into the SDK's view layer until COBOL support #36 retires it._CALLABLES_LOOKUP_TABLEis behavioural, not a refactor: today a miss silently fabricates a callable withis_implicit=Trueand-1sentinels rather than failing, so consumers may depend on edges resolving to synthetic nodes. That lands in leg 3 (python-sdk: Java models → schema v2 (two-layer views) #310), not here.config_reads_unresolvedvsconfig_reads,base_classesvsbase_types/interfaces,attributesvsfields, and v1 line fields retained alongsidespan). The SDK absorbs them; each is a line item COBOL support #36 can retire.Definition of done
cldk/models/cpg/exists and no language model package redefines a spine field.codeanalyzer-python1.4.0 output, and every public accessor's name, signature and return type is unchanged — proven by the existing Python facade tests running unmodified.analysis.jsonand the Python Neo4j backend return the same facts for the same run.pyproject.tomlpinscodeanalyzer-python==1.4.0.2.0.0-rc.1cut; Incorporate codeanalyzer-python v1.2.0 #315, Incorporate codeanalyzer-python v1.3.0 #316, Incorporate codeanalyzer-python v1.4.0 #317 and Python get_method_bodies lacks the None-code omission filter (twin of the TS #298 rule) #301 closed.