Skip to content

Commit 4f6fdac

Browse files
authored
Merge pull request #28 from Litenova-Solutions/release/v4.2
Release v4.2.0: daemon-owned single-writer index, operational-error taxonomy, performance milestone (R42-R50)
2 parents f12b65f + 97c7a75 commit 4f6fdac

316 files changed

Lines changed: 24814 additions & 3473 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-sdk.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: CI SDK
2+
3+
# RequiresSdk integration tests need a working .NET SDK and the bundled build-capture worker.
4+
# They are excluded from the default CI leg (Category!=RequiresSdk) for fast feedback.
5+
6+
on:
7+
pull_request:
8+
branches: [main, master]
9+
push:
10+
branches: [main, master]
11+
12+
jobs:
13+
sdk-tests:
14+
name: RequiresSdk tests (${{ matrix.rid }})
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
include:
20+
- os: windows-latest
21+
rid: win-x64
22+
- os: ubuntu-latest
23+
rid: linux-x64
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup .NET
30+
uses: actions/setup-dotnet@v4
31+
with:
32+
dotnet-version: '10.0.x'
33+
34+
- name: Install Linux publish prerequisites
35+
if: runner.os == 'Linux'
36+
run: |
37+
sudo apt-get update
38+
sudo apt-get install -y clang zlib1g-dev
39+
40+
- name: Restore
41+
run: dotnet restore Fuse.slnx
42+
43+
- name: Build
44+
run: dotnet build Fuse.slnx --configuration Release --no-restore
45+
46+
- name: Test RequiresSdk
47+
run: dotnet test Fuse.slnx --configuration Release --no-build --verbosity normal --filter "Category=RequiresSdk"

.github/workflows/ci.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ jobs:
2424
shell: pwsh
2525
run: ./build/verify-version.ps1
2626

27+
- name: Verify RequiresSdk CI legs
28+
shell: pwsh
29+
run: ./build/verify-ci-sdk.ps1
30+
31+
- name: Verify briefing drift guard
32+
shell: pwsh
33+
run: ./build/verify-briefing.ps1
34+
2735
- name: Validate MCP registry manifest
2836
shell: pwsh
2937
run: |
@@ -83,7 +91,7 @@ jobs:
8391
run: dotnet tool install --global dotnet-coverage
8492

8593
- name: Test with coverage
86-
run: dotnet-coverage collect "dotnet test Fuse.slnx --configuration Release --no-build --verbosity normal" --output coverage.cobertura.xml --output-format cobertura
94+
run: dotnet-coverage collect 'dotnet test Fuse.slnx --configuration Release --no-build --verbosity normal --filter "Category!=RequiresSdk"' --output coverage.cobertura.xml --output-format cobertura
8795

8896
- name: Upload coverage to Codecov
8997
uses: codecov/codecov-action@v5

AGENTS.md

Lines changed: 10 additions & 5 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 115 additions & 8 deletions
Large diffs are not rendered by default.

Directory.Build.props

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<!-- Single source of truth for the product version, applied to every Fuse assembly so the CLI, the host,
55
and FuseBuildInfo (the index version stamp) all report the same number. The release tag must match this
66
(enforced by build/verify-version.ps1); bump every package in lockstep with build/set-version.ps1. -->
7-
<Version>4.1.0</Version>
7+
<Version>4.2.0</Version>
88
<TargetFramework>net10.0</TargetFramework>
99
<ImplicitUsings>enable</ImplicitUsings>
1010
<Nullable>enable</Nullable>
@@ -23,6 +23,12 @@
2323
writes and test method names unrelated to async correctness. Suppress the family repo-wide to keep the
2424
zero-warning gate; the host transport code itself is written fully async. -->
2525
<NoWarn>$(NoWarn);VSTHRD002;VSTHRD003;VSTHRD100;VSTHRD101;VSTHRD103;VSTHRD110;VSTHRD111;VSTHRD114;VSTHRD200</NoWarn>
26+
<!-- Microsoft.Build.Locator 1.11.2 added the MSBL001 check that errors when the transitive Microsoft.Build.*
27+
assemblies (pulled by Microsoft.CodeAnalysis.Workspaces.MSBuild) are copied to output. Fuse never loads
28+
those copies: every entry point calls MSBuildLocator.RegisterDefaults() before touching any MSBuild type,
29+
so the real MSBuild is resolved from the installed SDK, not the restored package. This is the documented
30+
case the opt-out is for, and it preserves the pre-1.11.2 behavior the tool already shipped with. -->
31+
<DisableMSBuildAssemblyCopyCheck>true</DisableMSBuildAssemblyCopyCheck>
2632
</PropertyGroup>
2733

2834
<PropertyGroup Condition="!$(MSBuildProjectName.EndsWith('.Tests'))">
@@ -54,4 +60,26 @@
5460
<HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
5561
<UseSystemResourceKeys>true</UseSystemResourceKeys>
5662
</PropertyGroup>
63+
64+
<!-- R29: a version bump in this file must be reflected in the built assembly without a manual clean. The
65+
incremental build can otherwise serve a stale-version bin after set-version.ps1. This target runs before
66+
every compile and writes a generated marker only when its content (the version) changed
67+
(WriteOnlyWhenDifferent), so the marker's timestamp advances exactly when Version changes. The marker is
68+
an unconditional Compile input, so CoreCompile stays up to date on a normal build but is forced to rerun
69+
(restamping the assembly version) when the version bump rewrites the marker. Cheap and harmless (one
70+
assembly metadata attribute); the unconditional Compile item keeps the input list stable to avoid churn. -->
71+
<Target Name="FuseStampVersionMarker" BeforeTargets="BeforeCompile;CoreCompile">
72+
<PropertyGroup>
73+
<_FuseVersionMarkerContent>// Generated by Directory.Build.props (R29): forces a recompile when Version changes.
74+
[assembly: System.Reflection.AssemblyMetadata("FuseBuildVersion", "$(Version)")]</_FuseVersionMarkerContent>
75+
</PropertyGroup>
76+
<WriteLinesToFile File="$(IntermediateOutputPath)FuseVersionMarker.g.cs"
77+
Lines="$(_FuseVersionMarkerContent)"
78+
Overwrite="true"
79+
WriteOnlyWhenDifferent="true" />
80+
<ItemGroup>
81+
<Compile Include="$(IntermediateOutputPath)FuseVersionMarker.g.cs" />
82+
<FileWrites Include="$(IntermediateOutputPath)FuseVersionMarker.g.cs" />
83+
</ItemGroup>
84+
</Target>
5785
</Project>

Directory.Packages.props

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,58 @@
11
<Project>
22
<PropertyGroup>
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4+
<!-- Pin transitive dependencies that have a PackageVersion here, so a vulnerable transitive can be lifted to a
5+
patched version without taking a direct dependency. Used for Microsoft.Bcl.Memory below. -->
6+
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
47
</PropertyGroup>
58
<ItemGroup>
69
<PackageVersion Include="DotMake.CommandLine" Version="3.1.0" />
710
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
8-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
9-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
10-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
11-
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
12-
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.14.0" />
13-
<!-- Pinned so the build-capture worker (which pulls Basic.CompilerLog's floor dependency on VisualBasic 4.8)
14-
resolves VisualBasic to 4.14, matching CodeAnalysis.Common 4.14; a 4.8 VB assembly over a 4.14 Common
15-
throws TypeLoadException. The worker never compiles VB; the pin is purely for version consistency. -->
16-
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.14.0" />
17-
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.14.0" />
18-
<PackageVersion Include="Microsoft.Build.Locator" Version="1.7.8" />
11+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.10" />
12+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.10" />
13+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.10" />
14+
<!-- The Roslyn family is pinned to one version. The metapackage (Microsoft.CodeAnalysis) and the *.Common
15+
components arrive transitively (Basic.CompilerLog.Util) at an older floor with exact-version dependencies
16+
that conflict with the 5.6.0 stack; pinning them forward via transitive pinning keeps the whole graph
17+
version-consistent, so no NU1608 constraint mismatch fails the MSBuildWorkspace design-time load. -->
18+
<PackageVersion Include="Microsoft.CodeAnalysis" Version="5.6.0" />
19+
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.6.0" />
20+
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="5.6.0" />
21+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.6.0" />
22+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.6.0" />
23+
<!-- Pinned so the build-capture worker (which pulls Basic.CompilerLog's floor dependency on an older VisualBasic)
24+
resolves VisualBasic to 5.6.0, matching CodeAnalysis.Common 5.6.0; a mismatched VB assembly over a newer
25+
Common throws TypeLoadException. The worker never compiles VB; the pin is purely for version consistency. -->
26+
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="5.6.0" />
27+
<!-- VisualBasic.Workspaces arrives transitively (Basic.CompilerLog.Util) at an older floor whose exact-version
28+
dependencies (Common = 4.8.0, etc.) conflict with the 5.6.0 stack. Pinned forward to 5.6.0 via transitive
29+
pinning so the whole Roslyn graph is version-consistent; otherwise the NU1608 constraint mismatch fails the
30+
MSBuildWorkspace design-time load and blocks fuse_refactor. -->
31+
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="5.6.0" />
32+
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="5.6.0" />
33+
<PackageVersion Include="Microsoft.Build.Locator" Version="1.11.2" />
1934
<!-- N4 tier-1 build capture. Referenced ONLY by the out-of-process Fuse.BuildCaptureWorker (never by the
2035
parent process that hosts MSBuildWorkspace), because the two Roslyn-loading closures conflict in one
21-
process; the worker uses build capture and never invokes MSBuildWorkspace, so its 4.8 floor resolves to
22-
this repo's 4.14 without breaking anything. -->
36+
process; the worker uses build capture and never invokes MSBuildWorkspace, so its floor resolves to
37+
this repo's 5.6.0 without breaking anything. -->
2338
<PackageVersion Include="Basic.CompilerLog.Util" Version="0.9.47" />
24-
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.0" />
25-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.3" />
39+
<!-- Transitive of Microsoft.ML.Tokenizers.Data.* and Basic.CompilerLog.Util. 9.0.4 (the version they request)
40+
carries a high-severity advisory (GHSA-73j8-2gch-69rq); pinned forward to the patched net10-aligned 10.0.10
41+
via CentralPackageTransitivePinningEnabled. Without this, MSBuild design-time restore fails the audit and
42+
MSBuildWorkspace refuses to load the solution, which blocked fuse_refactor. -->
43+
<PackageVersion Include="Microsoft.Bcl.Memory" Version="10.0.10" />
44+
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.10" />
45+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.10" />
2646
<PackageVersion Include="Microsoft.ML.OnnxRuntime" Version="1.27.0" />
27-
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="1.0.2" />
28-
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.Cl100kBase" Version="1.0.2" />
29-
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.O200kBase" Version="1.0.2" />
30-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
31-
<PackageVersion Include="ModelContextProtocol" Version="0.8.0-preview.1" />
47+
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="2.0.0" />
48+
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.Cl100kBase" Version="2.0.0" />
49+
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.O200kBase" Version="2.0.0" />
50+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.8.1" />
51+
<PackageVersion Include="ModelContextProtocol" Version="1.4.1" />
3252
<PackageVersion Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.3" />
3353
<PackageVersion Include="StreamJsonRpc" Version="2.21.10" />
34-
<PackageVersion Include="System.IO.Hashing" Version="9.0.0" />
35-
<PackageVersion Include="xunit" Version="2.9.2" />
36-
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
54+
<PackageVersion Include="System.IO.Hashing" Version="10.0.10" />
55+
<PackageVersion Include="xunit" Version="2.9.3" />
56+
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
3757
</ItemGroup>
3858
</Project>

Fuse.slnx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Project Path="src/Core/Fuse.Fusion/Fuse.Fusion.csproj" />
2020
<Project Path="src/Core/Fuse.Indexing/Fuse.Indexing.csproj" />
2121
<Project Path="src/Core/Fuse.Semantics/Fuse.Semantics.csproj" />
22+
<Project Path="src/Core/Fuse.Scoping/Fuse.Scoping.csproj" />
2223
<Project Path="src/Core/Fuse.Workspace/Fuse.Workspace.csproj" />
2324
<Project Path="src/Core/Fuse.Retrieval/Fuse.Retrieval.csproj" />
2425
<Project Path="src/Core/Fuse.Context/Fuse.Context.csproj" />
@@ -46,6 +47,7 @@
4647
<Project Path="src/Core/Fuse.Semantics/Fuse.Semantics.csproj" />
4748
<Project Path="src/Core/Fuse.Workspace/Fuse.Workspace.csproj" />
4849
<Project Path="src/Core/Fuse.Retrieval/Fuse.Retrieval.csproj" />
50+
<Project Path="src/Core/Fuse.Scoping/Fuse.Scoping.csproj" />
4951
<Project Path="src/Core/Fuse.Context/Fuse.Context.csproj" />
5052
</Folder>
5153
<Folder Name="/src/Plugins/">

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ syntax-level indexing for that project and reports the mode.
4747
- **Pack branch context.** `fuse_review` seeds on the git diff and returns related callers,
4848
handlers, and tests with provenance. On 69 recorded pull requests the median response was
4949
1,026 tokens at 93.4 percent precision (`review.json`).
50-
- **Read warm.** On the recorded NodaTime run, exact symbol lookup took 2.2 ms at the
51-
median, task localization 23.4 ms, and review planning 97.8 ms (`performance.json`;
52-
timings are environment-dependent).
50+
- **Read warm.** On the recorded NodaTime run (semantic tier, 14,760 symbols), exact
51+
symbol lookup took 1.8 ms at the median, task localization 15.7 ms, and review planning
52+
106.3 ms (`performance.json`; timings are environment-dependent).
5353

5454
<p align="center">
55-
<img src="assets/fuse-wiring-example.svg" alt="Fuse resolves an interface through dependency injection registration to its concrete implementation and related callers." width="820">
55+
<img src="assets/fuse-typed-wiring.svg" alt="Fuse resolves an interface through dependency injection registration to its concrete implementation and related callers." width="820">
5656
</p>
5757

5858
## Use It During Daily Work

SECURITY.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,21 @@ Out of scope:
3737
## Safe Defaults
3838

3939
Fuse indexes and serves code locally. It does not send your repository to a remote model as part of indexing. Verify MCP client configuration if you use cloud-hosted models alongside Fuse tools.
40+
41+
## Local-Trust Host IPC
42+
43+
`fuse host` exposes a JSON-RPC surface over a named pipe (Windows) or Unix domain socket (Linux and macOS). Fuse treats this as **local-trust IPC**, not a network-authenticated service.
44+
45+
**Any local user who can open the pipe can call RPC** once they hold the session token from `fuse/handshake`. On a typical developer workstation, any process running as your OS user can connect to local pipes and sockets. The predictable per-repository endpoint name is intentional (clients find the daemon without an out-of-band address), not a secret.
46+
47+
Three mechanisms reduce casual abuse without pretending the endpoint is internet-hardened:
48+
49+
| Layer | Mechanism | Limit |
50+
|-------|-----------|-------|
51+
| Endpoint | Pipe or socket name derived from the repository root | Does not hide the endpoint from other same-user processes |
52+
| Handshake | Random session token required on every method after `fuse/handshake` | Not a substitute for login; a same-user peer can observe the handshake |
53+
| Served root | Every RPC with a `root` argument must match the daemon's `--directory` | Blocks pivoting to a different repository path through the RPC surface |
54+
55+
On Windows, set `FUSE_HOST_RESTRICT_PIPE=1` before starting `fuse host` to restrict the named-pipe ACL to the current user only (off by default). Unix domain sockets remain governed by filesystem permissions under the system temp directory.
56+
57+
For the full threat model, exposure table, and operational guidance, see [Host RPC threat model](https://fuse.codes/docs/internals/host-rpc) (`site/content/docs/internals/host-rpc.mdx` in the repository).

0 commit comments

Comments
 (0)