Skip to content

Migrate to canonical schema v2: can:// ids, statement-level CPG, identity-only edges #179

Description

@rahlk

Parent: codellm-devkit/.github#35 · Roadmap: docs/design/roadmap.md (candidate 9)
Identity grammar spec: can-uri-service-segment.md · codellm-devkit/.github#39

Skeleton — bodies to be filled in by the maintainer.

Problem

codeanalyzer-java is the only analyzer still on schema 1.1.0, and the only one whose shape canonical v2 explicitly forbids rather than merely differs from.

  • No can:// ids. Python and TypeScript both emit them; Java does not.
  • No statement-level nodes in the Neo4j projection. schema.neo4j.json declares 16 labels — JApplication, JCompilationUnit, JType, JCallable, JCallSite, JField, JParameter, JVariable, JAnnotation, JComment, JCrudOperation, JCrudQuery, JEnumConstant, JInitializationBlock, JPackage, JRecordComponent — and none is a body/statement node. Deferred deliberately in .claude/SCHEMA_DECISIONS.md Callable signature and patch for expression resolution failure #9: "Statement-level CPG (CFGNode etc.) stays a follow-up." This is that follow-up.
  • Dependence edges are callable→callable. J_CONTROL_DEP / J_DATA_DEP / J_HEAP_DATA_DEP connect JCallable to JCallable (SCHEMA_DECISIONS.md Callable signature and patch for expression resolution failure #9), where canonical v2 places cfg / cdg / ddg at statement→statement on the callable.
  • Rich edges. The emitted shape drives python-sdk's JGraphEdges, whose source and target are full JMethodDetail objects rather than node ids (cldk/models/java/models.py:517-523). Canonical v2's expansion rubric: "Never: … add a rich-edge variant."

Scope boundary

Brings the analyzer's emitted contract to canonical v2. Does not change python-sdk's Java models — that is codellm-devkit/python-sdk#309, and it is blocked on this issue, not the reverse. Does not settle the entrypoint vocabulary (JEntrypoint marker + is_entrypoint), which is a separate design session.

Goals

  • can://<service>/<lang>/<file>/<type>/<sig> ids, with Java's signatureOf() pinned (generics, overloads, <init>) — note the service segment is outermost and there is no <app> segment (spec D1/D2); the app-name CLI option becomes --service, same default (input directory name)
  • Statement-level body nodes in both projections, on the settled body-node model
  • cfg / cdg / ddg / summary re-anchored from callable→callable to statement→statement
  • Identity-only edges — endpoints are ids, no nested callables
  • SCHEMA_VERSION 1.1.0 → 2.1.0 (not 2.0.0 — Java emits no can:// id today, so it lands directly on the service-segment grammar and never has to migrate off 2.0.0), with .claude/SCHEMA_DECISIONS.md updated
  • Passes the shared conformance suite (Shared conformance suite: check every analyzer against canonical v2 .github#38) and the projection-parity gate (Projection-parity gate: prove analysis.json and the Neo4j graph agree .github#37)

Caveats and known risks

  • WALA node identity is SSA instruction order, not AST source spans (SCHEMA_DECISIONS.md Update excluding signature-related files #5): node_id 0 is a synthetic ENTRY, then SSA instructions by iindex. Canonical v2 addresses sub-callable nodes by @line:col. These do not map cleanly — WALA nodes are SSA instructions, not AST regions, and source lines come from ECJ/CAst positions with a -1 sentinel when unavailable. This is the hard part of the issue and may force either a Java-specific local-id form recorded in SCHEMA_DECISIONS.md, or a change to the canonical grammar. It should be raised in the contract spec (Canonical Neo4j projection contract: merge labels, body-node model, can:// grammar .github#36), not discovered during implementation.
  • CFG edge kinds are derived, not labelled by WALA (SCHEMA_DECISIONS.md Update main.yml #6) — true/false by successor order, loop_back by iindex comparison. Deterministic but approximate; carry the documentation forward rather than silently absorbing it.
  • No SUMMARY edges today (SCHEMA_DECISIONS.md Add thrown exceptions to callable info in symbol table #7) — WALA computes HRB summaries lazily inside Slicer.
  • This is a breaking change for every python-sdk consumer of JGraphEdges. It must ride one migration with codeanalyzer-python 3.0.0 and the SDK, per the epic's release plan.
  • TODO

Definition of done

  • TODO — exact conditions. At minimum: the conformance suite and parity gate both pass, and no JGraphEdges-shaped rich edge remains in the emitted contract.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions