Skip to content

Commit 3de7223

Browse files
authored
Merge pull request #221 from SimplyLiz/develop
release: v9.2.0 — analyzeOutgoingImpact, symbolExists, Cartographer 3.0.0
2 parents 32dc5c2 + acece7f commit 3de7223

59 files changed

Lines changed: 10641 additions & 334 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
cache: true
4848

4949
- name: Install scip-go
50-
run: go install github.com/sourcegraph/scip-go/cmd/scip-go@latest
50+
run: go install github.com/scip-code/scip-go/cmd/scip-go@latest
5151

5252
- name: Run tests
5353
run: go test -v -race ./...

.github/workflows/ckb.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
run: go build -ldflags="-s -w" -o ckb ./cmd/ckb
8989

9090
- name: Install SCIP indexer
91-
run: go install github.com/sourcegraph/scip-go/cmd/scip-go@latest
91+
run: go install github.com/scip-code/scip-go/cmd/scip-go@latest
9292

9393
# ───────────────────────────────────────────────────────────────────────
9494
# Cache & Index
@@ -114,7 +114,7 @@ jobs:
114114
echo "╔═══════════════════════════════════════════════════════════════════════════════╗"
115115
echo "║ INDEXER NOT FOUND ║"
116116
echo "╠═══════════════════════════════════════════════════════════════════════════════╣"
117-
echo "║ Go: go install github.com/sourcegraph/scip-go/cmd/scip-go@latest ║"
117+
echo "║ Go: go install github.com/scip-code/scip-go/cmd/scip-go@latest ║"
118118
echo "║ TypeScript: npm i -g @sourcegraph/scip-typescript ║"
119119
echo "║ Python: pip install scip-python ║"
120120
echo "║ Rust: cargo install scip ║"
@@ -989,7 +989,7 @@ jobs:
989989
run: go build -ldflags="-s -w" -o ckb ./cmd/ckb
990990

991991
- name: Install SCIP indexer
992-
run: go install github.com/sourcegraph/scip-go/cmd/scip-go@latest
992+
run: go install github.com/scip-code/scip-go/cmd/scip-go@latest
993993

994994
- name: Cache
995995
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5

.github/workflows/cov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
cache: true
3232

3333
- name: Install scip-go
34-
run: go install github.com/sourcegraph/scip-go/cmd/scip-go@latest
34+
run: go install github.com/scip-code/scip-go/cmd/scip-go@latest
3535

3636
- name: Run tests with coverage
3737
run: |

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,6 @@ testdata/**/pubspec.lock
4949

5050
# Vendored Cartographer Rust build artifacts
5151
third_party/cartographer/mapper-core/cartographer/target/
52+
53+
# MCP runtime caches (pinned to commit hash, regenerated on startup)
54+
internal/mcp/.cartographer_cache.json

CHANGELOG.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,132 @@ All notable changes to CKB will be documented in this file.
44

55
## [Unreleased]
66

7+
## [9.2.0] - 2026-04-25
8+
9+
### Added
10+
11+
- **`analyzeOutgoingImpact` — forward call graph** (MCP + CLI) — mirror
12+
of `analyzeImpact` answering *"what does this symbol call?"* instead of
13+
*"who calls it?"*. New `Engine.AnalyzeOutgoingImpact` drives off LIP
14+
v2.3.5's `query_outgoing_impact` RPC, folds the result through the same
15+
`ImpactItem` pipeline as the incoming side (with `direct-callee` /
16+
`transitive-callee` kinds), and surfaces semantically coupled callees
17+
alongside the static graph. Degrades cleanly when LIP isn't running:
18+
the response is empty with a provenance warning, never an error.
19+
Surfaces include `ckb impact outgoing <symbolId>` (with `--min-score`
20+
for the semantic threshold), the `analyzeOutgoingImpact` MCP tool, and
21+
a new `ProvenanceCLI.Warnings` field so LIP-degradation messages reach
22+
JSON consumers.
23+
- **`symbolExists` MCP tool** — exact-match boolean oracle that returns
24+
`{exists, kind, location?}` for a fully-qualified symbol ID. Built for
25+
LLMs to ground references *before* they cite them in code, without
26+
spending tokens on a 20-result `searchSymbols` payload. Cheaper than
27+
`getSymbol` for the "does this thing actually exist" check.
28+
- **LIP enrichment folds into `analyzeImpact`** — tier-1 tree-sitter
29+
callers that LIP discovers (when `scip-go` emits no `Call` roles, e.g.
30+
Go method dispatch) are now folded into the same `directImpact` /
31+
`transitiveImpact` lists as SCIP's own results, deduplicated by
32+
`(file, name)`. Driven by a new `BlastRadiusEnricher` interface so the
33+
fold path is the single source of truth for both incoming and outgoing
34+
impact analysis. Items LIP marks `edges_source=empty` are skipped (LIP
35+
signalling no static evidence); `tier1`, `scip_with_tier1_edges`, and
36+
`scip_only` all fold the same way. Risk score now picks up
37+
semantic-coupling signals via the same enricher pipeline.
38+
- **`register_project_root` on LIP handshake** — Engine startup now
39+
registers the repo root with the daemon so LIP canonicalises file URIs
40+
against a known anchor, matching the v2.3.1 contract. Eliminates the
41+
URI-shape drift that previously caused tier-1 callers to dedup
42+
incorrectly against SCIP results.
43+
44+
### Changed
45+
46+
- **`analyzeImpact` risk score now weighted by bridge centrality**
47+
`calculateAggregatedRisk` multiplies the weighted-mean score by
48+
`1 + max(BridgeScore)/1000` (capped at 2.0) over the changed files, so a
49+
change landing on a critical architectural path (high betweenness) is
50+
reported as riskier than the same-shape change in a leaf module. Implements
51+
the behaviour that `CARTOGRAPHER_STRATEGY.md` had already documented but
52+
the code was not actually doing. Bridge lookups match by both `Path` and
53+
`ModuleID`; if no changed file matches the graph, the multiplier is 1.0
54+
and no informational factor is appended. Only runs when the binary was
55+
built with `-tags cartographer` (graph is a no-op otherwise). A new
56+
`bridge_centrality` informational factor surfaces in `RiskScore.Factors`
57+
when the multiplier fires; its `Weight` is 0 because it applies
58+
multiplicatively, not as a weighted-mean input.
59+
60+
### Cartographer
61+
62+
- **Vendored Cartographer fully synced to upstream 3.0.0** — the
63+
vendored tree under `third_party/cartographer/mapper-core/cartographer/`
64+
was 391 lines behind on `diagram.rs` alone, and 10 `.rs` files plus
65+
`Cargo.toml` had drifted. Full sync brings in doc-node graph support
66+
(`cartographer_doc_index`, `cartographer_doc_context`, `cartographer_query_docs`
67+
FFI entry points — Go bindings can be added as a follow-up),
68+
LIP-style `Range` / `at_range` on `GraphEdge`, PascalCase bare-identifier
69+
resolution for doc backtick refs, and the overlays feature on diagrams.
70+
New `scripts/sync-cartographer.sh` is now the supported path for future
71+
syncs — rsync-based, explicit path list, emits next-step commands. No
72+
local patches needed against upstream.
73+
- **Diagram overlays in `renderArchitecture` / `ckb diagram`** — the
74+
vendored `diagram.rs` was synced from upstream Cartographer, so the
75+
Mermaid/DOT output now decorates the base import graph with
76+
architectural signals: cycle members get a thick red border (pivots
77+
dashed), cycle-internal edges a heavy red arrow, layer violations pick
78+
up per-type dashed/dotted edge styling, and hot nodes
79+
(`hotspot_score ≥ 70`) get an orange border plus DOT size scaling.
80+
Mermaid is border-only for hot nodes (no sizing primitive). Cycle red
81+
takes precedence over hot orange on the same node — architectural
82+
signal wins over performance signal.
83+
- **`renderArchitecture` MCP tool** — returns the project's module-level
84+
import graph as Mermaid or Graphviz (DOT), ready to paste into IDEs
85+
that render Mermaid inline (Cursor, Claude Desktop, VS Code markdown
86+
preview, GitHub). With `focus` set, returns an undirected BFS
87+
neighborhood around the anchor module to `depth` (default 2); without,
88+
returns the top-N most-connected nodes (default cap 40). Response
89+
includes `truncated: true` when the node cap kicked in. Backed by the
90+
new `cartographer_render_architecture` FFI export; CLI and MCP outputs
91+
are produced by the same shared renderer.
92+
- Go binding `cartographer.RenderArchitecture()` in `internal/cartographer/bridge.go` (+ no-op stub for the no-tag build).
93+
94+
### Fixed
95+
96+
- **Vendored Cartographer `rebuild_graph` deadlock** — upstream
97+
`ApiState::rebuild_graph` held the `mapped_files` Mutex across its
98+
loop and then called `resolve_import_target`, which re-acquired the
99+
same non-reentrant `std::sync::Mutex`. Any project with a resolvable
100+
import deadlocked — the `cartographer diagram` / `cartographer health`
101+
CLIs hung, and the Go bridge's `cartographer.MapProject` would block
102+
any time CKB fed it a repo with imports. Fixed in the vendored tree
103+
(and contributed back upstream) by splitting the resolver: a public
104+
method that locks, and a private helper that takes the already-held
105+
map; `rebuild_graph` now calls the helper. Discovered during
106+
end-to-end smoke testing against CKB itself (1093 files). Regression
107+
test added upstream.
108+
- **`localize-tree-sitter-symbols.sh` dropped grammar C parsers** — the
109+
script extracted archive members via `ar x`, which silently clobbers
110+
files when multiple members share a name. Cargo emits a `parser.o`
111+
and `scanner.o` per grammar crate (tree-sitter-c, -cpp, -rust, -go,
112+
etc.), so `ar x` left only the *last* grammar's C parser on disk,
113+
producing a localized archive missing `_tree_sitter_c` / `_tree_sitter_cpp`.
114+
The script now feeds the archive directly to `ld -r` with
115+
`-force_load` (Mach-O) / `--whole-archive` (ELF), which pulls every
116+
member in without touching the filesystem. The `rust_tree_sitter` C
117+
ABI refs to `_tree_sitter_c` and `_tree_sitter_cpp` now resolve
118+
inside the combined object as expected.
119+
- **Tree-sitter symbol collisions at link time**`libcartographer.a`
120+
previously exported its bundled tree-sitter runtime and grammar
121+
symbols, which collided with `go-tree-sitter` when building CKB with
122+
`-tags cartographer` (`ld: 246 duplicate symbols`). `make build-cartographer`
123+
now post-processes the archive via
124+
`scripts/localize-tree-sitter-symbols.sh` (vendored under
125+
`third_party/cartographer/mapper-core/cartographer/scripts/`), which
126+
partial-links archive members into one combined object and localizes
127+
`ts_*` / `tree_sitter_*`. `cartographer_*` FFI exports stay global.
128+
Beyond the duplicate-symbol error, this also rules out a silent
129+
memory-corruption class of bug where Cartographer's Rust code could
130+
have bound to the consumer's tree-sitter copy at global resolution
131+
time if the two versions' struct layouts ever drifted.
132+
7133
## [9.1.0] - 2026-04-16
8134

