Repository navigation
Description
Evaluated repowise 0.42.0 (self-hosted, AGPL, pip install repowise) against this repo on 2026-08-15, including a full-history index (all 3,464 commits), health, the web dashboard, and a real coverage ingestion. Decision: not integrating now. Revisit when the C++ symbol graph is trustworthy. This issue holds the evidence so the evaluation is not repeated from scratch.
What works well enough to use today
- Co-change analysis — the one that paid for the exercise. It surfaced that
OloEditor/src/Panels/SceneHierarchyPanel.cppcarries 95 hand-maintainedDrawComponent<T>rows + 94DisplayAddComponentEntry<T>entries and was missing fromCLAUDE.md's cross-binding checklist (it was mentioned only in the undo/redo section). Skipping it is a silent failure — the component round-trips through scene YAML and save-games perfectly and is simply invisible in the editor. Checklist since fixed. - Code health (CCN / nesting / NLOC) — computed per-function from the AST, so none of the graph problems below apply. It carries its own predictive-validity check, which measured 19/20 lowest-health files had a bug fix in the last 6 months, 3.19× the 30% baseline, after coverage was ingested.
- Duplication / Extract-Helper plans — concrete line ranges, cheap to verify.
What is not usable on this codebase
dead-code/get_dead_code— sampled 40 findings at confidence 1.00 withsafe_to_delete: true; 40/40 were false positives, six hand-verified. It reportedSAVE_COMPONENT(118 real call sites) as safe to delete, plus everyHandle_*MCP tool handler and the entire C#ScriptGlueinterop layer.- The symbol graph itself — both incomplete and unsound. It misses real edges (a call to a header-declared function attaches to the declaration, orphaning the
.cppdefinition) and invents false ones (astaticTU-local function reported asused_bytwo files containing zero occurrences of its name). bug_magnets— effectively a 2026-only signal:is_fixis detected from commit messages, and 386 of 430 detected fix-commits are in 2026, when conventional-commit prefixes were adopted. Extending to full history added churn but almost no new fix signal.hotspots— recency-biased; files with 3 commits get flagged at churn percentile ~0.89.
Why not wire it into the agent loop
Of its ten MCP tools, the ones an agent naturally reaches for (get_dead_code, get_context, get_symbol, get_risk) are graph-derived, and the graph fabricates edges. A missing capability makes an agent grep; a confidently-wrong one makes it reason from fiction. Given this repo already has a deep CLAUDE.md, the docs/agent-rules/ corpus, a working MCP diagnostics server and SonarQube, the marginal value is low and the downside is real.
Revisit trigger
Filed upstream with minimal repros; re-check these before re-evaluating:
- repowise-dev/repowise#1601 — header declaration steals the call edge (the big one — explains most of the false positives)
- repowise-dev/repowise#1600 —
.inlnot a recognised C++ extension; also silently drops ingested coverage for those files - repowise-dev/repowise#1602 — function-pointer and macro-argument references not counted as uses
- repowise-dev/repowise#1603 —
initwrote project-local.mcp.json/.vscode/with no opt-out (already fixed on theirmain; the.mcp.jsonreflow half remains open)
Re-evaluate when #1601 and #1602 are released, since together they cover the bulk of the false positives. #1600 is cheap for them and would also unblock coverage for our 13 generated .inl files.
If revisited, the shape to aim for
- Keep it a CLI / dashboard tool invoked deliberately; do not register the MCP server in
.mcp.jsonuntil the graph is trustworthy. - Re-index per-milestone, not continuously — co-change and health go stale slowly.
- Do not run it in worktrees:
.repowise/is ~390 MB per checkout and auto-seeds into each new worktree, against ~48 GB free onE:. .repowise/andcoverage/are gitignored as of this issue.
Incidental win, independent of the decision
The evaluation produced a working C++ coverage pipeline: OpenCppCoverage (no instrumented rebuild — it reads the existing Debug PDBs) run over the full 5,811-test suite in six resumable chunks, merged to Cobertura. Baseline 59.6% line coverage (108,713 / 182,316 lines, 1,255 files). Script at scripts/ is not committed yet — worth doing separately if we want this repeatable, since nothing in the repo could answer the coverage question before.
Score
capability: 3
craft: 1
stability: 3
decay: 1
effort: 3
confidence: 0.5
learning: 3
fun: 3
kano: delighter
blocked_by: []
blocks: []
blocked_by_external: ["repowise-dev/repowise#1655 - used_by built from header/impl pairing (open)", "repowise-dev/repowise#1601 member-function call edges (comment 5313639721)"]
scored: 2026-10-15
Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort, derived by the picker.
Scoring notes: decay 1 because waiting is actively cheaper here — the blocker is upstream maturity, so the cost of delay falls rather than rises. confidence 0.5 because delivery depends entirely on fixes outside our control. blocked_by deliberately left empty rather than pointing at cross-repo issues, since the rank renders it literally and never rechecks it.
Activity
coderabbitai commentedon Aug 16, 2026
🔗 Related PRs
#334 - MCP: per-worktree discovery-file isolation + skill auto-attach (
#316… [merged]#419 - chore(sonar): fix analysis scope (
#411items 2,4) + code-review rule alignment [merged]#678 - feat(mcp): audience-tagged content blocks + Tier 3 runtime-endpoint ADR (
#673) [merged]#788 - docs+workflow: halve CLAUDE.md, index agent-rules by failure mode, batch the PR loop, add a build mutex [merged]
#790 - feat(mcp): dual-era outbound client + a
logging-deprecation offramp carrier (#777) [merged]🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
docs(claude): add SceneHierarchyPanel to the cross-binding checklist
drsnuggles8 commentedon Aug 16, 2026
Looks like master/main fixed most of my initial problems, should revisit it tomorrow
drsnuggles8 commentedon Aug 17, 2026
Re-evaluation, 2026-08-17 — still deferred; the revisit trigger needs rewriting
Re-ran the evaluation against upstream
main. Verdict unchanged: do not integrate, do not register the MCP server. The headline false positives from the original evaluation are gone from the output, but they left for the wrong reason, and the bug that actually blocked us is untouched.The trigger fired on paper, not in fact
All three C++ graph issues are fixed and merged, but not released:
.inl/.ipp/.tppnot C++v0.43.0shipped 2026-08-15 17:50Z — before all three.mainis 35 commits ahead of the tag. So this was tested by installinggit+https://github.com/repowise-dev/repowise@maininto a throwaway venv, not a release.--no-editor-setupnow exists (the #1603 opt-out), and it worked: no tracked file was modified.Index: 2,665 files, 39,483 symbols, 124,116 edges, 10m27s (
--mode fast).Sampled false-positive rate: 30/40, down from 40/40
Random sample (seed 815) of 40 findings with
safe_to_delete: trueandconfidence: 1.00, from a population of 460. Each hand-verified.The 10 true positives were all genuine "declared in the header, defined in the .cpp, never called" — e.g.
SoundGraphCache::Has,ReadU32Array, fourFGenericPlatformMemoryplatform stubs.So #1601 appears fixed for free functions and still broken for member functions, which is where most of our code lives.
s_ClientDriver.AttachTo(*client, *scene)inNetworkManager.cpp:556is engine code, not a test, and is still not counted.The improvement is not what it looks like
The two cases named in the original evaluation —
SAVE_COMPONENTand theHandle_*MCP handlers — are gone from the dead-code output. Neither is a real fix:SAVE_COMPONENTappears in 9 files, includingSaveGameSerializer.cppand the generatedSaveGameComponentCapture.Generated.inl. repowise reports exactly oneused_by:SaveGameSerializer.h, which contains zero occurrences. All 9 real sites are still missed.Handle_AssetsListis used atMcpToolsAssets.cpp:157(tool.Handler = Handle_AssetsList;), in its own file. repowise misses that and reportsused_by: McpServer.cpp, which contains zero occurrences.Both dropped off the
safe_to_deletelist because a fabricated edge made them look reachable. The FP rate improved partly by the graph being wrong in the opposite direction, which makes the rate itself a poor measure of progress.The blocker was never filed — and it reproduces 9/9
#815 originally recorded that the graph "invents false ones (a
staticTU-local function reported asused_bytwo files containing zero occurrences of its name)." That was never filed upstream; #1600–#1602 are all about missing uses, not invented ones.Every
used_byedge checked this run is fabricated — 9 for 9, zero correct:used_byVkCheckVulkanRendererAPI.h,VulkanBufferResources.h,VulkanBindingState.hPerezRowProceduralSky.hSingleChannelImageModel.h,ModelImporter.hWorldStateHashGoapPlanner.hSAVE_COMPONENTSaveGameSerializer.hHandle_AssetsListMcpServer.cppThe shape is consistent: a use is attributed to the header paired with the defining
.cpp(or to a file that includes it), whether or not the symbol is named there. This is the mirror image of #1601 — that one moved the edge onto the declaration, this one attributes it at file granularity via the include graph rather than by an actual reference.This is the bug that made
get_context/get_symbol/get_dead_codeunsafe for an agent, and it is exactly as bad as it was in August. A missing edge makes an agent grep; a fabricated one makes it reason from fiction.Revised revisit trigger
The old trigger ("re-evaluate when #1601 and #1602 are released") is now wrong — it would have told us to integrate. Replace it with all of:
used_bybug is filed and fixed. Not yet filed — needs an isolated repro first, per our own standing rule.v0.44.0can).Until then: unchanged guidance — CLI/dashboard only if used at all, no
.mcp.jsonregistration, don't run it in worktrees. Co-change and per-function health remain the sound parts; this run reproduced the health signal at 20/20 lowest-health files had a bug fix in the last 6 months, 3.4× the 29% baseline.Local index left at
.repowise/(344 MB, gitignored) for follow-up; safe to delete.drsnuggles8 commentedon Aug 17, 2026
Correction + upstream filings (minimal repros built)
Built minimal repros before filing, per our standing rule. That exercise corrected one claim in my previous comment and sharpened the rest.
Retracted: "the headline wins are fabricated edges masking the FPs"
I wrote that
SAVE_COMPONENTand theHandle_*handlers left the dead-code list because a fabricatedused_bymade them look reachable. That was wrong. The repro disproves it directly:used_by: <paired header>and is still correctly reported as dead. So a fabricated edge does not suppress a finding.#defineis reported), soSAVE_COMPONENTwas not skipped for being a macro.tool.Handler = Handle_Alpha;) does now resolve — the run logsReference edges resolved total=1and the handler is not flagged.So
SAVE_COMPONENTandHandle_*cleared because #1600 and #1602 genuinely fixed them. Credit where due; my mechanism claim was unfounded. The 40/40 → 30/40 improvement is real, not an artifact.The rest of the previous comment stands: 30/40 sampled findings are still false positives, and the graph still fabricates
used_byedges 9 for 9.Filed upstream
used_bybuilt from the header/impl pairing, not from resolved call edges — names a file that never references the symbol, omits the one that doestype_useedge → reportedsafe_to_deleteAll three reproduce in ≤6 files with no build system, verified compiling and linking with clang++ before filing. The mechanism for #1655 is named in repowise's own debug log (
header_pair_edges added=N, tracking the number of header/impl pairs), and for the member-call gap the log showsCall edges resolved total=1against two real cross-file calls.Two of the three findings are things the repro sharpened rather than confirmed: the fabricated-edge bug turned out to be a
used_byconstruction problem rather than a general graph-soundness problem (dead-codeitself is unaffected), and the member-function gap turned out to be a clean one-declaration/one-definition case rather than the overload ambiguity the maintainer had already documented as out of scope.Revisit trigger, restated
Unchanged in substance from the previous comment, now pointing at real issue numbers — revisit when all of:
context/get_context/get_symbol, i.e. for ever registering the MCP server)v0.44.0can)Items 2 and 3 together account for 27 of the 30 false positives, so if both land the dead-code FP rate should fall to roughly 3/40 rather than 30/40. That is the point at which
dead-codebecomes worth re-sampling; #1655 is the separate gate for the MCP server.drsnuggles8 commentedon Oct 10, 2026
Upstream status 2026-10-10: repowise#1656 closed 2026-08-22; #1655 (used_by built from the header/impl pairing) is still open; latest release is v0.55.0 (2026-10-04). Under the trigger restated on 2026-08-17 (#1655 + member-function #1601 + #1656 + a release), the gate has not fired. The body's original trigger (#1601/#1602 released) and the score's blocked_by_external are superseded by that comment.