Skip to content

fix(codegraph): bump the lci-codegraph pin to pick up both extraction fixes - #596

Merged
stephane-segning merged 1 commit into
mainfrom
claude/codegraph-rename-and-fixes
Aug 7, 2026
Merged

fix(codegraph): bump the lci-codegraph pin to pick up both extraction fixes#596
stephane-segning merged 1 commit into
mainfrom
claude/codegraph-rename-and-fixes

Conversation

@stephane-segning

Copy link
Copy Markdown
Contributor

1. Summary

This PR changes:

  • Repoints the lci-codegraph git dependency at the renamed repository — vymalo/codegraphvymalo/lci-codegraph, so the repo name matches the crate name it publishes under
  • Bumps the pinned rev from 03aa2b4 to 287d590, picking up two behaviour fixes to the extraction path
  • Updates ROADMAP.md, docs/adr/0086, and docs/indexing-and-storage.md to record the defects as fixed rather than open

It solves:


2. Intent

The intent of this PR is:

To land two real indexing defects that affect this workspace's live behaviour, and to stop relying on a GitHub redirect for the dependency URL.

Both bugs are in the path this workspace actually runs. agent-runner calls walk_checkout_from_env(&checkout, /* build_graph */ true) — the graph-enabled walk — which is precisely the path that bypassed the binary guard, and the trait-method gap silently removed symbols from both retrieval surfaces at once (no :Symbol node for Neo4j, no chunk for pgvector). A Rust trait interface contributed nothing to either.

The trait fix has a non-obvious shape worth understanding before reviewing. Simply classifying the declaration would also have made it a call target, competing with its own implementation for the same bare name. The resolver is precision-favouring — it drops ambiguous calls rather than fanning out — so a trait with exactly one impl would have gone from one candidate to two and every call to that method would have stopped resolving. Fixing a missing-symbol bug by silently deleting calls edges is a worse trade. Upstream therefore treats a declaration as a definition but not a call target, pinned by an end-to-end test.

