Repository navigation
dotnet-toolkit is now navigation-only. It locates symbols, references, implementations and call
paths; Read fetches the text, Edit/Write change it, dotnet build is the gate. The one tool-made
edit that remains is rename_symbol, because a solution-wide semantic rename is the one edit a string
replacement cannot make safely. The full reasoning — what the 1.x write path was measured to do on a
real repo, and the principles the cut rests on — is in
docs/design/navigation-only.md.
Removed
validate_patchand everything that existed only for it: drafts,baseVersionleases, the
compile ladder, analyzer runs, the two write guards (guard-cs-edit,guard-cs-bash-write), and
the patch-specific bullets of the write-time checklist. Measured on FluidScript: fewer than half of
382 calls did what they were sent to do; 33 % were refused pre-flight by the lease protocol working
as designed; line-anchored ranges failed at the closing brace in a way no fix short of string
anchoring removes — andEditalready is string-anchored.- Source text from every tool.
get_symbol'ssourcecomponent, its:code/@linesgrammar and
contentVersion;get_references'includeBodies;search_index'sreadcolumn andintent.
get_symbolis a locator:declarationSitesrows carryfile,signatureLine,startLine(doc
comment included) andendLine, one per part of a partial, and a rangedReadof that span is the
text. - The development log:
search_log,recentLog,feature_log. Nothing writes it any more. dotnet-guard-redteamanddotnet-guard-audit: there is no enforcement left to bypass.
Added
- The index follows every edit. A
PostToolUsehook (refresh-cs-files) sends the files an
Edit,Write,NotebookEdit,apply_patchorBashcall wrote to the running server, which
re-indexes just those documents; the mtime sweep catches the rest.search_index,sym_ids,
get_referencesand the hierarchies see the change before the next call. Previously only a full
rebuild (a patch apply,reload_workspace, or a restart) updated them. get_referencesnames dispatch. Rows a call reaches only through an interface or base member
are markedindirect: trueand carryvia(the member the call binds to); the envelope splits
directItems/indirectItemsand explains once indispatchNote.search_index(query: "IFoo", implements: "IFoo")listsIFoo's direct implementers — the
obvious call for "who implements this" used to return nothing, since ranking the interface's own
name never scores a type that implements it. An empty page underimplements:always carries
implementsHintsaying which zero it is.get_project_graphseparates declared from inherited edges:.csprojreferences in
references/referencedBy, SDK-inherited ones intransitiveReferences/transitivelyReferencedBy.entryPointHinton a routed action ([HttpGet],[HttpPost],[Route], …) says its callers
are HTTP clients outside the compilation and to grep the route template over the client code before
treating it as unused.- The read advisory reaches the model, and states its cost. A whole-file
Read/catof a
compiled.csfile now draws "this read injects all N lines (about T tokens); a ranged Read of one
declaration's span returns only those lines", plus a running per-session tally. Before 2.0.0 the
note went to the user's transcript only. Ranged reads,grep, and write-shaped commands (sed -i)
draw nothing. get_retrieval_metricsreportswholeFileCsReadsper agent and per agent/tool, from the same
predicate the advisory uses.search_indexaccepts list-shaped filters (kinds: ["method","property"]), explains a zero-hit
query (names and doc summaries only — literals and comments are aGrep), andget_symbolon a
single symbol always carriesxmlDoc.get_call_hierarchy's description steers "how does A reach B" toget_call_slice(measured: 18k
tokens against a few hundred).
Changed
dotnet-performanceruns without switching guard state. Claude Code's auto-mode classifier
deniesset_hook_guards— and any agent prompt mentioning suspended or blocked guards — as
self-modification, which stopped every auto-mode run at pass 2. The three probes now run at the
default state and the meter'swholeFileCsReadsis the discipline check; suspend/block survives
only as an opt-in strict variant outside auto mode. Both 2026-09-20 runs completed in auto mode.dotnet-initadds only read-only tools to a repo's allowlist (15 entries);rename_symbol
andset_hook_guardsare never allowlisted.- Old quarantined cache files are capped at the newest two.
- Response contract
ctx-contract/4.0→4.2. 4.0: the removals above. 4.1:signatureLine
always present and first afterfile;via/dispatchNote; single-symbolxmlDoc;
get_project_graphedge split. 4.2: theimplementslisting shape andimplementsHintcases;
wholeFileCsReads.
Measured
First runs on the navigation-only surface (both tool families available, the shipped default):
FluidScript (316 files, 649 types) 1.53× and PandaAI (329 files, 551 types) 1.77× less context
injected than the raw route, 19/19 scored questions correct against the raw route's 16/19, and the
MCP route reached for on every question without a nudge. Full tables, per-question detail and where
the raw route won: docs/benchmarks.md.