Install CodeGraph + Semble, real competitor A/B (B10), and fix embeddings LFS incident - #17
Merged
Merged
Conversation
… (B10) Wires CodeGraph (colbymchenry/codegraph) into .mcp.json alongside the already-configured Semble, and adds a new benchmark (B10) that spawns real MCP servers for ci, CodeGraph, and Semble and runs the same B4/B6 self-repo tasks through all three — token cost, tool-call count, and a grep-oracle accuracy check on find_callers (CodeGraph misses a cross-crate caller that ci resolves correctly). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X83MzmbseyW5v3j9mka5Sc
…l forever Root cause of the embeddings_status: "failed" incident: a checkout without git-lfs installed leaves the vendored default embedding model (crates/ci-core/assets/potion-code-16m/model.safetensors) as a ~130-byte LFS pointer stub instead of real weights. `include_bytes!` bakes that stub into the binary either way, so the build "succeeds" and the failure only surfaces at runtime, permanently, with no clear diagnosis. - Embedder::load now detects an unusable vendored asset and automatically falls back to a one-time HuggingFace Hub download of the same default model (cached locally afterward), instead of failing forever. This is a functionality/reliability concern, not a privacy one — no code or repo content is ever sent anywhere; only a public static model file is fetched. - New semantic_search.allow_network_fallback config flag (default true) for anyone who wants semantic search to stay strictly zero-network: with it set to false, an unusable vendored asset reports the new embeddings_status: "offline_unavailable" (a known policy outcome) instead of silently attempting a network call or reporting the more generic "failed". - Hardened the infra that produced the incident: session-start-build-ci.sh and the documented cloud Setup Script now attempt `git lfs pull` before building; scripts/mcp-launcher.sh's is_binary_fresh also treats vendored assets as freshness inputs, so a fixed LFS asset invalidates a previously-built stale binary instead of being silently ignored. - Regression test (default_vendored_asset_is_not_an_lfs_pointer) catches this exact failure mode at test time instead of at first-run in production. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X83MzmbseyW5v3j9mka5Sc
Fixes the verify job's `cargo fmt --all -- --check` failure from the previous commit — pure formatting, no logic change (confirmed via diff_impact: 0 affected symbols). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X83MzmbseyW5v3j9mka5Sc
rebuild_graph's MAX_CALLEE_CANDIDATES fallback fanned out one edge to every same-named symbol in the repo when a call's receiver type couldn't be inferred, with no way to exclude candidates that couldn't possibly be the real target (e.g. String::as_str()/serde_json::Value::as_str() getting attributed to unrelated same-named enum methods). Root-caused via a live CodeGraph-vs-ci comparison that surfaced identical caller lists for 5 distinct as_str definitions. Adds a sound (not heuristic) exclusion: a call site immediately `?`-tried or `.unwrap()/.expect()`-chained can only target a candidate whose own signature returns Option/Result — provable from the parse tree alone via a new `looks_option_or_result_chained` check, peeling exactly one level through `.and_then(|x| ..)` since Option/Result::and_then's signature requires the closure to return a matching Option/Result. Candidates that survive the filter but remain ambiguous get a new `EdgeConfidence::Ambiguous` tier instead of masquerading as ordinary `textual` edges. Verified against a fresh isolated build + full reindex of this repo: crate_map.rs::from_cargo_metadata's false as_str edges are gone entirely; remaining unresolvable fan-out is now honestly labeled `ambiguous`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X83MzmbseyW5v3j9mka5Sc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.mcp.jsonvianpx -y @colbymchenry/codegraph serve --mcp, zero-setup parity with the existingsembleentry (which was already configured/working, no changes needed there).benchmarks/b10_real_competitor_ab/): spawns real MCP servers forci, CodeGraph, and Semble and runs the same 4 self-repo tasks used by B4/B6, measuring token cost, tool-call count, and a grep-oracle accuracy check onfind_callers.benchmarks/lib/generic_mcp_client.py(spawn-agnostic MCP stdio client, reusable beyondci) andbenchmarks/lib/competitor_tasks.yaml(same task IDs astasks.yaml, mapped to CodeGraph/Semble tool calls).benchmarks/README.md(adds B9 "Scaling Curve" as its own planned row, B10 as Implemented) anddocs/comparison.md(points to the real measured numbers instead of only public-docs comparison).Key finding (B10)
On
find_callers(collect_source_files), checked against a grep oracle:cifound 2/2 real callers; CodeGraph missed 1/2 — a cross-crate caller reached via a fully-qualified path (ci_core::indexer::pipeline::collect_source_filesin a different crate). Semble has no call-graph concept, so that task is markedunsupportedfor it and excluded from the accuracy comparison (still measured for token/call cost, not hidden, per this repo's "report bad numbers honestly" policy).Token ratios are reported but explicitly annotated as not a ranking — e.g. CodeGraph's 564x ratio on
pre_edit_blast_radiusreflects a terser response format (bare symbol list vsci's source + risk assessment +is_hub+suggested_next), not better compression of the same answer. Full nuance inbenchmarks/b10_real_competitor_ab/README.md.Second commit: embeddings self-heal from an unresolved Git LFS pointer
While running B10, this session's own
ciserver reportedembeddings_status: "failed". Root cause: this container's checkout never ran git-lfs, so the vendored default embedding model (crates/ci-core/assets/potion-code-16m/model.safetensors) was left as a ~130-byte LFS pointer stub instead of real weights —include_bytes!bakes that stub into the binary regardless, so the build "succeeds" and the failure only surfaces at runtime, permanently, with no clear diagnosis.Fix, researched against how comparable tools (CodeGraph, Serena, model2vec-rs upstream) handle local embedding models, then adapted to
ci's own constraints:Embedder::loadnow detects an unusable vendored asset and automatically falls back to a one-time HuggingFace Hub download of the same default model (cached locally afterward), instead of failing forever. This is a functionality/reliability concern, not a privacy one — no code or repo content is ever sent anywhere; only a public static model file is fetched.semantic_search.allow_network_fallbackconfig flag (defaulttrue) for anyone who wants semantic search to stay strictly zero-network: with it set tofalse, an unusable vendored asset reports the newembeddings_status: "offline_unavailable"(a known policy outcome) instead of silently attempting a network call or reporting the more generic"failed".session-start-build-ci.shand the documented cloud Setup Script now attemptgit lfs pullbefore building;scripts/mcp-launcher.sh'sis_binary_freshalso treats vendored assets as freshness inputs, so a fixed LFS asset invalidates a previously-built stale binary instead of being silently ignored.default_vendored_asset_is_not_an_lfs_pointer) catches this exact failure mode at test time instead of at first-run in production.Test plan
codegraph initran successfully against self-repo (83 files, 1,628 nodes, 4,423 edges)benchmarks/.venv/bin/python benchmarks/b10_real_competitor_ab/run_benchmark.pyruns end-to-end and produces the reported numberscargo test --release --workspace— all green (ci-core 388 passed, ci-server 96+2 passed, ci-cli builds clean)ci serveprocess with the rebuilt binary goesdownloading → embedding → ready, andsearch(kind="semantic")returns correct resultsmcp__ci__diff_impact(staged=true)run before both commits — reviewed the one genuinely high-risk-flagged symbol (EmbedStatus::as_str, 21 "callers") and confirmed 20/21 are unrelated textual name-collisions (String::as_str, etc.); the one real caller (embed_status_str) is the intended call site.mcp.jsoncodegraph entry spawns cleanly in a fresh Claude Code / Cursor session🤖 Generated with Claude Code
Generated by Claude Code