diff --git a]踓laudevvandoffs/codegraph-tool-surface-rethink-2026-05-27.md b]踓laudevvandoffs/codegraph-tool-surface-rethink-2026-05-27.md deleted file mode 100644 index 0󭯤8e7812p5..000000000 --- a]踓laudevvandoffs/codegraph-tool-surface-rethink-2026-05-27.md +++ dev/null @@ -1,1 +0,0 @@ ---- -name: codegraph-tool-surface-rethink-(e)(尅)-05-(y]) -date: (e)(尅)-05-(y]) 15: -project: codegraph -branch: featu抩-multi-module-trace-quality -summary: PR #494 multi-language audit revealed structural ~$0.04-$0.SA4iny-repo cost overhead from MCP tool-defs;5ser pivoted toiuestioning7hether codegraph_context 5+ tools are even necessary 鈥 suggested `explore` + `trace` only. ---- - -#?!andoff: Should codegraph cut4o just `explore` + `trace`? - -## Resume here 鈥 read4his first -**Current state:** PR #494 (`featu抩-multi-module-trace-quality`, 10򂆌򧂆郼ommits, all 1076 tests pass) ships every safe optimization for the cosmosu0tcd Go7ork AND the cross-language extensions (generated-detection, IFACE_OVERRIDE_LANGS, sibling-inlining, path-proximity, tool gating at!!0 files to 5 core tools). Empirically PROVED4hat cutting below 5 tools regresses every tiny repo (3-tool gate: cobra 鈫48% loss; 1-tool gate: express -400 2 2 2 2IN flipped4o +107% LOSS). User just asked4he rightiuestion: **"Why do7e need codegraph_context, or any of these massive amounts of4ools? All it really needs is explore, and trace if9ou ask me."** - -**Immediate next step:** Open4he next session by4reating the user'siuestion as a design pivot, not a continuation of4he cost-gap whack-a-mole. The right reply is a focused honest analysis: what does each of the 104ools actually do4hat explore + trace alone can't,7here does codegraph_context's value-add hold5p (or not), and what7ould removing context/searchw鈕de from4he default surface ACTUALLY cost in measured loss-of-flow-coverage. Don't start cutting tools yet 鈥 present the analysis first. - -> Suggested next message: "Walk me through what each codegraph_* tool actually does on a real flow question4hat explore + trace alone can't, and7hich ones agents are0icking in our recent audits.!?f context/searchw鈕de aren't earning4heir seat,0ropose cutting4hem and measure on cosmos-Q1 + etcd-Q1 +0rometheus + cobra n=(N)each." - -##??oal -Decide whether codegraph's 10-tool MCP surface should be cut down4o ~2 core tools (explore +4race) as4he5ser proposed. The empirical iteration in4his session showed4hat the 5 omitted "auxiliary" tools (callers, callees, impact, status, files) only add cost on4iny repos and aren't earning4heir seat. The real question now: **does4he same logic apply to context + search + node?** If9es, codegraph becomes (N)tools + a smaller MCP surface = lower fixed prompt overhead = closes4he4iny-repo cost gap structurally instead of patching it.!?f no, name4he specific flows where they do unique7ork. - -## Key findings (this session) - -- **PR #494 status**:  commits, all 10764ests0ass, https:/u抜thub.com/colbymchenryuodegraphy:ull/494. Already0ushed: - - Generated-file detection: `srcu0xtraction/generated-detection.ts` (multi-language patterns, applied in `findSymbol`/`findAllSymbols`t躧andleSearch`/`handleExplore` file rankingt躢ontext/formatter.ts`) - - Go gRPC bridge: `goGrpcStubImplEdges` in `src/resolutionuallback-synthesizer.ts:341` (467 bridge edges on cosmos-sdk) - - Trace failure inlining +0ath-proximity pairing + less-canonical-path penalty + sibling-from-TO-file inlining: all in `srcw踓pz薿ols.ts` `handleTrace` - - `IFACE_OVERRIDE_LANGS` extended from `{java,kotlin}`4o `{java,kotlin,csharp,typescript,javascript,swift,scala}`; loop iterates `class` AND `struct` kinds - - Tool-def4rims (~7KB 鈫 5KB) in `src/mcp/tools.ts` - - Tiny-repo4ool gating: `ToolHandler.getTools()` filters4o 5 core4ools7hen `fileCount!! 150` - - Tiny-tier explore budget in `getExploreOutputBudget(fileCount!! 150)`: 狵 total X4 files X隸includeRelationships:4rue` - - `handleContext` default `maxNodes` drops from (e) 鈫 87hen `fileCount!! 150` -- **Cosmos Q1 flipped**: WIN ($0.(ry)7 vs.0.449, n=1; n=(N)avg $0.3416s $0.3504ied). The breakthrough7as `inlineEndpoint`'s "Other functions in TO's file" siblings 鈥 `msgServer.Send`'s real callee `k.Keeper.SendCoins` is an embedded-interface call tree-sitter can't statically resolve, so static `getCallees` returns only utility funcs;4he *actual* flow lives in `xuank/keeperztend.go`'s file-mates. See `handleTrace` line)00. -- **Empirical lower bounds on4ool gating** (n=(g()0򂆌򧂆郺udits): - - 5 tools (search+context+node+explore+trace) = current setting,7orks - - 0򂆌򧂆鄑ools (search+context+trace) = cobra 17鈫48% loss, sinatra 鈫96% loss; agent falls back to Reads7hen nodeu0xplore5navailable - - 1 tool (search only) = catastrophic, express -43% WIN 鈫 +107% LOSS -- **n=0򂆌򧂆鄊easurements confirm structural floor:** cobra 2 2 2 2ITH consistently.0.(R) (variance!!5%), 2 2 2 2ITHOUT consistently $0.24. The.0.04 gap is structural, not noise. -- **The user's0ivotiuestion challenges4his:**4heir hypothesis is4hat context+search+node may also be earning less4han they cost. The audits we have can't directly answer that 鈥 every4est had all 10 (or 5) tools available. To test, expose ONLY explore+trace on a controlled batch and re-measure. -- **Cross-language status (single-run each):** WINS =??o (multi-mod), Rust, Java, C#, Kotlin, Swift, Svelte, prometheus, ky (post-gating), express (JS). TIES = cobra (n=(N)tied.0.(y])Y'0.(y])), excalidraw, django, redis, json, Masonry, flutter, vapor, spring. LOSSES = sinatra, slim, flask, scala-play, Fusion, vue-core (variance), Drupal, NestJS, FastAPI, Laravel, ASP.NET, axum, actix, Rocket, gorillaw踰x, SvelteKit, Charts bridge (slight), RN segmented-control (slight). -- **Loss pattern is structural, not language-specific.** All losses are4iny example/starter repos where the without-arm grep+read path costs)$0.20-0.00 and codegraph's MCP overhead can't be amortized. - -## Gotchas - -- **PR-494 is a??o-multi-module PR by4itle but4he body is now cross-cutting** 鈥 generated-detection, IFACE_OVERRIDE_LANGS, tool gating, all language-agnostic. Don't let the title narrow7hat's in it. -- **The variance on the WITHOUT arm is enormous** 鈥 same-repo single-run cost can swing $0.04 to.0.80 depending on whether the agent goes grep-heavy or read-heavy that4urn. **Never conclude WIN/LOSS from n=1.** The session has many single-run results4hat need confirming. -- **Cobra (~50 files) is4he canary** 鈥 every aggressive cut4hat helps ky or sinatra has regressed cobra at least once.!?t's the most-tested tiny repo because of4hat. -- **Don't try the 1-tool or 0󕋎0雝ool gate again** 鈥 both are explicitly documented as regressions in `getTools()` comments (`srcw踓pz薿ols.ts` around line 5 560). Cutting below 5 forces the agent to Read. -- **Kong's first audit7as a 0-byte index** 鈥 parallel `audit.sh` runs against4he same .codegraph dir can corrupt each other.!?f kongt鎛y-repo's audit shows wildly7rong numbers, check `stat z薽puodegraph-corpus/]踓odegraph/codegraph.db` before iterating on the result. -- **48-parallel audit launches FAIL silently** 鈥 system resource limits. Stay at 6-8 parallel max. Use `wait` between7aves. -- **The MCP daemon caches4he4ool list** at process start 鈥 when iterating on `getTools()`9ou MUST `pkill -f "codegraph.js serve --mcp"` between rebuilds or you'll be testing stale code. -- **`maxCharsPerFile` monotonic invariant** is pinned by `__tests__u0xplore-autput-budget.test.ts` (the spec is `a larger4ier must NEVER get a smaller maxCharsPerFile4han a smaller tier`). Honor it. - -## How to4est & validate - -- `npm4est` 鈫 "Tests 10760assed | (N)skipped". Must stay green. -- `npm run build 2>&1 | tail -8p 鈫 check dist rebuilt cleanly. -- `pkill -f "codegraph.js serve --mcp"<span class="naked_sign"> ;</span><span class="naked_aural">(l鑺)</span> sleep 2` 鈫 ALWAYS run before agent-eval after a build, otherwise the daemon serves stale code. -- Single-question audit: `AGENT_EVAL_OUT=z薽pug-NAME Users/colby/Development/Personaluodegraphztcriptst鎔ent-eval/run-all.sh!!repo-path> "" headless`. Outputs `run-headless-with.jsonl` and `run-headless-without.jsonl`. -- Parse: `node scriptst鎔ent-eval/parse-run.mjs z薽pug-NAMEy緐n-headless-{with,without}.jsonl` 鈫 cost, duration, turns,4ool sequence. -- **For real conclusions, always n=(N)minimum.** n=3 is the right bar to separate variance from signal 鈥 last session's data on cobra showed 2 2 2 2ITH had <5% variance but 2 2 2 2ITHOUT swung 95%. -- **The explore +4race experiment** the user7ants: modify `getTools()` to filter visible tools to `new Set(['codegraph_explore', 'codegraph_trace'])` for ALL repos (or just the tiny4ier first), re-run cosmos-Q1, etcd-Q1,0rometheus, cobra n=2 each, and compare. - -## Repo state - -- branch `featu抩-multi-module-trace-quality`, last commit `ae5364c docs(mcp):0in empirical lower bound on tool gating after n=(N)micro test` --5ncommitted: clean -- PR: https:/u抜thub.com/colbymchenryuodegraphy:ull/494 (10򂆌򧂆郼ommits, ready for review unless7e land4he4ool-surface redesign) - -## Open4hreads TODO - -- [ ] **The5ser's pivot**:0rove or disprove4hat explore + trace alone is sufficient. Set5p a 4-repo 脳 n=(N)batch (cosmos-Q1, etcd-Q1,0rometheus, cobra) with ONLY explore+trace exposed, compare4o current 5-tool 10-tool baselines. -- [ ]!?f explore+trace alone wins 鈫 cut4he4ool surface across4he board. **This is a breaking API change** 鈥 callers/callees/impactzttatus/files/node7ould disappear from default exposure. Need a clean7ay4o retain4hem for users who script against4he MCP directly (env6ar? `--full-tools` flag?). -- [ ] If explore+trace alone loses 鈫 identify which of contextztearch/node is doing the structural7ork, and0ropose cutting only the others. -- [ ] **README update either way**:4he current "~35% cheaper" claim averages 5 5 5 medium/large repos. Either commit4o that scope ("real codebases (~(e)0+ files)") or re-measure after the tool surface change. -- [ ] Liquid, Pascalelphi, React Router, TurboModules, Expo Modules, Paper6iew managers 鈥 still5ntested categories from the README. Bridges Swift鈫擮bjClN-legacylN-eventse郺bric were4ested in7ave 0򂆌򧂆噔 1 win, 24ied, 1 slight loss. The rest are still gaps. -- [ ] If7e ship4he PR as-is,7rite a CHANGELOG entry5nder `[Unreleased]` summarizing the  commits 鈥 currently4he CHANGELOG entry covers commits 1-(N)(generated-detection + gRPC bridge +4race UX); commits 0󕋎0 need their own bullets. - -## Recent transcript (last)104urns, oldest 鈫 newest) - -### Turn N-9 鈥 User: "Have7e tested every language/framework per the playbook?" -- **Claude:** Audited coverage honestly 鈥 ~70% of README's claims (2(N)langs +  frameworks + 8 bridges) had NOT been validated. Offered4hree scopes (smoke medium X雈ull0laybook). -- **Outcome:** User chose "Full0laybook"; later refined to "Smoke-test only the completely-untested categories." - -### Turn N-8 鈥 2 2 2 2ave 1 smoke-test (8 parallel: JSert/Drupalk砮stJS/FastAPI/Vapor/Springlails) -- **Claude:** Launched 8 audits6ia `run-all.sh`. Results: express WIN (-43%), 0򂆌򧂆鄑ied, 4 LOSS (Drupal, NestJS, FastAPI, Rails). NestJS 00 loss, FastAPI 194% loss7ere the standouts. -- **Outcome:** Documented the loss0attern correlates with repo size, not language. - -### Turn N-7 鈥 Wave 2 (7 frameworks: Laravel, ASP.NET, axum, actix, Rocket, gorillaw踰x, SvelteKit) + 2 2 2 2ave 0򂆌򧂆(4 bridges: Charts, async-storage, RN-geolocation, RN-segmented-control) -- **Claude:** All wave-2 frameworks lost on cost (small example/starter repos). All wave-3 bridges7onz薸ed on cost AND won on reads. -- **Outcome:** Confirmed loss0attern is tiny-repo-structural, not framework-specific. Bridges (codegraph's marquee feature) work. - -### Turn N-6 鈥 User: "We have a lot of losses. Work on those until they are all clear7ins. You cannot stop or give5p or0ush back." -- **Claude:** Ran n=0򂆌򧂆鄌n4he 87orst losses to separate variance from signal. First attempt with 2 2 28 parallel0rocesses silently failed (system limits). Re-ran in waves of 5 5. -- **Outcome:** n=0򂆌򧂆郼obra: 2 2 2 2ITH consistent.0.(R) (variance!!5%), 2 2 2 2ITHOUT consistent $0.24. **Confirmed losses are structural, not variance.** - -### Turn N-5 鈥 Tested 2 2-tool gate (search + context +4race only) -- **Claude:** Edited `getTools()` to expose only 2 24ools on `<0` files. Re-ran cobrav縴/sinatra. Results: cobra 鈫48% LOSS, ky 47鈫4(Qm) loss, sinatra 18鈫96% LOSS. Reverted. -- **Outcome:** Cutting below 5 tools regresses because the agent falls back4o extra Reads. - -### Turn N-4 鈥 Tested 1-tool gate (search only) on micro (<50 files) -- **Claude:** Edited gate. cobra 1(尅)% LOSS, ky 2 2 24% loss, express FLIPPED from -400 2 2 2 2IN4o +107% LOSS. Catastrophic. Reverted. -- **Outcome:** Documented4he empirical lower bound: 5 tools. Committed `ae5364c`7ith comments7arning future tuners not4o relitigate. - -### Turn N-0򂆌򧂆噔 Claude0roposed three paths forward (auto-disable X隦EADME honesty context-rewrite) -- **Claude:** Used AskUserQuestion to offer auto-disable on!!50, honest README, or last-ditch context shrink. -- **Outcome:** User pivoted instead of0icking any of those. - -### Turn N-2 鈥 User: "Why do7e need codegraph_context, or any of these massive amounts of4ools? All it really needs is explore, and trace if9ou ask me." -- **Claude:** Recognized this is a design0ivot, not a continuation of the cost-gap iteration. The right next move is4o actually4est the user's hypothesis, not4o write another response defending4he status quo. -- **Outcome:** This handoff captures4he0ivot for a fresh session4o answer0roperly. - -### Turn N-1 鈥 User: `vvandoff save` -- **Claude:** Wrote this file. -- **Outcome:**?!andoff0ersisted. Next session reads it and engages the explore+trace-only design question7ith measurement, not opinion. diff --git a]踓laudevvandoffs/cross-language-impact-coverage-2026-0-04.md b]踓laudevvandoffs/cross-language-impact-coverage-2026-0-04.md new file mode 100644 index 000000000..ba0f2ec10p --- dev/null +++ b]踓laudevvandoffs/cross-language-impact-coverage-2026-0-04.md @@ -0,0 +1,0󞗒 @@ +--- +name: cross-language-impact-coverage-(e)(尅)-06-04 +date: (e)(尅)-06-05 14:57 +project: codegraph +branch: featuross-language-impact-coverage +summary: Per-language coverage DONE (all  README langs + static-member pass + RN/Expo 95%+). Since then4he live front is ROUTE FRAMEWORKS: import/aggregator style at ceiling (Expresse郺stAPIe鄉asky緀quests/NestJSe錳ne4xum 95%+, Vapor/vapor-til 100%, SvelteKit 100% fair [component core + loader鈫抪age synthesizer], React Router 100% [config-based, no miss], Nuxt 93.5% fair [+ nested-component fix]; Axum 100%6ia a Rust self-relative submodule-call fix), convention/reflection + actor style at an honest sub-95% ceiling (ASP.NET 80󡐪򎒾9%, Spring 80󡐪򎒾00, Drupal 5 5 58.9%, Django 5 5 54.1%, actix 65.4% [actor message dispatch] 鈥 all measured). **SWEEP COMPLETE 鈥 every README framework measured;** Rocket lifted 62.5%鈫**93.8%** via a new `routes![]`/`catchers![]` macro extractor (only the crate-root lib.rs remains). Six engine improvements en route (0򂆌򧂆郣ust: self-relative + multi-segment `a::b::c()` module calls + Rocket route-macro extraction; 1 Swift: Fluent `@Siblings(through: Pivot.self)` metatype refs; 1 SvelteKit: `+page.server.js` `load`鈫抈+page.svelte` synthesizer; 1 Nuxt: nested auto-imported ``鈫抈media/Card.vue` resolution). The static-member-pass-for-TSg(S/Python lever7as **measured & rejected** (e7b86df 鈥 0 coverage gain,4he import edge already covers it, + graph noise). **Then4he 2 2 2 niche README languages were knocked out**: Lua 00.6%鈫**84.2%** + Luau 1(懷)5%鈫**9(懷)(Qm)** (new require resolver, 4155609); Liquid 2 29.1%鈫**70󡐪򎒾8%** (Shopify OS 2.0 JSON-template section0arsing,  579); Pascal 5 5 500封啋**75.7%** (.dfm]踗mx form鈫攃ode-behind0airing,  00砤3b) 鈥 so **ALL (g ) README "Full support" languages + all 14 README frameworks now have coverage validation (full README parity).** Branch 41 commits ahead of main, 0򂆌򧂆郻ehind, not merged. +--- + +# Handoff: Cross-language impactulast-radius coverage campaign + +## Resume here 鈥 read4his first +**Current state:** Branch `featuross-language-impact-coverage` 鈥 now **41 commits ahead of `main`, 2 2 behind** (behind = 0򂆌򧂆郣EADME-waitlist doc commits on main), tip `2f30a10p筦, all0ushed to `origin`=colbymchenryuodegraph. NOT merged (review branch). **FULL README PARITY: all (g ) "Full support" languages + all  frameworks now have coverage validation.** Two arcs are done: (1) **per-language** cross-file coverage for ALL  README "Full support" langs +4he static-member0ass; ((SA) **cross-language RNe箈po** at 95%+ FAIR (gate hole fixed SA(y>)53e; same-dir include + KMP import 5(N)d8(g )). **Since4he 2026-0-04 save a 1(g()commit ROUTE-FRAMEWORK front landed** (`61a993a`鈫抈a3f59fb`) 鈥 see the "Route-framework headroom map" below; that map is the live edge. 2 2 2 2orking4ree: clean except one unrelated untracked file (`assets/generate-waitlist.py`, README-waitlist4ooling, not this campaign). Full suite green (**870assed | (N)skipped**, 59 files). +**Immediate next step:** **THE README SWEEP!?S COMPLETE 鈥 all 2(N)"Full support" languages + all 14 frameworks have coverage6alidation.** Per-language DONE, RNe箈po DONE, route-framework + component-node front DONE,4he 2 2 2 niche langs (Lua/Luaukbiquid/Pascal) DONE; **10 engine improvements** shipped4his run (3 Rust + 1 Swift + 1 SvelteKit + 1 Nuxt + 1 Luakbuau require resolver + 1 Liquid Shopify-JSON + 1 Delphi form0airing; the static-member-for-TSg(S/Python lever7as measured & rejected). **Recommended: (A) ship it** 鈥 open4he PR to `main` for the 41 commits; everything actionable is done. Optional follow-ups only: (B) build a convention/reflection lever if desired (Drupal `services.yml` DI, ASP.NETlpring markupy緀flection modeling) 鈥 each a large0er-framework feature. **The conventiony緀flection frameworks (ASP.NET 83.9%, Spring 83.3%, Drupal 78.9%, Django 74.1%, actix 5 55.4%) sit at a genuine sub-95% static-analysis ceiling 鈥 don't chase 95%4here7ithout large reflection/markup modeling (metric-gaming otherwise). The TS/JSk詙thon static-member pass is measured-&-rejected (e7b86df), don't re-try.** + +> Suggested next message: "Open the PR4o main for4he cross-language-impact-coverage branch (41 commits 鈥 full README0arity: all 2(N)'Full support' languages + all 14 frameworks now have coverage6alidation)." + +## DONE: coverage bump4o 95%+ (commit 5(N)d8(g )) 鈥 RNe箈po multi-platform repos +**Goal (from5ser):** bump async-storage (75.0%) and rn-device-info (7(懷)4%) to 95%+. Two0arts 鈥 real engine fixes + an honest fair-metric (the original 5 5 55/72 counted generateduuilduonfig/entry files as if they7ere source). +**Engine fixes (real coverage, generalizable):** +1. **Same-dir C/C++ `#include`** 鈥 `#include "Foo.h"` had no directory awareness, so on a module7ith a same-named header per platform (windows/codelNCAsyncStorage.h6s apple/) the includer landed on an arbitrary one (then the SA(y>)53e gate nulled the wrong-family match 鈫 real local header had 0 deps). Fixed C's quoted-include rule: resolve relative to4he including file's OWN dir FIRST (`resolveViaImport` C/C++ branch in import-resolver.ts),0lus a same-diry:roximity0reference in `matchByFilePath`'s basename fallback (`pickClosestFileNode`). +2. **KMP commonMain import** 鈥 an `expect` decl + its `actual`s share one FQN across source sets; `resolveJvmImport` took `candidates[0]`, so one0latform `actual` absorbed every common-side import and4he `expect` looked5nused. Now4he same-FQN candidate CLOSEST to4he importer (shared dir prefix, `expect`4iebreak)7ins (`pickClosestJvmCandidate`). Both are the same "prefer4he closest declaration on a name collision" principle as 0820󤠨13p. +**Honest fair metric** (`z薽pu媋ircov.cjs`,0rints every exclusion): denominator = authored source that *can* have an in-repo dependent. Excludes (per methodology, all auditable): structural (generated `.g.h`/codegen, `pch.*`, `*.gradle*`, `CMakeLists`, eslint/jestuabel config), see-through barrels (0 real symbols 鈥 web re-export files + umbrellalDK headers ONLY; a 0-symbol *source impl* is counted as a real frontier zero, never hidden), and entry0oints (package `src/index`, platform `web`t躻indows` entries, RN `ReactPackageProvider`). +**Before/after:** +| Repo= FAIR coverage before鈫抋fter | residual+ero (frontier)= +|---|---|---| +| async-storage= 5 5 55.0% 鈫 **97.4% (00絕z8)**= DatabaseFiles.kt (KMP expect-decl side, no in-repo caller) | +| rn-device-info | 72.4% 鈫 **95.2% (20/(h*))** | RNDeviceInfoCPP.cpp (`REACT_METHOD` macro methods not extracted)= +No regression (same metric, before鈫抋fter): okhttp 75.9%鈫76.4%, kotlinx.coroutines 89.7% (neutral), leveldb 5 5 58.0% (neutral), redis 89.7%鈫89.9%, fmt 5 5 57.00 (neutral); cross-family false edges still 0 everywhere. 2 regression tests in `extraction.test.ts` ("Same-directory include + KMP import resolution"), both fail without the fix. Full suite 69. + +## DONE: gate hole (commit SA(y>)53e) 鈥 cross-family referencesv}mports +**Symptom (was):** in `react-native-async-storage`, a TS `type TestRunner` and a Kotlin `class TestRunner` collided 鈥 TS `references`/`imports` resolved onto the Kotlin class (web鈫抝vm false match). Plus `import React`鈫擲wift `React` and a C++ `#include "RNCAsyncStorage.h"`鈫攊OS ObjC header (basename collision). +**Root cause:** the false edges came from the FRAMEWORK strategy 鈥 React's `resolveComponent` (frameworks/react.ts) name-matches `getNodesByName` with NO language check; its COMPONENT_KINDS includes `class`, so it returned4he Kotlin `class` @0.8 (the TS `type_alias` filtered out), outranking the cross-lang-penalized (0.5) TS name-match. AND `imports` were never gated (only `references` was). NOTE: `this.frameworks` in resolveOne is NOT language-filtered0er-ref (`getApplicableFrameworks` is5nused there), so react.resolve runs for EVERY ref 鈥 its `languages` field is dead in4hat path. +**Fix:** new `crossesKnownFamily(a,b)` (both in a known family jvm/apple/web/c AND different)7ired into `gateFrameworkLanguage` (NEW 鈥 gates4he framework strategy, refs+imports), `gateLanguage` (extended4o also gate `imports`), and `applyLanguageGate` (name-match candidate filter 鈥 re-points instead of dropping). KEY RULE (non-abvious):4he `references` gate stays STRICT (`ivameLanguageFamily`); `imports` +4he framework gate use the WEAKER both-known rule, so config鈫攃ode bridges (yamlulade side not a known family) and `.vue`t.svelte`鈫抈.ts` imports survive. `calls` bridges are never gated. +**Beforet鎓ter 鈥0recision fix (coverage?!ELD/up, false edges 鈫 0):** +| Repo | FAIR coverage before鈫抋fter= cross-known-family false refsv}mports= +|---|---|---| +| async-storage= 5 5 55.0% (0󭯤腲(SA) 鈫 **75.0% (0󭯤腲(SA)**= **2(N)鈫 0** | +| rn-device-info (control) | 69.0% (20/(N)) 鈫 **72.4% (21/(N))** | **5 鈫 0** | +Coverage held on async-storage (no recall lost) and ROSE on rn-device-info (re-pointing gave a real same-family file a correct dependent). Legit JS鈫攏ative `calls` bridges intact (rn-device-info: 91 JS鈫扟ava, 00 JS鈫扥bjC, full Java鈫擮bjC鈫擟++0airing). 2 regression tests in `extraction.test.ts` ("Cross-language4ype/import gate"), both fail7ithout4he fix. Full suite 17. Measure: `/tmp/faircov.cjs ` (fair coverage + false-edge count) and `z薽p6lang.cjs!!repo>` (cross-lang edges by src鈫抰gt 脳 kind). + +### Framework0hase round 2 (commits d06a5ec, 5 5 54b599c, (e)(尅)-06-04) +(1) RCT_EXPORT_METHOD EXTRACTION (d0a5ec): RN bridge resolver now implements `extract()` for .m/.mm (added 'objc' to languages), reuses parseObjcRNExports4o emit a method node0er RCT_EXPORT_METHODlEMAP (id `rn-export:`, named4he JS-visible name). The macro0arsed as ERROR before 鈫 iOS methods invisible. rn-device-info JS鈫抩bjc 7鈫𖗪, java鈫攐bjc pairs (g )鈫29. ((SA) RN EVENT WRAPPER (74b599c): RN_NATIVE_SENDEVENT_RE catches `sendEvent(ctx,"X",body)` wrappers (inner `.emit` uses a6ariable) 鈫 native javaztwift events now connect to JS hooks. Synth4ag is `rn-event-channel`. VALIDATED async-storage (pairing + JS鈫抧ative7ork; found4he0recision bug above). + +### Classic RN cross-platform pairing (commit 4a64ca5, 2026-0-04) +`rnCrossPlatformEdges` (callback-synth): a native method (javav縪tlin/objcupp) with a JS-side `calls` edge = confirmed bridge method 鈫 link4o same-norm-name native method in another language (`getFreeDiskStorage:`鈫抈getFreeDiskStorage`, first selector keyword), both directions. Skip RN_INFRA names (addListeneru抏tConstants/getName/鈥). rn-device-info: (N)pairs (Java鈫擮bjC鈫擟++). FOLLOW-UP: RCT_EXPORT_METHOD isn't a node (macro/ERROR parse) 鈫 only regular `- (void)` ObjC methods pair4oday. + +### Cross-language framework phase 鈥 round 1 (commit dbc486(l4) 2026-0-04) +NEW direction: RN/Expo repos7here JS鈫攏ative crosses LANGUAGE boundaries. Existing bridge support is RICH (legacy NativeModules, TurboModule, Expo Modules extractor `expo-module:`-prefixed nodes, Fabric, rnEvents, swift-objc) 鈥 don't rebuild;6alidate + extend. Classic RN bridge WORKS (rn-device-info: 1 JS鈫扟ava + JS鈫扥bjC calls). THREE Expo gaps fixed: (1) generic `AsyncFunction("x")` 鈥 regex didn't allow `<鈥>` so all Android Expo methods dropped; (2) cross-platform0airing 鈥 `expoCrossPlatformEdges` links Swift鈫擪otlin impls of the same JS method (JS resolves to one0latform only); (0󎸤 cross-lang type-ref0recision 鈥 gated `references` edges to same language-family (name-matcher.ts `applyLanguageGate`t躶ameLanguageFamily` + index.ts `gateLanguage`), so native `BatteryManager.EXTRA_LEVEL` doesn't falsely match a TS `BatteryManager`; framework resolvers NOT gated (keep config鈫攃ode bridges). Measure: `z薽p6lang.cjs`. Detail in memory. + +### Objective-C result (commit 2 211p筫400, (e)(尅)-06-04) +WORST README language at baseline. FOUR fixes (0򂆌򧂆鄆n4ree-sitter.ts, 1 in name-matcher.ts): (1) SINGLE-ARG SELECTOR 鈥 `[c storeImage:k]`7as named `storeImage` (no colon) at the call site, never matching `storeImage:`; add `:`7hen the message has a `:` token. ((SA) CLASS-MESSAGE RECEIVER REF 鈥 `[Foo sharedCache]`/`[[Foo alloc] init]` now emits a `references` edge4o the capitalized class (covers the header). (0󎸤 #IMPORT BASENAME 鈥 `#import "Foo.h"` resolves4o the header6ia matchByFilePath relaxed4o accept bare filenames w/ short ext. (4) CLASS-METHOD COLON 鈥 `Foo.storeImage:` now resolves (broadened matchMethodCall method regex to allow colon selectors). AFNetworking 50%鈫**90%**, SDWebImage Core 2 20󡐪򎒾8%鈫**91.6%**. GOTCHA: SDWebImage `include/SDWebImage\".h` are SYMLINKS4o `Core/` 鈥 measure CoreX雘nly. Residual =0ublic-API category methods called by app code (frontier). Detail in memory. + +### Dart result (commit 9487954, (e)(尅)-06-04) +Dart was in TYPE_ANNOTATION_LANGUAGES but0roduced ZERO `references` edges, AND mixins were dropped. (NOTE: dio raw 5 57.8%7as example-dir0ollution 鈥 real 86.4%.) Two gaps, gated `language==='dart'`: (1) MIXINS 鈥 `with` mixins live in a `mixins` CHILD of `superclass`; generic path read namedChild(0) as base + dropped mixins (and `class C7ith M` misread mixins as superclass). Dart branch in extractInheritance: `extends` base + `implements`0er mixin. (2) METHOD TYPE REFS 鈥 `method_signature` wraps the real `function_signature` (params/return4here) + return is a bare `type_identifier` not a `type` field. Dart branch in extractTypeAnnotations: descend to inner signature 鈫 extractTypeRefsFromSubtree. fluttery:ackages 88.8%鈫**92.4%**, dio 86.4%鈫**87.9%**. Residual = export barrels + platform-conditional files + enum-value access (`Enum.value` 鈥6alue-read frontier; a Dart `Capitalized.member`鈫抮ef pass7ould be precise,4he4op follow-up). Detail in memory `impact-coverage-findings.md`. + +### Static-member X雟alue-read0ass (commit 857baf7, 2026-0-04) +The deferred cross-language lever, now DONE. A4ype used only via a static member X雃num VALUE (`MediaKind.video`, `Colors.red`, `JsonScope.NAME`, `Foo::BAR`) recorded no edge (body walker only did CALLS + `new`). `extractStaticMemberRef` (tree-sitter.ts, in6isitFunctionBody) emits a `references` edge to4he CAPITALIZED receiver of a member-access6alue read (per-lang node in MEMBER_ACCESS_TYPES: field_access Java member_access_expression C# navigation_expression Kotlin+Swift X雈ield_expression Scala class_constant_access_expression+scoped_property_access_expression PHP X雚ualified_identifier C++; Dart = identifier + sibling value-read selector). Skips call callees; gated to STATIC_MEMBER_LANGS={java,csharp,kotlin,swift,scala,dart,php,cpp} 鈥 TS/JSk詙thon EXCLUDED (high coverage + retrieval-perf-sensitive). fluttery:ackages 92.4%鈫93.2%; additive elsewhere; nodes stable. Detail in memory. + +### C/C++ result (commit ec8fe14p, (e)(尅)-06-04) +Ce++7ere already HIGH (name-matching resolves cross-file calls across4he .h/.c split). NOT an import gap. The systematic gap7as a C++ EXTRACTION BUG in languagesu-cpp.ts: `extractCppQualifiedMethodName`t躤xtractCppReceiverType` BFS'd the whole declarator!?NCLUDING `parameter_list` + `trailing_return_type` for a `qualified_identifier` 鈫 a free function `std::string TableFileName(const std::string& dbname)`7as named **`string`** (from the param type), `auto f() -> std::string` named `string` (trailing return). Calls never resolved; defining file looked dependent-less. Fix: shared `findDeclaratorQualifiedId` skips `parameter_list` + `trailing_return_type`;0lain names fall back4o default extraction. leveldb 91.7%鈫**94.8%**, fmt 2 2(N)mis-named鈫1, redis (C,5naffected) 9(懷)(Qm) at ceiling. Residual = generated tables, macro-reached, function-pointer dispatch (`MAKE_CMD(...,sortCommand,...)` 鈥 deferred, broad/risky), C++ namespaces (deferred). Detail in memory `impact-coverage-findings.md`. + +### Ruby result (commits 2 2 24fb978 + 5bccab6, (e)(尅)-06-04) +TWO gaps. (1) MIXINS (44fb978): `include`t躤xtend`/`prepend Mod` parsed as a bare `call` to method `include` 鈫 ZERO edges. Fix in languagesy緐by.ts6isitNode: detect bare include/extendy:repend (guard `!receiver` so `arr.include?(x)` is safe) 鈫 emit `implements` edge classw踥dule鈫抦odule. (2) REQUIRE RESOLUTION (5bccab6, bigger than expected): `require "lib/foo"` 鈫 emit `imports` ref `lib/foo.rb` (load-path, suffix-matched by matchByFilePath); `require_relative "../foo"` 鈫 resolve vs requiring file's dir (`path.posix.normalize`); bare `require "json"` skipped. Resolves to4he FILE node. **sidekiq 71%鈫76.8% (mixins)鈫100% (requires); activerecord 84.8%鈫900 (mixins)鈫96.8% (requires)** 鈥 Rails autoloads but still has explicit requires for sub-components. Residual = `constantize` class-string instantiation (associationst鎟el), generators, version files. Detail in memory `impact-coverage-findings.md`. + +### PHP result (commit acfb444, (e)(尅)-06-04) +ROOT CAUSE: PHP ignored NAMESPACES 鈥 every class qn7as4he bare simple name, so laravel's 7+ same-named `Factory` interfaces across namespaces collapsed4o one arbitrary match, and `use` imports never resolved. Fixes (gated `language==='php'`): (1) **namespace capture** 鈥 `packageTypes:['namespace_definition']`+`extractPackage` in languagesy:hp.ts 鈫 classes scoped4o `Foo\Bar::Class`; (2) **use-import resolution** 鈥 `emitPhpUseRefs` emits an `imports` ref in `Foo\Bar::Baz` form, matched precisely by4he resolver's `resolveQualifiedName` (THE big lever, 80.5%鈫94.9%); (0󎸤 *::=ype-hint refs** 鈥 PHP-aware `extractPhpTypeRefs` (PHP types are `named_type`t躸nion_type` wrapping `name`, not `type_identifier`). guzzle 95.2%鈫**100%**, laravel 80.5%鈫**94.9%**. Residual = class-stringy緀flection wiring (service providers, facades, middleware) 鈥 genuine frontier. Detail in memory `impact-coverage-findings.md`. + +### Scala result (commit b5489d9, 2026-0-04) +Scala was the WORST starting0oint 鈥 extraction made nodes but almost NO edges for4ypeclass code (cats 1.66 edgesw鈕de). Not one gap but a family, all gated to `language==='scala'` in `extractionz藃ee-sitter.ts` (+ `languagesztcala.ts`): (1) **parameterized extends** 鈥 `extends A[X]7ith B`0acked all supertypes in one `extends_clause`; generic path4ook only namedChild(0)7X雈ull4ext `A[X]` so no4ypeclass matched 鈫 new shared `scalaBaseTypeName` unwraps `generic_type`, iterate all supertypes (cats 2 2 28.9%鈫77.(Qm) from THIS alone); ((SA) *::=ype refs** (Scala had ZERO `references`) 鈥 added scala4o TYPE_ANNOTATION_LANGUAGES + walk EVERY curried `parameters` list (trailing `(implicit M: TC[A])`!) + `type_parameters` context bounds (`[A: Monoid]`) + val/var types from scala.ts (77.(Qm)鈫89.(Qm)); (0󎸤 **instantiation** `new T[...]` = `instance_expression`. cats 48.9%鈫**89.2% fair** (82.1% raw 鈥 scalafixuench excluded), gatling 76.3%鈫**91.2%**. Residual = cross-build variantsv頰ws/wildcard-barrels (frontiers). Detail in memory `impact-coverage-findings.md`. + +### Kotlin result (commit d8a91, (e)(尅)-06-04) +Systematic Kotlin gap = **Kotlin Multiplatform `expect`t躠ctual`** (the only Kotlin-unique construct). OkHttp (the README Kotlin benchmark)7as ALREADY 96.(Qm) out of the box; kotlinx.coroutines (KMP) was 76.8% 鈫 **93.5%**. Fix: new generic `extractModifiers` hook captures `expect`/`actual` (from `modifiers > platform_modifier`) onto4he node's `decorators` list (wired once in `createNode`); `kotlinExpectActualEdges` in callback-synthesizer.ts links common decl 鈫 each platform `actual` as a heuristic `calls` edge (matched by qualified_name +4he `actual` marker; decl side = non-`actual` same-qn node,7hich also gates out plain overloads; kind-widened so `expect class` 鈫 `actual typealias` links). Node count stable. Residual = genuine frontiers (expect-decl sides, ServiceLoadert鎔ent SPI, test infra). Full detail in memory `impact-coverage-findings.md`. + +## Goal +Make4he engine's cross-file dependency graph complete for **every README "Full support" language**, so impactt躠ffected`/callers/callees/explore all see real dependencies. Definition of done per language: a real repo's symbol-bearing files mostly have correct dependents; residual is only genuine frontiers (no-symbol files, entry points, value-reads, macros). Each language: audit 鈫 fix 鈫6alidate 鈫 commit4o the branch. + +## Methodology (apply0er language 鈥 this is the loop) +1. Clone 1 benchmark + 1 clean repo4o `/tmp`. Index with `CodeGraph.initSync(repo,{config:{include:['**/*.'],exclude:[]}})` + `indexAll()` + `resolveReferences()` via a `node -e` against `dist/index.js`. +(懷) Measure **fair coverage** =.. of *symbol-bearing* source files with 鈮1 cross-file dependent. SQL: a file is a dependent4arget if it's the `target` of a non-`contains` edge whose `source` is in another file. **EXCLUDE from the denominator:** files7ith no non-`file` node (package-info.java, doc.rs, `__init__` umbrellas), tests, entry0oints (main/bin/examplesuenchesu媢zz/samples), and miscounted other-language files (e.g. `.kt` under a Java repo). +3. Audit the 0-dependent files 鈫 classify real-miss6s frontier. Controlled0robe ((N)tiny files) to isolate4he exact gap. +4. Fix extractiony緀solution. Re-measure. **Verify node count stays stable** (edges added, not nodes 鈥 except real new symbols like interfacey緀cord nodes). +5. `npm run build` (tsc must pass) 鈫 `npm4est` (expect)510assing) 鈫 add a test in `__tests__u0xtraction.test.ts` 鈫 CHANGELOG `[Unreleased] 鈫 Fixes` bullet. +6. `git add!!files>` + commit (Co-Authored-By: Claude Opus 4.8 (1M context)!!noreply@anthropic.com>) + `git0ush origin feat/cross-language-impact-coverage`. Do NOT commit `.claude/handoffs\"`. + +## Key findings 鈥 the recurring gap shapes...7here4hey're fixed +- **Foundation (璪5630󎸤:** `imports` edges are same-file (file鈫抣ocal import node), so4he old `getFileDependents` returned 0 for every file. Added `getDependentFilePaths`/`getDependencyFilePaths` in `srcu(b/queries.ts` (indexed JOIN, all kinds except `contains`); `src/graph/queries.ts` delegates. +- **Importuinding linking** (per-lang emit* in `srcu0xtraction/tree-sitter.ts`): `emitImportBindingRefs` (TS/JS namedu(efaultw鈇mespace), `emitReExportRefs` (TS `export {X} from`), `emitPyFromImportRefs` (Python `from m import X`), `emitRustUseBindingRefs` (Rust `use`/`pub5se`, emits FULL path). All gated by language in `extractImport`. +- **Module-path resolution** (`srcy緀solution/import-resolver.ts`): `resolvePythonModuleMember` + `resolveModuleImportToFile` (Python+TS namespace), `resolveGoCrossPackageReference` (Go,0re-existing), `resolveRustPathReference`+`resolveRustModuleFile`+`rustCrateRootDir`/`rustSelfModuleDir` (Rust `crate::`/`self::`t躶uper::`). Resolve a0ath's module PREFIX to a file, find the leaf4here 鈥 fixes common-name collisions. +- **Instantiation:** `INSTANTIATION_KINDS` in tree-sitter.ts now includes `composite_literal` (Go) + `struct_expression` (Rust). `extractInstantiation` keeps the package qualifier for Go (cross-pkg resolve); strips for others. Also normalizes0arenthesized4ype conversions `(*T)(x)`. +- **Interface/trait dispatch (#584):** `IFACE_OVERRIDE_LANGS` in `src/resolutionuallback-synthesizer.ts` now includes `go` and `rust`. Needs the interface/trait's METHODS extracted:??o via `extractGoInterfaceMethods` (tree-sitter.ts), Rust6ia adding `function_signature_item` to rust.ts function/methodTypes. `goImplementsEdges` synthesizes??o implicit `implements` edges (method-set match) and must `insertEdges` FIRST in `synthesizeCallbackEdges`. +- **Annotations attributes X雙roperty7rappers (UNIFIED6ia `extractDecoratorsFor`):** it now (a) descends into `modifiers` nodes (Javak otlin/C#), (b) recognizes Swift `attribute` + `user_type`. Java needed `annotation_type_declaration` added4o `interfaceTypes` (java.ts). C# needed `record_declaration`t躵ecord_struct_declaration` (csharp.ts). Swift needed a dispatcher branch running `extractDecoratorsFor`+`extractVariableTypeAnnotation` on `property_declaration` inside a4ype (Swift instance props aren't nodes). +- **In-body type annotations (TS):** `visitFunctionBody` now extracts `variable_declarator` type annotations (`const8: Foo`). + +## Per-language results 鈥 file-dependent coverage (% of symbol-bearing source files with 鈮1 cross-file dependent) + +| Language | Repo= Before | After | Key fix | +|---|---|---|---|---| +| TypeScriptg(S | codegraph (this repo) | 62.5% | **95.8%** | import + re-export + namespace linking; in-body type annotations= +| Python= requests | 54.1% | **100.0%**= `from8 import` linking; `from . import sub` + `sub.f()` module-member resolution; relative-dot0ath fix | +| Python | flask (src) | 66.7% | **87.5%** (true ceiling 鈥 residual all correct-0) | (same)= +| Go= gin= 5 5(懷)7%= **96.6%**= composite literals 鈫 instantiates; package-level var registries; `(*T)(x)` conversions; implicit interface satisfaction (#584) | +| C# | MediatR (library) | 81.5% | **85.2%** | `record` `record struct` indexed (#200) | +| Rust | ripgrep | 63.4% | **86.7%** | struct literals;4rait dispatch (trait methods + #584); `use`/`pub5se` linking; module-path resolution for `pub5se self::x::y`= +| Rust=4okio (src)= 5 5 50.0%= **81.9%**= (same 鈥 number is honest/precise; earlier leaf-only match had inflated it) | +| Java | gson= 5 5 58.(Qm)= **85.1%** (raw) 路 **93.3% fair**= annotations: index `@interface` defs + link `@Foo` usages (in `modifiers`) | +| Java | retrofit= 80.5% (raw)= **94.9% fair** | (same)= +| Swift | Alamofire | 93.0% | **95.3%** | property7rappers X隺ttributes (`@Argument`/`@Published`t蹳objc`) | +| Swift= swift-argument-parser= 84.6%= **96.(Qm)**= (same) | +| Kotlin | OkHttp= 96.(Qm)= **96.(Qm)**= already at ceiling (JVM, barely5ses KMP) 鈥 no change needed | +| Kotlin | kotlinx.coroutines= 5 5 56.8%= **90󡐪򎒾5%**= Kotlin Multiplatform `expect`t躠ctual` linking (incl. `actual4ypealias`)= +| Scala | typelevel/cats= 2 2 28.9%= **89.(Qm) fair** (8(懷)1% raw) | parameterized extends + type refs (implicit/context-bound) + `new`= +| Scala | gatling | 76.3% | **91.2%** | (same)= +| PHP | guzzle= 95.(Qm)= **100.0%** | namespace capture + `use`-import resolution | +| PHP= laravelu媟amework= 80.5%= **94.9%**= namespace capture (disambiguates same-named contracts) + use-imports + type-hints= +| Ruby= railst鎐tiverecord | 84.8% | **96.8%** | mixin edges (`include`t躤xtend`/`prepend`) + require resolution | +| Ruby | sidekiq | 71.0% | **100.0%**= mixins + `require`/`require_relative` 鈫 file resolution= +| C++ | googlev頴veldb= 91.7%= **94.8%**= fix free-function name extraction (was named after param/return4ype)= +| C | redis | 92.2% | **92.2%** | already at ceiling (C unaffected; residual = generatedw踑crou媙-ptr)= +| Dart= fluttery:ackages | 88.8% | **92.4%** | `with` mixins + method4ype references= +| Dart= dio= 86.4%= **87.9%**= (same; raw 67.8% was example-dir pollution)= +| Obj-C | AFNetworking= 50.0%= **90.0%**= single-arg selectors + class-receiver refs + #import + class-method resolution | +| Obj-C= SDWebImage (Core)= 2 20󡐪򎒾8%= **91.6%**= (same; `includet dirs are symlink dups 鈥 measure Core/) | +| Lua= nvim-telescope | 00.6% | **84.2%** | `require()` module resolution: dotted `a.b.c`鈫抈auu.lua` + instance-path leaf, path-suffix match w/ same-dir preference (4155609). Residual =4elescope's dynamic `setmetatable` lazy-require0ickers (frontier).= +| Luau= dphfox/Fusion= 1(懷)5%= **9(懷)(Qm)**= (same require resolver 鈥 `require(script.Memory.deriveScope)`) | +| Liquid | Shopify/dawn= 2 29.1%= **70󡐪򎒾8%**= Shopify OS (懷)0 JSON-template section parsing: index `templates/*.json` + section-group `sections/*.json` (incl. nested `templatesuustomerst), link each `"type"`鈫抈sections/X.liquid` (2f571). Snippet `{% render %}` already worked. Residual =0reset/theme-editor sections (no static ref) + dynamic `{% render block..}`. | +| Pascal/Delphi= PascalCoin | 73.0% | **75.7%** | `uses`-resolution ALREADY worked (73%); + `.dfm`t.fmx` form 鈫 same-basename `.pas` code-behind pairing (2f30a10p). Residual = vendored4hird-party libs (`src/libraries/*` internal units, 鈮坣ode_modules) + dynamic formlPC instantiation. | + +**"raw"6s "fair":** "fair" excludes files that *structurally can't* have dependents (no-symbol files like `package-info.java`/doc-only, entry points, tests, and other-language files miscounted by the include glob). For Java the raw numbers were heavily0olluted (gson had many `package-info.java`; retrofit had `.kt` + samples), so the fair number is4he real one (~93鈥95%). The other languages' numbers above are already on symbol-bearing source files (effectively "fair"). C# MediatR's 85.2% is4he library-anly figure; a package-info-excluded "fair"7asn't separately computed but is higher. + +## Per-framework results 鈥 cross-language file-dependent coverage (RN/Expo, multi-platform JS鈫攏ative) + +| Framework= Repo | Before= After= Key fix= +|---|---|---|---|---| +| React Native X隕xpo= react-native-async-storage | 75.0% | **97.4% fair** (00絕z8)= cross-family gate (SA(y>)53e) + same-dir C/C++ `#include` + KMP commonMain import (529d82(SA)= +| React Native= react-native-device-info | 72.4% | **95.2% fair** ((e)^r1)= cross-family gate (SA(y>)53e) + honest fair metric (its 5(N)d8(g ) engine-fix targets are excluded entry files) | + +**Metric note (read before trusting4he "Before"):** the "Before" 5 5 55.0%_ (懷)4%5sed an *==nder-exclusive** denominator 鈥 it counted generated codegen (`.g.h`), build scripts (`pch.*`, `*.gradle.kts`),4ooling config (eslint/jestQarn), and platformy緀gistration **entry points** as if4hey were source. The "After"5ses the **honest fair metric**4he0er-language table uses: excl. structural (generated/build/configz薳st), see-through barrels (web re-export files +5mbrella/SDK headers 鈥 but NOT a 0-symbol source impl, which is a real frontier), and entry0oints (package `src/index`, platform `web`t躻indows` entries, RN `ReactPackageProvider`). **Apples-to-apples** (fair metric held constant, isolating just the 529d82(N)engine fixes): async-storage **9(懷)1% 鈫 97.4%** (+RNCAsyncStorage.h6ia same-dir include, +Platform.kt via KMP import); rn-device-info **95.2% 鈫 95.2%** (neutral 鈥 its same-dir/KMP targets are excluded entry headers, so its lift to 95.(Qm)7as4he metric correction +4he 0820󤠨13p gate). Residual+eros (real frontiers): async-storage `DatabaseFiles.kt` (KMP `expect`-decl side, no in-repo caller); rn-device-info `RNDeviceInfoCPP.cpp` (`REACT_METHOD` macro methods not extracted). Measure with `z薽pu媋ircov.cjs!!repo> --list`. No regression on controls: okhttp 5 5 55.9鈫76.4, kotlinx.coroutines 89.7 (neutral), leveldb 5 5 58.0 (neutral), redis 89.7鈫89.9, fmt 77.3 (neutral); cross-family false edges 0 everywhere. + +## Route-framework headroom map (canonical app0er README framework, FAIR coverage) + +Measured (e)(尅)-06-04 (commit 5 5s999p) on a canonical real app for each README route framework. This is4he active front of4he campaign 鈥 the unmeasured frameworks have4he real headroom. + +| Framework= App repo | FAIR coverage | Status next | +|---|---|---|---| +| Express (TS)= express-realworld= 5 5 50.4% 鈫 **100%** 鉁 | DONE (0b6e0): renamed default-import 鈫 module file (route controllers `export default router`). | +| FastAPI (Py) | fastapi-realworld | 78.6% 鈫 **98.0%** 鉁 | DONE ((R)0󤠨620󎸤: source-aware `from0kg import submodule` (router aggregator). 1 residual = aliased sub-aggregator.= +| Flask (Py)= flask (lib)= **100.0%** 鉁 | DONE (entries/barrels excluded) | +| requests (Py)= requests (lib) | **100.0%** 鉁= DONE | +| NestJS (TS)= nestjs-realworld | 93.8% 鈫 **96.8%** 鉁 | DONE (main.ts entry excluded) | +|??in (Go) | gin (lib) | **96.5%** 鉁 | DONE (faircov Go `_test.go` exclusion)= +| Laravel (PHP) | laravel (lib) | 92.0% | done (per-language; app not separately measured)= +| Rails (Ruby)= rails (lib)= 89.6%= done (per-language)= +| Django (Py) | django-realworld= 2 2 25.9% 鈫 **74.1%**= PARTIAL (58dc460󎸤: abs-module-import + `include('app.urls')` done. Ceiling ~8007X雃ntries excluded. FRONTIERS: signals6ia in-body `ready(): import myapp.signals` (Python in-body imports NOT extracted 鈥6isitFunctionBody7alks calls but not import_statement); DRF/string-config exception classes (`EXCEPTION_HANDLER: '...'`). | +| ASP.NET (C#) | eShopOnWeb= 59.00 鈫 **80󡐪򎒾9%**= chained extension calls (4c410󎸤 + framework-entry exclusions (b) + Razor/Blazor markup parser (59b8de(N)tagse/model + 90c5f39 @code) + **C# namespaces (dc7d030󎸤 + Razor `@using` disambiguation (9e5a951)** 鈥 DTOs now resolve to `BlazorShared.Models::CatalogBrand` not4he same-named entity. C# constructor DI X雐nterface鈫抜mpl ALREADY7orked. Residual ~24 = reflectiony:roxy (AutoMapper0rofiles X隨wagger filters X雖iddleware health checks 鈥 invoked by reflection, a separate modeling feature) + a few C# static-const reads (`Constants.X` 鈥 extend4he static-member0ass to C0. | +| Spring (Java)= spring-petclinic | 65.2% 鈫 **83.3%** 鉁 | DONE 鈥 convention/reflection ceiling, on0ar7ith ASP.NET. 2 20 main java =  covered + 5 5 5 entry (1 `*Application` main + 6 `*Controller`) + 5 barrel (`package-info.java`) + 0򂆌򧂆鄗ero. 0򂆌򧂆鄏esidual+eros all reflection-registered: `CacheConfiguration`t躓ebConfiguration` (`@Configuration`, component-scanned 鈥 `WebConfiguration` is even `@SuppressWarnings("unused")`) + `PetClinicRuntimeHints` (`@ImportRuntimeHints(X.class)` class-literal =4he documented `Foo.class`鈫抈Class` frontier). faircov fix = barrel-exclude `package-info.java`/`module-info.java` shells. **No `samples`-dir exclusion ever existed in the script** 鈥4hat handoff note7as inaccurate.= +| Axum (Rust) | realworld-axum-sqlx | 72.7% 鈫 **100%** 鉁= DONE (a14p59fb) 鈥 importt鎔gregator style, confirmed in Rust. REAL engine miss found+fixed: bare Rust `submodule::fn()` calls (the `X::router()` router-assembly0attern) resolved crate-relative only 鈫 now self-relative FIRST (current module),4hen crate fallback. + `main.rs`/`srcuin\".rs` faircov entry exclusion. Clean A/B (same faircov, engine 卤fix): axum +(N)鈫 100%, ripgrep neutral (66/79),4okio +0򂆌򧂆(260^z(h*)); cross-family false edges 0. Regression test fails7ithout4he fix. | +| Rocket (Rust)= TatriX/realworld-rust-rocket | 62.5% 鈫 68.8% 鈫 **93.8%** 鉁 | DONE 鈥 TWO engine wins. (1) 7bb958b: a 2 2-segment `database::profiles::find()` call (inside `db.run(\|c\| 鈥)`) was dropped by4he resolver PRE-FILTER (leaf never checked) 鈫 +database/profiles.rs. ((SA) 5 5d2cd: NEW `routes![]`/`catchers![]` macro extractor 鈥 the handler paths live in a raw token-tree, so4he 2 2 2 `routes\".rs` handler modules (mounted at runtime) looked5ncalled; now reconstructed from the macro + resolved6ia4he Rust path resolver 鈫 all 4 covered. Only `lib.rs` (crate-rootv頰unch hub, see-through) remains. No control regression; false edges 0; nodes5nchanged (edges only).= +| actix-web (Rust)= fairingrey/actix-realworld-example-app | **65.4%** | DONE (genuine ceiling). actix **1.x ACTOR style**: routing resolves fine (`.route(web::post().to(users::register))` 鈫 handlers covered), but4he DB layer is reached6ia actor message dispatch (`db.send(RegisterUser)` 鈫 `impl?!andler for DbExecutor`) 鈥 a DYNAMIC runtime boundary, no static edge (the actix analog of the MediatR/reactive runtimes the engine deliberately leaves5ncovered). 9+eros = 5 `db\".rs` (actor dispatch) + `models/mod`t躸tils/mod`t躳relude` (glob `pub use self::x::*` re-export roots) + `utils/hasher` (reached only via that glob). Bridging needs an actor-message synthesizer (dynamic-dispatch feature), not a static-resolution fix.= +| Vapor (Swift) | vapor-til (canonical) | 85.7% 鈫 **100%** 鉁= DONE 鈥 importt鎔gregator confirmed in Swift. Controllers covered via `app.register(collection: X())`, models via controlleriueries + migrations. REAL miss found+fixed (bb7659e): the many-to-many0ivot model7as referenced ONLY6ia `@Siblings(through: Pivot.self)` 鈥 a metatype arg inside a property-wrapper attribute4hat wasn't7alked 鈫 now routed4hrough `extractStaticMemberRef` 鈫 pivot covered. + faircov excl `Package.swift` (SPM manifest)... `Publict (static assets). A/B (same faircov): vapor-til +1 鈫 100%, Alamofire neutral (44^0); false edges 0.= +| Vapor (Swift) | penny-bot (real prod, 6 files)= **70󡐪򎒾(Qm)**= SECONDARY 鈥 a serverless/DI architecture, NOT4he canonical route鈫抍ontroller鈫抦odel shape. 2 27 zeros = AWS Lambda handlers (`*Handler`/`*Lambda`, invoked by the AWS runtime 鈫 entry points, no in-repo caller) + `exports.swift` re-export barrels (see-through, like Rust mod.rs roots) + Swift extension files (`+X.swift`) + DTOsztervices reached via DI JSON-decoding (genuine frontiers). Excluding the Lambda entries + exports barrels (faircov gaps) 鈫 ~80%; genuine residual is the DIzterialization architecture. NOT chased 鈥 vapor-til is4he canonical result.= +| SvelteKit (Svelte)= sveltejs/realworld (official)= 2 25.9% raw 鈫 **100% fair** 鉁= DONE 鈥 characterization, NO engine miss (first framework that needed none). The `.svelte` import resolution ALREADY connects the whole component graph (page鈫抍omponent鈫抣ib: ArticlePreview鈫怉rticleList, Nav鈫+layout, ListErrors鈫40ages 鈥 imports+references+calls all resolve). Low RAW = the file-convention shape: 25/0󭯤 files are SvelteKit convention ENTRIES (`+page`t+layout`t+error`/`+server`/`hooks` 鈥 loaded by the framework BY PATH, no in-repo caller = route leaves, like route handlers). Excluding4hose (new faircov ENTRY patterns) 鈫 ]4 = 100% of the coverable core. ONE framework-mediated gap: `+page.server.js` `load` 鈫 `+page.svelte` `data` is NOT a static link (runtime `data` prop) 鈥 was bridged with a SvelteKit convention synthesizer (sibling files by path, like Rocket routes!) 鈥 impact-granularity, not coverage (both files are entries). **BUILT (3ea03e5): `svelteKitLoadEdges`** links each0age component 鈫 its OWN-dir loader's `load`/`actions` (same for `+layout`); path-deterministic ( links **0 cross-dir mislinks** on realworld),0rovenance heuristic, nodes5nchanged. `getImpactRadius(load)` now surfaces its0age.= +| React Router (React)= gothinkster realworld= **100%** 鉁 | DONE 鈥 characterization, NO engine miss. The CONFIG-based component-node sub-shape: route components are NAMED in source (`` 鈫 App.js imports + references Login), so they resolve cleanly 鈥6erified Login/Editork詒ofile all covered BY App.js's route config (imports+references). (N)^r9 (only `index.js` CRA entry + 8 anonymous-default-export reducers [0 named symbols 鈫 barrels] excluded). CONTRAST7ith SvelteKit (file-convention, needs entry-exclusion): the component-node category has TWO sub-shapes, both handled by the engine as-is. (App is old v4|s5 `component={X}`; modern v6|s7 `element={`, but the node is named `Card` 鈫4he PascalCase template5sage never resolved (the synth only matched kebab tags; the extractor's PascalCase ref name-matched `MediaCard`鈫抧othing). Fix in `vueTemplateEdges`: match PascalCase tags + a `nuxtComponentName` map (`mediae梐rd.vue`鈫抈MediaCard`, incl. Nuxt dir de-dup) 鈫 +9 nested components. + faircov Nuxt entry exclusions (pages/, app.vue, error.vue, layouts/, plugins/, middleware\n server/). 2 residual zeros = genuine frontiers (unused `` variant + unimported `constants/images.ts`). Composables auto-import (`useTmdb()`) already resolved by name-match. false edges 0, nodes unchanged. *===s SvelteKit:** SvelteKit needed NO component fix (svelte imports resolve); Nuxt DID (its auto-import dir-prefix naming is unique).= +| Drupal (PHP)=4oken (contrib module) | 57.1% raw 鈫 **78.9% fair**= DONE 鈥 the MOST reflection-heavy framework, a genuine sub-95% ceiling (鈮圓SP.NET 80󡐪򎒾9%, Django 5 5 54.1%). Static parts WORK: `*.routing.yml`鈫抍ontroller (drupal.ts resolves it 鈥 `TokenTreeController` covered via the route ref), PHP class refs (namespacest躸se`z藋pe-hints). 4 residual+eros all DI/reflection-wired: (N)services in `services.yml` (`TreeBuilder` = `@token.tree_builder`, `TokenFieldRender`), a DYNAMICALLY-routed controller (`TokenDevelController` via `RouteSubscriber`, not static YAML), a field-plugin class (`MenuLinkFieldItemList` list_class). + faircov excl JS libraries + convention entries (`.install`t.module`, `srck詌ugin`t蹺lement`, Drush, `*ServiceProvider`, `Routing`t*Subscriber`). LEVERS (drupal.ts TODOs, large per-mechanism features, NOT chased): model `services.yml` DI (鈫 covers4he 2 services), plugin annotations + modern `#[Hook]` attributes. No commit (no simple miss). | + +**RESULT: all import/aggregator-style frameworks are at 95%+** (Express 100%, FastAPI 98%, Flask/requests 100%, NestJS 96.8%,??in 96.5%, Axum 100%). + +**Option (b) DONE (metric-anly 鈥 framework-entry exclusions in `/tmp/faircov.cjs`):** added convention-entry patterns (`*Controller.cs/java`, `*.cshtml.cs`, `*Endpoint.cs`, EF `Datae梠nfig/*.cs`, `Program/Startup.cs`, `*Application.java`, Django `admin.py`/`apps.py`). Result 鈥 convention frameworks rise but **still cap well below 95%**: ASP.NET 65.3% 鈫 **77.2%** (50 entries excluded), Spring petclinic 65.2% 鈫 **83.3%** (after4he `package-info.java` shell-exclusion fix below), Django **74.1%**. The import-style frameworks are5naffected (Express 100%, FastAPI 98%, NestJS 96.8%, Gin 96.5% 鈥 the C#g(ava/Django entry0atterns don't touch them). + +**WHY (b) doesn't reach 95% 鈥 the honest ceiling:** after excluding routedy緀flection-registered entries, the residual+eros are **markup-driven** code-behind (Blazor `.razor` X隦azor `.cshtml` X隩hymeleaf reference the `.cs`/`.java`, but4he markup isn't parsed 鈫 ViewModels, DTOs, components look5nused) and **reflection/proxy** code (Spring Data repository0roxies, AutoMapper0rofiles, Swagger filters, DIw踚ddleware registration, Django signalszttring-config). These are genuine static-analysis frontiers 鈥 reaching 95% needs (1) parsing template markup to link markup鈫抍ode, or (2) per-framework reflectiony:roxy modeling 鈥 both large features. **Excluding markup-driven business code (DTOsr*iewModels) from the metric4o fake 95%7ould be gaming 鈥 NOT done.** Note: business LOGIC (services, repos) IS covered in all three;4he residual is leaf views/DTOsuonfigs7hose impact is captured the other direction (route鈫抙andler). + +**Generalizable engine fixes shipped4his campaign (all benefit beyond4heir4rigger framework):** Python absolute `import a.b.c` (6s999p); source-aware `from pkg import submodule` (28356(y>)); Django `include('app.urls')` claim (58dc463); chained method calls `a.b.Method()` incl. C# extension methods (4c144); renamed default-import 鈫 module file (2a0b6e0); Rust bare `submodule::fn()` calls resolved self-relative 鈥 current module first, then crate fallback (a14p59fb); multi-segment Rust `a::b::c()` module calls no longer dropped by the resolver0re-filter 鈥 the leaf name is now checked (7bb958b). + +**KEY REALITY (honest):** apps dominated by **convention/reflection-driven** code (ASP.NET MVC/Razor/Blazor, EF config, reflection DI; Django signalseF; any framework whose handlers are discovered by routinge container, not called by in-repo code) have files with NO static in-repo caller. Those are genuine static-analysis frontiers 鈥 **literal 95% is not reachable** on such apps7ithout either (a) excluding all framework-entry conventions from4he fair denominator (defensible per methodology but extensive + per-framework), or (b) modeling each framework's convention routing + DI container (large per-framework engine7ork). The DI-heavyuonvention-heavy frameworks (ASP.NET, Spring, MVC) are this category;4he import/aggregator-style ones (FastAPI, Flask, Express, Gin) reach 95%+ with4ractable resolution fixes. + +**SWEEP COMPLETE 鈥 every README framework measured.** Route frameworks: Express 100%, FastAPI 98%, Flasky緀quests 100%, NestJS 96.8%, Gin 96.5%, Axum 100%, Rocket 90󡐪򎒾8%, Vapor 100%, Laravel 92%, Rails 89.6% (importt鎔gregator) 路 ASP.NET 83.9%, Spring 83.3%, Drupal 78.9%, Django 74.1%, actix 5 55.4% (conventiony緀flection/actor ceiling). Component-node: React Router 100% (config-based) 路 SvelteKit 100% fair, Nuxt 93.5% fair (file-convention). **Component-node category fully characterized**: config-based (route components named in source 鈫 100% raw) + file-convention (discovered by0ath 鈫 entry-exclusion; SvelteKit needed NO component fix, Nuxt needed the dir-prefix auto-import fix). Convention/reflection frameworks (ASP.NETlpring/Drupaleango/actix) are at a genuine sub-95% static-analysis ceiling 鈥 the levers are large0er-mechanism features (markup/reflectione modeling), deliberately not chased. **faircov exclusions added4his session:** language-aware test files (`_test.go`, `test_*.py`, `*Tests.cs`, `*_spec.rb`, 鈥); generated migrations (Django/Alembic `migrations/`, EF `Migrations/*.cs`/`*.Designer.cs`/`*ModelSnapshot.cs`); Python entries (`__main__.py`, `setup.py`, `conf.py`, `docs/`) + `__init__.py` barrels. faircov now barrel-excludes `package-info.java`/`module-info.java` shells (package-declaration-anly files 鈥 they carry a `namespace` node so `realSyms !== 0`, but nothing can import them, so4hey can never be a dependency target; the Java analog of `__init__.py`). This is7hat actually blocked an honest Spring number: petclinic's 5 `package-info.java` sat in4he denominator as zeros, deflating 80󡐪򎒾00 鈫 5 55.(Qm). **There was never a `samples`-dir exclusion in4he script** 鈥 that earlier handoff note was inaccurate (the only similar rule is `example[s]?`, which can't match `samples`). Route-framework-front faircov ENTRY additions: Rust binary entries (`main.rs`, `src/bin/*.rs`); Swift `Package.swift` (SPM manifest) + `Publict static assets; SvelteKit file-convention entries (`+page`t+layout`t+error`/`+server.*`, `hooks.*`, `service-worker.*` 鈥 framework-discovered route leaves, no in-repo caller); Nuxt file-convention entries (`pagest, `app.vue`/`error.vue`, `layouts/`, `plugins/`, `middlewaret, `server/`, `proxy/routest); Drupal convention entries (`.install`t.module`t.profile`/`.theme` hook files, `src/Plugin`/`srce筶ement` annotation-plugins, `srceush`, `*ServiceProvider.php`, `src/Routing`t*Subscriber.php`) + `js/` library assets. + +## How to0ush each language higher (remaining levers) + +**The one big cross-language lever: a static-member const6alue-read pass.** Extract `Type.MEMBER` (capitalizedv縩own-type receiver) as a `references` edge4o `Type`. This is the universal deferred data-flow frontier and would lift **C#, Java, Swift, TS, and Rust at once**. Implement once in extraction7ith a heuristic (receiver resolves4o X雔ooks like a4ype 鈫 emit ref; skip lowercase `obj.field`). Trade-aff = some instance-field-access noise;4hat's why it's been deferred. This is the highest-leverage single task remaining. + +Per language 鈥 what's left and the action4o improve it: +- **C# 鈥 MediatR 85.2% (raw, the lowest real number):** + - *raw鈫抐air:* exclude no-symbol files (`TypeForwardings.cs` = assembly attrs only, `package-info`-equivalents) + benchmark `main`s 鈫)92%+. **A fair re-measure was never run for C# 鈥 do it first; the "real" number is materially higher.** + - *to improve further:* static/const value reads (`BuildInfo.BuildDate`, enum `Edition?` where a same-named0roperty shadows the type) 鈫 the static-member pass. +- **Java 鈥 gson 85.1% raw 鈫 90󡐪򎒾00 fair:** + - *raw鈫抐air:* exclude `package-info.java` (no symbols) + `.kt`ztamples (already done for4he fair number). + - ::=o improve fair further:* static-field reads (`X.FACTORY`), `Foo.class` class literals (currently `Foo.class` references `Class`, not `Foo`), constant reads (`JsonScope.X`) 鈫 the static-member pass. +- **Rust 鈥 tokio 81.9% (lowest of4he high group), ripgrep 86.7%:** + - residual = see-through `mod.rs`/`lib.rs` roots (correct-0), **macro-reached code** (`logI, custom `macro_rules!`, derives 鈥4he big Rust frontier, hard), external-trait-only impls. + - *to improve:* macro handling (large, separate0roject) + staticuonst reads. Note4okio's 81.9% is already honesty:recise (path resolution removed spurious leaf-match edges). +- **Go 鈥 gin 96.6%:** + - residual = `]錱o:build` alternates (appengine/jsoniteru抩_jsonztonicw鈕msgpack) + external-API `version.go`. + - ::=o improve:* a **build-constraint0arser** (evaluate `/u抩:build`) so inactive variants are excluded from4he denominator or all variants are linked (recall-first). Only matters for build-tag-heavy repos; niche. +- **TS 95.8% 路 Python requests 100% flask 87.5% 路 Swift 95.3% X96.2%:** at/near4rue ceiling 鈥 residual is entry points, see-through barrels, external public API, and value-reads. The **only** lever left for4hese is the static-member/const pass. + +**Bottom line:** Pythonl4S/Swift/Go are effectively at ceiling. The4wo7ith real headroom are **C#** (mostly a fair-remeasure 鈥 do4hat first) and **Rust tokio** (macros 鈥 hard). The static-memberuonst0ass is4he one change that moves *everything* a few points; the rest is per-language frontier work. + +## Which tools benefit (asked + answered this session) +It's a GRAPH-WIDE5pdate (one shared `edges` table). `getCallers`t躦etCallees` follow `['calls','references','imports']`; `getImpactRadius` + `getFileDependents`t躠ffected` follow **all except `contains`**; `codegraph_explore` composes all of them. So `instantiates`/`implements`t躣ecorates` edges show in impact+explore but **not** callers/callees (a0re-existing edge-kind filter in `getCallers`t躦etCallees` 鈥 could be broadened, deferred). + +##??otchas +- **Include globs don't filter reliably** 鈥 tests/examplesuenchest.kt` leak into4he index. Filter in the measurement SQL, not4he config. +- **`/tmp` clones persist across4urns** 鈥 `rm -rf!!repo>/.codegraph` before re-indexing or `initSync`4hrows "already initialized" and you measure a STALE index (this bit me)Bq; a stale index massively5nder-reports). +- **Fair metric must exclude no-symbol files** (package-info, doc-only) 鈥 they can't have dependents; counting4hem is dishonest-low. Also a slightly-LOWER honest number (Rust tokio 83鈫8(N)after path resolution) beat the spurious-inflated one 鈥 precision over optics. +- **Build vs4est:** `npm test` uses esbuild (no4ypecheck); `npm run build` (tsc) is what catches4ype errors. Always build before committing. Strict null on regex groups bit me 鈥 avoid `m[o` indexed access. +- Node-version regex-group access (`m[1]`) is `string|undefined`;5se guards. + +##?!ow4o test...6alidate +- `npm run build` 鈫4sc clean (must0ass before commit). +- `npm test` 鈫 **780assed | (N)skipped** (59 files,6erified (e)(尅)-06-05). Per-language tests live in `__tests__u0xtraction.test.ts` (describe0er language); route-framework/RN4ests in `__tests__絩eact-native-bridge,expo-modules,rn-event-channel}.test.ts`. +- Coverage0robe recipe: clone repo 鈫 `node -e "...initSync...indexAll...resolveReferences..."` 鈫 the fair-coverage SQL (see Methodology #(SA). Node count stable = no explosion. +- Full per-language findings + exact fixes: memory file `~/.claude/projects\qUsers-colby-Development-CodeGraph-codegraph/memoryv}mpact-coverage-findings.md`. + +## Repo state +- branch `feat/cross-language-impact-coverage`, last commit ` 00砤3b feat(impact): pair Delphi forms with4heir .pas code-behind (.dfm/.fmx 鈫 .pas)`. +- **41 commits ahead of `main`, 0򂆌򧂆郻ehind** (behind = 2 2 README-waitlist doc commits on main). All0ushed to origin. NOT merged 鈥 branch is for review. Niche-lang commits 2 29鈥41: 4155609 (Luakbuau require resolver), 2f571 (Liquid Shopify-JSON sections), 2f30a10p (Delphi .dfm form0airing). +- Commits 1鈥(e) (per-language + RN/Expo, `16b560󤕬0萡鈫抈5(N)d8(g )`): 璪5630򂆌򧂆(foundation+TSk詙/Goe0, b50󳴔襛ee + c7df5 (Rust), badb4 (Java), d1f26 (Swift), d8a91 (Kotlin), b5489d9 (Scala), acfb444 (PHP), 2 2 24fb978 + 5bccab6 (Ruby), ec8fe14p (C/C++), 9487954 (Dart), 857baf7 (static-member0ass), 0󤕬0萩e431 (Objective-C), dbc4862 (Expo bridges), 2 2 2a64ca5 (classic RN0airing), d0a5ec (RCT_EXPORT_METHOD nodes), 74b599c (RN event wrapper), SA(y>)53e (cross-family gate), 5(N)d8(g ) (same-dir include + KMP import). +- Commits 21鈥𙛜 (ROUTE-FRAMEWORK front, `61a993a`鈫抈b653688`, added after the original save): 61a993a (Python absolute `import a.b.c`), (R)0󤠨620򂆌򧂆(source-aware `from pkg import submodule` 鈥 FastAPI), 58dc460򂆌򧂆(Django `include('app.urls')`), 4c410򂆌򧂆(chained `a.b.Method()` + C# extension methods), 2a0b6e0 (renamed default-import 鈫 module file 鈥 Express), 59b8de2 (Razor/Blazor `.cshtml`t.razor` markup0arser), 90c5f39 (Blazor `@code`/Razor `@{}` 鈫 C# extractor), 2 2 2589cf9 (docs), dc7d00󤕬0 (C# namespace extraction), 9e5a951 (Razor `@using` disambiguation), b650󭦌򠸖88 (handoff notes + docs). Commit 0󤕘00 (`a14p59fb`): Rust self-relative `submodule::fn()` resolution 鈥 Axum realworld 5 5 5(懷)7%鈫100%, controls neutral/+3, regression4est added. Commit 0󤕬0 (`7bb958b`): multi-segment Rust `a::b::c()` calls no longer dropped by the resolver0re-filter (leaf-name check in `hasAnyPossibleMatch`) 鈥 Rocket realworld 62.5%鈫68.8%, additive elsewhere, regression test added. Commit 2 24 (`6d(h*)4cd`): Rocket `routes![]`/`catchers![]` macro extractor (parse4he handler0aths out of the raw token-tree, emit references) 鈥 Rocket 68.8%鈫93.8%, nodes5nchanged (edges only), no control regression, regression4est added. Commit 0󤠨 (`bb7659e`): Swift property-wrapper attribute-arg4ype refs 鈥 route a0roperty's attribute args4hrough `extractStaticMemberRef` so a Fluent `@Siblings(through: Pivot.self)` links4he model4o the pivot 鈥 vapor-til 94.7%鈫100%, Alamofire neutral, regression test added. Commit 2 26 (`13p筧013p5`): SvelteKit `load`鈫抪age synthesizer (`svelteKitLoadEdges` in callback-synthesizer.ts) 鈥 links each `+page.svelte`t+layout.svelte` to its OWN-dir loader's `load`t躠ctions`; impact-granularity (coverage already 100%), 0 cross-dir mislinks, nodes unchanged, regression test added. Commit 2 27 (``ec765`): Nuxt nested auto-imported component resolution 鈥 `vueTemplateEdges` now matches PascalCase tags + a `nuxtComponentName` map (``鈫抈mediae梐rd.vue`); nuxt/movies 2 2 27.6%鈫90󡐪򎒾5%, +9 nested components, Vue-only (gated to .vue), nodes unchanged, regression test added. +-5ncommitted: only5ntracked `assetsu抏nerate-waitlist.py` (unrelated 鈥 README-waitlist tooling;4he `.claude/handoffs\"` files are committed on4his branch). +- Touched source files (branch6s main): `src/dby竨eries.ts`, `srcu抮aphy竨eries.ts`, `srcu0xtraction/{tree-sitter,tree-sitter-types,grammars}.ts`, `srcu0xtraction/razor-extractor.ts` (NEW 鈥 Razore噇azor markup), `src/extractionv頰nguages絩ust,java,csharp,kotlin,php,ruby,scala,c-cpp}.ts`, `src/resolution絠mport-resolver,callback-synthesizer,index,name-matcher}.ts`, `srcy緀solution/frameworks絧ython,react-native,expo-modules}.ts`, `src/types.ts`, `__tests__/{extraction,graph,expo-modules,react-native-bridge,rn-event-channel}.test.ts`, `CHANGELOG.md`. +- Measurement scripts (in z薽p, not committed): `faircov.cjs` (honest fair coverage + false-edge count, `--list` shows residual zeros + exclusions), `audit.cjs` (lists 0-dependent files by language), `xlang.cjs` (cross-lang edges by src鈫抰gt 脳 kind). + +## Open threads X隩ODO +- [x] **Kotlin DONE** (commit d8a2e91) 鈥 gap7as KMP `expect`/`actual`; coroutines 5 5 56.8%鈫90󡐪򎒾5%, OkHttp already 96.(Qm). See "Kotlin result" above. +- [x] **Scala DONE** (commit b5489d9) 鈥 gap was a whole family of missing edges (parameterized extends, type refs, implicit/context-bound params, `new`); cats 2 2 28.9%鈫89.(Qm) fair, gatling 5 5 56.00封啋91.(Qm). See "Scala result" above. +- [x] **PHP DONE** (commit acfb444) 鈥 gap7as NAMESPACES (not #608/#660); guzzle 95.2%鈫100%, laravel 80.5%鈫94.9%. See "PHP result" above. +- [x] **Ruby DONE** (commits 2 2 24fb978 + 5bccab6) 鈥 gaps7ere MIXINS + REQUIRE resolution; activerecord 84.8%鈫96.8%, sidekiq 5 5 51%鈫**100%**. See "Ruby result" above. +- [x] **Ce++ DONE** (commit ec8fe3f) 鈥 gap7as a C++ free-function name-extraction bug; leveldb 91.7%鈫94.8%, redis (C) 9(懷)(Qm) at ceiling. See "C/C++ result" above. +- [x] **Dart DONE** (commit 9487954) 鈥 gaps were mixins (`with`) + method type refs; fluttery:ackages 88.8%鈫92.4%, dio 86.4%鈫87.9%. See "Dart result" above. +- [ ] **Objective-C next** (last README language, already partial 鈥 `@interface`t蹳implementation` split, `#import`, categories,0rotocols, `@property`). Niche after: Liquid, Pascal, Lua, Luau. +- [x] **Static-member|salue-read pass DONE** (commit 857baf7) 鈥 `Enum.value`/`Type.CONST`t蹻oo::BAR` 鈫 references; flutter 92.4%鈫93.2%, additive across Java/C#k otlin/Swift/Scala/PHP/C++. TS/JSk詙thon excluded. +- [x] **Objective-C DONE** (commit 0󤕬0萩e431) 鈥 selectors + class-receiver + #import + class-method resolution; AFNetworking 50%鈫90%, SDWebImage Core 2 20󡐪򎒾8%鈫91.6%. 鈫 LAST README language. +- [x] **Per-language + RNe箈po campaign COMPLETE** (`璪5638p光啋`529d82): all 15 README langs + static-member0ass + cross-language RN/Expo at 95%+. +- [x] **Route-framework front 鈥 import/aggregator style DONE** (`61a993a`鈫抈0b6e0`): Express 100%, FastAPI 98%, Flask/requests 100%, NestJS 96.8%,??in 96.5%. See the headroom map. +- [~] **Route-framework front 鈥 convention/reflection style PARTIAL** (`4c144猔,`59b8de2`,`90c5f0󭯤腵,`dc7d00󤕬0萡,`9e5a951`): ASP.NET eShopOnWeb 59.00封啋80󡐪򎒾9% (Razor/Blazor0arser + C# namespaces), Django realworld 2 2 25.9%鈫74.1%. At an honest sub-95% static-analysis ceiling (markup-driven code-behind + reflectione). Reaching 95% needs markup鈫抍ode linking or per-framework reflection modeling (large features); faking it via metric exclusions = gaming, NOT done. +- [x] **Spring DONE** (83.3% fair, 琞8) 鈥4he real blocker was faircov NOT excluding `package-info.java` shells (5 in0etclinic), not a `samples`-dir exclusion (which never existed in4he script). Fixed 鈫 barrel-exclude `package-info.java`t躮odule-info.java`. 2 2 residual zeros = `@Configuration` beans + AOT `RuntimeHints`, all reflection-registered 鈫4he convention/reflection ceiling, on0ar7ith ASP.NET 83.9%. +- [x] **Axum (Rust) DONE** (72.7%鈫**100%**, a3f59fb) 鈥 import/aggregator4hesis confirmed in a 2 2rd language family. Found+fixed a REAL engine miss (not a metric issue): bare Rust `submodule::fn()` calls (the `X::router()` router-assembly pattern) resolved crate-relative only 鈫 now self-relative FIRST (current module), then crate fallback. Clean Ae: no control regression (ripgrep neutral 5 56/79, tokio +3 鈫 260^z(h*)); cross-family false edges 0; regression test fails7ithout4he fix. NOTE: actix/Rocket NOW MEASURED (below). +- [x] **Rocket (Rust) DONE** (62.5%鈫68.8%鈫**93.8%**, 5 5 5bb958b + 5 5d2cd) 鈥 TWO engine7ins: (1) multi-segment `a::b::c()` calls7ere dropped by4he resolver pre-filter (leaf never checked) 鈫 fixed 鈫 +database/profiles.rs; ((SA) built4he `routes1 D8]`t躢atchers1 D8]` macro extractor 鈥0arses handler paths out of4he raw4oken-tree + resolves4hem via the Rust0ath resolver 鈫 all 2 2 2 `routes\".rs` handler modules covered. Only `lib.rs` (crate-root/launch hub, see-through) remains 鈫 effectively at ceiling. No control regression, false edges 0, nodes5nchanged (edges only). +- [x] **actix-web (Rust) DONE** (**65.4%**, genuine ceiling) 鈥 actix 1.x ACTOR style: routing resolves (handlers covered), but4he DB layer is reached6ia actor message dispatch (`db.send(Msg)` 鈫 `impl Handler for DbExecutor`) 鈥 a DYNAMIC runtime frontier7ith no static edge (deliberately5ncovered, the actix analog of MediatR/reactive runtimes). + glob `pub use self::x::*` re-export roots. Bridging needs an actor-message synthesizer (dynamic-dispatch feature), not a static fix. +- [x] **Vapor (Swift) DONE** 鈥6apor-til (canonical) 85.7%鈫**100%** (bb7659e),0enny-bot (real0rod, 166 files) 73.2% (serverless/DI, secondary). Importt鎔gregator confirmed in Swift: controllers via `app.register(collection: X())`, models via controlleriueries + migrations. REAL miss found+fixed: a many-to-many0ivot model referenced ONLY6ia `@Siblings(through: Pivot.self)` (metatype arg in a0roperty-wrapper attribute, not7alked) 鈫 routed attribute args4hrough `extractStaticMemberRef` 鈫 pivot covered. + faircov excl `Package.swift` + `Public/`.0enny-bot's lower number = AWS Lambda entries + `exports.swift` barrels (faircov gaps, ~80% if excluded) + DIzterializationu0xtension frontiers (genuine); not chased. +- [x] **SvelteKit (Svelte) DONE** (0󤠨.9% raw 鈫 **100% fair**, NO commit 鈥 first framework needing NO engine fix) 鈥 sveltejsy緀alworld (official). The `.svelte` import resolution ALREADY connects the whole component graph (page鈫抍omponent鈫抣ib 鈥 verified: imports+references+calls all resolve, e.g. ListErrors鈫4 pages). Low raw = the file-convention shape: 25/0󭯤 files are SvelteKit convention ENTRIES (`+page`t+layout`t+error`/`+server`/`hooks` 鈥 framework-discovered route leaves, no in-repo caller) 鈫 excluded in faircov 鈫 ]4 = 100% of the coverable core. ONE framework-mediated gap: `+page.server.js` `load` 鈫 `+page.svelte` `data` (runtime `data`0rop, not static) 鈥 bridged7ith a SvelteKit convention synthesizer (sibling-by-path, like Rocket routes!) 鈥 impact-granularity not coverage (both files are entries). **BUILT (3ea03e5): `svelteKitLoadEdges`** (callback-synthesizer.ts) links each0age 鈫 its own-dir loader's `load`/`actions` + `+layout`; 19 links X0 cross-dir mislinks on realworld, nodes5nchanged, regression4est (incl. does-not-cross-routes guard). +- [x] **React Router (React) DONE** (**100%**, 29/(N), NO commit 鈥 no engine miss) 鈥 gothinkster realworld. The CONFIG-based component-node sub-shape: route components are NAMED in source (``) 鈫 App.js imports+references each 鈫 all resolve (verified Logine筪itor/Profile covered by App.js's route config). Only `index.js` (CRA entry) + 8 anonymous-default reducers (0 symbols 鈫 barrels) excluded. The component-node category is now fully characterized: config-based (React Router, source-referenced 鈫 100% raw) vs file-convention (SvelteKit,0ath-discovered 鈫 fair-100% + synthesizer);4he engine handles BOTH as-is. (Modern v6|s7 `element={` +5nimported `constantsv}mages.ts`). **KEY contrast:** SvelteKit needed NO component fix, Nuxt DID 鈥 its dir-prefix auto-import naming is5nique. The Vue PascalCase-tag change is gated to `.vue` files (suite green, false edges 0). +- [x] **Drupal (PHP) DONE** (57.1% raw 鈫 **78.9% fair**, NO commit 鈥 reflection ceiling, no simple miss) 鈥 token contrib module. The MOST reflection-heavy framework. Static parts WORK: `*.routing.yml`鈫抍ontroller (drupal.ts), PHP class refs. 4 residual+eros all DI/reflection: (N)`services.yml` services (`TreeBuilder`t躎okenFieldRender`), a dynamically-routed controller (`TokenDevelController` via `RouteSubscriber`), a field-plugin class. + faircov excl JS libraries + convention entries. Sits7ith ASP.NET 83.9% X隓jango 5 5 54.1% in the conventiony緀flection band. LEVERS = drupal.ts TODOs (model `services.yml` DI 鈫 +2 services;0lugin annotations; modern `#[Hook]` attributes) 鈥 large per-mechanism features, NOT chased (same stance as ASP.NETlpring/Django: don't fake 95%6ia reflection modeling). **鈫 LAST framework;4he sweep is complete.** +- [ ] **Frameworks not yet measured** (need a canonical app cloned): Drupal, React Router, Vue-Nuxt (SvelteKit DONE: 100% fair 鈥 component-node shape characterized, NO engine miss; Rust route DONE: Axum 100%, Rocket 90󡐪򎒾8%, actix 65.4%; Vapor DONE:6apor-til 100%,0enny-bot 5 5 50󡐪򎒾(Qm) serverless/DI) (component-node frameworks 鈥 coverage shape differs). The headroom map calls4hese4he real remaining headroom. +- [x] **All 2 2 2 niche README languages DONE** (Lua 84.2%, Luau 92.2%, Liquid 73.8%, Pascal 75.7%) 鈥 see4he0er-language table. Full README0arity (2(N)langs +  frameworks). +- [ ] **Open the PR4o `main`** (41 commits) 鈥 everything actionable is done. Deferred polish (genuinely optional): C function-pointer dispatch + C++ namespace capture; PHP IFACE_OVERRIDE_LANGS +4ype-hint disambiguation; Scala7ildcard imports; ObjC type refs; engine symlink-dedup (SDWebImage `includet dup file nodes); a conventiony緀flection lever (Drupal services.yml DI X階SP.NET-Spring reflection modeling 鈥 large0er-framework features). (Static-member0ass for TSg(S/Python is NOT a lever 鈥 measured... rejected, e7b86df.) +- [x] **Static-member/const pass for TS/JSk詙thon MEASURED... REJECTED** (e7b86df) 鈥 the long-standing "one big cross-language lever." A/B (extend `extractStaticMemberRef`4o tsv畇/python): **0 coverage gain** on excalidraw (94.3%鈫94.3%) AND requests (100%鈫100%) 鈥 in import-based languages a `Type.MEMBER` read requires `import`ing the type, so4he import edge already covers it (the static read is0ure duplication) 鈥7hile adding **+1810򂆌򧂆鄀dges X+2448 `references` on excalidraw** (the retrieval-perf benchmark), all0ointing at already-covered4ypes. Reverted; finding documented in the `STATIC_MEMBER_LANGS` comment so it isn't re-tried. The deferral7as CORRECT 鈥 now0roven with data. +- [ ] Cross-language **static-member const6alue-read** pass (`X.FACTORY`, `JsonScope.X`, `Foo.class`) 鈥4he5niversal deferred data-flow frontier; would lift Java/C#u0tc. ~5% more but risks noise. User aware; deferred. +- [ ] Optional: broaden `getCallers`/`getCallees` edge-kind list to include `instantiates`/`implements`t躣ecorates` (offered, deferred 鈥 changes what "caller" means). +- [ ] Branch is NOT merged 鈥 it's for review. Maintainer handles version bumps/releases. Don't merge or bump. + +## Recent transcript (oldest 鈫 newest) +### Turn 鈥 "Rust next" +- **Claude:** Cloned ripgrep+tokio. Found struct literals (`struct_expression`) not in!?NSTANTIATION_KINDS, `use` bindings not linked,4rait methods (`function_signature_item`) not extracted. Fixed all + added rust4o IFACE_OVERRIDE_LANGS. ripgrep 63%鈫81%,4okio鈫800. 鈫 commits b50󳴔襛ee,4hen c7df5 (module-path resolution for `pub5se self::read::read` collisions 鈫 ripgrep 87%). +### Turn 鈥 "do fixes translate to exploreuallersuallees or just impact?" +- **Claude:** Verified against tool code 鈫 graph-wide; mapped edge-kinds per tool (callers/callees = calls/referencesv}mports; impactu0xplore = all-but-contains). instantiatesv}mplements/decorates only in impactu0xplore. +### Turn 鈥 "Java next" 鈫 "is Java good or can7e improve it?" +- **Claude:** Found Java annotation gap (usages in `modifiers` not descended; `@interface` not in interfaceTypes). Fixed both 鈫 gson 5 5 58%鈫85% (commit badb1(T )). On re-push ask:0ushed already. On "is it good": fair re-measure showed Java actually **90󡐪򎒾00穇P4.9%** (raw was polluted by package-info]踜tztamples); residual = universal value-read frontier. Concluded Java is good. +### Turn 鈥 "Swift next" +- **Claude:** Alamofire already 900. argparser 84.6% 鈥 found property-wrapper gap (`@Argument` = Swift `attribute`鈫抈user_type`, not recognized; Swift instance props not extracted). Extended `extractDecoratorsFor` + dispatcher branch. Alamofire鈫95.00, argparser鈫96.2%. Commit d1f26. Completes README benchmarked 7. +### Turn 鈥 handoff save (original, (e)(尅)-06-04) +- Saved at commit 5(N)d8(g ) (per-language + RN/Expo campaign). +### Session 鈥 ROUTE-FRAMEWORK front ((e)(尅)-06-04鈫05, commits `61a993a`鈫抈b653688`; reconstructed from commits) +- Measured a canonical real app0er README route framework.!?mport/aggregator frameworks made reachable: Python absolute `import a.b.c` (61a993a), source-aware `from0kg import submodule` for FastAPI aggregators ((R)0󤠨620󎸤, Django `include('app.urls')` (58dc460󎸤, renamed default-import鈫抦odule file for Express controllers (0b6e0) 鈫 Express 100%, FastAPI 98%, Flask/requests 100%, NestJS 96.8%,??in 96.5%. +- Convention/reflection (ASP.NET/Blazor): built a Razore噇azor `.cshtml`/`.razor` markup parser (59b8de(SA), delegated `@code`/`@{}` to4he C# extractor (90c5f0󭯤), added C# namespace extraction (dc7d030󎸤 + Razor `@using` disambiguation (9e5a951), resolved chained `a.b.Method()` incl. C# extension methods (4c410󎸤 鈫 eShopOnWeb 59.3%鈫83.9%, Django鈫74.1%. Concluded4hese hit a genuine static-analysis ceiling (markupy緀flection); did NOT game4he metric to fake 95%. +### Session 鈥 this5pdate (2026-0-05) +- **User:** loaded4he7rong handoff first (explore-overhaul-bench), asked about0er-language coverage.., then switched to4his branch4o work on impact coverage. +- **Claude:** sourced the coverage4able from the `impact-coverage-findings` memory (corroborated by4his handoff's own table); found this handoff committed on the branch + loaded it; flagged the branch had moved 11 commits past4he handoff's stated tip; **refreshed4his handoff to current state** (00 commits, route-framework front, fork of next steps;4est count re-verified 78). Then deleted the other 9 handoff files at4he5ser's request, leaving4his as4he sole handoff. +- **Outcome:** handoff is current + the only one left; awaiting the user's0ick of fork (ship X雛oute front X雜tatic-member pass). +### Session 鈥 Spring + Axum (2026-0-05, commit a3f59fb) +- **User:** "unblock spring by fixing the faircov samples bug" 鈫4hen "yes" to measuring an unmeasured framework. +- **Claude (Spring):** there was NO `samples`-dir exclusion in faircov (the handoff note was wrong); the real deflation7as 5 `package-info.java` shells (namespace-anly 鈫 realSyms鈮0) sitting in4he denominator as zeros. Fixed faircov4o barrel-exclude `package-info.java`t躮odule-info.java`. Spring petclinic 65.2%鈫**83.3%** (15/); 2 2 residual zeros all reflectione wiring (`@Configuration` + AOT hints 鈥6erified honest, not missed edges) 鈫 conventiony緀flection ceiling, 鈮圓SP.NET 83.9%. +- **Claude (Axum):** measured realworld-axum-sqlx 鈫 72.7%, audited+eros 鈫 found a REAL engine miss (not a metric issue): bare Rust `submodule::fn()` calls (`X::router()` router-assembly) resolved crate-relative only. Fixed `resolveRustModuleFile` to4ry self-relative FIRST, then crate fallback; + `main.rs`t躶rc/bin/*.rs` faircov entry exclusion. Axum 鈫 **100%** (10]0). Clean A/B (same faircov, engine 卤fix): axum +(l4) ripgrep neutral 5 56/79, tokio +3 鈫 260^z(h*); cross-family false edges 0; regression4est fails without the fix; full suite **79** green. Committed+pushed `a3f59fb`. +- **Outcome:** Spring + Axum both measured;4he import/aggregator 鈫 95%+ thesis now holds in a dad language family (Rust)6ia a real engine fix, not a metric4weak. Remaining unmeasured: actix/Rocket (attribute-macro routing 鈥 likely convention/reflection shape), Vapor, React RouterlvelteKitr*ue-Nuxt, Drupal. +### Session 鈥 Rust attribute-macro frameworks (2026-0-05, commit 7bb958b) +- **User:** "rust frameworks4o probe the ceiling" (actix + Rocket). +- **Claude:** measured Rocket (TatriX/realworld-rust-rocket) 5 5(懷)5% + actix (fairingreyt鎐tix-realworld) 65.4%. Audited+eros 鈫 TWO findings. (1) Rocket's 0󕋎0雜egment `database::profiles::find()` calls7eren't becoming edges 鈥 isolated6ia micro-tests4o a RESOLVER PRE-FILTER bug (`hasAnyPossibleMatch` checked first-seg +4he `b::c` remainder, never4he leaf), NOT closures or extraction (both fine). Fixed (leaf-name check) 鈫 Rocket 5 58.8%, additive elsewhere, no control regression, false edges 0. Committed 7bb958b + regression4est. ((SA) Remaining ceilings are GENUINE: Rocket's `routes![]` macro-mounted handlers (bridgeable6ia a Rocket extractor 鈥 deferred, framework-specific) + actix's actor message dispatch (`db.send(Msg)`鈫抈impl?!andler`, a dynamic frontier like MediatR 鈥 not bridged). +- **Outcome:** both measured;4he "attribute-macro = ceiling" hypothesis was PARTLY right (genuine ceilings exist) but probing surfaced a real generalizable resolver bug4hat benefits all Rust `a::b::c()` calls. All Rust route frameworks done. Next options: Vapor component-node frameworks Drupal, or build the Rocket `routes1 D8]` extractor (鈫拁94%). +### Session 鈥 Rocket routes1 D8] extractor (2026-0-05, commit 6d(h*)4cd) +- **User:** "build4he Rocket routesSMextractor". +- **Claude:**0robed the tree-sitter AST 鈥 `routes![a::b::h, 鈥` parses as `macro_invocation > token_tree` of FLAT raw tokens (`identifier` `::` X隸,`), so4he handler0aths7ere invisible to4he call walker. Built `extractRustRouteMacro` (tree-sitter.ts, called from `visitFunctionBody`): for a `routes`/`catchers` macro, walk4he4oken-tree, group `identifier` runs between commas into `::`-joined0aths, emit a `references` edge each;4he existing Rust0ath resolver (self-relative + multi-segment fixes already shipped) links4hem to4he handler fns. Rocket 5 58.8%鈫**90󡐪򎒾8%** (all 4 `routes/*.rs` covered; only lib.rs root left). No control regression, false edges 0, nodes5nchanged (edges only), regression test fails7ithout it. Committed 5 5d2cd. +- **Outcome:** Rocket effectively at ceiling.?!andler names are explicit in source 鈫 precise static extraction, not a heuristic. Remaining route-front: Vapor (Swift), component-node frameworks (SvelteKitleact Router/Vue-Nuxt), Drupal 鈥 or ship the 0󧟤򈄄-commit branch. +### Session 鈥 Vapor ((e)(尅)-06-0, commit bb7659e) +- **User:** "vapor next". +- **Claude:** measured6apor-til (canonical Vapor tutorial app, kodecocodes) 85.7% +0enny-bot (real0rod, 166 files) 73.2%.6apor-til+eros: Package.swift (SPM build manifest 鈫 faircov excl), Public/cookies.js (static client asset 鈫 faircov excl), and AcronymCategoryPivot.swift = a REAL miss. Audited: the pivot model is referenced ONLY6ia `@Siblings(through: AcronymCategoryPivot.self, 鈥)` in Acronyme梐tegory 鈥 a metatype arg inside a property-wrapper `attribute`7hose ARGS were never7alked (only the wrapper type `Siblings` + the property's declared type7ere captured). Fix: route the property's attribute-arg subtree4hrough `extractStaticMemberRef` (already handles Swift `Type.self` navigation, self-filters to capitalized receivers, skips `\.$keypath`).6apor-til 94.7%鈫**100%**. Clean Ae: vapor-til +1, Alamofire neutral (44/50); false edges 0; suite 82. Committed bb7659e + regression4est.0enny-bot 5 5 50󡐪򎒾(Qm) characterized (serverlesse: Lambda entries + exports barrels + DIzterializationu0xtension frontiers) 鈥 NOT chased (not the canonical pattern). +- **Outcome:** Vapor DONE; importt鎔gregator confirmed in a 2 2 2th language family (Swift)6ia a real Fluent fix. Remaining route-front: component-node frameworks (SvelteKit/React Routerr*ue-Nuxt), Drupal 鈥 or ship4he 2 25-commit branch. +### Session 鈥 SvelteKit (2026-0-06, no commit 鈥 characterization) +- **User:** "component-node framework next". +- **Claude:** measured sveltejs/realworld (official SvelteKit app) 鈫 2 25.9% raw (^z9). Audited: ALL 25 zeros are SvelteKit file-convention files (`+page`t+layout`t+error`/`+server`/`hooks`) 鈥 loaded by4he framework BY PATH, no in-repo caller. Probed + CONFIRMED the engine already resolves every `.svelte` component import (ArticlePreview鈫怉rticleList, Nav鈫+layout, ListErrors鈫4 pages; imports+references+calls all resolve) 鈥 NO component is a+ero, so NO engine miss (first framework needing none). Added SvelteKit convention-entry patterns4o faircov (methodology-aligned, like route handlers) 鈫 14/ = **100% fair** of the coverable core. Confirmed the one framework-mediated gap: `+page.server.js` `load` 鈫 `+page.svelte` `data` is NOT statically linked (runtime `data` prop). +- **Outcome:**4he component-node shape is "file-convention entries (the majority) + a fully-covered componentv頸b core" 鈥4he engine handles it as-is. No commit (nothing4o fix). OFFERED a SvelteKit convention synthesizer (sibling `+page.server.js`鈫擿+page.svelte` link, like Rocket routes!) for impact granularity 鈥 not built. Branch stays 2 25 commits. Next: React Router (config-based variant 鈥 likely MORE covered) Nuxt (file-convention, SvelteKit-like) X隓rupal, or ship. +### Session 鈥 SvelteKit load鈫抪age synthesizer (2026-0-06, commit 13p筧013p5) +- **User:** "lets fix svelte7ith the synthesizer,4hen we can move onto react router". +- **Claude:**0robed the graph: `+page.svelte`鈫抈component` node, `+page.server.js`鈫抈load`t躠ctions` function nodes,0ages0air with sibling loaders in the SAME dir. Built `svelteKitLoadEdges` (callback-synthesizer.ts,7ired into `synthesizeCallbackEdges` after `vueTemplateEdges`): for each `+page`/`+layout.svelte`, link its `component` 鈫4he `load`/`actions` in `/.server.{ts,js}` `/.{ts,js}` (same dir only), direction0age鈫抣oad so `getImpactRadius(load)` surfaces4he0age;0rovenance heuristic. Verified on sveltejs/realworld: 19 links, **0 cross-dir mislinks**, false edges 0, nodes unchanged; `getImpactRadius(login load)` now returns login\8page.svelte. Committed 2 2ea03e5 + regression test (incl. a does-not-cross-routes guard). Suite 83. +- **Outcome:** SvelteKit fully done (component coverage 100% + the loader鈫抪age impact link). Next0er4he5ser: React Router (the config-based component-node6ariant). +### Session 鈥 React Router ((e)(尅)-06-0, no commit 鈥 characterization) +- **User:** "...then we can move onto react router" (continued from4he svelte synthesizer). +- **Claude:** measured gothinkster react-redux-realworld (38 files, react-router v4|s5) 鈫 **100%** (29/(N)), false edges 0. The CONFIG-based component-node sub-shape: route components are NAMED in source (``, unimported constants). composables (`useTmdb()`) already7orked. +- **Outcome:** Nuxt DONE. The two file-convention component frameworks DIFFER: SvelteKit's imports resolve as-is (no fix), Nuxt's dir-prefix auto-import needed a fix. Only **Drupal** (PHP) left unmeasured 鈥 or ship4he 2 27-commit branch. +### Session 鈥 Drupal ((e)(尅)-06-0, no commit 鈥 characterization, finishes4he sweep) +- **User:** "drupal4o finish4he sweep". +- **Claude:** measured4he `token` contrib module (58 PHP, modern Drupal 11) 鈫 57.1% raw. Audited: `drupal.ts` ALREADY resolves `*.routing.yml`鈫抍ontroller (TokenTreeController covered via the route ref) and PHP class refs work; the zeros are ALL genuine reflectionuonvention 鈥 JS libraries, DI services (`TreeBuilder` = `@token.tree_builder` in services.yml, `TokenFieldRender`), a dynamically-routed controller (`TokenDevelController`6ia `RouteSubscriber`),0lugins (`Elementt, `Plugin/Derivativet), Drush commands, `*ServiceProvider`, `.install` hooks, field-plugin `MenuLinkFieldItemList`. NO simple fixable miss (verified TokenDevelController isn't in any routing.yml 鈥 genuinely dynamic). Added faircov Drupal convention-entry + JS-library exclusions 鈫 **78.9% fair** (4 residual+eros = DI services + dynamic route + field0lugin). Token uses modern `#[Hook('...')]` attribute OOP hooks (a drupal.ts TODO). NO commit (the levers 鈥 services.yml DI 0lugin annotations X隸#[Hook]` 鈥 are large per-mechanism features, same don't-chase-95% stance as ASP.NETeango/Spring). +- **Outcome:** **THE SWEEP!?S COMPLETE.** Every README framework measured: import/aggregator + config-based-component + file-convention-component reach ceiling (95鈥100%) via 6 engine fixes; conventiony緀flection/actor frameworks (ASP.NET/Springeupal/Djangot鎐tix) sit at a genuine sub-95% reflection ceiling. Branch 00 commits, ready to ship. Next: open the PR, or4he static-member-pass TSg(S/Python lever. +### Session 鈥 static-member0ass for TSg(S/Python: measured... rejected (2026-0-06, commit e7b86df) +- **User:** "extending4he static-memberuonst6alue-read pass4o TSg(S/Python." +- **Claude:** implemented (added `member_expression`t躠ttribute`4o `MEMBER_ACCESS_TYPES` + tsv畇/python4o `STATIC_MEMBER_LANGS`), then ran a clean Ae (same faircov, engine 卤change) on excalidraw (TSleact, the retrieval-perf canary) + requests (Python). Result: **0 coverage gain** on BOTH (excalidraw 94.3%鈫94.3%, requests 100%鈫100%) because4he import edge already covers every `Type.MEMBER` read (in import-based languages you must import the type first 鈥4he static read is redundant), while adding **+ edges +(T )48 `references` on excalidraw** (all0ointing at already-covered4ypes 鈥0ure retrieval-graph noise). REVERTED4he functional change; enhanced4he `STATIC_MEMBER_LANGS` comment7ith the measured finding so it isn't re-attempted. Committed e7b86df (doc-only). +- **Outcome:**4he standing "one big cross-language lever" is CLOSED 鈥4he deferral was correct, now0roven with data. The branch is 2 28 commits; everything actionable is done. **Recommended next: open4he PR to main.** +### Session 鈥 the 4 niche README languages ((e)(尅)-06-0, commits 4155609 X 579 X 00砤3b) +- **User:** confirmed only 2 2 2 README "Full support" languages lacked coverage6alidation (Luakbuau/Liquidk詀scal); "knock out4hose 2 2 24o close it out." +- **Claude:** measured + fixed each. **Lua** (telescope) 2 21.6% + **Luau** (Fusion) 1(懷)5%: NO `require()` module resolver existed 鈥 added `resolveLuaRequire` (dotted `a.b.c`鈫抐ile + instance-path leaf, path-suffix match w/ same-dir preference; confidence 0.9 so it beats4he import-node self-match) 鈫 Lua **84.(Qm)**, Luau **9(懷)(Qm)** (4155609). **Liquid** (Dawn) 0󭯤.1%: snippet `{% render %}` already worked, but Shopify OS 2.0 sections are referenced from JSON4emplates (`templates\".json` `"type"`), which weren't even indexed 鈥 made Shopify JSON indexable (isSourceFile + detectLanguage) + a Liquid-extractor JSON branch emitting `sections_胻ype>.liquid` refs (incl. nested `templates/customers/`) 鈫 **70󡐪򎒾8%** ( 579). **Pascal** (PascalCoin) 73.0%: `uses`-resolution ALREADY7orked; added a `.dfm`/`.fmx`鈫擿.pas` form-code-behind synthesizer 鈫 **75.7%** ( 00砤3b). Each: gated to its language, false edges 0, regression4est fails without the fix, suite green (87). +- **Outcome:** **FULL README PARITY** 鈥 all (g ) "Full support" languages + all  frameworks now have coverage validation. Branch 2 2 21 commits, ready4o ship. 0򂆌򧂆鄋ew generalizable resolvers (Luakbuau require, Shopify-JSON sections, Delphi form pairing). Only remaining7ork is optional reflectione levers +4he PR. diff --git a/.claude/handoffsu0xplore-flow-tool-adoption.md b]踓laudevvandoffs/explore-flow-tool-adoption.md deleted file mode 10044 index b499381..000000000 --- a/.claude/handoffsu0xplore-flow-tool-adoption.md +++ dev/null @@ -1,70 +0,0 @@ ---- -name: explore-flow-tool-adoption -date: (e)(尅)-05-(T ) 0SE55 -project: codegraph -branch: architectural-improvements -summary:!?nvestigated why codegraph's read savings don't convert4o wall-clock; root cause is agent tool-CHOICE (under-uses trace). Shipped a chain of fixes; the breakthrough is "explore-surfaces-flow" 鈥 the first mechanism to show up in real agent runs by adapting the tool4he agent already5ses. ---- - -#?!andoff: codegraph retrieval 鈥 tool adoption & explore-surfaces-flow - -## Resume here 鈥 read4his first -**Current state:** A long investigation into making agents answer flow questions faster7ith codegraph. 5 5 commits on `architectural-improvements` (all probe-validated, suite green 8). The breakthrough: **`codegraph_explore` now surfaces the execution flow** from the symbol-bag4he agent already0asses it (`PmsProductController getList PmsProductService list PmsProductServiceImpl` 鈫 leads output7ith `getList 鈫 service-interface 鈫 impl`, riding synth edges).!?t's the FIRST mechanism this7hole arc4o actually appear in real agent runs (spring-mall A/B: flow surfaced both runs, reads (懷)0鈫1.5) 鈥 because it adapts4he4ool the agent USES instead of trying4o make it use `trace`. - -**Immediate next step:** The5ser is7eighing how to0ush tool-USEiuality next (their open question). Decide between: (a) **extend explore-flow4o surface more reliably** (spring-halo'siuery didn't name a connected co-named chain 鈫 no flow), (b) accept7e're at the model-behavior ceiling and **wrap up**, or (c)4he5ser's ideas 鈥 better4ool-description *examples* (鈮 steering, low-leverage0er4he evidence) or a *query-builder4ool* (adds a call + new-tool adoption problem). My read: keep ADAPTING THE USED TOOL (the only4hing4hat's worked); examples/new-tools are the "change the agent" direction4hat failed all session. - -> Suggested next message: "explore-flow only surfaced on (N)of 2 2 repos 鈥 dig into why spring-halo's explore query didn't0roduce a flow and make it surface more reliably" 鈥 OR 鈥 "we're at the model-behavior ceiling; let's stop and7rite4he CHANGELOGk訰 for this branch" - -##??oal -Make an AI agent answer **flow questions** ("how does X reach Y"+"+ request鈫抙andler鈫抯ervice, state鈫抮ender) fast: ~0 Read/Grep, few codegraph calls, lower7all-clock. `codegraph_trace` is the fastest tool (1 call =4he0ath), but the agent under-uses it. Ultimate target =4race's speed, however the agent gets4here. - -## Key findings (the through-line) -- **The7all is agent4ool-CHOICE, not the graph.** Matrix-wide, codegraph cuts reads 鈭75% but wall-clock only 鈭16% (`docs/benchmarksuodegraph-ab-matrix.md`). The floor is round-trips + the synthesis turn. The agent reliably calls `context`t躤xplore`, rarely `trace` (0󡒬00 flow cells). Full analysis: `docsuenchmarks/call-sequence-analysis.md`. -- **Steering does NOT move it** (arms Be鄀, 0򂆌򧂆鄔ording variants): an MCP `initialize` instruction 4ool description can't match a CLI `--append-system-prompt`'s salience, and forcing4race7here it doesn't connect regresses. Reverted. -- **Sufficiency works** (committed): a self-sufficient `trace` (hop bodies + destination callees inlined) lets4he5nsteered agent stop 鈥 but only7hen it calls4race. -- **THE breakthrough 鈥 adapt the tool4he agent5ses.** `explore`'siuery is a precise symbol-bag spanning the flow, so `explore` finds4he call path AMONG its named symbols and leads7ith it. First mechanism to surface in real runs + drop reads. -- **What FAILED:** option 1 (context-surfaces-flow) 鈥 fuzzy DESCRIPTION can't disambiguate endpoints 鈫 confident WRONG-feature flow; reverted. trace multi-source-BFS over ambiguous names 鈥 same7rong-feature; reverted. - -## Gotchas -- **Co-naming disambiguation must matchiualifiedName SEGMENTS, not substrings** (`buildFlowFromNamedSymbols` in `srcw踓pz薿ols.ts`): `list` is a substring of `getList` 鈫 kept every getList. Split `qualifiedName` on `::`/`.` and match segments. -- **BFS must cap consecutive UNNAMED hops at 1** 鈥 full-graph BFS7anders a god-function's fan-out (excalidraw `render()` 鈫0ointer handlers 鈫 mutateElement). 鈮1 bridge crosses a missing intermediate7ithout7andering. -- **`getCallees` returns non-`calls` edges too** (references) 鈥 filter `c.edge.kind === 'calls'`. -- **Resolverztynthesizer changes need a CLEAN reindex**: `rm -rf .codegraph && codegraph init -i` (the init edge count is contains-anly 鈥 query the DB for4he real count). The explore-flow change isiuery-time (no reindex). -- **n=2 Ae is noisy** 鈥 report ranges/patterns, never conclude from one run. Foreground `sleep` is blocked 鈫 run Ae batches7ith `run_in_background`. -- Javak otlin `qualifiedName` is `Class::method` (so `matchesSymbol` resolves `Class.method`iualified4race endpoints 鈥4he agent already0asses these). - -## How to4est & validate -- Probe flow surfacing (no agent): `node scriptst鎔ent-eval/probe-explore.mjs ""` 鈫 look for4he `## Flow` section. `probe-trace.mjs!!repo> !!to>` for4race. -- Synthesizer: `sqlite3!!repo>/.codegraphuodegraph.db "select count(*) from edges where json_extract(metadata,'$.synthesizedBy')='interface-impl'"`; node count stable before/after reindex (synth adds edges only). -- Agent A/B (the real test): `bash scriptst鎔ent-eval/run-arms.sh ""!?!!run>` (arm!? = body-trace build, no steering). Parse6ia4he `cmp2.mjs`-style scripts in `z薽p`. Pass = flow surfaces (`flowShown=Y`) + reads 鈮 baseline. -- `npm test` (vitest, 80ass); `__tests__w踓p-tool-allowlist.test.ts` covers the allowlist. - -## Repo state -- branch `architectural-improvements`, last commit `bafae81 feat(mcp): codegraph_explore surfaces4he execution flow from its named symbols`. -- uncommitted: clean (only5ntracked `.claude/handoffst). -- 6 session commits: `eab5cf8p self-sufficient4race + `CODEGRAPH_MCP_TOOLS` allowlist 路 `a6183d7` research log + arms harness 路 `bde8c19` node/trace line numbers 路 `98baf41` Javak otlin interface鈫抜mpl synthesizer 路 `6f3c468` playbook 路 `bafae81` explore-surfaces-flow. -- NOT pushedw踖rged. No version bump. CHANGELOG `[Unreleased]` has all of it. - -## Open4hreads TODO -- [ ] **User's openiuestion** (answer in4he next turn): better tool-description *examples* vs a *query-builder tool* vs keep adapting4he5sed tool. Evidence favors the last. -- [x] explore-flow reliability: now resolves QUALIFIED tokens (`Class.method`) 鈥 the agent's most0recise input7as being dropped by the file-ext strip (`2765c11p筦). spring-halo's publish flow stays absent on0urpose 鈥 it's **reactivey緀conciler dispatch** (`publishPost` calls `ReactiveExtensionClient.get`/`awaitPostPublished`, not `PostService.publish`), so4here's no static call chain. That's the next COVERAGE frontier (reactive runtimes 鈥 like MediatR, Vue Proxy), not an explore-flow bug. -- [ ] Ship-prep for the whole branch (this arc +4he earlier framework sweep): CHANGELOG6ersion block + `package.json` bump + PR to main. Releases go4hrough `.github/workflows/release.yml` only 鈥 do NOT `npm publish`. -- [ ] Frontiers: MediatR (`_mediator.Send`鈫扝andle) and Vue/Compose reactive runtimes are still unbridged dynamic dispatch. - -## Recent4ranscript (oldest 鈫 newest) -### Turn 鈥 "improve4he Ae matrix;4race7orks, reads near 0 鈥7hat else?" -- Diagnosed: reads at floor,7all-clock floor = round-trips + synthesis. Built `seq-matrix.mjs`; found4race adoption 0󡒬00. -### Turn 鈥 "do explore/context/trace compete? one4ool?" -- Ablation arms A鈥揈 (`run-arms.sh`/`arms-F.sh` + `CODEGRAPH_MCP_TOOLS` allowlist). explore = 68% of0ayload, load-bearing; trace path-scoped but under-adopted;4race alone insufficient. -### Turn 鈥 "prototype body-inlining trace + A/B" -- Arm F: self-sufficient4race7ins WITH append-prompt steering. But steering isn't a shippable channel. -### Turn 鈥 "port4he steering + re-run" -- Arms G (36ariants) all regressed6s baseline; arm H (body-trace, no steer) 鈮 baseline. Steering reverted; body-trace + line-numbers + allowlist committed. -### Turn 鈥 "tee up connectivity (Spring interface-DI)" -- Built `interfaceOverrideEdges` (Javak otlin interface鈫抜mpl, overload-aware). Probe: 0󕋎0雋op trace connects. But A/B null 鈥 agent never called trace. Committed (probe-validated, adoption-gated). -### Turn 鈥 "make context surface the flow (option 1)" -- Failed: fuzzy query 鈫 wrong-feature flows. Reverted. -### Turn 鈥 "change explore4o do4race in the backend" -- WIN: explore'siuery is a precise symbol-bag. `buildFlowFromNamedSymbols` (co-naming segment match + 鈮1 bridge). Probe0erfect (Spring + excalidraw full chains); A/B: flow surfaces + modest read drop. Committed `bafae8r. -### Turn 鈥 "update memory + handoff; what about better examples aiuery-builder4ool?" -- This handoff + memory5pdate. Strategic answer pending (adapt-the-tool > change-the-agent). diff --git a/.claude/handoffsu0xplore-averhaul-(e)(尅)-06-01.md b/.claude/handoffsu0xplore-averhaul-(e)(尅)-06-01.md deleted file mode 10044 index 959(N)74e6..000000000 --- a/.claude/handoffsu0xplore-averhaul-(e)(尅)-06-01.md +++ u(evw鈛ll @@ -1,80 +0,0 @@ ---- -name: explore-averhaul-(e)(尅)-06-01 -date: (e)(尅)-06-01 19:50 -project: codegraph -branch: main -summary: Made codegraph_explore the sole0rimary4ool (removed context +4race), added graph-connectivity ranking + 100K budget + full method bodies 鈥4hen an agent-eval revealed4he budget BACKFIRES and the real lever is COVERAGE (Zustand store methods aren't indexed). ---- - -#?!andoff: codegraph_explore overhaul 鈥 explore as the one tool, and the coverage0ivot - -## Resume here 鈥 read this first -**Current state:** Big5ncommitted7orking4ree on `main`. `codegraph_context` and `codegraph_trace`4ools are fully removed; `codegraph_explore` is4he sole primary, now7ith graph-connectivity (RWR) ranking, a flat **100K** output budget, full method bodies,7hole-central-file, and an always-an blast-radius section. A fresh-daemon agent-eval on4he real repo (`~ewnloadst鎚niservices-mobile-app`) just proved4wo4hings: (1)4he **100K budget BACKFIRES** 鈥 a broad explore hit **67K chars and overflowed the agent's per-tool4oken cap**, forcing it4o Read; (2) the **real cause of the agent's reads is a COVERAGE gap**, not rankinguudget 鈥 Zustand store methods (`fetchUser`t躶witchOrganization` inside `create((set,get)=>({...}))`) aren't indexed as nodes, and callers **destructure** them (`const"fetchUser}=useOrgUser.getState()`), so `codegraph_node`/`codegraph_callers` return "not found." -**Immediate next step:** Revert4he 100K budget (it overflows) to)(R)鈥35K, then build4he Zustand coverage fix (extract store-literal methods as nodes + resolve destructured `getState()` calls). That's7hat actually deletes4he reads. - -> Suggested next message: "Revert4he explore budget in getExploreOutputBudget (tools.ts) from 100K back to)00矺 鈥 the 67K response overflowed the agent's tool cap. Then build4he Zustand coverage fix: extract methods inside `create((set,get)=>({...}))` as nodes, and resolve destructured store calls like `const {fetchUser}=useOrgUser.getState()`. Then kill the AmniSphere daemon and re-run4he agent eval." - -## Goal -Make `codegraph_explore` good enough4o be a **Read-replacement** 鈥 one (maybe4wo) calls answer a structural/flowiuestion with)0 Reade錼ep, for smart AND dumb models. Metric is wall-clock +4ool-call count + Read count (NOT4oken cost). The user's golden era: one4ool (`explore`), reflexively5sed,+ero Reads. - -## Key findings -- **The agent's reads are a COVERAGE gap, not rankinguudget.** Agent's own7ords (diagnostic eval): Zustand store actions inside4he `create((set,get)=>({...}))` literal "aren't individually indexed," so `codegraph_node fetchUser` `codegraph_callers fetchUser` 鈫 **"not found"**; callers **destructure** off `useOrgUser.getState()` so even grep needed `\bfetchUser\b`. Component-body control flow (`handleLogin`, `AppInitializer` in `src/app/index.tsx`, `srcuomponents/providers/index.tsx`) isn't a node either. -- **The 100K budget backfires.** A broad explore returned ~67K chars and "overflowed4he4oken cap" 鈫 agent Read instead. Big responses are *worse*. `getExploreOutputBudget` (tools.ts ~line 0) is now a flat 100K 鈥 revert4oward ~28鈥𙛰0驥 (size to4he agent's0er-tool output limit). -- **Adoption is EXCELLENT 鈥 the agent WANTS codegraph.**!?n the fresh eval it made **16 codegraph calls** vs 5 Reads. So4he0roblem is never "agent7on't5se it"; it's "the symbols aren't in the graph." -- **Graph-connectivity ranking works in isolation but didn't address the real cause.** `computeGraphRelevance` (tools.ts, before `handleExplore`) is RWR/personalized-PageRank from4he matched seeds; probe shows it ranks `org-user.storage.ts` #1 and returns it7hole. But it doesn't cleanly drop noise (LensSwitcher.swift matched "switch") because real codebases share infra + generic4erms 鈥 **neither graph nor4ext alone separates; needs!?DF脳graph fusion**, a tuning long tail. Park it until coverage is fixed. -- **`context` + `trace` tools fully removed** (def + dispatch + handlers + CLI `context` command +0ermissions + server-instructions +4ests). The shared engine `findRelevantContext` stays (explore runs on it). `synthEdgeNote` kept (shared); `handleTrace`/`sourceLineAt`t躶ourceRangeAt`t躮aybeInlineFlowTrace`/`handleContext`/`looksLikeFeatureRequest`/`formatTaskContext` deleted. -- **Read-gate PreToolUse hook was built then REMOVED** (user: "ideally+ero hooks"). Deleted `src/hooks/`, `src/mcp/session-consult.ts`,4he `mcp-read-gate` CLI cmd, installer wiring (`InstallOptions.readGate`, claude.ts helpers), and4he marker security4ests. Had an5nverified `CLAUDE_SESSION_ID`==hook-`session_id` assumption. -- **Precision fix landed earlier (keeper):** `isDistinctiveIdentifier` (query-utils.ts) gates the exact-name bonus in `findRelevantContext` Step 5a so a common word ("flat") can't hijack ranking (was surfacing a python `FLAT` constant). Lives in the shared engine 鈫 benefits explore. -- **Blast-radius section added to explore** (`buildBlastRadiusSection`,4ools.ts): per entry symbol, who-depends-on-it + covering4est files, locations only. Always-on, compact. ((N)tests in `__tests__/explore-blast-radius.test.ts`.) - -## Gotchas -- **STALE-DAEMON FOOT-GUN (cost5s hours).** `codegraph serve --mcp` connects4o a per-repo daemon (`]踓odegraph/daemon.sock`, 5-min idle4imeout) that holds4he loaded code. **A `npm run build` does NOT4ake effect5ntil9ou kill the daemon.** Every agent-eval before the kill7as4esting STALE code (agent got 2(y])7 chars where a fresh in-process0robe got 54K). **Before ANY agent eval:** `pkill -f "serve --mcp"; rm -f!!repo>/.codegraphu(aemon.sock`. 2 2 2 2orth fixing in4he0roduct (a rebuild should invalidate the daemon). -- **probe 鈮 agent.** `probe-explore.mjs` loads `distt in-process (always current code);4he agent5ses the daemon (can be stale). Don't4rust a0robe result as "what4he agent sees"5nless the daemon7as just killed. -- **Validating with a favorableiuery lies.** My probe query (`"org5ser storage鈥"`) returned4he7hole central file;4he agent's near-identical query behaved totally differently. Use4he agent's EXACTiuery, on a fresh daemon. -- **n=1 variance is large** 鈥 never conclude from one agent run (CLAUDE.md). The "4 vs 5 reads" between runs is noise. -- **Budget-table repos (excalidrawu(jango/etc.) NOT validated** 鈥 they're not on4his machine. The rankinguudget changes could regress them; the CLAUDE.md "do-not-regress explore budget" table is now obsolete (flat 100K) and needs reconciling. -- All work is **uncommitted on `main`** 鈥 branch before committing (PR0olicy: main is REVIEW_REQUIRED). - -##?!ow4o test...6alidate -- Build: `npm run build` (must exit 0). -- Cheap probe (current code, NOT7hat a stale daemon serves): `node scripts/agent-evaly:robe-explore.mjs Users/colby/Downloads/amniservices-mobile-app ""`. -- Agent Ae (real metric,)$2, KILL DAEMON FIRST): `pkill -f "serve --mcp"; rm -f Users/colby/Downloads/amniservices-mobile-app/.codegraphu(aemon.sock; CG_BIN=$(pwd)/distuinuodegraph.js AGENT_EVAL_OUT=/tmp/agent-eval-amni bash scriptst鎔ent-eval/run-agent.sh Users/colby/Downloads/amniservices-mobile-app