Repository navigation
feat(#1707): extract the NodeType compile toolchain into MeshWeaver.Compiler - #1712
Conversation
…ompiler — the framework identity pins the toolchain, not the graph Everything that shapes a dynamic NodeType compile's GENERATED INPUT moves below MeshWeaver.Graph into a dedicated MeshWeaver.Compiler assembly: the skeleton generator, CodeQueryResolver (+ CodeConventions), @@-include shaping and source aggregation/filter/join order (NodeCompileShaping), the reference set (CompileReferences), #r/generator shaping (GeneratorPipeline), parse/compile options + the staged, verified emit + the emit canary (EmitPipeline), failure diagnostics (CompileDiagnostics), the framework identity (FrameworkBuildIdentity, now also the process-lifetime FrameworkVersion accessor), the store naming (FileSystemAssemblyStore), and the pure adoption gate. FullMvidAssemblies flips to [MeshWeaver.Compiler, MeshWeaver.NuGet] — the NuGet entry closes a pre-existing hole (NuGetDirectiveParser/resolver shape compile input but were surface-hashed only). Graph body edits stop rebaking the world; 'rebuild only when we need to' (#1696) now holds in practice. The store's filename hash is a digest of the EMITTED bytes, so the extraction is complete by construction: any input-shaping left behind would serve stale DLLs. The mesh-actor half (discovery, impersonation, IoPool scheduling, status write-backs) stays in Graph and orchestrates the toolchain — one pipeline for the portal's on-demand compile, the batch bake, and the CI bake host. Moved public types keep their namespace and are TypeForwardedTo from Graph so modules compiled against earlier releases keep binding. Plugin.Build's IdentityAssembly anchor follows the toolchain (MeshWeaver.Compiler.dll); the manifest-less local fallback is the anchor's MVID (every persistent-store host ships a surface manifest and resolves the s-hash even locally). First roll after this merges mints a new identity (one-time full rebake — the key scheme changed), after which internal-only and Graph-body merges invalidate nothing. Docs (CiContentBake, NodeTypeCompilation incl. the corrected HasUsableBuild rules, ReleaseProcess, Modules, BuildCoordination) and all tests adapted. Part of #1707 (slice 1); under #1660. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR extracts the dynamic NodeType compilation toolchain out of MeshWeaver.Graph into a new MeshWeaver.Compiler assembly, so the framework build identity can pin a smaller, lower-churn implementation boundary while keeping Graph responsible for the mesh-actor/orchestration side.
Changes:
- Introduces
src/MeshWeaver.Compiler/and moves compile-input shaping + Roslyn emit pipeline + identity plumbing into it (with Graph keeping orchestration and adding type-forwards for binary compatibility). - Re-anchors framework identity/full-MVID exceptions to
MeshWeaver.Compiler(+MeshWeaver.NuGet) and updates callers/tests accordingly. - Updates documentation (architecture + What’s New) to reflect the new toolchain assembly and revised identity/compile-skip semantics.
Reviewed changes
Copilot reviewed 40 out of 45 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| MeshWeaver.slnx | Adds the new MeshWeaver.Compiler project to the solution. |
| src/MeshWeaver.Compiler/MeshWeaver.Compiler.csproj | New compiler/toolchain project (Roslyn dependency + IVT for key consumers/tests). |
| src/MeshWeaver.Compiler/README.md | Documents the purpose/scope of the extracted compiler assembly. |
| src/MeshWeaver.Compiler/NodeCompileShaping.cs | Extracts “generated input” shaping (include scan/anchor, query fold, snapshot race, join order). |
| src/MeshWeaver.Compiler/CompileReferences.cs | Centralizes Roslyn reference set construction (TPA baseline + module composition seam). |
| src/MeshWeaver.Compiler/GeneratorPipeline.cs | Centralizes #r/generator shaping and generator execution pipeline. |
| src/MeshWeaver.Compiler/SourceGeneratorLoader.cs | Loads/discovers Roslyn generators from #r-resolved assemblies. |
| src/MeshWeaver.Compiler/EmitPipeline.cs | Extracts parse/compile/emit pipeline + disk emit retry/verification + canary. |
| src/MeshWeaver.Compiler/EmittedArtifact.cs | Carries emitted artifact fingerprint used to verify staged disk output. |
| src/MeshWeaver.Compiler/CompileDiagnostics.cs | Centralizes compile-failure formatting + structured diagnostic derivation + discovery reporting. |
| src/MeshWeaver.Compiler/CompilationInputs.cs | Shared compilation input model for LSP/speculative compilation. |
| src/MeshWeaver.Compiler/SpeculativeCompilation.cs | Updates speculative compilation to use the shared skeleton diagnostics sentinel. |
| src/MeshWeaver.Compiler/FrameworkBuildIdentity.cs | Moves/updates framework identity resolution and full-MVID exception membership. |
| src/MeshWeaver.Compiler/FileSystemAssemblyStore.cs | Re-anchors assembly-store framework tag to FrameworkBuildIdentity.FrameworkVersion. |
| src/MeshWeaver.Compiler/DynamicMeshNodeAttributeGenerator.cs | Moves skeleton/provider source generation into the toolchain assembly. |
| src/MeshWeaver.Compiler/CodeConventions.cs | Defines toolchain-owned “Code” node conventions/constants to prevent drift. |
| src/MeshWeaver.Compiler/CodeQueryResolver.cs | Updates query resolution defaults/filters to use toolchain conventions. |
| src/MeshWeaver.Compiler/CompilationException.cs | Moves the public compile exception type (kept in MeshWeaver.Graph.Configuration namespace). |
| src/MeshWeaver.Compiler/AssemblyStoreExtensions.cs | Moves assembly-store DI helpers into the extracted toolchain layer. |
| src/MeshWeaver.Graph/MeshWeaver.Graph.csproj | References MeshWeaver.Compiler and documents the split of responsibilities. |
| src/MeshWeaver.Graph/Properties/CompilerTypeForwards.cs | Type-forwards moved public types to preserve binary compatibility for older module builds. |
| src/MeshWeaver.Graph/Configuration/MeshNodeCompilationService.cs | Refactors to use toolchain shaping/emit/diagnostics instead of inlining those behaviors. |
| src/MeshWeaver.Graph/Configuration/NodeTypeCompilationHelpers.cs | Delegates framework identity resolution to FrameworkBuildIdentity (toolchain anchor). |
| src/MeshWeaver.Graph/Configuration/PrebuiltAssemblySeeder.cs | Updates comments/identity references to align with new framework identity resolution. |
| src/MeshWeaver.Graph/Configuration/MeshNodeLanguageService.cs | Aligns skeleton diagnostics sentinel with toolchain constant. |
| src/MeshWeaver.Graph/Configuration/CodeNodeType.cs | Aliases code-node conventions to toolchain constants to prevent drift. |
| src/MeshWeaver.Hosting/NodeTypeBatchBake.cs | Uses NodeCompileShaping.ApplyQueryChange for query chunk folding semantics. |
| src/MeshWeaver.Plugin.Build/FrameworkIdentity.cs | Re-anchors identity reading to MeshWeaver.Compiler as the identity assembly. |
| src/MeshWeaver.Plugin.Build/ModulePackCommand.cs | Updates CLI docs/defaults to read the identity anchor from MeshWeaver.Compiler.dll. |
| test/MeshWeaver.Graph.Test/FrameworkBuildIdentityTest.cs | Updates identity tests for new anchor and FullMvidAssemblies membership. |
| test/MeshWeaver.Graph.Test/CodeIncludePatternTest.cs | Re-points include-pattern assertions to NodeCompileShaping. |
| test/MeshWeaver.Graph.Test/RecursiveCompilationTest.cs | Re-points query fold assertions to NodeCompileShaping.ApplyQueryChange. |
| test/MeshWeaver.Graph.Test/EmitToDiskWithRetryTest.cs | Re-points emit publication contract tests to EmitPipeline. |
| test/MeshWeaver.Graph.Test/CompileFailureReportedOnceTest.cs | Re-points log-once/emit failure tests to EmitPipeline. |
| test/MeshWeaver.Hosting.Monolith.Test/SourceSnapshotEstablishmentTest.cs | Re-points snapshot race tests to NodeCompileShaping.RaceSourceSnapshot. |
| test/MeshWeaver.Hosting.Monolith.Test/CodeEditRecompileTest.cs | Re-points snapshot race tests to NodeCompileShaping.RaceSourceSnapshot. |
| test/MeshWeaver.Hosting.PostgreSql.Test/BatchBakeSourceDiscoveryScaleTests.cs | Adjusts commentary around the query-fold contract after extraction. |
| test/MeshWeaver.Observability.Test/TestTraceLogFaultTest.cs | Updates expected stack frame to the new EmitPipeline location. |
| src/MeshWeaver.Documentation/Data/Architecture/NodeTypeCompilation.md | Updates architecture docs to reflect toolchain extraction + identity semantics. |
| src/MeshWeaver.Documentation/Data/Architecture/CiContentBake.md | Updates CI bake docs to reflect toolchain anchor + full-MVID membership. |
| src/MeshWeaver.Documentation/Data/Architecture/ReleaseProcess.md | Updates release process docs to reflect toolchain anchor change. |
| src/MeshWeaver.Documentation/Data/Architecture/Modules.md | Updates module packaging docs to reference the new identity anchor. |
| src/MeshWeaver.Documentation/Data/Architecture/BuildCoordination.md | Updates build coordination docs to reference resolved framework identity. |
| src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-17-the-compiler-is-its-own-assembly.md | Adds a What’s New entry describing the extraction and why it matters. |
Suppressed comments (1)
test/MeshWeaver.Hosting.PostgreSql.Test/BatchBakeSourceDiscoveryScaleTests.cs:116
- This doc comment says
NodeCompileShaping.ApplyQueryChangeis internal toMeshWeaver.Graph, but it now lives inMeshWeaver.Compiler. The comment should reflect the new location (and can fully-qualify the symbol so it stays correct without extrausings).
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…e PG scale test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Test Results (shard 2)2 377 tests +2 2 373 ✅ +2 6m 16s ⏱️ -13s Results for commit fa5aa57. ± Comparison against base commit 9ac552d. This pull request removes 1 and adds 3 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results 65 files ±0 65 suites ±0 45m 16s ⏱️ -2s Results for commit fa5aa57. ± Comparison against base commit 9ac552d. This pull request removes 1 and adds 3 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
… (CompileReferences._default) The #890 debt field moved homes in the extraction (MeshNodeCompilationService ._references -> CompileReferences); the guard failed on the auto-property's compiler-generated backing field. Explicit _default field so the allowlist names something readable; same debt, same issue numbers (#890/#1438). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mespace; the identity pins the toolchain's computed dependency closure Namespace unification (maintainer): everything in the MeshWeaver.Compiler assembly now lives in the MeshWeaver.Compiler namespace; the type-forwards are dropped. Swept before the break: no in-mesh source (repo content trees) and no live-portal content (memex/atioz/systemorph nodeType:Code searches) references any moved type by its old MeshWeaver.Graph.Configuration name; the namespace itself keeps existing in Graph for the actor-side types, so in-mesh 'using MeshWeaver.Graph.Configuration;' lines stay valid. Closure identity (maintainer: 'must track dependencies of the compiler itself — if any have changed, need to recompile'): FullMvidAssemblies is now COMPUTED — the toolchain roots (MeshWeaver.Compiler, MeshWeaver.NuGet) plus their transitive MeshWeaver dependency closure, derived from the shipped assemblies' AssemblyRef metadata so every host computes the identical set and a new toolchain dependency can never be silently outside the identity. A body-only change in a closure member (Mesh.Contract, ContentCollections, …) now recompiles content; under deterministic builds a platform update that touches none of the closure moves nothing. Docs, README, and the identity tests updated (closure membership pin + pure closure-walk test + mirrored ImplMvidOf resolution in the manifest test). Full solution Release -warnaserror green; Graph.Test 1222/1222. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#1707 slice 1 — the framework identity pins the toolchain, not the graph
Everything that shapes a dynamic NodeType compile's generated input moves below
MeshWeaver.Graphinto a dedicatedMeshWeaver.Compilerassembly (refs: Mesh.Contract, ContentCollections, MeshWeaver.NuGet, Roslyn — no Layout/Data/Messaging.Hub):DynamicMeshNodeAttributeGenerator,CodeQueryResolver,CompilationInputs,SourceGeneratorLoader,SpeculativeCompilation,EmittedArtifact,SourceSnapshot,FrameworkBuildIdentity(+ the process-lifetimeFrameworkVersionaccessor lifted out ofNodeTypeCompilationHelpers),FileSystemAssemblyStore(the store naming/tag),AssemblyStoreExtensions,CompilationException;MeshNodeCompilationServiceas pure toolchain classes:NodeCompileShaping(include pattern/anchor, seamed@@resolution, query-result fold, snapshot race, dedup/executable filter,\n\njoin),CompileReferences(TPA baseline + module composition),GeneratorPipeline(#rstrip + generator execution),EmitPipeline(canonical options, staged+verified atomic disk emit, memory emit, emit canary),CompileDiagnostics;Identity
FullMvidAssembliesflips to[MeshWeaver.Compiler, MeshWeaver.NuGet]— the NuGet entry closes a pre-existing hole (NuGetDirectiveParser/resolver shape what Roslyn is fed but were surface-hashed only). Graph body edits stop rebaking the world; #1696's "rebuild only when we need to" now holds in practice. The store filename's "content hash" is a digest of the emitted bytes (zero input-drift coverage), so the extraction must be complete — any input-shaping left in Graph would serve stale DLLs; that is why the aggregation/join/options/emit all moved, not just the generator.Plugin.Build's
IdentityAssemblyanchor follows the toolchain (MeshWeaver.Compiler.dll); the manifest-less local fallback is the anchor's MVID (single-file attributable for packers; every persistent-store host — portals, bake host, mw-plugin-test — ships a surface manifest and resolves the s-hash even locally). Moved public types keep theMeshWeaver.Graph.Configurationnamespace and areTypeForwardedTofrom Graph, so modules compiled against earlier releases keep binding.Ops note
First roll after this merges mints a new identity — a one-time full rebake (the key scheme changed), exactly like #1696's first roll. After that, internal-only and Graph-body merges invalidate nothing; the closure pin test (
CanonicalList_MatchesTheTesterClosure) demanded and got the canonical-list entry.Verification
-c Release -warnaserror: greenMeshWeaver.Graph.Test: 1221/1221 (incl. rewrittenFrameworkBuildIdentityTest— new anchor, FullMvid membership pin, PE-read agreement re-anchored)Hosting.Monolith.Test(SourceSnapshotEstablishment + CodeEditRecompile): 16/16 ·Observability.Test(TestTraceLogFault): 6/6DocumentationLinkIntegrityTest+WhatsNewEntryIntegrityTest: greenPart of #1707; under #1660.
🤖 Generated with Claude Code