9135
### Added

CLAUDE.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,22 @@ golangci-lint run
7878
./ckb setup --tool=vscode
7979
```
8080

81+
## Release Process
82+
83+
Releases are fully automated via `.github/workflows/release.yml`, triggered by pushing a `v*` tag.
84+
85+
**Steps to release:**
86+
1. Bump version in `internal/version/version.go`, `npm/package.json`, `testdata/review/sarif.json`
87+
2. Update `CHANGELOG.md`
88+
3. Merge to main, tag `vX.Y.Z`, push the tag
89+
4. The pipeline handles everything else:
90+
- Runs `go test -race ./...`
91+
- GoReleaser builds cross-platform binaries and uploads to GitHub Releases
92+
- Updates Homebrew tap (`SimplyLiz/homebrew-ckb`)
93+
- Publishes `@tastehub/ckb` + 5 platform packages to npm
94+
95+
**Do not manually `npm publish`** — the pipeline does it with checksummed binaries from GoReleaser.
96+
8197
## npm Distribution (v7.0)
8298

8399
CKB is also available via npm:

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ build: build-cartographer
1414
build-cartographer:
1515
@echo "Building Cartographer static library..."
1616
@cd $(CARTOGRAPHER_DIR) && cargo build --release
17+
@echo "Localizing tree-sitter symbols (prevents link-time collisions with go-tree-sitter)..."
18+
@cd $(CARTOGRAPHER_DIR) && scripts/localize-tree-sitter-symbols.sh target/release/libcartographer.a
1719
@echo "Library: $(CARTOGRAPHER_LIB)"
1820

1921
## Build without Cartographer (no Rust toolchain required — for CI and contributors)

0 commit comments

Comments
 (0)