-
-
Notifications
You must be signed in to change notification settings - Fork 10
Cartographer
Cartographer is a Rust library that CKB embeds via CGo FFI to provide architectural analysis, semantic retrieval, and git history intelligence. It runs in-process — no daemon, no IPC, no subprocess — making calls as fast as a function call into a shared object.
Without Cartographer, CKB relies on SCIP index, tree-sitter, and git CLI for everything. Cartographer adds a layer of structural intelligence on top of those:
| Feature | What it tells you |
|---|---|
| Dependency graph | Every file and its import edges, with cycle detection and god-module identification |
| Architectural health | A 0–100 score built from bridge count, cycle count, god-module count, layer violations, and coupling |
| Layer enforcement | Validates your layers.toml rules and reports which files cross the boundaries |
| Cycle detection | Circular dependencies with severity and pivot-node identification |
| God modules | Overly-connected files (high degree + low cohesion) that become chokepoints |
These feed the getArchitecture, getModuleOverview, and reviewPR (arch-health check) tools.
SimulateChange predicts — before you touch anything — what happens if a module's signature changes:
- Which modules are affected
- Whether the change would create a new cycle
- Whether it would introduce a layer violation
- Risk level and health delta
This is what powers analyzeImpact when Cartographer is available.
SkeletonMap and RankedSkeleton give CKB a tree-sitter-powered view of your codebase compressed to a token budget:
- Every file reduced to its signatures (no bodies)
- PageRank ranking personalised around focus files
- BM25 + PageRank combined retrieval pipeline (
QueryContext) - Context bundle quality scoring (
ContextHealth) — composite A–F grade
These make explainFile, getArchitecture, and the retrieval pipeline significantly more accurate because they're graph-aware, not just lexical.
Beyond what git CLI provides:
| Function | What it detects |
|---|---|
| GitChurn | Per-file commit counts over the last N commits |
| GitCochange | File pairs that change together (temporal coupling) |
| HiddenCoupling | File pairs with high co-change but no import edge — implicit coupling invisible in the static graph |
| ShotgunSurgery | Files ranked by co-change dispersion: changing them historically required simultaneous changes across many unrelated files |
| Semidiff | Function-level diff between two commits (not just line-level) |
| Evolution | Architectural health snapshots across git history — how your health score has moved over the last N days |
These feed getHotspots, the coupling check in reviewPR, the dead-code check (via unreferenced symbol discovery), and the co-change dispersion tool.
UnreferencedSymbols finds public symbols that appear nowhere across the project — without needing a SCIP index. It's used as a Cartographer-tier fallback for reviewPR's dead-code check when SCIP isn't available.
BlastRadius computes the graph-theoretic blast radius of a module or file: direct dependents, transitive dependents, and a maximum-related limit. Used by get_blast_radius and the blast-radius check in reviewPR.
RenderGraph walks the same module graph that powers getArchitecture and emits diagram syntax — Mermaid for inline rendering in GitHub/GitLab/Notion, Graphviz DOT for dot -Tsvg pipelines. Powers the renderArchitecture MCP tool and ckb arch render CLI.
| Tool | Cartographer functions used |
|---|---|
getArchitecture |
MapProject, Health, CheckLayers
|
renderArchitecture |
MapProject, RenderGraph
|
getModuleOverview |
MapProject, GetModuleContext
|
analyzeImpact |
SimulateChange |
analyzeOutgoingImpact |
(LIP query_outgoing_impact — Cartographer not on this path) |
getHotspots |
GitChurn, GitCochange
|
get_blast_radius |
BlastRadius |
reviewPR (arch-health check) |
Health, MapProject
|
reviewPR (coupling check) |
HiddenCoupling |
reviewPR (dead-code check) |
UnreferencedSymbols |
reviewPR (layer check) |
CheckLayers |
reviewPR (split check) |
Semidiff |
explainFile |
SkeletonMap, RankedSkeleton
|
understand / explore
|
QueryContext |
watch_graph |
MapProject (periodic) |
listKeyConcepts |
BM25Search, RankedSkeleton
|
| Shotgun surgery detection | ShotgunSurgery |
| Architectural evolution | Evolution |
When Cartographer is not compiled in, these tools degrade gracefully — they fall back to SCIP-only analysis, git CLI, or return reduced results. No errors.
CKB works fine without Cartographer for:
- All SCIP-based symbol queries (
search,refs,callgraph,impactvia SCIP graph) - Ownership, decisions, ADRs
- Secret detection
- Documentation intelligence
- Federation / multi-repo
- LIP and LSP integration
Cartographer is additive. If you don't build with it, you lose the architectural intelligence layer and the git-history coupling analysis — everything else is unaffected.
Cartographer requires a Rust toolchain (stable channel). The library lives in third_party/cartographer/.
- Go 1.21+
- Rust (
rustup install stable) - A C compiler (Xcode Command Line Tools on macOS,
build-essentialon Debian/Ubuntu)
cd src
# Recommended: build with Cartographer (default make target)
make build
# This is equivalent to:
make build-cartographer # compiles Rust → libcartographer.a
go build -tags cartographer -o bin/ckb ./cmd/ckb/...cd src
make build-fast
# or:
go build -o bin/ckb ./cmd/ckb/...The stub (internal/cartographer/bridge_stub.go) is compiled instead: every function returns an "unavailable" error, and all callers in the query engine check cartographer.Available() before calling through.
ckb statusLook for the Analysis Tier line:
Analysis Tier: Full (SCIP + Cartographer) ← Cartographer compiled in
Analysis Tier: Standard (SCIP) ← without Cartographer
Analysis Tier: Fast (tree-sitter) ← no SCIP index either
cd src
make test-cartographerCartographer is statically linked into the CKB binary via CGo. There are no runtime dependencies — no shared library to install, no daemon to start.
CKB binary
└── cartographer (static, -lcartographer)
├── libcartographer.a (compiled from Rust sources in third_party/)
└── cartographer.h (C FFI header)
The FFI boundary uses JSON over C strings — each function returns a *C.char pointing at a JSON {"ok": true, "data": ...} envelope. Go decodes it and returns typed structs. The string is freed by cartographer_free_string() immediately after decoding.
The build tag cartographer selects between bridge.go (real CGo) and bridge_stub.go (no-ops). Both export the same Go API, so the rest of CKB is tag-agnostic.
src/
third_party/
cartographer/
mapper-core/
cartographer/
src/ ← Rust sources (extractor, mapper, api, etc.)
include/
cartographer.h
target/
release/
libcartographer.a ← compiled output (git-ignored)
internal/
cartographer/
bridge.go ← CGo bindings (build tag: cartographer)
bridge_stub.go ← no-op stubs (build tag: !cartographer)
types.go ← shared Go types
The Rust sources are a git subtree of the Cartographer repository. To update them:
git subtree pull --prefix src/third_party/cartographer \
https://github.com/SimplyLiz/Cartographer.git main --squash