Documentation
¶
Overview ¶
cmd/ckg/bench_mcp.go — `ckg bench-mcp` measures p50/p95/p99 latency of every registered MCP tool against a real graph.db. Counterpart to bench-server: where bench-server exercises the HTTP layer, bench-mcp exercises the in-process tool handlers directly (no subprocess spawn, no JSON-RPC framing).
Why in-process rather than spawning `ckg mcp`: we want to attribute latency to the graph layer (store reads, BM25 ranking, subgraph walk) rather than to the stdio + JSON-RPC framing on top. If the in-process numbers are dominated by the graph layer, the stdio hypothesis ("framing dominates") is wrong; if they're trivial, then a follow-up bench-mcp-stdio would be worth building. This commit takes the cheaper measurement first.
cmd/ckg/bench_mcp_stdio.go — `ckg bench-mcp-stdio` measures MCP tool latency through a real `ckg mcp` subprocess. Counterpart to bench-mcp's in-process measurement: the difference between the two attributes the cost of stdio + JSON-RPC framing to the right side of the boundary.
Concurrency is implicitly 1 — the stdio pipe carries one in-flight request at a time. Production MCP clients (Claude Desktop, etc.) also drive a single connection per server, so this matches the production load profile.
cmd/ckg/bench_server.go — `ckg bench-server` measures p50/p95/p99 latency of every /api/* endpoint against a real graph.db. Serves a performance baseline that future PRs can re-run to detect regressions; the JSON output is machine-readable so a comparison table can be diffed in CI.
The server runs in-process via httptest (no port allocation, no cleanup races). Each endpoint is hit `iterations` times sequentially per worker, with `concurrency` workers in parallel — the same load profile the dogfood plan calls "warm cache, steady-state read".
MCP tool latency is intentionally out of scope: the stdio transport would require subprocess spawning and JSON-RPC framing, which dwarfs the cost of the HTTP measurement we actually care about for regression-tracking. A future bench-mcp subcommand can layer on when that signal becomes valuable.
cmd/ckg/benchmark.go — `ckg benchmark` measures the token-reduction payoff of using the graph instead of feeding the agent the raw corpus. Inspired by graphify's benchmark.run_benchmark (benchmark.py:64-110) but adapted to CKG's richer node/edge schema:
Corpus baseline: sum of source-file bytes for the indexed languages, converted to tokens via the standard ~4 chars-per- token heuristic (matches OpenAI/Anthropic averages for English+code; fine for ratio reporting).
Graph-query cost: pick the top-N god nodes as proxy "questions", BFS k=3 hops from each, render the subgraph as a compact text answer (`Symbol → Symbol` chains), and count the resulting tokens.
Reduction ratio: corpus_tokens / avg(query_tokens). A 100x ratio means the graph reaches the same answer using 1% of the tokens a naive grep-everything pass would consume.
The numbers are approximate by design — point estimates for the "is the graph worth the build cost" decision, not precision metrics.
cmd/ckg/eval_retrieval.go — `ckg eval-retrieval` runs the LLM-free retrieval probes from eval/retrieval/*.yaml against a built graph and emits per-fixture recall/precision/F1 plus an aggregate gate result. EV1 Phase 2.
cmd/ckg/evidence.go — `ckg evidence` runs the H3 EvidencePack assembler from a one-shot CLI invocation, no `ckg serve` required. Targets shell scripts, CI pipelines, and ad-hoc inspection where the long-running server would be overkill.
The CLI mirrors the /api/evidence query shape:
ckg evidence --graph DIR [--intent TEXT] [--issue ID]
[--seed-qname QNAME] [-k N] [--budget N] [--offset N]
[--format json|text]
At least one of --intent or --issue is required (matches the server- side check). text format emits a compact human-readable summary (commit subject + first few patch lines + issue badges); json emits the full pkg/evidence.Pack so downstream tooling can pipe through jq / Go templates / etc.
cmd/ckg/export_json.go — single-file JSON export of the full graph.
Use case: portable graph snapshot for downstream tools, AI assistants, or alternative viewers. Mirrors graphify's `graph.json` ergonomic (one file you can ship anywhere) while preserving CKG's richer schema (32 edge types, 34 node types, confidence labels, dispatch_kind).
Default output is minimal: nodes + edges + manifest summary. The shipped JSON is <100MB for the go-stablenet-scale graph (~220K nodes / 1.9M edges) and parses in ~1s on commodity hardware. Pass --pretty for human-readable indentation; the default packs each row on one line for grep/jq friendliness on large files.
cmd/ckg/path.go — `ckg path A B` finds the shortest path between two nodes in the graph, printing the symbol chain + edge types along the way. Inspired by graphify's `graphify path "A" "B"` ergonomic (__main__.py:1622-1683).
Resolution order for each argument:
- Exact qualified_name match (the deterministic case for fully qualified inputs like `pkg.SubPkg.Foo`).
- Exact name match — when ambiguous, picks the highest-PageRank candidate so a user typing a bare `Run` resolves to the project's primary Run() rather than a test-fixture Run().
- ID prefix match — useful when copy-pasting from /api/edges output that surfaces 16-char node IDs.
BFS is undirected because "how are X and Y related" doesn't depend on edge direction (matches graphify's nx.shortest_path default behaviour).
cmd/ckg/query.go — `ckg query "<question>"` answers a free-form question by searching for matching symbols + their k-hop graph neighbourhood, then rendering a compact markdown answer with cited symbols and source locations. LLM-free — pure structural retrieval, suitable for piping into an agent that wants a token-bounded brief of the relevant code surface.
Inspired by graphify's `graphify query "..."` (analyze.suggest_questions + manual BFS), but explicitly keyword-driven rather than NLU. The query engine: (1) tokenise the question, (2) score every node by keyword overlap on Name + QualifiedName, (3) BFS from the top-K seeds with a hop budget, (4) render the visited subgraph as markdown + citations.
Token budget is rough — the renderer trims the visited set when the estimated token count would exceed --budget (graphify default 2000).
cmd/ckg/quickstart.go — single-command path from "I have a repo" to "viewer is open in my browser". Inspired by graphify's `/graphify .` ergonomic; collapses the `ckg build` + `ckg serve` pair (plus an optional `ckg report`) into one entry point so first-time users don't have to learn the multi-step workflow before seeing results.
Usage:
ckg quickstart # build ./, output to ./ckg-out, serve on 8080 ckg quickstart --src ./apps # build a subtree ckg quickstart --no-serve # build + report only, skip the HTTP server ckg quickstart --no-report # skip GRAPH_REPORT.md generation
The quickstart command is intentionally a thin orchestrator over the existing build/serve/report subcommands — every option those expose is reachable directly when the user needs finer control.
cmd/ckg/report.go — generate a human-readable GRAPH_REPORT.md from a built graph.db. Inspired by graphify's GRAPH_REPORT.md (god nodes, surprising connections, suggested questions) but extended with CKG's 6-graph axis breakdown so the report carries the full picture of the codebase across structural / semantic / execution / concurrency / distributed / temporal axes.
Use case: ship a single markdown alongside graph.db / graph.json so reviewers, agents, and managers have a quick primer on the codebase without booting the viewer. The report is purely derived — re-run any time without re-building.