name: impact-coverage-per-language-2026-06-03 date: 2026-06-03 21:30 project: codegraph branch: main
affected work across every languageCurrent state: TypeScript is DONE and validated (full suite green, 1134 passed). Three fixes landed (uncommitted on main): the affected/getFileDependents query fix, in-body type-annotation extraction, and import/re-export linking. The latter took file-dependent coverage on this repo from 62.5% → 95.8% (residual 5 files are all correctly-zero: worker scripts + see-through barrels + a CLI entry). I had just asked (via AskUserQuestion) which language to do next — Python / Java / Go / C# — and the user rejected the question and ran /handoff save instead.
Immediate next step: Pick the next language and replicate the methodology: measure coverage on a real repo → audit the 0-dependent files → fix extraction/resolution → validate node-stability + tests. Don't re-ask with a tool; just start (the user declined the menu).
Suggested next message: "Let's do Python next. Index a real Python repo, measure file-dependent coverage the same way, audit the 0-dependent files, and tell me what the real gaps are before we fix anything."
The engine's impact tool (symbol-level getImpactRadius and file-level getFileDependents/affected) must capture all real cross-file dependencies for every supported language — recall-first ("never miss the affected feature"). "Coverage" = % of source files with ≥1 cross-file dependent. 100% is the WRONG target (entry points / workers / see-through barrels genuinely have 0); the real bar is no real dependency missed, validated by auditing every 0-dependent file.
affected was returning 0 for every file. Root cause: imports edges in this graph are same-file (file → its own local import nodes); getFileDependents followed imports-only → 0 cross-file dependents for 72/72 files. Fix: src/db/queries.ts new getDependentFilePaths/getDependencyFilePaths (one indexed JOIN, all edge kinds except contains); src/graph/queries.ts getFileDependents/getFileDependencies now delegate. Un-breaks findCircularDependencies too.visitFunctionBody (src/extraction/tree-sitter.ts ~line 2143) extracted calls but never type annotations, so const items: Foo[] = [] inside any function/method/object body created no edge. Fix: extract type annotation from variable_declarator nodes in the body walker, attributed to the enclosing symbol (no new nodes). Gated on nodeType === 'variable_declarator' && TYPE_ANNOTATION_LANGUAGES.has(language) → effectively TS/TSX only (Rust/Go/Java/C# use different AST shapes, e.g. Rust let_declaration/type field — verified Rust returns 0).src/extraction/tree-sitter.ts: emitImportBindingRefs (per named/default/aliased binding, ~line 1750) called from extractImport (~line 1626, TS/JS gate); emitReExportRefs (per export {X} from './y') called from a new export_statement-with-source dispatch branch (~line 381). Both push imports refs attributed to the file node; the resolver maps them to the definition via resolveViaImport. This is the 62.5%→95.8% win.TYPE_ANNOTATION_LANGUAGES (src/extraction/tree-sitter.ts ~line 2564): typescript, tsx, dart, kotlin, swift, rust, go, java, csharp.~/.claude/projects/-Users-colby-Development-CodeGraph-codegraph/memory/impact-coverage-findings.md..codegraph/codegraph.db was from Jun 2 and under-reported massively (types.ts showed 13 dependents; a fresh reindex gave 35, then 47 after fixes). Always measure on a FRESH reindex into a temp dir, never the repo's live .codegraph. (Also load-bearing for docker-app: it MUST reindex before computing impact.)src/types.ts vs src/resolution/types.ts vs src/ui/types.ts). Match on full path.from x import Y, Java import com.x.Y, Rust use ...::Y) port from the TS approach; package/namespace imports (Go import "pkg"→pkg.Func, C# using NS) need a different design (no per-binding names).import Button from './x' where the default export isn't named Button) doesn't link — resolveViaImport matches local name, no default-export tracking. Affects calls too (pre-existing), rare here. Out of scope unless prevalent in the next language.main and uncommitted — branch before committing (CLAUDE.md rule). Maintainer handles version bumps/releases.npm test → full suite, expect 1134 passed | 2 skipped (was 1131 before the import-linking tests).npx vitest run __tests__/extraction.test.ts -t "dependency linking" → the 3 new import/re-export tests.npx vitest run __tests__/graph.test.ts → strengthened "File dependency analysis" (real cross-file assertions, not just Array.isArray).Coverage probe recipe (reuse for the next language; swap the glob ext):
npm run build
NEW=$(mktemp -d); cp -R <repo>/src "$NEW/src" # or clone a real repo
node -e "const {pathToFileURL}=require('node:url');(async()=>{const idx=await import(pathToFileURL(require('path').resolve('dist/index.js')).href);const CG=idx.default?.default??idx.default??idx.CodeGraph;const cg=CG.initSync('$NEW',{config:{include:['**/*.py'],exclude:[]}});await cg.indexAll();cg.resolveReferences();cg.destroy();})();" 2>&1 | grep -vE "Experimental|trace"
# coverage:
sqlite3 "$NEW/.codegraph/codegraph.db" "WITH src AS (SELECT DISTINCT file_path fp FROM nodes WHERE kind='file'), deps AS (SELECT tgt.file_path fp, COUNT(DISTINCT s.file_path) n FROM edges e JOIN nodes tgt ON tgt.id=e.target JOIN nodes s ON s.id=e.source WHERE e.kind!='contains' AND s.file_path!=tgt.file_path GROUP BY tgt.file_path) SELECT (SELECT COUNT(*) FROM src) files, (SELECT COUNT(*) FROM src WHERE COALESCE((SELECT n FROM deps WHERE deps.fp=src.fp),0)>0) with_deps;"
# audit 0-dependent files: list them, classify imported-but-unlinked (real miss) vs not-imported (correct).
Per-language method: small + medium + large real repos; for each, run the coverage probe, then a controlled mini-probe (write 2 files isolating each suspected gap — in-body type, value import, re-export) to see exactly which edges resolve. Fix extraction/resolution. Re-validate: coverage up, node count stable, full suite green, ≥1 dedicated test.
main, last commit 629d847 fix(extraction): index Vue <template> component usages (#629 follow-up) (#659)CHANGELOG.md, __tests__/extraction.test.ts, __tests__/graph.test.ts, src/db/queries.ts, src/extraction/tree-sitter.ts, src/graph/queries.ts[Unreleased] → Fixes has 2 new bullets (the affected fix + the "recognize far more dependencies" completeness bullet).codegraph-pro — user said they'll do it via upstream merge (don't touch pro).main, uncommitted; branch first).codegraph-pro to copy over.imports edges all same-file; 72/72 files under-reported to 0).Outcome: Implemented the affected fix fresh (getDependentFilePaths/getDependencyFilePaths), tests, CHANGELOG. Asked how to scope the broader cross-language effort + pro port.
Claude: Audited → biggest factor was a STALE index (47.5%→62.5% on reindex). Found in-body type annotations dropped by visitFunctionBody; fixed + tested. Coverage 62.5%, node count stable.
Outcome: TS in-body type fix landed; reported the stale-index trap + per-language nature.
Claude: Explained 100% file-coverage is wrong (workers/barrels). Audited 0-dependent files → 42/45 were imported-but-unlinked (real misses). Root cause via clean probe: value imports / re-exports create no edge. Implemented emitImportBindingRefs + emitReExportRefs. Coverage 62.5%→95.8%; residual 5 all proven correct-zero. Full suite green (1134), tests added.
Outcome: Import/re-export linking landed + validated. Updated memory.
Claude: Asked (AskUserQuestion) which language: Python/Java/Go/C#, with import-model rationale.
Outcome: User rejected the question and ran /handoff save. → Next session: pick a language and start measuring (don't re-ask via tool).