Real Refactor / Opus 4.8

Changing a core dependency
ctxo vs coding blind

Add one mandatory parameter to the most-used method in a production backend. Both runs find what breaks. Only one of them stays reliable getting there.

The Use Case
"Add a required CancellationToken to our connection factory"
A real refactor on a production C# backend (clean architecture, ~3,500 indexed symbols). IConnectionFactory.CreateConnectionAsync() is the database access primitive: almost every repository, sync service, API endpoint and background job calls it. Making the parameter mandatory ripples through the whole codebase. The question every engineer asks first: what exactly breaks?

The Change

C# / Roslyn tier ~3,500 symbols Claude Opus 4.8

Add a non-optional CancellationToken to the interface method and its single implementation. Every call site that omits it stops compiling. The same prompt, the same model, the same codebase. The only variable: does the agent have ctxo, or does it work the file system by hand?

Two Approaches

With ctxo: one deterministic tool chain - search_symbols, get_symbol_importance, find_importers, get_blast_radius, get_why_context.

Without ctxo: grep, ripgrep, file reads, and parallel sub-agents - many rounds, manual reconciliation, no graph to lean on.

Live Comparison
Side by side, in the terminal
Two Claude Code sessions, same task. Left leans on ctxo's dependency graph. Right is told not to use it.
claude - with ctxoone pass
› what breaks if I make CancellationToken required on IConnectionFactory.CreateConnectionAsync?
→ ctxo search_symbols "CreateConnectionAsync"
IConnectionFactory.CreateConnectionAsync (method) · 1 impl
→ ctxo get_symbol_importance
★ PageRank #1 of 3,583 symbols (inDegree 140)
→ ctxo get_class_hierarchy
descendants: 1 (ConnectionFactory) · no hidden impls
→ ctxo find_importers
140 callers · 155 call sites · 54 files
→ ctxo get_blast_radius
impactScore 260 · risk 1.0 · 18 clusters
"Change impacts 18 clusters - multi-team review recommended"
→ ctxo get_why_context
no reverts · no anti-patterns · snapshot current
✓ Full impact map in one chain.
The single most central symbol in the codebase. 155 sites across 54 files will not compile - API, sync, crypto, reports.
6 tool calls0 sub-agents0 retriesdeterministic
claude - without ctxomany rounds
› what breaks if I make CancellationToken required? (do NOT use ctxo)
$ grep "CreateConnectionAsync" (built-in)
→ only IConnectionFactory.cs · 1 match?!
is this abstraction even used? looks like dead code...
$ rg "\.CreateConnectionAsync\(" (raw ripgrep, retry)
155 matches / 54 files - built-in tool had misfired
⇉ dispatch 2x Explore sub-agents
agent A: 70 · agent B: 63 · counts disagree
re-verify every line by hand (sub-agents not trusted)
$ rg ... ×10 more rounds + read ×4
reconcile, dedup, cross-check each claimed call site
✓ Same answer - eventually: 155 sites / 54 files
no centrality. no history. no risk score.
nearly mislabeled the #1 symbol as unused.
~15 tool calls2 sub-agentsgrep misfiredvaries per run

Tool-call and sub-agent counts are exact (read off the transcripts). Wall-clock was not stopwatched, so we describe it directionally: ctxo runs as a single fast pass; the manual route needs many sequential rounds plus parallel sub-agent dispatch.

Head to Head
Same destination, measured
Both reach the correct set of breakages. The difference is the path, the reliability, and what each one can even see.
MetricWith ctxoWithout ctxo
Tool calls to the answer6 (one chain)~15 + 2 sub-agents
First-pass resultcorrectgrep misfired - 1 match, "looks like dead code"
Centrality of the symbolPageRank #1 of 3,500, instantlynot computable by grep
Call sites found155 / 54 files155 / 54 files (after recovery)
Vs compiler ground truth155 = 154 build errors + 1 in a skipped test project. Exact.same set, reached the expensive way
Cross-cutting signal18 clusters - multi-team reviewflat list, no boundary view
Git history / anti-patternschecked in one call (clean)not checked
Reproducibilityidentical every rundepends on tool + sub-agent luck

Ground truth was produced by actually applying the change on a throwaway branch and running dotnet build. The compiler reported 154 missing-argument errors plus 14 downstream type-inference cascades; the one remaining predicted site lived in a test project that was skipped once the core project failed to compile. ctxo's prediction matched the compiler exactly.

What Actually Differed
Reliability, not recall
A strong model can grep its way to the right list. The question is what it costs, what it misses on the way, and whether you can trust the run.

With ctxo

  • One deterministic chain returns the full reverse-dependency graph
  • Names the single most central symbol in the codebase (PageRank #1)
  • Symbol-scoped: counts only real callers, never text collisions
  • Surfaces 18 affected clusters and a multi-team review signal
  • Reads git intent and anti-pattern history in the same pass
  • Returns indexed facts - nothing to hallucinate

Without ctxo

  • The built-in grep misfired and returned a single match
  • The agent nearly concluded a critical primitive was dead code
  • Recovery needed raw ripgrep plus two parallel sub-agents
  • Sub-agent counts disagreed (70 vs 63) and had to be re-verified by hand
  • No centrality, no cluster view, no history - just a flat list
  • In a sister run, manual reasoning fabricated call sites that had to be grepped away

Verdict: same answer, different reliability

At Opus 4.8 the manual route eventually arrives at the correct set. That is the honest result, and it is exactly why the difference matters: getting there meant a misfired grep that almost flagged the codebase's most-used method as unused, two sub-agents whose answers disagreed, and a stack of rounds reconciling it all by hand. ctxo returned the same set as one deterministic chain, named it the #1 symbol by PageRank, mapped 18 clusters, and checked the git history - with nothing to fabricate.

Reliable

Indexed facts, symbol-scoped, identical every run. No misfires, no fabricated call sites.

Sees the invisible

PageRank centrality, cluster blast radius and git intent - signals grep structurally cannot produce.

Proven

Its prediction matched the compiler exactly, and it has caught real bugs in real production history.