This is a rev bump in its own PR, as the extraction PR (#595) said it should be — the pin is the only guard this workspace has against upstream drift, so moving it is a deliberate act, not a side effect.


3. Scope

In Scope

  • The dependency URL and rev in services/agent-runner/Cargo.toml, plus the resulting Cargo.lock change
  • Documentation that referenced the old repository URL or described the two defects as open

Out of Scope

  • Any code change in this workspace. services/agent-runner/src/indexer/graph.rs is untouched; the crate's public API is unchanged.
  • Re-indexing existing repositories. Already-indexed repos keep their current graph and chunks until their next index task; the fixes apply to future indexing runs, not retroactively. Worth knowing that trait symbols will not appear for a repo until it is re-indexed.
  • The remaining upstream bug. Adversarial review of the fix found the same declaration-vs-implementation ambiguity in the Java tags.scm path — confirmed pre-existing, not a regression, tracked as Java interface methods: single-impl calls are dropped as ambiguous (the tags-path twin of #1) vymalo/lci-codegraph#5. Not fixed here; the ROADMAP records it as open.

4. Verification

I verified this change by:

  • Running automated tests
  • Running manual tests
  • Checking logs
  • Checking metrics
  • Testing error cases
  • Testing permissions/security behavior
  • Testing rollback or failure behavior, if relevant

Commands run:

cargo build --workspace --locked
cargo test --workspace --exclude control-plane --locked
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo run --locked --package xtask -- dependency-hygiene
grep -ro "vymalo/codegraph" --exclude-dir=target --exclude-dir=.git --exclude-dir=node_modules . | wc -l

Results:

$ cargo build --workspace --locked
    Finished dev profile

$ cargo test --workspace --exclude control-plane --locked
    41 test binaries reporting ok, 0 failed

$ cargo fmt --all -- --check
    (clean)

$ cargo clippy --workspace --all-targets --locked -- -D warnings
    (no warnings)

$ cargo run --locked --package xtask -- dependency-hygiene
    exit 0

$ grep -ro "vymalo/codegraph" ... | wc -l
    0

Lockfile resolves to the new URL and rev:

$ grep -A2 'name = "lci-codegraph"' Cargo.lock
name = "lci-codegraph"
version = "0.1.0"
source = "git+https://github.com/vymalo/lci-codegraph?rev=287d590e143656fcf52116fc0b6655904c764b4d"

Upstream verification for the pinned rev: CI green on all 8 jobs including the Docker-backed container suites (Neo4j round-trip, glibc + musl build, pinned real-world repository clones), coverage 95.40% lines. Both fixes carry regression tests, and the two tests that previously asserted the buggy behaviour were inverted rather than deleted.


5. Screenshots / Evidence

Add evidence here:


6. Risk Assessment

Risk level:

  • Low
  • Medium
  • High

Potential risks:

  • Index output changes shape. Trait declarations now produce additional :Symbol nodes and additional chunks, so a trait-heavy repository yields more nodes and more embedding calls per index run. That is the point of the fix, but it is a real cost and volume change.
  • graph_find_symbol can now return two nodes for one method name (the declaration and its implementation) where it previously returned one. A consumer assuming uniqueness by label would see a behaviour change.
  • Binary files are now skipped entirely on the graph path rather than producing garbage chunks. Any existing garbage chunks persist until re-index.
  • Stale index state. Repos indexed before this lands keep their old graph until their next index task, so the two retrieval surfaces will disagree with a freshly-indexed repo for a while.

Mitigation:

  • The structural pass is best-effort by design — a graph failure is logged, not fatal — so the blast radius of anything unexpected here is a degraded graph, not a failed task.
  • Upstream pins the resolver behaviour with an end-to-end test asserting a single-impl trait method call still resolves to the implementation, so the "more nodes" change cannot quietly become "fewer edges".
  • Re-index happens automatically on the next default-branch push per repo, so stale state self-heals without operator action.
  • Reverting is a one-line rev change back to 03aa2b4.

7. AI Usage Declaration

AI was used for:

  • Understanding existing code
  • Generating code
  • Refactoring
  • Generating tests
  • Drafting documentation
  • Reviewing the diff
  • Not used

Human verification:

  • I understand every meaningful change in this PR
  • I checked generated code manually
  • I checked generated tests manually
  • I removed unsupported AI assumptions
  • I accept responsibility for this PR

Both upstream bugs were independently reproduced with a minimal driver before any code changed, and the upstream fix was put through an adversarial review that drove the public API against fixtures on both branches — which is how the remaining Java issue (#5) and a missing WalkStats counter were found.


8. Reviewer Focus

Please focus your review on:

  • Correctness
  • Architecture
  • Security
  • Performance
  • Tests
  • Maintainability
  • Product intent
  • Edge cases

Specifically:

  • Is the added index cost acceptable? Every bodiless trait method is now an extra chunk and an extra embedding call. For a trait-heavy Rust repo that is a measurable increase per index run.
  • Does anything downstream assume one graph node per method name? The declaration and implementation now both appear, which is correct but new.
  • Should this workspace gain its own test over indexer/graph.rs? It has none, and never did — the golden lives upstream. A rev bump could in principle compile cleanly and still change the emitted graph, and nothing here would catch it.

… fixes

Repoints the git dependency at the renamed repository (vymalo/codegraph ->
vymalo/lci-codegraph, so it matches the crate name it publishes under) and
bumps the pinned rev to 287d590.

That rev carries two behaviour fixes to the indexer's extraction path, both
of which affect this workspace's live indexing:

- Rust trait methods declared without a default body were extracted by
  nothing — no graph node AND no chunk — so a trait interface contributed
  zero callable symbols to either retrieval surface. They are now
  definitions, but deliberately not call targets: letting a declaration
  compete with its own implementation for the name would have made every
  single-impl trait method call ambiguous, and this resolver drops ambiguous
  calls rather than fanning out.
- The binary/NUL guard was bypassed on the graph-enabled walk, the path this
  workspace actually runs, so raw NUL bytes reached chunk content.
  PostgreSQL's `text` type rejects the NUL codepoint outright, so that failed
  at persist time far from its cause.

Docs updated to match: ROADMAP now records the defects as fixed rather than
open, and notes the one still open upstream (the same ambiguity in the Java
tags path, found by adversarial review of the fix).

Verified: cargo build --workspace --locked, cargo test --workspace --exclude
control-plane --locked, cargo fmt --check, cargo clippy --workspace
--all-targets -D warnings, xtask dependency-hygiene.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

✅ AI Governance check passed

This PR declares AI usage, references a source of truth, and provides verification evidence. Thank you.

@stephane-segning
stephane-segning merged commit 1a0f676 into main Aug 7, 2026
12 checks passed
@stephane-segning
stephane-segning deleted the claude/codegraph-rename-and-fixes branch August 7, 2026 02:31
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