All notable changes to Fuse are documented here. The format is based on Keep a Changelog. Fuse 4.0.0 is the first public release; it carries the whole product and there is no prior public version to migrate from.
- The
fuse.jsonschema the CLI writes is now published athttps://fuse.codes/schema/v4.4/fuse.schema.json, so an editor can validate a file written byfuse init. fuse indexnow exposes a repository-owned job lifecycle.fuse index status,fuse index cancel, andfuse index clean --yesreport, cancel, and remove only documented derived index files. Start, status, and cancel support JSON output.fuse mcp doctorreports the running binary, PATH lookup, selected MCP client registration and command, managed-instruction version, optional Claude hooks, daemon protocol, repository identity, and active index job. It supports human output and--json.
- Indexing starts at the syntax tier.
fuse index --semanticexplicitly continues into selected-workspace compiler analysis after syntax rows are available, without starting a build-capture worker. Matching callers join one daemon-owned job instead of colliding with the SQLite writer. - Host protocol 11 replaces
fuse/indexwithfuse/indexStart,fuse/indexStatus, andfuse/indexCancel.fuse/openIndexedincludes the current job snapshot while syntax data is being built. fuse_workspace action=indexnow starts or joins the daemon job,action=statusreports job details without creating an index, andaction=cancelrequests shared-job cancellation. A source edit starts a refresh job before a read returns indexed facts.- Syntax refreshes now build their inventory from
git ls-files -s -zand porcelain-v2 status. Clean tracked files reuse the Git blob id, while dirty and untracked files stream a SHA-256 hash. Unchanged files no longer have their derived rows or FTS documents rewritten. - Generated files retain declarations, signatures, routes, and outlines without indexed method bodies or comments. Files over the 5 MiB source limit retain inventory metadata with an
inventory_onlydetail level. Schema 18 uses contentless-delete FTS5 documents linked throughsearch_documents; existing derived indexes rebuild. - Completed and cancelled index jobs now truncate the SQLite WAL. Full rebuilds set incremental auto-vacuum mode and compact FTS5 once; ordinary refreshes use one bounded merge and at most 1,024 reclaimed pages. An incompatible index removes only its known derived files, including obsolete reduction-cache sidecars and
r60-semantics.json. - Reduction output and per-file analysis now share a repository-scoped, daemon-owned memory cache capped at 64 MiB. The cache uses least-recently-used eviction and ends with the process; Fuse no longer creates
fuse-cache.db. fuse mcp installnow writes the v4.4 managed agent guidance by default.--no-rulesskips that block, while--with-hooksremains explicit. Re-running installation replaces only the marker-delimited Fuse block and preserves surrounding user content.- Daemon and MCP startup no longer load an MSBuild solution in the background. Compiler state starts only for an explicit semantic index or a compiler-backed request.
- File-specific
fuse_checkresolves SDK default compile items and explicit linkedCompileitems before compiler work. It verifies every project that owns a linked source file in sequence, and no longer selects a full solution for a single-file check. fuse_testandfuse testnow group selected covering types by their owning projects. Each project receives only its own test filter and runs in sequence, including every owner of a linked test source file.- Refactor requests now use the daemon's host-owned warm-solution cache. Repeated rename, signature, type, and code-fix requests no longer create an independent compiler-state cache per MCP call.
- Production builds treat compiler warnings as errors. Obsolete Roslyn event subscriptions, ambiguous XML documentation, and nullable test setup were corrected before enabling the gate.
- A default syntax job no longer tries to select a compiler workspace. Repositories with multiple root solution filters now complete syntax indexing; only
fuse index --semanticasks for an unambiguous target. - Generated declaration indexing now retains type-level symbols and signature chunks only. Generated member rows no longer inflate the symbol, chunk, and full-text tables, while exact generated-type lookup remains available.
- Index JSON snapshots now use named lifecycle values and follow the same redirected-output cadence as terminal progress: phase changes, ten-percent buckets, or five-second heartbeats.
- Starting an index job no longer runs synchronous SQLite setup on the caller thread. A locked store now yields the bounded syntax-building header instead of waiting for the writer timeout.
- The daemon watcher now ignores
.gitmetadata. Git commands used by inventory no longer trigger a second refresh job after each completed index. - Direct CLI impact and review-handoff calls now use the host-owned index runtime. Concurrent reads no longer create conflicting isolated job managers.
- Retained completed, cancelled, and failed jobs now preserve their terminal elapsed duration instead of continuing to age in
fuse index status. - Refactor operations now use an already-loaded host warm-solution cache before MSBuild registration. A daemon-held compiler snapshot remains available when local SDK discovery cannot run.
- Read-only index opens no longer rerun database pragmas or create schema tables. A contended find request now returns its availability header within the short read timeout. Resident compiler projection uses the same Git blob and SHA-256 identities as the scanner, so its follow-up reconcile does not rewrite unchanged files. Corrupt non-database files reach the derived-data recovery path instead of being described as a generic schema mismatch.
- Daemon graph, scope, explain, and diagnostics RPC reads now wait for their repository-owned syntax job instead of applying the MCP deferral deadline. Resident signature lookup returns known compiler metadata while its syntax job starts through the selected local or daemon access path, and a deferred impact read returns its availability header instead of
internal_error:. - A command that spawns the shared daemon no longer hangs a piped or redirected caller. The daemon inherited the caller's standard handles, so its stdout stayed open for the daemon's whole idle window and a shell pipeline, CI log capture, or agent harness kept waiting long after the command finished. The daemon now receives its own streams, is marked detached, and reports through its rolling file log only.
fuse updatestarts its detached updater the same way. fuse context --seed <name>resolves a name at the syntax tier. Seeds were matched only against the typed graph, so with syntax-first indexing the command returned an empty payload without saying why; a name now plans its declaring file and names the tier in the provenance line.fuse initwrites the workspace path with forward slashes.fuse.jsonis committed, so a file written on Windows has to resolve on Linux and macOS, where a backslash is an ordinary filename character.dotnet build Fuse.slnx -c Releasenow builds the product in Release. The solution declared its source folders as nested elements, which the SLNX parser does not map to a build type, so everysrcproject compiled intobin/Debugwhile the test projects built Release. Folder declarations are flat and the Debug and Release build types are declared explicitly.- Cancelling an index job that finishes concurrently no longer risks an
ObjectDisposedException. The job manager owns each job's cancellation source and releases it at shutdown rather than when the worker exits.
- The MCP tool surface is one operation type per tool (
WorkspaceToolOperations,FindToolOperations,ContextToolOperations,ImpactToolOperations,CheckToolOperations,TestToolOperations,RefactorToolOperations,ReviewToolOperations,ReduceToolOperations) behind one handler type per tool, replacing theFuseToolOperationspartial class and its pass-throughFuseToolsfacade. Availability-header formatting and index-store access are separate collaborators. Tool names, arguments, descriptions, and output are unchanged. - Index job lifecycle types live under
Mcp/Jobs, host RPC contracts are split by subject underHost/Rpc/Contracts, each index lifecycle command has its own file, and warm-service installation, warm-service state, and Fuse peer-process discovery are separated from their launchers. Persisted index-job metadata keys and the derived-file reader are declared once and shared.
- The packaged CLI no longer includes
fuse eval,fuse resident-latency, orfuse testexec. Benchmark source and recorded results remain in the separateFuse.Benchmarks.slnxsolution and are not part of normal product validation. fuse localizeandfuse resolveare removed. Usefuse find <query> --kind taskfor task localization andfuse find <query> --kind service|request|route|config|symbolfor exact lookup and wiring resolution.- The
git_cochangetable, collector, retrieval prior, ranking diagnostic configuration, andFUSE_COCHANGEsetting are removed. The recorded historical ranking results remain in the repository. FUSE_BUILD_CAPTUREno longer selects an index path. Build capture is invoked only by portable capture and compiler-backed verification.
- Every MCP tool except
fuse_reducenow exposesworkspace_identity_unresolved:when the requested folder is not inside a Git repository.fuse_reduceremains available because it does not use the workspace index. - Warm indexes now carry a repository identity and complete file-inventory manifest in
index_meta, including a build-state marker, file count, inventory hash, and completion time.
- The nearest enclosing
.gitdirectory or file is now the canonical identity for MCP tools, daemon endpoints, cold-build coordination, writer locks, project-scoped MCP installation, scanning, and queries. Calls from nested folders therefore share one repository-root index.fuse host, eager warming, and workspace-scoped MCP operations do not start for unresolved folders. fuse mcp installoutput and documentation now separate MCP registration,--rulesinstruction files,--with-hooksClaude Code hooks, and the Fuse executable. Project scope resolves to the enclosing Git root and refuses an unresolved folder; user scope controls client availability but does not bypass runtime workspace identity.- Warm reconciliation now scans the complete inventory, indexes added files, hard-deletes removed file rows and their FTS/co-change data, and automatically replaces the index after a change storm.
fuse_testnow validates or warms the index before covering-test selection and returns the bounded availability header during a build or contention. An explicitfuse_workspace action=indexrefreshes a non-empty daemon-owned index.fuse index --forcenow discards the derived tables before rebuilding.
- A non-empty partial database can no longer suppress repository indexing. A missing, interrupted, wrong-root, count-mismatched, or hash-mismatched manifest triggers an automatic rebuild, covering the case where indexing a nested
bin/Releasefolder left only runtime JSON files in the repository database.
fuse mcp installnow writes native project and user configuration for OpenCode, Kilo Code, Codex, and Grok Build, alongside Claude Code, Cursor, and GitHub Copilot. OpenCode and Kilo Code use theirmcpJSON command-array shape; Codex and Grok Build usemcp_servers.fuseTOML tables. The installer also writes documentedAGENTS.mdlocations when--rulesis set.- The documentation site adds a persistent .NET discovery article and new social cards for the project overview and benchmark results.
fuse mcp install --rulesnow writes task-specific Fuse guidance instead of telling every agent to start withfuse_workspace action=map. The rules route Git reviews tofuse_review, exact indexed lookup tofuse_find, open-ended work tofuse_find kind=task, and state the single-file boundary offuse_check, the staged multi-file behavior offuse_refactor, the limits of focused tests and review, and the usableupgrade_pendingindex state. MCP server instructions and generated client rules now share one source.- Installer rules are written only for clients whose MCP registration succeeded. A failed Claude Code user registration no longer writes a global rule or project
.gitignoreentry. - Built-in MCP playbooks no longer describe
fuse_reviewas regression proof or direct agents to apply a multi-file refactor through the single-filefuse_workspace action=applyoperation. - The README, landing page, getting-started guides, product overview, roadmap, and announcement article now describe Fuse as a persistent .NET discovery and compiler-verification layer for coding agents. Project status badges and refreshed blog-card metadata make the current release and supporting evidence easier to locate.
- Resident watcher projection now stores each projected source file's current content hash. The N6 reconciliation pass therefore recognizes the projection as current instead of re-indexing every source file through its syntax-only fallback, which had cleared the persisted DI, route, and other semantic edges after a settled edit. Existing indexes do not need rebuilding.
- In daemon mode, live
fuse doctor, stagedfuse_refactor, and capture-backed oraclefuse_checknow execute through typedfuse hostRPCs, so the per-root host owns the held warm solution and pooled worker instead of each MCP process constructing a competing compiler state (R61). Unavailable or protocol-mismatched hosts retain the existing in-process fallbacks and output.FUSE_COMPILER_STATE_CAPdefaults to 1: activating resident, warm-solution, or capture-worker state releases the other held state for that root. Host protocol 10 addsfuse/doctor,fuse/refactor, andfuse/checkCapture. - Tier-1 build capture now projects cross-project
testsedges before serializing its graph, so default-capturefuse_testselects the same covering tests as the ordinary semantic path. The projection remains target-framework scoped, preserving canonical union availability. This changes extraction contract 3 and capture-bundle format 4; existing.fuse/fuse.dbfiles rebuild and older capture bundles must be re-captured. - Tier-1 multi-target capture now writes one canonical semantic representation per stable declaration and graph fact, with
tfm_availabilityrows recording every target framework where it exists (R60). The deterministic primary-TFM rule prefers modernnetX.Y, thennetcoreapp, thennetstandard, then legacy targets, with the highest version in a family; primary-only and non-primary-only facts both remain. This adds relational schema 17 and extraction contract 2, so every existing.fuse/fuse.dbrebuilds once. The index recordsmulti_tfm_union_loss=0after a complete union. The capture graph adds target-framework data, so capture-bundle format 3 requires re-capturing older bundles. - SQLite pool cleanup is now scoped to the exact
WorkspaceIndexConnectionFactorythat owns a corrupt or disposed index database. Test fixtures no longer clear every SQLite pool in their shared parallel test process, preventing one fixture from disposing another fixture's pooled native connection during open, write, or teardown. The store path, WAL behavior, recovery result, and single-writer contract are unchanged. - Workspace discovery deprioritizes auxiliary build and tooling solutions (under
build,eng,tools,scriptsdirectories) below the repo's product solution, so a repo that ships a tooling solution alongside its real one (for example NodaTime'sbuild/Tools.slnxnext tosrc/NodaTime.slnx) binds the product solution instead of the tooling one. Previously the alphabetical tie-break could pick the tooling solution ("build" sorts before "src"), producing a thin semantic graph (NodaTime bound only 2 tooling projects, 343 symbols, instead of the 21-project library). Pin explicitly with afuse.json"solution"key. The benchmark corpus manifest gained an optional per-reposolutionfield that writes that pin on restore. - The self-contained runtime binaries publish ReadyToRun (R50), guarded by
ReadyToRunPublishProfileTestsso a profile cannot silently drop it: a one-shot CLI invocation pays less JIT warmup on cold start (measured on win-x64,fuse --version: ~150 ms with ReadyToRun versus ~188 ms without, environment-dependent). The framework-dependent dotnet tool stays portable IL (no RID to crossgen for), and the long-lived daemon pays JIT once per session, so it is unaffected. Full AOT is not used (its native link is unavailable in the build environment). Corrects the docs, which had listed ReadyToRun on the framework-dependent tool. - Parallelized the per-project wiring-analyzer graph pass in the cold semantic index (R45): the pass now runs concurrently across projects (bounded by processor count) and merges positionally, so the flattened nodes and edges are byte-identical to the sequential pass. Each project's graph is independent (it binds its own compilation with no shared state), so distinct compilations parallelize rather than serialize. Measured on eShopOnWeb (10 projects): the analyzer pass dropped from ~3.4s to ~0.75s with identical output; Suite A stays 24/24.
- Deduplicated Roslyn parsing in the semantic index pipeline (R47): on the semantic/capture path each C# file is now parsed once and the syntax tree is shared between the chunk (symbol) and route extractors, instead of each extractor re-parsing the file's content string. This removes a parse per file on the cold-index hot path with byte-identical chunk and route output (the two extractors previously parsed the same content with the same default parse options). The syntax-only tier is unchanged. No effect on the semantic graph (nodes/edges come from the analyzer pass, which is untouched).
- Watcher-invalidated warm Solution cache (R54): when the daemon or an in-process resident MCP server observes a settled C# source change, it evicts the held MSBuild solution for that root. A clean warm
fuse_refactoror livefuse_workspace action=doctorthen skips the fallback directory scan; the no-watcher path keeps its scan-based freshness check. Generated and build-output paths do not evict the solution because they are outside the tracked source set. - Pooled build-capture check worker (R48): without a resident workspace, an oracle
fuse_checkkept a long-lived worker per captured compiler log instead of spawning, rehydrating, and exiting on every check. The worker rehydrates the log once and answers many checks over its stdio (each speculative edit forks the in-memory document), so the second and later checks in a session skip the rehydrate (measured on a captured log: ~1.7s spawn-per-call per check versus a pooled session that rehydrates once and answers subsequent checks near-instantly). Check honesty is preserved exactly (the pooled worker runs the identical fork-and-diagnostics code, so a pooled verdict equals a spawn-per-call verdict; check-gate false-green 0 / false-red 0 unchanged). Bounded byFUSE_CHECK_WORKER_CAP(default 2) andFUSE_CHECK_WORKER_IDLE_MINUTES(default 30); a cold, absent, or failed pooled worker falls back to the spawn-per-call path, never worse. - Lazy pooled check rehydration (R53): the first pooled oracle
fuse_checknow reads captured source ownership metadata and rehydrates only the C# project that contains the requested file. Later checks reuse that project; a request for another project rehydrates that project on demand. The existing fork-and-diagnostics path is unchanged, so verdicts retain the full-log path's check-honesty contract. - MSBuild toolchain warmed at daemon/serve start (R44): the daemon (and in-process
fuse mcp servewhen not delegating) registers the MSBuild locator and primes the served root's solution into the warm-solution cache (R42) in the background at startup, so the firstfuse_refactororfuse_workspace doctorof a session does not pay the multi-second locator-plus-first-load warmup (measured on the Fuse repo: a ~5.9s background warmup moved the load off the first refactor, which then reused the primed cache with no reload). Fire-and-forget and best-effort, never blocks startup; opt out withFUSE_MSBUILD_WARMUP=0. fuse_workspace action=doctorserves the load tier from the persisted index (R43): the per-project semantic-load diagnosis (achieved tier, selected solution, each project's load outcome) is stamped intoindex_metaat index time and reported straight from the warm index in sub-second time - a single stamped-row read, independent of repo size - instead of re-running the full MSBuild/Roslyn load (measured tens of seconds on a large repo). Because the stamp is written by the same code the live diagnosis uses, it matches what a live load would report and reflects exactly what was indexed. A newrefreshparameter (--refreshon the CLIfuse doctor) forces a live load; doctor also falls back to a live load automatically when no stamp is present yet. The output names its source (diagnosis source: warm indexordiagnosis source: live MSBuild load).- Daemon-held warm Solution shared across refactor and doctor (R42):
fuse_refactorandfuse_workspace action=doctor's live load now reuse a per-root, MSBuild-loaded RoslynSolutionheld in the long-lived serve/daemon process instead of re-openingMSBuildWorkspaceon every call. A second refactor or doctor in the same session skips the full design-time load (measured on the Fuse repo, environment-dependent: refactor first call ~23.7s, warm reuse ~0.45s; doctor ~13.9s to ~0.87s). Correctness is preserved by a cheap freshness signature (a pruned.csfile scan): an edit, addition, or deletion forces a fresh load, so a reused solution yields the same diff a cold load would, and a changed tree pays the same cost as today (never worse). Memory is bounded by a hard LRU cap (FUSE_WARM_SOLUTION_CAP, default 3) and an idle window (FUSE_WARM_SOLUTION_IDLE_MINUTES, default 30), each disposing the evicted workspace; the held-solution RSS ceiling was ~594 MB at cap 3 on the Fuse repo. This is a read/compile cache and never writes the tree (D2) or the index (D13/R19). - CI SDK workflow (
.github/workflows/ci-sdk.yml) runsCategory=RequiresSdkintegration tests on win-x64 and linux-x64 with the .NET 10 SDK; the default PR leg excludes them viaCategory!=RequiresSdk.build/verify-ci-sdk.ps1fails when either leg is missing or misconfigured. build/verify-briefing.ps1fails on stale product claims inbriefing.md(fourteen MCP tools,ext/vscode, retired tool names); wired into the default CI build job.FUSE_HOOK_VERBOSE=1logs swallowed hook RPC failures to stderr with method name and error code; default remains silent.fuse update --force-kill-peersrestores the pre-4.2 broad peer termination behavior; the default path terminates only the updating tool's own child lineage and same-install peers.- Unified API surface reference (
reference/api-surfaces) maps each user intent to the MCP tool, CLI command, and host RPC method;ApiSurfacesDocParityTestskeeps the doc in sync with shipped tools and RPC methods. FUSE_HOST_RESTRICT_PIPE=1restricts the Windows named pipe ACL to the current user; default remains open to local processes.- Recorded index hot-path profile artifact (
tests/benchmarks/results/profile-v42.json) with schema validation inProfileV42ResultTests; regenerate withfuse eval profile-v42 --repo NodaTime. - Narrow index store ports behind
WorkspaceIndexStore:IndexSchemaMigrator,FtsSearchEngine,SymbolGraphStore, andSessionStore. - Shared
Fuse.Scopingmodule with a singleContextPlantype used by Fusion focus scoping and MCP review/localize. - Semantic-tier provider seam (
ISemanticLanguageProvider,SemanticLanguageProviderRegistry); C# registers throughCSharpSemanticLanguageProviderfrom the Roslyn plugin;Fuse.Semanticsno longer references the Roslyn plugin project directly. - Host RPC outcome tests for protocol version mismatch, served-root rejection, reconcile stamped headers, and
fuse_checkgrade stamping. IndexCoordinator: one writer queue per workspace root; cross-process contention returnsindex_busy:instead of throwing.- Stable operational error prefixes on MCP tools and mirrored CLI commands:
index_busy:,index_not_built:,workspace_not_found:,validation_error:,index_rebuilding:, andinternal_error:. - Fast
fuse_workspace action=statusandaction=doctorsummary header: read-onlyindex_metawhen.fuse/fuse.dbexists; cold workspaces reportnot_indexedwithout creating the database. WorkspaceIndexStore.OpenForReadAsyncfor warm read opens that verify schema without writingindex_meta.fuse_checkandfuse_testrun compiler-grade verification before opening the store; repair-packet enrichment is omitted with a named note when the store is unavailable.- Daemon-owned index writes (G5 phase 2):
fuse hostowns index open, reconcile, syntax-first, and semantic upgrade;fuse mcp servedelegates store-backed calls over the pipe when the daemon is active.FuseHostService.ProtocolVersionbumped to 8. - Loud observability of degraded states (R37): degraded paths are counted (
fuse.degraded.statemetric, tagged by kind: index_busy, index_rebuilding, integrity_failed, deferred, lexical_fallback, verify_abstained; also queryable in-process), the availability header carries an actionable wait hint on every not-ready state (building_syntax,upgrade_pending,index_busy,index_rebuilding,stale_as_of) plus aprogress: building for ~Nsline during a cold build,fuse_workspace action=doctorreports store size, last-written time, index integrity (R31), skipped files (R35), running daemons (R28), and the degraded-state counts this session, and the daemon writes a size-rotating log at{user-data}/logs/fuse-host.log. No degraded state is silent. - Upgrade resilience: staged switch with health check and rollback (R33): the detached updater now captures the previously installed version, health-checks the new binary after
dotnet tool update(it starts and reports a version), and rolls back to the previous version on failure, so an unattended in-session auto-update never bricks the tool. A healthy switch logs areindex scheduled on next opensignal (the extraction-contract check, R22/R23, rebuilds the index if needed).UpgradeHealthCheckis the in-process gate behind the decision. - Daemon lifecycle visibility (R28): each
fuse hostwrites a descriptor (served root, PID, version, start time) to a machine registry under{user-data}/daemons/on start and removes it on shutdown;fuse_workspace action=doctorlists running daemons and prunes descriptors whose process is dead, so accumulated or version-mismatched daemons are visible. One daemon per root is enforced by the single-instance lock; idle daemons shut down afterFUSE_DAEMON_IDLE_MINUTES; in-session auto-update hands off via the detached updater (waits for the process to exit) rather than a kill race. - Abstain and defer to native when not semantic-ready (R30): a not-ready read (cold, building, rebuilding, or contended) returns a fast structured deferral signal -
grade: deferred (not semantic-ready)plus theindex_state,files_indexed, build progress, and a use-your-native-search-and-retry hint - instead of a diluted or silent-empty result; the deferral is counted (fuse.degraded.statekinddeferred). For fuse-only or CLI setups with no native search to defer to,FUSE_LEXICAL_FALLBACK=1instead serves a scoped, ranked raw-text result fromfuse_findgradedlexical-fallback(honest bound: it does not out-scan ripgrep; its win is scope plus answer shape). - Live incremental index (R39): when the daemon is active, a debounced file-system watcher (including
.git/HEADand.git/index, so branch switches and pulls are caught) reconciles changed files into the index through the single-writer coordinator, so reads stay fresh with no per-read reconcile cost. Overlap-guarded and best-effort; a periodic safety reconcile catches dropped events and on-read reconcile remains the backstop. Default-on with the daemon; opt out withFUSE_WATCH=0. - Eager warm-on-start indexing (R38): a served repo warms its index in the background at daemon/serve start, before the first tool call, so a cold repo does not pay the full cold cost on the first read. Default-on; opt out with
FUSE_EAGER_INDEX=0, or warm explicitly with the newfuse warm <path>command. The warm runs through the shared cold-start coordinator (deduped with a racing first read) and is best-effort so it never blocks startup. - Bounded, visible cold start (R27): the first read on a cold repo runs the syntax-first index build in the background (deduplicated per root) and waits only up to
FUSE_COLD_READ_DEADLINE_MS(default 2500 ms); if the build outruns the deadline the read returns a boundedindex_state: building_syntaxheader withfiles_indexedinstead of blocking for the whole build (tens of seconds on a large repo), and a second read in the same session serves the warming index. A small repo whose build finishes within the deadline serves results on the first read; a synchronous in-process caller is unaffected. - Atomic, conflict-checked apply (R36):
fuse_workspace action=apply write=truenow writes to a temp file and renames it into place (atomic on the same volume), so an interrupted write never leaves a half-written file. A newexpectedHashparameter (the SHA-256 of the content the edit was derived from) makes apply refuse with avalidation_error:conflict rather than clobbering a file that changed since. Dry-run-by-default and the workspace-root escape refusal are unchanged. fuse_reviewbounds a large diff (R26): when the changed-file set exceeds a cap (default 150, override with themaxChangedFilesparameter orFUSE_REVIEW_MAX_CHANGED_FILES), it returns the changed-file list and a narrow-the-base-ref note instead of running blast-radius resolution unbounded. A normal PR-sized diff is unaffected.maxTokensstill bounds output.- Availability headers on store-backed read tools lead with
index_state:(not_indexed,building_syntax,upgrade_pending,ready,index_busy,stale_as_of) plusfiles_indexedwhen known; blocked reads return the header as the tool body within bounded time instead of hanging. - Corrupt or version-incompatible
fuse.dbself-heals: derived index data is deleted and rebuilt from source with serialized recovery per root; MCP callers receiveindex_rebuilding:instead of an unhandled exception.
- Dependencies upgraded to latest stable: the Roslyn stack (
Microsoft.CodeAnalysis.*) 4.14.0 to 5.6.0,ModelContextProtocol0.8.0-preview.1 to 1.4.1 (stable; the call-tool metrics filter moved toWithRequestFilters),Microsoft.ML.Tokenizers(+ data) 1.0.2 to 2.0.0,Microsoft.NET.Test.Sdk17.12.0 to 18.8.1,xunit.runner.visualstudio2.8.2 to 3.1.5,Microsoft.Build.Locator1.7.8 to 1.11.2, and the net10-aligned runtime libraries (Microsoft.Data.Sqlite,System.IO.Hashing,Microsoft.Extensions.*) to 10.0.10. The Roslyn family (including the metapackage and*.Common/VisualBasic.Workspacesthat arrive transitively viaBasic.CompilerLog.Util) is pinned to 5.6.0 throughCentralPackageTransitivePinningEnabled, so the whole compiler graph is version-consistent (no NU1608 mismatch).Microsoft.Build.Locator1.11.2 adds the MSBL001 copy check, opted out viaDisableMSBuildAssemblyCopyCheckbecause every entry point resolves MSBuild from the installed SDK viaMSBuildLocator.RegisterDefaults()(documented inDirectory.Build.props). - Index freshness is decoupled from the product version (R22): reuse is gated on the relational schema version AND a new extraction-contract version (
WorkspaceIndexSchema.ExtractionContractVersion, stamped asindex_extraction_versioninindex_meta), never onfuse_version. A minor or patch upgrade that does not change what is extracted now reuses a good index instead of forcing a reindex on every bump (withFUSE_AUTO_UPDATEdefault-on, the old policy discarded a good index on each minor bump). Thefuse_versionstamp is kept for diagnostics only. Migration: a pre-4.2 index carrying onlyfuse_versionrebuilds once on first open to gain the extraction stamp, then reuses. This supersedes the earlierFuseBuildInfo.IsCompatiblemajor.minor index-open gate (capture-bundle compatibility still uses it). FUSE_DAEMONdefaults on forfuse mcp serve; setFUSE_DAEMON=0to run in-process without the sharedfuse hostdaemon per repository.FUSE_AUTO_UPDATEdefaults on forfuse mcp serve; the updater runs after session exit without killing sibling sessions (stopOtherHosts: false). SetFUSE_AUTO_UPDATE=0to opt out.fuse mcp installwrites command-only client config (noenvblock); agent-first defaults (daemon, auto-update, background upgrade, build capture) ship in the binary unless explicitly opted out.fuse updatedefault peer termination is narrowed to the updating install's lineage; unrelatedfuse mcp servesessions in other repositories are not killed.fuse_workspace action=statusno longer triggers a full syntax-first index on a cold workspace; useaction=indexto build explicitly.- Warm
WorkspaceIndexStorereads useOpenForReadAsyncinstead of write init, reducing lock contention during background semantic upgrade. briefing.mdbody aligned with nine MCP tools, no VS Code extension (D15), and canonical benchmark figures fromtests/benchmarks/results.roadmap/README.mdnotes thatbriefing.mdtracks shipped product, not the executable checklist.SECURITY.mdlocal-trust subsection documents host pipe limits andFUSE_HOST_RESTRICT_PIPE.AGENTS.mddesign invariants updated for default-on daemon (D13), single-writer index, semantic provider seam, and index self-heal policy.
FtsCandidateGeneratorand theFUSE_FLAT_FTS=1diagnostic flag;LexicalCandidateGeneratoris the sole lexical retrieval path.
- Opt-in always-on warm service (R40):
fuse warm --service install|uninstall|status|runmanages a background OS service (Windows service, launchd agent, or systemd user unit) that keeps recently-used repos warm before a session opens.install/uninstallactually attempt the platform registration and fall back to the exact manual command when they cannot (for example without elevation on Windows);runis the service loop that re-warms the recently-used repos (tracked in a bounded LRU under{user-data}/warm-service/) on an interval. Guardrails are enforced: store-backed only (never a resident Roslyn compilation), a hard LRU cap (5 repos), battery-aware pause (GetSystemPowerStatuson Windows), idle-evict, and a clean uninstall with a first-run notice. It is never installed byfuse mcp installand stays opt-in for the agent-first default (R38/R39 cover the agent case); a promotion to opt-out requires measuring idle RSS/CPU/battery and showing they are light.
- Faster indexing: the git co-change collector no longer runs on the default index path (R41). The co-change prior is off in the shipping ranking (Decision D6, net-negative on the corpus), so mining and storing co-change on every index - a large share of the index hot path in
profile-v42.json(thegit logwalk) - was wasted work. It is now gated behindFUSE_COCHANGE(default off), removing that cost from every default index. No ranking or semantics change (the prior was already default-off, so its collected data was unused by default):fuse eval semanticsremains 24/24 (recall/precision 1.0) and the ranking default arm is unaffected.
- Per-root fallback store for non-git directories (R34): a directory outside a git repository now gets its own store at
~/.fuse/roots/{hash}/fuse.db(keyed by a hash of the normalized absolute path) instead of the single shared~/.fuse/fuse.db, so two unrelated non-git workspaces never collide on one store.FUSE_USER_DATAstill redirects the base. Migration: the old shared~/.fuse/fuse.dbfallback is abandoned, not migrated (it is derived data); delete it and the next index rebuilds per-root. The per-root stores under~/.fuse/roots/are safe to delete to reclaim space.
- Fault-injection resilience harness (R32):
ResilienceHarnessTestsinjects each fault (SQLite busy/locked, missingchunk_fts, sharing violation, corrupt database, extraction-version skew, integrity violation, unexpected exception) and asserts the invariant across the tool surface - a stable operational prefix or a graded answer, never an unhandled exception and never silent-empty. It is the standing guard that keeps the resilience contract true.
- Release build reliably propagates the version (R29): a
build/set-version.ps1bump is now reflected in the built assembly without a manual clean. AFuseStampVersionMarkertarget (inDirectory.Build.props) writes a generated marker only whenVersionchanges, forcingCoreCompileto restamp the assembly version, so the incremental build can no longer serve a stale-versionbin.build/verify-version.ps1 -BuildbuildsFuse.Cliand asserts the builtfuse --versionequals the codebase version and that the Releasefuse.dllis produced, as a release safety net against a mis-versioned or missing artifact.
- Skip-and-continue indexing on hostile inputs (R25/R35): a single unreadable, permission-denied, or oversized file no longer aborts the index. The scanner bounds per-file size at
FUSE_MAX_FILE_BYTES(default 5 MB), catches per-file IO/access failures, skips the file with a recorded reason, and keeps indexing the good files; the skipped set is recorded underskipped_filesinindex_metaand surfaced byfuse_workspace action=doctor. Symlink loops and directory symlinks are pruned by the existing reparse-point handling. - Indexing scope excludes vendored and generated trees (R25): the file scanner honors a
fuse.jsonignorearray (directory names, merged with.fuseignoreand the built-in defaults) and prunes any nested version-control root (a vendored checkout or submodule with its own.git) in the directory-walk path, matching the git-native path which already excludes.gitignored trees such astests/benchmarks/.corpusandsite/node_modules. There is no silent file cap;fuse_workspace action=statuscounts reflect the real source set. - Semantic solution/project discovery targets the repository's own solution (R24): a solution at or near the repo root is preferred over one nested under a test, fixture, or sample directory, so a repo like Fuse (root
Fuse.slnxplus a nestedtests/.../SampleShop.sln) no longer binds the typed graph to the fixture solution. Multiple distinct root-level solutions are resolved by name order and the choice is surfaced indoctor; when the only solutions are under fixture directories but the repo has real projects, those projects are loaded instead. A newfuse.jsonsolutionkey pins the target explicitly, andfuse_workspace action=doctornames the selected solution and warns on ambiguity or a fixture-directory selection.
SqliteExceptiondatabase locked duringOpenIndexedAsyncno longer escapes MCP tool boundaries as an opaqueAn error occurred invoking ...error; CLIfuse findno longer crashes with a stack trace on index lock.- Read-tool store opens and the per-read reconcile now apply a short (1 s) SQLite
busy_timeout, so a contended store surfaces theindex_busyavailability header within a couple of seconds instead of blocking on the 30 s write-path timeout; cold index builds keep the long timeout. This makes the R20 "blocked reads return the header within bounded time" contract hold in practice. - Host RPC error responses serialize
StreamJsonRpc.Protocol.CommonErrorDatathrough the source-generatedFuseHostJsonContext; previously any RPC method that threw surfaced aNotSupportedExceptionat the transport instead of the actual error (the ambient-verification hooks then stayed silent on real failures). fuse_checkdelta mode initializes the session-baseline store when the index is not yet built, matching the host RPC baseline path, instead of abstaining with "index unavailable" while a resident workspace is active.- Served-root binding enforced on every host RPC entry point that carries a
rootargument. operator.mdxno longer overclaims automaticfuse.dbrecreation; corrupt index recovery matches the implemented self-heal path.- A version/schema-mismatch rebuild now produces a fully working, searchable index (R23): the rebuild path re-probes FTS, recreates
chunk_fts, and stamps the index mode, instead of returning early and leaving a store that had indexed files but nochunk_fts. Previously the next search threwinternal_error: SQLite Error 1: 'no such table: chunk_fts'. - A search issued against a store missing
chunk_ftsnow maps to theindex_rebuilding:operational prefix (viaSearchIndexUnavailableException) and triggers a rebuild, never a rawinternal_error: SQLite Error. - FTS availability is a single source of truth (R23):
OpenForReadAsyncandGetStateAsyncreconcile thefts_availablestamp against the actualchunk_ftstable, so the availability line and the status body never disagree, and a stamp of "available" over a store missing the table forces a rebuild rather than serving broken search. - A store with indexed symbols but zero chunks on an FTS-available runtime is never reported
index_state: ready(R23); it reportsindex_rebuildingso the read path repairs it instead of serving silent-empty results. - Self-verifying index (R31): cheap state-based invariants (
IndexIntegrity) are checked on open and status - schema version set, index mode set (neverunknown), and chunks present when symbols exist on an FTS-available runtime. A store failing any invariant is never reportedready; it reportsindex_rebuildingand is repaired. A full index pass records the result underindex_integrityinindex_meta, andfuse_workspace action=status/doctorsurface the integrity line. - Semantic-tier symbols are persisted on the build-capture and resident-projection index paths (found by dogfooding v4.2 on the Fuse repo itself). The build-capture worker and
ProjectFromCompilationsAsynckeyed extracted symbol, node, route, DI, and options file paths to each project's directory rather than to the workspace root; on any nested layout (a project in a subdirectory, the normal case) those project-relative paths never matched the root-relativefiles.normalized_paththe store links foreign keys against, so every symbol was dropped (thesymbolstable ended up empty) and every node stored a nullfile_id. The result:fuse_find kind=symbolreturned zero hits for every query on a semantic index that reported thousands of symbols. The worker now takes the workspace root (passed via a new bounded--rootargument) andProjectFromCompilationsAsyncpasses the root, so all extracted rows are root-relative and resolve. No on-disk format change: v4.2.0 is unreleased and the capture bundle'sfuse_versionmajor.minor gate already refuses pre-4.2 bundles, so no re-capture beyond the normal cross-version rebuild is needed. Migration: reindex once (fuse_workspace action=index, or delete.fuse/fuse.db); an index built by a pre-fix v4.2 build has no symbols and should be rebuilt. - The
availability:header line now reports the reconciled FTS availability (WorkspaceIndexState.FtsAvailable, the stamp AND thechunk_ftstable), completing R23's single-source-of-truth guarantee. Previously the header readWorkspaceIndexStore.FullTextSearchAvailable, which reflects only whether that store instance initialized FTS; on the fast-status path the state is read without opening the store, so the property stayed default-false and the header could say "full-text search unavailable" while the status body correctly said "available". fuse_refactornow works on repositories that use the XML solution format (.slnx), including Fuse itself. Native.slnxparsing inMSBuildWorkspace.OpenSolutionAsyncshipped in Roslyn 5.0 (this release moves to 5.6.0), so the refactorers no longer fail with "No file format header found". The refactorers' load gate was also corrected to refuse only on genuine load failures (WorkspaceDiagnosticKind.Failure, captured and named) rather than on anyWorkspaceFailedevent; benign warnings (unresolved analyzer assemblies, SDK-resolver notes) that a healthy multi-project solution routinely emits no longer force an abstention. Shared asWorkspaceLoadFailures.Track, used by rename, change-signature, move-type/extract-interface, and apply-codefix. Verified: a solution-wide rename on Fuse produces the correct 15-file staged diff.fuse_reviewon a workspace that is not a git repository (or with an unresolvable base ref) now returns a cleanvalidation_error:naming the missing git precondition, instead of an opaqueinternal_error:.ChangeSourceExceptionandChangeDetectionExceptionare expected operational conditions for the change-scoped tools, so they map tovalidation_errorin the operational-error taxonomy. Found by smoke-testing a non-.NET directory.- Pinned the transitive
Microsoft.Bcl.Memory(pulled byMicrosoft.ML.Tokenizers.Data.*andBasic.CompilerLog.Util) forward from 9.0.4 to the patched 10.0.10; 9.0.4 carries a high-severity advisory (GHSA-73j8-2gch-69rq) that also made MSBuild's design-time restore fail the NuGet audit and blockedfuse_refactorfrom loading the workspace. fuse_reviewno longer hangs underfuse mcp serve(found by dogfooding). Subprocess spawns (GitChangeDetector, plus defensivelyGitFileEnumerator,GitCoChangeCollector,GitStatsProvider, and thedotnet buildinBuildGradeChecker) did not redirect their child's stdin, so inside the serve process the child inherited the live MCP client pipe as stdin and could block indefinitely;fuse_reviewwas the only default tool that spawns git, so it hung while every non-git tool answered. The CLI was unaffected (its stdin is a real console). Each spawn now redirects and immediately closes the child's stdin (the child gets EOF; none of these commands read stdin). Verified:fuse_reviewover a real diff now returns in about 30 seconds with the correct public-API delta.
- Fuse brand icon (
assets/fuse-icon.png,assets/fuse-icon.svg) on the NuGet package gallery, MCP Registry manifest, WinGet locale, site favicons, and the repository README. - Host RPC threat-model documentation (
internals/host-rpc) describes the local-trust IPC model: predictable per-root pipe or socket, handshake session token, and served-root binding on RPC methods that carry arootargument. The page documentsfuse/checkandfuse/checkOverlay. - Opt-in MCP metrics via
FUSE_METRICS=1(fuse.tool.duration,fuse.index.mode,fuse.reconcile.stamped) usingSystem.Diagnostics.Metrics(no OpenTelemetry dependency). WorkspacePathResolverconfines MCP file arguments (fuse_check,fuse_test,fuse_reduce,fuse_context, and related paths) to the workspace root.fuse.json/.fusercparse failures write a warning to stderr with the file path instead of failing silently.FUSE_MCP_INSTALL_HOMEredirects user-scope MCP install paths for isolated testing; user-scope install coverage for Cursor and Copilot.- Integration tests for split-store cache recovery, storm reconcile (>300 dirty files), MCP read-after-edit freshness, resident storm eviction (301-file batch), and workspace path escape refusal.
- Derived key-value cache data (reduction cache and per-file analysis index) now lives in
.fuse/fuse-cache.dbinstead of sharing.fuse/fuse.dbwith the semantic index. Existing cached entries infuse.dbare not migrated; rerun with--use-cacheor--use-persistent-indexto rebuild the derived cache. The semantic index infuse.dbis unchanged. ExperimentalOptionsnow carries only focus/change scoping and emission-shaping knobs the fusion pipeline consumes (CentralityWeight,TieredEmission,SketchHugeFiles,DowngradeBeforeDrop,ProximityEdges,ProjectGraph). Query-path retrieval levers were removed from this type; open-ended localize and related lexical ranking live inFuse.Retrieval.- Host RPC methods that carry a
rootargument reject calls where the root differs from the daemon's served root (the--directorythefuse hostprocess started with). - Syntax indexing routes exclusively through
SemanticIndexerand language syntax providers; the standaloneSyntaxIndexertype is removed. - The retired flat FTS candidate generator is gated behind
FUSE_FLAT_FTS=1diagnostic mode; shipping default remainsLexicalCandidateGeneratoronly. - Performance documentation and README warm-latency figures align with
tests/benchmarks/results/performance.jsonandresident-latency.json. briefing.mdopening reflects nine MCP tools, no VS Code extension (D15), and corpus-v2 localize recall (37.7 percent).- The fuse.codes landing page uses a centered hero with terminal-style install commands, benchmark stats, and a shared site footer; WinGet manifests are included in
set-version.ps1andverify-version.ps1.
- When FTS5 is unavailable at index init, the store persists
fts_available=falsein index meta, names it infuse_workspacestatus and the availability header, andfuse_find kind=taskrefuses with an actionable message instead of returning empty hits. SqliteKeyValueStorecorruption recovery refuses to delete the semantic index database; onlyfuse-cache.dbis recreated on corruption.
fuse mcp install --rulesat project scope appends.fuse/to.gitignorewhen no equivalent entry exists (same helper asfuse init).- Connect-your-agent documentation covers manual registration for other MCP clients (Windsurf, Cline, Zed, and custom agents) over the same
fuse mcp servestdio server.
- Consumer copy on fuse.codes, the README, and the docs index uses mechanism-first language for senior .NET developers and MCP authors (warm index, typed graph, verification grade) instead of two-beat marketing slogans.
- Docs and install help state that MCP read tools build
.fuse/fuse.dbon first use;fuse indexorfuse_workspace action=indexremain optional pre-warm steps before the agent's first turn. - Product copy names Cursor, Claude Code, and Copilot as common MCP clients with auto-install, not as an exclusive list; any MCP-compatible client can run
fuse mcp serve. - The landing page hero is simplified: one demo, Connect and Quickstart CTAs, proof stats and install blocks moved below the fold.
- Mermaid flowcharts and theme-aware SVG diagrams render on the documentation site instead of appearing as raw code blocks.
- Portable capture bundles no longer fail the secret scan on Roslyn
RegexGenerator.g.csemitted files.
Fuse is a resident .NET compiler service for AI agents. It holds a workspace's Roslyn compilations in memory, verifies a proposed edit before it lands, computes a change's blast radius, stages compiler-executed refactors as diffs, runs the covering tests for a symbol, and resolves what the code actually runs. Every answer is stamped with a verification grade, and Fuse abstains honestly when it cannot answer at compiler grade rather than guessing. Scoped, reduced context and a deterministic lexical retrieval channel are the supporting machinery that feed those answers. It ships as a .NET global tool (fuse) and as a Model Context Protocol server (fuse mcp serve).
The server exposes a loop-shaped surface of eight tools, each one mental act, plus fuse_reduce as the one out-of-loop utility. The loop is teachable in a tool description: after an edit run fuse_check; before a signature change run fuse_impact; before done run fuse_review.
fuse_workspace- status and lifecycle.action=status(index mode, verification grade, freshness),index(build or refresh the index),map(symbols, routes, counts),doctor(per-project semantic-load diagnosis), andapply(write a proposed single-file edit to the working tree - the one explicit tree-write path, a dry run unlesswrite=true, refusing any path that escapes the workspace root).fuse_find- the find union, keyed bykind:symbol|path|text|all(exact lookup),service|request|route|config(resolve wiring to implementation, handler, action, or options),signatures(a symbol's exact signature, resolved from a resident compilation's real metadata when one serves the root),neighbors(callers and implementers), andtask(rank candidate files with the graded refuse-and-route contract). No source bodies.fuse_context- emit scoped, reduced source with a semantic manifest and per-file provenance for selected seeds.fuse_impact- blast radius for a symbol (callers, implementers, referencing types) from the persisted graph; also a NuGet upgrade break set viapackage:{id,fromVersion,toVersion}.fuse_check- typecheck a proposed single-file edit and return the diagnostics it would produce, with repair packets on API-shape errors. The verification-grade ladder means it never shrugs: oracle-grade against the build-captured compilation when tier-1 is available, else build-grade by runningdotnet buildscoped to the owning project, abstaining only when even the toolchain cannot run.fuse_test- run the covering tests for a symbol (the tests that reach it through the persistedtestsedges), scoped by filter so the whole suite never runs. Candidate racing (candidates): speculatively typecheck several proposed single-file edits against one resident compilation and get a per-candidate verdict plus a winner by strict dominance (a clean candidate beats any with errors; ties reported), so an agent weighing plausible fixes learns which survives without picking on vibes.fuse_refactor- compiler-executed, verify-gated refactors staged as a diff: rename, add/remove/reorder-parameter, add-cancellation-token, extract-interface, move-type, apply-codefix. Each recompiles and returns the diff only when no new diagnostic is introduced, else abstains.fuse_review- diff-first change impact and packed context, opening with a public API delta and carrying a paste-ready PR handoff packet (handoff=true) gated on a clean check session.fuse_reduce- compact a known set of files or raw content; the one utility outside the loop.
The MCP server also exposes playbook prompts (anchored plans that teach the verified-edit loop) and addressable resources for the map, localize, context, review, status, diagnostics, diff, and session-ledger workflows.
- The verification-grade ladder. Every
fuse_checkanswer is stampedoracle(a speculative in-memory typecheck against the tier-1 build-captured compilation),build(the realdotnet buildtoolchain scoped to the owning project, parsed into the same shape), orabstain(only when even the toolchain cannot run, always naming the missing prerequisite). The build-grade path never writes the working tree; it mirrors the owning project to a temporary directory with the one file replaced and project references rewritten to absolute paths. Because a rehydrated compilation is analyzed, never emitted, strong-name signing is neutralized before its diagnostics are read, so a captured relative key-file path that does not resolve in the rehydration sandbox never surfaces as a spurious signing error (CS7027) nor drops a cleanly building strong-named repository below tier-1. - Delta mode and persisted sessions. Pass a
sessionid with no content andfuse_checkreturns the diagnostics your on-disk edits introduced or resolved since the session baseline. Baselines persist to the store, so a restarted process resumes intact;markGreenresets the baseline andfullreturns the whole current set. Delta mode never runs a build; it reads whole-state diagnostics from a live resident workspace and abstains when none serves the root. - Repair packets. An API-shape diagnostic (a missing member, an unknown type, a missing argument, a wrong-type assignment) carries a machine-applicable fix (the offending token and the nearest recorded name to substitute), rendered as an
apply: replace 'X' with 'Y'line, drawn from the persisted symbol table so the fix costs no round-trip. - Analyzer and nullable parity. When a resident workspace serves the root,
fuse_checkalso runs the repository's configured analyzers and nullable warnings against the overlay at the editorconfig severities, so a green check matches what CI's build step enforces. On by default for the single-file verify, off for the hot per-edit delta path. - Graded claims and the evidence ledger. The statements Fuse emits are graded by the evidence behind them:
verified(compiler- or test-grade),partially verified(graph-grade, the inflation guard),stale, andcontradicted. Claims accumulate into a session ledger addressable as a resource.
A resident workspace rehydrates a tier-1 build capture once and holds the per-project Roslyn compilations in memory, so a proposed edit typechecks against a live compilation with no build and no disk write, and a file watcher keeps it current. It is opt-in this release (FUSE_RESIDENT), projecting the changed cone into the store so store-backed reads reflect edits.
One fuse host daemon per repository can hold the resident workspace as a shared asset, so multiple agent sessions and the ambient hooks read one warm compilation instead of each paying its own cold start and memory. A daemon acquires a single-instance lock per root (a redundant second host exits cleanly), stops itself after an idle window (FUSE_DAEMON_IDLE_MINUTES), and refuses a protocol-mismatched client so a stale client after an upgrade triggers a clean restart. fuse mcp serve with FUSE_DAEMON=1 delegates its resident checks to the daemon over the pipe instead of holding its own workspace, falling back to in-process when no daemon can start; fuse workspace status names the daemon (PID, uptime, memory). Measured on NodaTime: two sessions cost one resident workspace (about 109 MB) instead of two. Opt-in this release.
fuse_refactor runs Roslyn-driven, verify-gated edits: rename (a same-named unrelated symbol is not renamed), the change-signature family (add/remove/reorder-parameter with semantic-safety abstentions, add-cancellation-token threading an in-scope token), extract-interface, move-type, and apply-codefix (driving a diagnostic to zero with the repository's own analyzer fixes). Every operation recompiles and returns a diff only when no new diagnostic is introduced, otherwise abstaining with the offending sites named.
- The persistent index. A single SQLite database at
.fuse/fuse.db(WAL mode) holds files, projects, symbols, chunks, a typed semantic graph, routes, and an FTS5 full-text index. The workspace loads through MSBuild and Roslyn with a syntax-only fallback; re-indexing is incremental per changed file, and no read tool serves silently stale data (a warm store is reconciled against the current on-disk content before it answers). - The wiring analyzers. The semantic analyzers resolve DI registration and constructor injection (including keyed DI), MediatR request-to-handler, ASP.NET route-to-action, options binding, EF Core, Scrutor decoration, factory and hosted-service registration, pipeline behaviors, minimal-API, gRPC, and SignalR. Persisted
referencesand DI-resolvedtestsedges backfuse_impactand covering-test selection. - Retrieval. A deterministic lexical channel (BM25F over the FTS5 table) with offline subword, stem, and comment bridges plus a dependency-centrality prior. No model is fetched or shipped. Ranked task localization is the fallback mode; the precise path is an anchor (symbol, route, service, request, config, git base) resolved through the graph. The git co-change prior is off by default: its semantic-mode re-adjudication on corpus v2 recorded it as net-negative to ranking (MRR 0.434 with the prior versus 0.489 without), so it was dropped from the shipping default; the ranking gate keeps it measured behind a diagnostic config.
- Multi-language syntax tier. A provider seam drives the syntax tier; C# is first-party, and Python and JavaScript/TypeScript are supported at the syntax tier. Each indexed file carries a
languagetag. The deep typed graph is C#/Roslyn only. - Tier-1 build capture is default-on and the worker is bundled. The oracle is the product: the build-capture worker ships inside the global tool (under
build-capture/besidefuse) and is discovered with no configuration, and tier-1 build capture is attempted by default. It degrades cleanly when no build target exists or a build fails (to the MSBuild and syntax tiers), and opts out withFUSE_BUILD_CAPTURE=0. Infuse mcp servethe cold start is syntax-first with a supervised background upgrade to the semantic/tier-1 graph, so the first reads return in seconds while the build runs behind them; the availability header names when a build is running for tier-1, andFUSE_BG_UPGRADE=0opts back into a synchronous first read.fuse indexon the CLI is always synchronous. - Portable capture bundles.
fuse capture --out <bundle>builds once and packages the compiler log, the extracted graph, and a versioned manifest;fuse index --from-capture <bundle>rehydrates the semantic graph and answersfuse_checkat oracle grade on a machine that cannot restore or build, with no build. The bundle never ships the MSBuild binary log, and a planted secret fails the capture closed. An in-repo GitHub Action captures a bundle onmain.fuse capture --merge <dir>assembles a bundle from per-project fragment binary logs (a build-target channel), equal in extracted graph to a direct capture; the bundle format is backward-compatible (a newer Fuse reads an older bundle; a bundle newer than the running Fuse is refused with an actionable message).
fuse_context plans and emits source at mixed render tiers with a semantic manifest and per-file provenance, honoring a token budget and eliding files already sent in a session. fuse_review opens with a public API delta (members added, removed, or changed between the git base and the working tree, each flagged breaking or additive) and produces a paste-ready PR handoff packet gated on a clean check session. The Roslyn skeleton reduction keeps every public and protected type and nearly all public methods while removing a large share of tokens; fidelity is measured against Roslyn as independent ground truth. Secret redaction runs before any source reaches a payload.
fuse index, map, localize, resolve, context, review, find, impact, check, test, refactor, diagnostics, doctor, reduce, up, verify, gate, init, update, mcp (install and serve), and host. fuse review --handoff and fuse impact --package mirror the agent verbs.
fuse check --delta prints the diagnostics your session's on-disk edits introduced or resolved since its baseline; fuse gate exits nonzero while the session has introduced errors it has not resolved (baseline discipline: only errors the session itself introduced block). Both connect to an already-running host over a pipe and never run a build; with no host serving the root they exit 0 silently, so a hook never blocks editing. fuse mcp install --with-hooks writes the matching Claude Code hooks into project .claude/settings.json.
fuse up diagnoses why a workspace does not load at oracle grade (per-project tiers and the concrete reason for each downgrade) and, with --apply, applies an install-free remedy (a NuGet source-mapping overlay for the NU1507 multi-source case) and re-attempts the load, never editing the repository. Consent-gated install remedies (an SDK band per global.json, a missing workload) run only behind --allow-install. fuse verify --ci-parity reads the repository's CI workflows, extracts the dotnet command sequence, and names the steps it cannot rehearse locally.
fuse_impact package:{id,fromVersion,toVersion} diffs the public API of two package versions (resolved from the local NuGet cache) and lists the breaking changes a bump would introduce, abstaining offline and naming its blind spots (reflection and dynamic usage; external call sites are not tracked) on every report.
Fuse ships under the Apache License, Version 2.0, with an explicit patent grant and a NOTICE file. Contributions require a Developer Certificate of Origin sign-off (git commit -s), enforced in CI.
Persistent cache and index data live in a single SQLite file at .fuse/fuse.db (WAL mode). The index records the Fuse build that wrote it and rebuilds itself on an incompatible upgrade rather than serving stale extraction. The product version lives in the codebase (Directory.Build.props), and one tag releases the NuGet package, the GitHub binaries, and the MCP registry manifest together.