From 0a6ad2c54d1eacf94a2975a6fc87c53f1f74e20f Mon Sep 17 00:00:00 2001 From: Rahul Krishna Date: Thu, 10 Sep 2026 18:31:37 -0400 Subject: [PATCH] chore(release): 2.0.0-rc.6 --- CHANGELOG.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6423a2e..f07df1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,74 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.0.0-rc.6] - 2026-09-10 + +The Java Neo4j backend stops being the lossy one about source text. Until now a graph-backed Java +analysis could answer *where* a node is far better than *what it says*: text existed only as +`:JCallable.code`, so a callable came back as its whole declaration where the local backend returned +the body block, a body node had no text at all, and a module-scope `locate` returned `""`. The +analyzer closed that gap in 3.2.0; this release takes it up, and moves the sibling pins to the +releases that closed the same gap for Python and TypeScript. + +### Breaking + +**The Java Neo4j attach floor moves to codeanalyzer-java 3.2.0.** A graph emitted by 3.1.x — served +silently until now — is refused at attach, naming what was found and the floor. + +The floor moves rather than degrading gracefully because the degradation would be silent and would +look like data. A 3.1.x graph has no `:JModule.source` and no byte offsets, so every text answer +would come back empty or as the old whole-declaration string, from accessors this release documents +as returning the same text as the local backend. An agent cannot tell "this node has no text" from +"this graph predates the property" — so the check belongs at attach, once, where it can say so. + +**Migration:** re-emit with `codeanalyzer-java 3.2.0 --emit neo4j`. Wipe the database first when the +graph predates 3.1.1, which moved the `can://` grammar. + +### Changed + +**Text is the same on both Java backends.** `JCallable.code`, `get_source`, `LocateResult.source` and +`describe` answer the same slice of the same file at every granularity — a callable's body block, a +type's or field's or local's declaration, a single statement or call site, and a module's whole text at +module scope. Each is a byte slice of `:JModule.source` taken at the node's own offsets, so the live +suites assert **equality** rather than `endswith` or "the same length". + +Three positions still have no text, on **both** backends and for the same reason each time — there is +nothing in the file to point at: an implicit compiler-generated `()`, an `@external` callable, and +a `resolve_value` ref (a `formal_in` vertex is a dataflow position, not a region of the file). +`module_source_unavailable` survives as a **data** diagnostic: it now fires on a module whose text the +analyzer could not read or decode, and on nothing else. + +Two removals fall out of it. `:JCallable.code` is no longer read — the slice replaces it — and +`body_end_byte` was never needed: across both committed fixtures, all 1,182 callables carrying both +spans end their body exactly where their declaration ends, because a Java declaration's last character +*is* its body's closing brace. That is asserted in the fixture builder rather than written down. + +**Analyzer pins move to `codeanalyzer-python==1.5.2` and `codeanalyzer-typescript==1.6.0`** +(`codeanalyzer-java` is already at 3.2.0). Both are Neo4j-projection-only conformance fixes: python +1.5.2 adds `:PyModule.source`, all six span properties wherever a span is declared, +`:PyVariable.value_json`, `:PyBodyNode.callee_signature`, `PY_IMPORTS.positions_json` and a span on +`PY_DECORATED_BY`; typescript 1.6.0 adds `:TSModule.source` and the four new span properties across ten +labels. Neither changes `analysis.json` — the TypeScript fixtures regenerated with the 1.6.0 wheel are +byte-identical to the 1.5.3 generation at all four levels apart from the `analyzer.version` stamp. + +**Neither sibling floor moves.** They stay 1.5.0 for Python and 1.5.2 for TypeScript: a floor move is +what would let the SDK *read* that new text, and that is uptake work the size of this release's Java +half, tracked in #396 and #391. The pin is what the SDK installs; the floor is what it requires of a +graph. Every sentence in the docs that read "the graph does not carry this" now says the SDK does not +read it, and names the issue that will. + +One thing does improve for free on a re-emitted Python graph: a call site's columns. The +reconstruction already reads `start_column` with a `-1` default, so 1.5.2 supplies real values and an +older graph still answers `-1` — data-driven, no version branch. + +### Verification + +The mocked, backend-contract and E2E tiers are green, and the Java E2E ran against the real 3.2.0 jar. +The **live** Java tiers — the ones that assert byte-for-byte equality across the two backends on +daytrader8 — assert the new behaviour but have not been run against a 3.2.0-emitted graph: the +verification corpus holds a 3.1.1 graph, which this release's own floor now refuses. Re-emitting it is +the outstanding verification debt, recorded rather than glossed. + ## [v2.0.0-rc.5] - 2026-09-10 Two changes, and they are the two halves of one question: what should happen when an analyzer ships diff --git a/pyproject.toml b/pyproject.toml index da8b19e..4ef0e17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cldk" -version = "2.0.0-rc.5" +version = "2.0.0-rc.6" description = "The official Python SDK for Codellm-Devkit." readme = "README.md" license = { text = "Apache-2.0" } diff --git a/uv.lock b/uv.lock index 03ada0d..fb3df06 100644 --- a/uv.lock +++ b/uv.lock @@ -300,7 +300,7 @@ wheels = [ [[package]] name = "cldk" -version = "2.0.0rc5" +version = "2.0.0rc6" source = { editable = "." } dependencies = [ { name = "codeanalyzer-python" },