Skip to content

Epic: canonical schema v2 consistency across codeanalyzer-* and python-sdk #35

Description

@rahlk

Spec

docs/design/roadmap.md (this epic's spec is its own first deliverable — see the sub-issue for the canonical projection contract).

Summary

Every codeanalyzer-* claims canonical schema v2 but implements it differently, and each analyzer's conformance test validates its emitter against its own declared schema rather than against canonical v2. codeanalyzer-python and codeanalyzer-typescript both read SCHEMA_VERSION = "2.0.0" while emitting materially different graphs. This epic settles the canonical projection contract, makes conformance a checkable predicate, and then brings python-sdk onto v2 with strong backwards compatibility.

Schema impact: this epic defines the shared vocabulary that the per-analyzer migrations then move to. It is the keystone, not an additive change.

Timing note — the divergence is pre-release, and that is the opportunity. The v2 work is unreleased on both analyzers. python-sdk/pyproject.toml pins codeanalyzer-python==0.3.1 (SCHEMA_VERSION 1.2.0) and codeanalyzer-typescript==0.4.3 (SCHEMA_VERSION 1.0.0) — both schema v1, and both SDK Neo4j backends match those pins exactly. codeanalyzer-typescript's tags stop at v1.0.0. So no consumer sees v2 today, and reconciling the two v2 lines before either ships is far cheaper than reconciling shipped contracts afterwards.

Affected repos

  • codellm-devkit/.github — the canonical projection contract spec, and the shared conformance suite if it has no better home
  • codeanalyzer-python — 9 Neo4j merge labels, split PyCallSite / PyCFGNode body model; migrates to the settled contract (major)
  • codeanalyzer-typescript — closest to canonical; its gap is the Neo4j projection (structured decorators and TSApplication.entrypoints reach analysis.json only)
  • codeanalyzer-java — no can:// ids, statement-level CPG deferred in .claude/SCHEMA_DECISIONS.md 📣 New Release: codeanalyzer-python 0.3.1 #9 (major)
  • codeanalyzer-clang — unassessed: no SCHEMA_DECISIONS.md, no declared schema version
  • python-sdk — one Node / Edge / Application model layer replacing four per-language model packages, under a backwards-compatibility policy
  • greenfield (codeanalyzer-go, codeanalyzer-dotnet Epic: codeanalyzer-dotnet (cansharp) — a C# analyzer for CLDK #34, kotlin, rust, swift, abap) — born conformant, never migrate

Design decisions

Locked by the planning pass (docs/design/roadmap.md, commit c58d8a2):

  • Group A is one design session, not five. The projection contract, body-node model, can:// grammar, parity gate and conformance suite are one decision seen from five sides: the suite cannot check ids it has not pinned or a body model it has not chosen, and the merge-label strategy is decided by the body-node model — TypeScript's unified TSBodyNode is why two merge labels suffice where Python needs nine.
  • Group C is one decision. "Strong backwards compatibility" is a constraint on the v2 model layer's shape, not a wrapper added afterwards.
  • The two projections must agree. Canonical v2 states analysis.json and the Neo4j graph are projections of one structure; nothing checks this today in any analyzer, and TypeScript demonstrably violates it.

Scope guard — explicitly OUT of this epic:

  • The entrypoint vocabulary (JEntrypoint marker / TSEntrypoint JSON collection / nothing in Python — already coined three ways). Its own design session, after this one.
  • The microservice initiative in full: multi-application normalization, service-boundary vocabulary, cross-service edges and dataflow, the SystemAnalysis facade.
  • Non-HTTP service boundaries; codeanalyzer-go levels L2–L4; collapsing the per-language SDK facades into one.

Release plan

Train Carries Notes
the contract spec, parity gate, conformance suite no release; deliverable is a spec and a test suite
codeanalyzer-python 3.0.0 migration major — merge labels and body-node model change; the current 2.0.0 label is inaccurate, so the bump corrects as much as it migrates
codeanalyzer-java 2.0.0 migration majorcan:// ids, statement-level CPG
codeanalyzer-typescript 2.1.0 migration additive MINOR — projecting to Neo4j what it already computes
codeanalyzer-clang TBD scope unknown until assessed
greenfield initial releases born conformant never migrate
python-sdk v2 model layer version depends on the backwards-compatibility policy — additive alongside the per-language models is a minor, replacing them is a major

Additionally: moving python-sdk's analyzer pins off the 0.x line is what makes v2 observable to any consumer at all. Until then a conformant analyzer changes nothing a user can see. Roadmap candidate 15.

Gating: the contract spec gates every migration. Any one conformant analyzer unblocks the SDK model layer. Python and Java ride one migration together with the SDK — two analyzer majors landing separately would force the SDK through two compatibility windows.

Definition of done (epic-level)

  • Every sub-issue closed and its gate green.
  • The conformance suite runs against every analyzer that has a Neo4j emitter and passes, checking against canonical v2 rather than each analyzer's self-declared schema.
  • The projection-parity gate proves analysis.json and the Neo4j graph carry the same facts for the same run, on every analyzer — including the decorators and entrypoints that codeanalyzer-typescript currently drops on the graph side.
  • No two analyzers declare the same SCHEMA_VERSION while emitting structurally different graphs.
  • python-sdk parses every conformant analyzer's output through one model layer, and the documented backwards-compatibility window is stated in its CHANGELOG with the deprecation signal in place.
  • python-sdk pins analyzer versions that emit canonical v2, so the contract reaches a consumer rather than stopping at the analyzers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    EpicCross-repo coordination epic

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions