Skip to content

release: v9.2.0 — analyzeOutgoingImpact, symbolExists, Cartographer 3.0.0#221

Merged
SimplyLiz merged 20 commits intomainfrom
develop
Apr 25, 2026
Merged

release: v9.2.0 — analyzeOutgoingImpact, symbolExists, Cartographer 3.0.0#221
SimplyLiz merged 20 commits intomainfrom
develop

Conversation

@SimplyLiz
Copy link
Copy Markdown
Owner

Summary

  • analyzeOutgoingImpact — forward call graph (MCP + CLI). Mirror of analyzeImpact answering "what does this symbol call?" — drives off LIP v2.3.5's query_outgoing_impact RPC, folds through the same ImpactItem pipeline, surfaces semantic callees alongside static. Degrades cleanly when LIP is down.
  • symbolExists MCP tool — exact-match boolean oracle ({exists, kind, location?}) for LLMs grounding references before citation. Cheaper than getSymbol for the existence check.
  • LIP tier-1 fold into analyzeImpact — tree-sitter callers LIP discovers (when scip-go emits no Call roles) become first-class impact items rather than sitting in a parallel summary field. Driven by new BlastRadiusEnricher interface so incoming/outgoing share one fold pipeline.
  • register_project_root on LIP handshake — daemon canonicalises file URIs against a known anchor, fixing tier-1 dedup against SCIP results.
  • Bridge centrality in risk scoreanalyzeImpact now multiplies the weighted-mean risk by 1 + max(BridgeScore)/1000 (capped at 2.0) over changed files, so changes on critical architectural paths score higher.
  • Cartographer 3.0.0 sync — full upstream sync, fixes rebuild_graph mutex deadlock, fixes tree-sitter symbol collisions at link time, adds renderArchitecture MCP tool with diagram overlays (cycles, hot nodes, layer violations).

Test plan

  • go test ./... green on develop
  • go test -race ./... (release pipeline runs this)
  • Smoke battery green (status, doctor, impact in/out, search, explain, refs, LIP-down)
  • Verified outgoing impact end-to-end against cargo-released lip-cli 2.3.5: 39 direct / 160 transitive callees on Engine.AnalyzeImpact, edges_source=scip_with_tier1_edges, truncation surfaces correctly
  • LIP-down degradation: with LIP_SOCKET unset, ckb impact outgoing returns empty result + warning, no error
  • Tag v9.2.0 after merge to trigger GoReleaser → Homebrew tap → npm publish

🤖 Generated with Claude Code

SimplyLiz and others added 18 commits April 16, 2026 08:40
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
reviewPR and analyzeImpact now consume LIP's QueryBlastRadiusBatch to
supplement SCIP static call graph with embedding-based semantic coupling.
One round-trip prefetch for all changed files, gated behind lipSupports.

Key invariant: UniqueCallerCount stays SCIP-only so review thresholds
never inflate from embedding noise. Semantic callers are additive in
SemanticCallerCount and carry a per-caller CouplingTier (static/semantic/
both) so consumers can distinguish certainty levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e helpers

AnalyzeImpact now enriches blast radius with LIP semantic coupling on the
same lipSupports gate as reviewPR. Both paths share lip.EntryToExternal and
lip.LookupSymbol — the private duplicates in review_blastradius.go are
removed. BlastRadiusEnricher.EnrichBatch is now actually used.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CouplingStatic was defined but never referenced — SCIP-only callers go
into UniqueCallerCount, not EnrichedCallers. Flagged by ckb review dead-code
check on develop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `renderArchitecture` MCP tool that returns the project's
module-level import graph as Mermaid or Graphviz (DOT), ready to paste
into IDEs that render Mermaid inline. With `focus` set, returns an
undirected BFS neighborhood around the anchor module; without,
returns the top-N most-connected nodes. `truncated: true` flags when
the node cap kicked in.

Wire the tool end-to-end: Go binding `RenderArchitecture` in
`internal/cartographer/bridge.go` (+ no-op stub), schema +
registration in `internal/mcp/tools.go`, handler in
`tool_impls_v86.go`. Vendored `lib.rs` gets a surgical patch
(`mod diagram;` + FFI export) and the regenerated `cartographer.h`;
new `src/diagram.rs` holds the shared renderer used by CLI and FFI.

Fix link-time duplicate-symbol collisions with `go-tree-sitter` under
`-tags cartographer`. `make build-cartographer` now runs the
vendored `scripts/localize-tree-sitter-symbols.sh` after cargo's
release build: it partial-links archive members so Cartographer's
internal ts_*/tree_sitter_* references resolve within the archive,
then marks those symbols local. cartographer_* FFI exports stay
global. Beyond unblocking the build, this prevents a silent
memory-corruption class of bug where Cartographer's Rust code could
have bound to the consumer's tree-sitter copy at global resolution
if the two versions' struct layouts ever drifted.

Also relocate `ErrUnavailable` from `bridge_stub.go` into
`types.go` so it's visible under both tag variants (the tagged
bridge references it unconditionally).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
calculateAggregatedRisk now multiplies the weighted-mean score by
1 + max(BridgeScore)/1000 (capped at 2x) over the graph nodes matching
the changed files, so a change landing on a critical architectural path
is reported as riskier than the same-shape change in a leaf module.
CARTOGRAPHER_STRATEGY.md had already claimed this behaviour — this
commit makes it real.

The lookup matches files by both Path and ModuleID. If no changed file
matches the graph (or the build is without -tags cartographer, where
MapProject returns ErrUnavailable), the multiplier is 1.0 and no
informational factor is appended — bridge weighting is additive, never
punitive when data is missing.

A new `bridge_centrality` RiskFactor surfaces in RiskScore.Factors when
the multiplier fires. Its Weight is 0 because it applies
multiplicatively, not as a weighted-mean input; Value carries the raw
max(BridgeScore)/1000 for consumer display.

Pure helper bridgeMultiplierFromGraph has 8 subtests covering empty
inputs, path/module matching, max-across-files, 2x cap, and path-wins
tiebreak. No cartographer build tag needed for the unit test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… query

QueryBlastRadiusBatch now returns *BlastRadiusBatchResult instead of a
bare map, so callers can tell "file not in the LIP index" apart from
"indexed, zero callers" — same on-wire format, new struct wrapper
exposes the not_indexed_uris list the daemon already returns. Callers
in blast_radius.go and review_blastradius.go updated; existing zero-
callers behaviour unchanged.

New QueryBlastRadiusSymbol wraps LIP's v2.3 query_blast_radius_symbol
RPC for direct symbol-URI lookups, sidestepping the batch-and-filter
workaround when the daemon supports it. AnalyzeImpact dispatches to
this path first under lipSupports("query_blast_radius_symbol"), and
falls back to the batch path on older daemons — so old LIP builds
degrade cleanly, new ones skip a round-trip.

BlastRadiusEntry gains a FileURI field mirroring the daemon's response,
so consumers can back-reference symbol→file without reparsing the URI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ize script

Vendored diagram.rs was 391 lines behind upstream — syncing pulls in the
Overlays feature (cycle borders, layer-violation edge styling, hotspot
sizing) so the libcartographer.a that CKB links against produces the
same diagrams as the Cartographer CLI. The only vendor-local delta is
`at_range: None` stripped from the test edge() fixture, since the
vendored api.rs predates GraphEdge.at_range; a NOTE comment marks this
for future syncs. All 20 diagram tests pass on the vendored copy.

Also fixes a latent bug in localize-tree-sitter-symbols.sh that surfaced
when rebuilding from the synced source: the script extracted archive
members with `ar x`, but Cargo emits multiple members named parser.o /
scanner.o (one per tree-sitter grammar crate), and `ar x` silently
clobbers them. After localization the archive ended up with
_tree_sitter_c and _tree_sitter_cpp as undefined references, breaking
`go build -tags cartographer`.

The script now feeds the archive straight to `ld -r` via -force_load
(Mach-O) / --whole-archive (ELF), skipping the filesystem extraction
entirely so duplicate-named members coexist in combined.o as intended.
Verified: go test -tags cartographer -run TestBridgeMultiplierFromGraph
links cleanly and passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The vendored Cartographer tree had drifted across 10 .rs files plus
Cargo.toml — diagram.rs alone was 391 lines behind. Prior syncs were
done file-by-file and kept missing things. Full sync to upstream 3.0.0
closes the gap.

FFI surface is purely additive (cartographer_doc_index,
cartographer_doc_context, cartographer_query_docs) so CKB's existing Go
bindings still link unchanged; the new FFI entry points can get Go
bindings in a follow-up when we want to expose doc-graph features
through MCP. Upstream's GraphEdge now carries an at_range: Option<Range>
field (LIP source position for doc backtick refs) so the vendor-local
at_range patch on diagram.rs tests is no longer needed.

scripts/sync-cartographer.sh is now the supported path for future syncs
— explicit path list rsync from an upstream checkout, so we catch every
file the next time upstream changes instead of discovering drift at
rebuild time. No local patches are applied; the script will fail loudly
if one ever becomes necessary so it's obvious at review time.

Verified: all 74 upstream cargo tests pass on the vendored copy;
make build-cartographer + go test -tags cartographer link cleanly and
the bridge-centrality test passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
MCP's cartographer cache is pinned to the current commit hash and
regenerated on every startup — not source, shouldn't track.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ApiState::rebuild_graph held the mapped_files lock across its loop and
then called resolve_import_target, which re-acquired the same
non-reentrant std::sync::Mutex — any repo with a resolvable import
deadlocked. diagram and health hung on CKB itself (1093 files) and the
Go bridge's cartographer.MapProject blocked under the same condition.

Split the resolver: a public method that locks and a private helper
that takes the already-held map; rebuild_graph now calls the helper.
Fix contributed upstream with a regression test; pulled back into the
vendor tree via scripts/sync-cartographer.sh — that sync also brings
in the upstream call_graph, diagram_export, and html_export modules
along with diagram/main updates from upstream [Unreleased].
Adds FoldExternalStaticItems in internal/impact/enricher.go. Folds
LIP's DirectItems / TransitiveItems into SCIP-derived ImpactItem lists,
gated on EdgesSource — fold-eligible for tier1 / scip_with_tier1_edges
/ scip_only, skip for empty. Dedups against existing SCIP callers by
(absolute file path, symbol name), filters Phase-4 file-only tails
(empty SymbolURI), defaults Distance when LIP omits it.

Also plumbs EdgesSource through the LIP client (client.go) and the
ExternalBlastRadius adapter (blast_radius.go), and prefers the SCIP-
form symbol URI in AnalyzeImpact via the new SCIPSymbolToURI helper
so symbols imported from SCIP round-trip cleanly to LIP.

This is step 1 of the fold work — the helper and its tests. Step 2
wires it into AnalyzeImpact's item pipeline (before budget truncation)
so direct/transitive arrays carry the unioned set.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fetch LIP enrichment up-front in AnalyzeImpact so tier-1 tree-sitter callers
fold into result.DirectImpact/TransitiveImpact before budget truncation.
Recompute BlastRadius over the unioned set (via new RecomputeBlastRadius)
when EdgesSource != empty so UniqueCallerCount/FileCount/RiskLevel reflect
LIP's static contribution. Semantic merge via MergeBlastRadius stays in the
summary path and reuses the already-fetched external result.

Also fix a latent single-symbol CLI gap: convertImpactResponse didn't carry
BlastRadius through, so `ckb impact <sym>` always returned blastRadius:null.
The diff/changeset path had it; now both paths do.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add RegisterProjectRoot RPC matching LIP v2.3.1 wire shape
({"type":"register_project_root","root":"..."} → DeltaAck) and fire
it from probeHandshake when the daemon advertises support. Once
registered, LIP canonicalises CKB's relative lip://local/<rel>
URIs against the absolute project root via longest-prefix match,
eliminating URI-mismatch bugs of the class hit during the Bug-B
debug cycle.

Feature-gated on HandshakeResult.supported_messages so older daemons
(pre-v2.3.1) skip the call rather than hit UnknownMessage. Empty
repoRoot also short-circuits — test harnesses without a root stay
silent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors query_blast_radius_symbol for the forward direction. Returns
an OutgoingImpactEntry with target_uri, direct_items (callees at
distance=1), transitive_items (distance>=2), semantic_items (seeded
from the target's embedding), edges_source, and truncated — the same
provenance and coupling vocabulary as blast radius so folds can be
routed through the shared ExternalBlastRadius pipeline.

OutgoingEntryToExternal converts the wire entry to the shared shape
with RiskLevel empty — outgoing impact doesn't carry its own
classification; CKB will derive one from the unioned callee set when
the analyzer path is wired.

Adds DirectCallee/TransitiveCallee ImpactKinds so folded items
classify correctly once the analyzer fold lands. Analyzer + CLI/MCP
surface are deferred until LIP v2.3.3 ships and the wire contract is
verified end-to-end.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ounding

Adds a new MCP tool and query engine method that answers "does this bare
symbol name exist in the index?" using a direct WHERE-clause query against
symbols_fts_content, bypassing FTS5 tokenisation entirely. This makes
class methods (saveReport, trackUsage) and object-property declarations
(setApiKey: t.procedure…) reliably findable by bare leaf name — the cases
that caused ~20–30% false-rejection rates in ArchReview's persona-swarm
validator when it used searchSymbols + client-side exact comparison.

Returns { exists, matches, kinds, receivers?, staleIndex? } — a cheap
boolean payload with no locations or ranking noise. Adds a note to the
searchSymbols description pointing callers to symbolExists for
authoritative lookups. Wire into all presets (core + review, refactor,
federation, docs, ops).

Acceptance criteria from the backlog spec all pass (11 tests).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Surfaces LIP v2.3.5's forward call graph ("what does X call?") as a
first-class CKB operation mirroring AnalyzeImpact in the reverse
direction. Requires a daemon advertising query_outgoing_impact;
degrades to an empty response with a provenance warning when the RPC
isn't supported.

- Engine: Engine.AnalyzeOutgoingImpact in internal/query, driven by
  the shared LIP fold pipeline via impact.FoldExternalCalleeItems.
- impact: new FoldExternalCalleeItems twin of FoldExternalStaticItems,
  both delegating to a shared kind-parameterised fold. Fixed a latent
  distance-default bug that treated DirectCallee items as distance=2.
- CLI: ckb impact outgoing <symbolId> with --min-score / --format.
  ProvenanceCLI gained a Warnings field so LIP-unavailable surfaces
  cleanly in JSON output.
- MCP: analyzeOutgoingImpact tool registered and dispatched.

Tests cover the engine method against a fake daemon, the fold-level
kind tagging and dedup semantics, and the lip→impact seam end-to-end.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
….0.0

Wire LIP v2.3.5's query_outgoing_impact through the engine, CLI
(`ckb impact outgoing`), and MCP (`analyzeOutgoingImpact`). Folds
LIP tier-1 callees through the same ImpactItem pipeline as the
incoming side and surfaces semantic coupling alongside the static
graph. Adds `symbolExists` MCP tool as a cheap boolean oracle for
LLMs grounding references before citation.

Risk score in `analyzeImpact` now picks up bridge centrality from
Cartographer (`1 + max(BridgeScore)/1000`, capped at 2.0) so changes
on critical architectural paths score higher than leaf-module changes
of the same shape.

Sync vendored Cartographer to upstream 3.0.0, fix `rebuild_graph`
deadlock, fix tree-sitter symbol collisions at link time, add
`renderArchitecture` MCP tool with diagram overlays.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 25, 2026

CKB Analysis

Risk Files +10641 -334 Modules

🎯 48 changed → 0 affected · 🔥 33 hotspots · 📊 7 complex · 💣 9 blast · 📚 197 stale

Risk factors: Large PR with 59 files • High churn: 10975 lines changed • Touches 33 hotspot(s)

👥 Suggested: @lisa.welsch1985@gmail.com (17%), @talantyyr@gmail.com (14%), @lisa@tastehub.io (10%)

Metric Value
Impact Analysis 48 symbols → 0 affected 🟢
Doc Coverage 6.598984771573605% ⚠️
Complexity 7 violations ⚠️
Coupling 0 gaps
Blast Radius 0 modules, 0 files
Index indexed (0s) 💾
🎯 Change Impact Analysis · 🟢 LOW · 48 changed → 0 affected
Metric Value
Symbols Changed 48
Directly Affected 0
Transitively Affected 0
Modules in Blast Radius 0
Files in Blast Radius 0

Symbols changed in this PR:

Recommendations:

  • ℹ️ 48 symbols have low mapping confidence. Index may be stale.
    • Action: Run 'ckb index' to refresh the SCIP index
💣 Blast radius · 0 symbols · 9 tests · 0 consumers

Tests that may break:

  • internal/impact/enricher_test.go
  • internal/lip/client_test.go
  • internal/mcp/presets_test.go
  • internal/mcp/token_budget_test.go
  • internal/query/impact_outgoing_test.go
  • … and 4 more
🔥 Hotspots · 33 volatile files
File Churn Score
CHANGELOG.md 16.60
cmd/ckb/impact.go 8.38
cmd/ckb/review.go 6.04
internal/cartographer/bridge.go 8.58
internal/cartographer/types.go 9.32
internal/impact/enricher.go 8.49
internal/lip/blast_radius.go 9.24
internal/lip/client.go 13.87
📦 Modules · 3 at risk
Module Files
🔴 third_party/cartographer 18
🟡 internal/query 10
🟡 internal/mcp 6
📊 Complexity · 7 violations
File Cyclomatic Cognitive
cmd/ckb/impact.go ⚠️ 24 ⚠️ 48
cmd/ckb/review.go ⚠️ 74 ⚠️ 193
internal/impact/enricher.go 15 ⚠️ 24
internal/lip/client_test.go 15 ⚠️ 36
internal/mcp/presets_test.go ⚠️ 21 ⚠️ 35
internal/mcp/token_budget_test.go 10 ⚠️ 24
internal/mcp/tool_impls.go ⚠️ 51 ⚠️ 135
💡 Quick wins · 10 suggestions
📚 Stale docs · 197 broken references

Generated by CKB · Run details

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 25, 2026

NFR Tests ✅ 39 unchanged

Comparing PR against main branch (dynamic baseline).

Regressions: 0 ✅

Thresholds: WARN ≥ +5% • FAIL ≥ +10%

All scenarios
Scenario Change Actual (B) Base (B) Time
analyzeChange / large +0.0% 193,169 193,169 1.114581ms
analyzeChange / medium +0.0% 38,575 38,575 201µs
analyzeChange / small +0.0% 4,046 4,046 32µs
analyzeChange / xlarge +0.0% 387,417 387,417 1.470438ms
analyzeImpact / large +0.0% 17,966 17,966 96µs
analyzeImpact / small +0.0% 1,924 1,924 18µs
batchGet / large +0.0% 11,789 11,789 60µs
batchGet / small +0.0% 4,733 4,733 42µs
batchSearch / large +0.0% 90,816 90,816 413µs
batchSearch / medium +0.0% 18,036 18,036 121µs
batchSearch / small +0.0% 3,379 3,379 21µs
explore / large +0.0% 94,262 94,262 518µs
explore / small +0.0% 4,253 4,253 34µs
findReferences / large +0.0% 445,943 445,943 1.912775ms
findReferences / medium +0.0% 44,123 44,123 276µs
findReferences / small +0.0% 4,395 4,395 41µs
getAffectedTests / large +0.0% 7,521 7,521 62µs
getAffectedTests / medium +0.0% 3,110 3,110 25µs
getAffectedTests / small +0.0% 903 903 17µs
getAffectedTests / xlarge +0.0% 14,870 14,870 108µs
getArchitecture / large +0.0% 6,690 6,690 59µs
getArchitecture / small +0.0% 960 960 13µs
getCallGraph / deep +0.0% 15,238 15,238 97µs
getCallGraph / shallow +0.0% 887 887 17µs
getHotspots / large +0.0% 16,748 16,748 136µs
getHotspots / small +0.0% 886 886 15µs
listEntrypoints / large +0.0% 23,798 23,798 113µs
listEntrypoints / small +0.0% 4,795 4,795 48µs
prepareChange / large +0.0% 16,194 16,194 102µs
prepareChange / small +0.0% 2,483 2,483 28µs
searchSymbols / large +0.0% 90,246 90,246 426µs
searchSymbols / medium +0.0% 17,766 17,766 149µs
searchSymbols / small +0.0% 3,588 3,588 54µs
summarizeDiff / large +0.0% 19,939 19,939 195µs
summarizeDiff / small +0.0% 2,133 2,133 53µs
traceUsage / large +0.0% 7,728 7,728 66µs
traceUsage / small +0.0% 725 725 12µs
understand / large +0.0% 460,608 460,608 2.440311ms
understand / small +0.0% 5,555 5,555 67µs

* = new scenario, compared against static baseline

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 25, 2026

CKB Review: 🟡 WARN — 51/100

59 files (+10975 changes) · 16 modules · c go rust
58 reviewable · 1 generated (excluded)

Changes 59 files across 16 modules (c, go, rust). 59 files across 14 independent clusters — split recommended; 8 new bug pattern(s) (22 pre-existing filtered). Consider splitting into 14 smaller PRs.

Check Status Detail
split 🟡 WARN 59 files across 14 independent clusters — split recommended
bug-patterns 🟡 WARN 8 new bug pattern(s) (22 pre-existing filtered)
coupling 🟡 WARN 4 commonly co-changed file(s) missing from changeset
risk 🟡 WARN Risk score: 1.00 (high)
format-consistency ℹ️ INFO 1 format consistency issue(s)
blast-radius ℹ️ INFO No symbols with callers in changes
generated ℹ️ INFO 1 generated files detected and excluded
test-gaps ℹ️ INFO 63 untested function(s) in changed files (showing top 10)
hotspots ℹ️ INFO 32 hotspot file(s) touched (top 10 shown)
unwired ✅ PASS All exported symbols are reachable from entrypoints
breaking ✅ PASS No breaking API changes
secrets ✅ PASS No secrets detected
dead-code ✅ PASS No dead code in changed files
health ✅ PASS 3 file(s) degraded, 0 improved (avg -0.2)
complexity ✅ PASS +859 cyclomatic complexity across 21 file(s)
tests ✅ PASS 12 test(s) cover the changes
comment-drift ✅ PASS No comment/code drift detected
arch-health ⚪ SKIP Cartographer not compiled in this build
layers ⚪ SKIP Cartographer not compiled in this build

Top Risks

  • Risk score: 1.00 (high)
  • 8 new bug pattern(s) (22 pre-existing filtered)
  • 4 commonly co-changed file(s) missing from changeset
Findings (23 actionable, 24 informational)
Severity File Finding
🟡 cmd/ckb/symbol.go Missing co-change: cmd/ckb/search.go (83% co-change rate)
🟡 cmd/ckb/symbol.go Missing co-change: cmd/ckb/status.go (83% co-change rate)
ℹ️ cmd/ckb/impact.go Complexity 91→108 (+17 cyclomatic) in formatImpactMarkdown()
ℹ️ internal/cartographer/bridge.go Missing co-change: third_party/cartographer/mapper-core/cartographer/include/cartographer.h (100% co-change rate)
ℹ️ internal/cartographer/bridge.go Complexity 114→120 (+6 cyclomatic) in SimulateChange()
ℹ️ internal/cartographer/bridge.go:679 'err' shadowed — redeclared with := at depth 1 (outer declaration at line 671)
ℹ️ internal/lip/client.go Complexity 140→161 (+21 cyclomatic) in GetEmbeddingsBatch()
ℹ️ internal/lip/client_test.go Complexity 207→246 (+39 cyclomatic) in TestDegradation_NoSocket()
ℹ️ internal/mcp/tool_impls.go Complexity 379→406 (+27 cyclomatic) in toolGetArchitecture()
ℹ️ internal/mcp/tool_impls_v86.go Complexity 39→49 (+10 cyclomatic) in toolQueryContext()

... and 13 more

✂️ Suggested PR Split (14 clusters)
Cluster Files Changes Independent
third_party/cartographer 18 +7118 −286
internal/query 10 +1539 −10
internal/mcp 6 +309 −15
internal/cartographer 5 +186 −5
internal/impact 5 +683 −1
.github/workflows 3 +5 −5
cmd/ckb 3 +178 −8
internal/lip 3 +534 −0
CLAUDE.md 1 +16 −0
internal/version 1 +1 −1

... and 4 more clusters

Code Health — 3 degraded

Degraded:

File Before After Delta Grade Confidence
internal/impact/types.go 86 84 -2 B→B 100%
internal/lip/client.go 75 73 -2 B→B 100%
internal/lip/client_test.go 65 63 -2 C→C 100%

^1 File could not be parsed by tree-sitter

New files: 5 (avg health: 71)

3 degraded · 0 improved · avg -0.2

Estimated review: not feasible as a single PR (59 files, 10975 lines, 14 clusters)

Reviewers: lisa.welsch1985 (17%) · talantyyr (14%) · lisa (10%)

golangci-lint flagged gofmt drift across the v9.2.0 surface
(impact types, MCP tool registration, symbol_exists, etc.).
Apply gofmt to all 9 files.

scip-go upstream renamed its module path from
github.com/sourcegraph/scip-go to github.com/scip-code/scip-go.
The release at v0.2.3 declares the new path in go.mod, which
makes the old import error out with a version-constraints conflict.
Update the install command in ci.yml, cov.yml, and ckb.yml; also
update the human-readable hint printed when the indexer is missing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 25, 2026

🟢 Change Impact Analysis

Metric Value
Risk Level LOW 🟢
Files Changed 58
Symbols Changed 48
Directly Affected 0
Transitively Affected 0

Blast Radius: 0 modules, 0 files, 0 unique callers

📝 Changed Symbols (48)
Symbol File Type Confidence
.github/workflows/ci.yml .github/workflows/ci.yml modified 30%
.github/workflows/ckb.yml .github/workflows/ckb.yml modified 30%
.github/workflows/cov.yml .github/workflows/cov.yml modified 30%
.gitignore .gitignore modified 30%
CHANGELOG.md CHANGELOG.md modified 30%
CLAUDE.md CLAUDE.md modified 30%
Makefile Makefile modified 30%
cmd/ckb/impact.go cmd/ckb/impact.go modified 30%
cmd/ckb/review.go cmd/ckb/review.go modified 30%
cmd/ckb/symbol.go cmd/ckb/symbol.go modified 30%
internal/cartographer/bridge.go internal/cartographer/bridge.go modified 30%
internal/cartographer/bridge_stub.go internal/cartographer/bridge_stub.go modified 30%
internal/cartographer/types.go internal/cartographer/types.go modified 30%
internal/impact/analyzer.go internal/impact/analyzer.go modified 30%
internal/impact/classification.go internal/impact/classification.go modified 30%
+33 more

Recommendations

  • ℹ️ coverage: 48 symbols have low mapping confidence. Index may be stale.
    • Action: Run 'ckb index' to refresh the SCIP index

Generated by CKB

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 25, 2026

Codecov Report

❌ Patch coverage is 41.51982% with 531 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/mcp/tool_impls.go 0.0% 121 Missing ⚠️
cmd/ckb/impact.go 3.1% 90 Missing and 1 partial ⚠️
internal/query/impact_outgoing.go 36.6% 70 Missing and 6 partials ⚠️
internal/query/impact.go 47.4% 45 Missing and 6 partials ⚠️
internal/query/review_blastradius.go 2.0% 47 Missing and 1 partial ⚠️
internal/lip/blast_radius.go 38.0% 43 Missing and 1 partial ⚠️
internal/lip/client.go 33.9% 35 Missing and 2 partials ⚠️
internal/impact/enricher.go 84.0% 10 Missing and 10 partials ⚠️
internal/mcp/tool_impls_v86.go 0.0% 19 Missing ⚠️
internal/query/symbol_exists.go 75.0% 11 Missing and 6 partials ⚠️
... and 2 more
Additional details and impacted files
@@           Coverage Diff           @@
##            main    #221     +/-   ##
=======================================
+ Coverage   43.1%   43.3%   +0.1%     
=======================================
  Files        530     534      +4     
  Lines      81525   82420    +895     
=======================================
+ Hits       35200   35749    +549     
- Misses     43825   44167    +342     
- Partials    2500    2504      +4     
Flag Coverage Δ
unit 43.3% <41.5%> (+0.1%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

📢 Thoughts on this report? Let us know!

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The test fake daemon recorded incoming requests via a goroutine
appending to a shared []map[string]any while the test main
goroutine read it through the snap() closure. Race detector caught
this on CI (TestAnalyzeOutgoingImpact_HappyPath). Wrap append and
read with sync.Mutex; snap() takes the lock around its copy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@SimplyLiz SimplyLiz merged commit 3de7223 into main Apr 25, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant