Repository navigation
refactor: separate the NodeType compile pipeline from the graph model (and its tests) - #2971
Conversation
MeshWeaver.Graph was 214 files / 55,636 lines and more than half of it was the
NodeType compilation pipeline, while MeshWeaver.Compiler — the project named
after the compiler — held only the 25-file Roslyn toolchain.
MeshWeaver.Graph 180 files 40,024 lines (was 214 / 55,636)
MeshWeaver.Compiler 25 files 5,552 lines (was 25 / 5,542)
MeshWeaver.Compiler.Pipeline 29 files 13,349 lines (new)
MeshWeaver.Graph.Contract 9 files 2,417 lines (new)
Graph -> Compiler.Pipeline -> { Compiler, Graph.Contract },
and nothing below Graph references Graph.
## Why four projects and not two
A two-way split is impossible as a move. The two halves were mutually recursive
through an 8-file / 11,059-line strongly-connected component straddling the
seam (MeshNodeCompilationService, NodeTypeCompilationHelpers, NodeTypeBakeStatus,
NodeTypeContractHandler, PrebuiltAssemblySeeder + MeshDataSource,
MeshNodeExtensions, MeshNodeTypeSource), so NO assignment of those files to two
projects is acyclic. Measured both ways: the minimal Compiler set is 69 files /
35,011 lines if Compiler depends on Graph, and 74 / 32,520 the other way — each
dragging in the layout areas, so neither is a compiler.
MeshWeaver.Graph.Contract carries the vocabulary both halves speak, so neither
can close a cycle through the other. It is 9 files, and it is a contract: no
NodeType implementations, no layout areas.
## Why the pipeline is NOT inside MeshWeaver.Compiler
MeshWeaver.Compiler is a full-MVID toolchain ROOT
(FrameworkBuildIdentity.ToolchainRoots), so a body-only change anywhere inside
it — or inside anything it references — re-bakes every NodeType on every mesh.
Issue #1707 factored the toolchain out of MeshWeaver.Graph precisely to make
that rule pin a small, low-churn assembly.
Folding the pipeline in tripled it (5,542 -> 18,891 lines) and turned the
platform's highest-churn code into a fleet-wide re-bake trigger.
FrameworkBuildIdentityTest caught it: FullMvidClosure_IsExactly_TheKnownSet went
red, with MeshWeaver.Graph.Contract and MeshWeaver.Kernel.Hub newly inside the
closure. So the pipeline sits ABOVE the toolchain and is surface-hashed, exactly
as it was inside MeshWeaver.Graph. That test is GREEN again: the full-MVID
closure is unchanged by this split. The two new assemblies join
ContentSurfaceAssemblies (surface-hashed), which is what the tester closure
computes.
## The four seams that had to be cut
None changes behaviour:
* NodeTypeBuildState (new) takes TryCreateReleaseNode and the compile-state
predicates off MeshDataSourceExtensions. They are extension methods and keep
the MeshWeaver.Graph namespace, so every call site binds unchanged; the two
qualified sites (NodeTypeBatchBake, NodeTypeLayoutAreas) are re-pointed.
* ICompileFailureNotifier inverts the pipeline's one call into
NotificationService, which reads the Notification* node types the pipeline
must not depend on. Registered in AddGraph, resolved OPTIONALLY — a hub
composed without AddGraph keeps a missing bell rather than a faulted compile.
* GraphNodeTypeNames holds the node-type name literals the pipeline writes and
reads (Activity, CompletionMemory, Release, ReleaseSegment). The registration
classes derive their consts from it, so each string still has one definition.
* The synced-query helpers the pipeline reads its sources through
(SyncedQueryDataSourceExtensions, SyncedQueryMeshNodes) hoist to
Graph.Contract as shared infrastructure.
Namespaces are deliberately UNCHANGED: the assembly moves, the namespace does
not, so no in-mesh plugin source and no sibling repo sees an API change.
Doc-comment crefs that would now cross an unreferenced assembly are demoted to
<c> text.
Behaviour: none intended. Full solution builds Release -warnaserror with
0 warnings, 0 errors.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The suite followed the code. 53 of 177 files move to
MeshWeaver.Compiler.Pipeline.Test — the ones whose subject is the compile
pipeline or the toolchain — so each test now sits beside what it tests.
MeshWeaver.Graph.Test 124 files 1,054 cases (was 177 / 1,622)
MeshWeaver.Compiler.Pipeline.Test 53 files 568 cases (new)
1,054 + 568 = 1,622 — the pre-split total. Both suites green, 0 failures,
0 skipped. No case was lost or silently stopped running.
Assignment is by SUBJECT, not by whether a test spins a mesh: each file is
scored on which project declares the types and members it exercises, plus a
filename-to-subject match (FooTest.cs -> Foo.cs). That is what puts
FrameworkBuildIdentityTest next to FrameworkBuildIdentity, which had been
separated from its own subject; it pins the framework identity every published
module binds against, and it runs green here.
CompileWarningsReachTheActivityTest moved too — it scored a tie, but it reaches
EmitPipelineAccess, so the compiler settled it.
MeshWeaver.Graph grants InternalsVisibleTo to the new suite for exactly one
file: OverlaySelfHealWatcherTest moved with its subject (OverlayHealBudget) but
the self-heal it exercises is armed by NodeTypeEnrichmentHelpers, which stays
with the hub enrichment.
Both projects are in MeshWeaver.slnx — a project assigned to a shard but absent
from the solution is built by nothing and reports nothing.
shard-assign.sh: MeshWeaver.Graph.Test 69 -> 64 and the new suite at 5, scaled
from a local run (59 s / 3 s). 🚨 These are ESTIMATES from one machine, not the
three-green-CI-runs the table asks for — re-measure from the per-project
`[CI] <name> exit=` markers once this has run. Shards stay balanced at
378/378/377/377/377/377 and the new suite lands on shard 3.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Caught by running scripts/check-type-forwards.py against the merge base before CI did. 42 public types left MeshWeaver.Graph in this branch — NodeTypeDefinition, BuildState, NodeTypeRelease, ReleaseArtifact, ServedBuildIdentity and the synced-query helpers to MeshWeaver.Graph.Contract; the pipeline's public surface (AssemblyCacheRetention, NodeTypeBakeStatus, NodeTypeCompileState, NodeTypeDependencyGraph, PrebuiltAssemblySeeder, DispatchCompileTrigger, …) to MeshWeaver.Compiler.Pipeline. Every module PUBLISHED BEFORE this split binds `MeshWeaver.Graph!<name>` by assembly-qualified name and resolves it at load. Without a forwarder each one dies with TypeLoadException on the first portal that adopts the new platform — #2370, which took down a production /mcp surface. Rebuilding consumers does not help; the ones already shipped are the point. Verified the guard is load-bearing rather than decorative: with TypeForwarders.cs removed the gate names all 42 and fails; with it, it passes. Forwarders, never shims — a forwarder keeps ONE type identity so is/as, serialization and reference equality survive the boundary. This is also the second reason the moved types kept their original namespaces: a forwarder cannot rename. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Conserving the work products of the split, per AGENTS.md. Two findings here
would otherwise live only in a PR body, and both were re-derived wrongly at
least once during this change:
* the model and the pipeline were mutually recursive through an 8-file /
11,059-line SCC, so a two-way split is impossible as a move — with the
measured closure in BOTH directions showing why each candidate "compiler"
is really a second Graph;
* MeshWeaver.Compiler is a full-MVID toolchain root, so moving code into it
is a fleet-wide re-bake decision rather than a refactor. That is the rule
that decides which side of the toolchain the pipeline sits on, and
FullMvidClosure_IsExactly_TheKnownSet is the gate that enforces it.
Also records the content-surface requirement (in-mesh source binds
NodeTypeDefinition, so both new assemblies must be on ContentSurfaceAssemblies)
and the type-forwarder rule for any future move between these assemblies.
Linked from Architecture.md's node-types row. DocumentationLinkIntegrityTest
passes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors the codebase structure by extracting the NodeType compilation “mesh-actor” pipeline out of MeshWeaver.Graph into a new MeshWeaver.Compiler.Pipeline project and introducing a small MeshWeaver.Graph.Contract project to hold the shared contract types, keeping dependencies acyclic while preserving namespaces for compatibility.
Changes:
- Introduces
MeshWeaver.Compiler.PipelineandMeshWeaver.Graph.Contract, updates references/IVT grants, and pins the framework surface identity to include the new assemblies. - Moves/splits NodeType compilation/build vocabulary (e.g.,
NodeTypeDefinition, build/release state, node-type name literals, compile-failure notification seam) intoGraph.Contract. - Adds a new dedicated test suite (
MeshWeaver.Compiler.Pipeline.Test) and updates CI shard weights accordingly.
Reviewed changes
Copilot reviewed 39 out of 116 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/MeshWeaver.Compiler.Pipeline.Test/ScanPinSupersessionTest.cs | Adds pipeline regression test around ALC pinning/supersession behavior. |
| test/MeshWeaver.Compiler.Pipeline.Test/ReflectionCacheEvictionTest.cs | Pins Autofac reflection-cache eviction to keep collectible ALCs GC-able. |
| test/MeshWeaver.Compiler.Pipeline.Test/RecyclingReadIsNotACompileVerdictTest.cs | Adds unit coverage for “availability failures are not compile verdicts” rules. |
| test/MeshWeaver.Compiler.Pipeline.Test/RecompileStormAbsorptionTest.cs | Adds tests ensuring identical-input compile requests are coalesced. |
| test/MeshWeaver.Compiler.Pipeline.Test/RecompileClosureTest.cs | Adds pure-unit tests for affected-set and ordering of recompiles. |
| test/MeshWeaver.Compiler.Pipeline.Test/OverlayHealBudgetTest.cs | Adds unit contract tests for overlay self-heal budgeting. |
| test/MeshWeaver.Compiler.Pipeline.Test/NuGetDirectiveParserTest.cs | Adds tests for parsing/stripping #r "nuget:..." directives. |
| test/MeshWeaver.Compiler.Pipeline.Test/NodeTypeCompileStateTest.cs | Pins compile-state projection/mirroring behavior and member-set alignment. |
| test/MeshWeaver.Compiler.Pipeline.Test/NodeTypeCompileStampTest.cs | Pins the shared compile stamp field-set across activation and batch bake. |
| test/MeshWeaver.Compiler.Pipeline.Test/NodeTypeAdoptionRegistryTest.cs | Adds tests for adoption interlock behavior (reservation/wait correctness). |
| test/MeshWeaver.Compiler.Pipeline.Test/ModuleFetchMaterialiseTest.cs | Pins fetch/materialise semantics (replace tree vs merge). |
| test/MeshWeaver.Compiler.Pipeline.Test/MeshWeaver.Compiler.Pipeline.Test.csproj | New test project targeting the extracted pipeline + dependencies. |
| test/MeshWeaver.Compiler.Pipeline.Test/LoadableBuildPredicateTest.cs | Pins loadable/settled predicates across typed and JSON content shapes. |
| test/MeshWeaver.Compiler.Pipeline.Test/InstalledModulesTest.cs | Adds tests around installed-modules fingerprinting and stamping. |
| test/MeshWeaver.Compiler.Pipeline.Test/GateSettleFailedBuildInputsTest.cs | Pins FailedBuildInputs stamping for adopt-only gate settles. |
| test/MeshWeaver.Compiler.Pipeline.Test/ForcedReleaseIsSpentTest.cs | Pins forced-release flag consumption by terminal writers. |
| test/MeshWeaver.Compiler.Pipeline.Test/EmitPipelineAccess.cs | Adds internal access shim for using compiler option factories in tests. |
| test/MeshWeaver.Compiler.Pipeline.Test/EmitCanaryVerdictTest.cs | Pins canary verdict logic (site-aware throw comparison). |
| test/MeshWeaver.Compiler.Pipeline.Test/EmitCanaryControlTest.cs | Pins that the canary “control” truly avoids shared file mappings. |
| test/MeshWeaver.Compiler.Pipeline.Test/CompletionRankKeyTest.cs | Pins culture-invariant, zero-padded completion sort key behavior. |
| test/MeshWeaver.Compiler.Pipeline.Test/CompileWarningsReachTheActivityTest.cs | Pins warning collection behavior (dedupe/cap) for successful compiles. |
| test/MeshWeaver.Compiler.Pipeline.Test/CompileThreadTest.cs | Pins compile leaf runs off ThreadPool (dedicated thread) behavior. |
| test/MeshWeaver.Compiler.Pipeline.Test/CompileSourceOrderTest.cs | Pins deterministic ordering of collected/combined compile sources. |
| test/MeshWeaver.Compiler.Pipeline.Test/CodeIncludePatternTest.cs | Pins include scanner pattern + anchoring behavior. |
| test/MeshWeaver.Compiler.Pipeline.Test/CellSurfaceSingleHomeTest.cs | Pins pure single-home derivation + JSON round-trip of cellSurface. |
| test/MeshWeaver.Compiler.Pipeline.Test/AlcDrainIsReactiveTest.cs | Pins reactive ALC drain semantics (no timer race unload). |
| src/MeshWeaver.PluginCatalog/PackageInstaller.cs | Updates doc reference to moved AwaitLoadableBuild helper (now in build-state seam). |
| src/MeshWeaver.Mesh.Contract/Services/IMeshQueryCore.cs | Adds IVT grants for new contract/pipeline assemblies. |
| src/MeshWeaver.Mesh.Contract/Services/IMeshNodeStreamCache.cs | Adds IVT grants for new assemblies/tests needing internal cache members. |
| src/MeshWeaver.Hosting/NodeTypeBatchBake.cs | Re-points release node creation helper to NodeTypeBuildState. |
| src/MeshWeaver.Graph/NodeTypeLayoutAreas.cs | Re-points source up-to-date predicate to NodeTypeBuildState. |
| src/MeshWeaver.Graph/MeshWeaver.Graph.csproj | Adds IVT for the new pipeline test suite and references the new projects. |
| src/MeshWeaver.Graph/Configuration/ReleaseNodeType.cs | Replaces string literals with GraphNodeTypeNames constants. |
| src/MeshWeaver.Graph/Configuration/GraphConfigurationExtensions.cs | Registers ICompileFailureNotifier implementation in AddGraph. |
| src/MeshWeaver.Graph/Configuration/CompletionMemoryNodeType.cs | Replaces string literal with GraphNodeTypeNames constant. |
| src/MeshWeaver.Graph/Configuration/ActivityNodeType.cs | Replaces string literal with GraphNodeTypeNames constant. |
| src/MeshWeaver.Graph/CompileFailureNotifier.cs | Adds graph-side delivery implementation of ICompileFailureNotifier. |
| src/MeshWeaver.Graph.Contract/ServedBuildIdentity.cs | Adds metadata-only MVID reading + mismatch/unverifiable helpers. |
| src/MeshWeaver.Graph.Contract/ReleaseArtifact.cs | Adjusts cross-assembly cref usage in docs/comments. |
| src/MeshWeaver.Graph.Contract/README.md | Documents contract purpose and contents post-split. |
| src/MeshWeaver.Graph.Contract/NodeTypeRelease.cs | Adjusts cross-assembly cref usage in docs/comments. |
| src/MeshWeaver.Graph.Contract/NodeTypeDefinition.cs | Moves definition type into the contract assembly (namespace preserved). |
| src/MeshWeaver.Graph.Contract/MeshWeaver.Graph.Contract.csproj | New contract project definition + references/IVT. |
| src/MeshWeaver.Graph.Contract/ICompileFailureNotifier.cs | Adds notification delivery seam interface for pipeline → graph. |
| src/MeshWeaver.Graph.Contract/GraphNodeTypeNames.cs | Centralizes node-type name literals shared across the split. |
| src/MeshWeaver.Graph.Contract/BuildState.cs | Moves build coordination state types into the contract assembly. |
| src/MeshWeaver.Data/Workspace.cs | Adds IVT grants needed by moved synced-query helpers/pipeline. |
| src/MeshWeaver.Compiler/MeshWeaver.Compiler.csproj | Extends IVT grants to the new pipeline and its tests. |
| src/MeshWeaver.Compiler/FrameworkBuildIdentity.cs | Adds the new assemblies to the surface-hashed content identity list. |
| src/MeshWeaver.Compiler.Pipeline/ScriptCodeGenerator.cs | Adds script source generator (used by scripting compilation service). |
| src/MeshWeaver.Compiler.Pipeline/RecompileClosure.cs | Adds pure helper for deriving affected NodeTypes and ordering recompiles. |
| src/MeshWeaver.Compiler.Pipeline/README.md | Documents pipeline project purpose and why it’s separate from toolchain. |
| src/MeshWeaver.Compiler.Pipeline/PrebuiltRequiredException.cs | Adds named exception for “prebuilt required but missing” refusal. |
| src/MeshWeaver.Compiler.Pipeline/OverlayHealBudget.cs | Adjusts docs to avoid cross-assembly cref. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeUnparkPostDeletionHandler.cs | Adds handler to clear parked state on NodeType delete. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeParkedException.cs | Adjusts docs to avoid cross-assembly cref. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeCompileState.cs | Uses GraphNodeTypeNames.Activity instead of graph-only constant. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeCompileParkRegistry.cs | Inverts notification dispatch through optional ICompileFailureNotifier. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeCompilationHelpers.cs | Re-points release node creation helper to NodeTypeBuildState. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeCompilationActivity.cs | Uses GraphNodeTypeNames.Activity constant. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeAdoptionRegistry.cs | Adds adoption reservation/wait interlock to prevent adoption/compile races. |
| src/MeshWeaver.Compiler.Pipeline/NodeSources.cs | Minor using/order adjustment post-move. |
| src/MeshWeaver.Compiler.Pipeline/MeshWeaver.Compiler.Pipeline.csproj | New pipeline project definition + package/project references and IVT. |
| src/MeshWeaver.Compiler.Pipeline/InstalledModulesFingerprint.cs | Adds mesh-scoped installed-module fingerprinting helper. |
| src/MeshWeaver.Compiler.Pipeline/CompletionUsageIndex.cs | Adds usage-based ranking corpus indexer (bounded, background build). |
| src/MeshWeaver.Compiler.Pipeline/CompletionMemoryStore.cs | Uses GraphNodeTypeNames.CompletionMemory constant. |
| src/MeshWeaver.Compiler.Pipeline/CompileThread.cs | Adds dedicated-thread runner for synchronous Roslyn leaf work. |
| src/MeshWeaver.Compiler.Pipeline/CompilationLock.cs | Adds file-based multi-process compilation lock helper. |
| src/MeshWeaver.Compiler.Pipeline/CompilationCacheOptions.cs | Adds compile pipeline timeout and cache configuration options. |
| MeshWeaver.slnx | Adds new projects to solution so they build/test in CI. |
| .github/scripts/shard-assign.sh | Updates shard weights and adds new pipeline test suite weight. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Test Results (shard 0)216 tests 216 ✅ 2m 30s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
Test Results (shard 5)1 126 tests 934 ✅ 1m 7s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
Test Results (shard 1)419 tests 419 ✅ 1m 33s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
Test Results (shard 4)1 640 tests 1 640 ✅ 1m 40s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
Test Results (shard 2)507 tests 507 ✅ 1m 32s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
Shard 5 red on the last run. All three are ratchet guards keyed by FILE PATH, and
this branch moved the files — same sites, same counts, new locations. Each guard
said so precisely: it reported the new path as a NEW SITE and the old path as
STALE, in matching numbers.
* ImpersonationScopeSites.allow — six pipeline files moved to
src/MeshWeaver.Compiler.Pipeline/, and TryCreateReleaseNode's single site
left MeshDataSource.cs for NodeTypeBuildState.cs.
* BlockingBridgeSites.allow — NodeTypeAdoptionRegistryTest (3) and
NodeTypeBakeStatusTest (2) moved to the pipeline suite.
* BareToObservableOnReadPathGuard.ScannedFiles — SyncedQueryDataSourceExtensions
moved to MeshWeaver.Graph.Contract. This one fails LOUD on a path that no
longer exists ("this guard would stop checking it and still pass"), which is
exactly right: a scanned-file list that silently stops scanning is worse than
no guard.
🚨 Renames only. No entry added, no count raised, no TotalBudget changed — the
budgets still balance because not one site was created or removed. An allow file
may only shrink, and this change does not grow one.
MeshWeaver.Documentation.Test: 166 passed, 0 failed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Test Results (shard 3)578 tests 578 ✅ 54s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
Test Results4 486 tests 4 294 ✅ 9m 19s ⏱️ Results for commit 514193d. ♻️ This comment has been updated with latest results. |
# Conflicts: # .github/scripts/shard-assign.sh # MeshWeaver.slnx
MeshWeaver.Graphwas 214 files / 55,636 lines and more than half of it was the NodeTypecompilation pipeline, while
MeshWeaver.Compiler— the project named after the compiler — held onlythe 25-file Roslyn toolchain. This separates them, and the test suite follows the same seam.
MeshWeaver.GraphMeshWeaver.CompilerMeshWeaver.Compiler.PipelineMeshWeaver.Graph.ContractMeshWeaver.Graph.TestMeshWeaver.Compiler.Pipeline.TestGraph → Compiler.Pipeline → { Compiler, Graph.Contract }. Nothing below Graph references Graph.1,054 + 568 = 1,622, the pre-split total — both suites green, 0 failed, 0 skipped.
The measurement: a two-way split is impossible as a move
I re-derived the closure rather than trusting the seed heuristic, and it does not reproduce a clean
cut. The two halves are mutually recursive through an 8-file / 11,059-line strongly-connected
component that straddles the seam:
No assignment of those files to two projects is acyclic. Measured both directions over all 214
files (a valid Compiler set must be closed under predecessors one way, successors the other):
Compiler → GraphCreateLayoutArea,MarkdownLayoutAreas,SettingsLayoutArea,SpaceNodeType,Logon/*Graph → CompilerSlideNodeType,DeckNodeType,MeshNodeCardControl,NodeIconPickerDialog,EmailTemplateNeither is a compiler. Hence the contract project — the structural answer, not the fixpoint one.
MeshWeaver.Graph.Contractis 9 files and it is a contract:NodeTypeDefinition,BuildState,NodeTypeRelease,ReleaseArtifact,ServedBuildIdentity, the synced-query helpers,GraphNodeTypeNames,ICompileFailureNotifier. No NodeType implementations, no layout areas — theSlideNodeType/DeckNodeType/AccessAssignmentNodeTypehits in the earlier estimate wereincidental (a name inside a registration list or a doc comment) and are not promoted here.
🚨 Why the pipeline is NOT inside
MeshWeaver.CompilerI built it that way first, and
FrameworkBuildIdentityTestcaught it — this is the finding worthreading.
MeshWeaver.Compileris a full-MVID toolchain ROOT (FrameworkBuildIdentity.ToolchainRoots):a body-only change anywhere inside it, or inside anything it references, re-bakes every
NodeType on every mesh. Issue #1707 factored the toolchain out of
MeshWeaver.Graphprecisely sothat rule pins a small, low-churn assembly.
Folding the pipeline in tripled it (5,542 → 18,891 lines), turned the platform's highest-churn code
into a fleet-wide re-bake trigger, and measurably widened the closure —
FullMvidClosure_IsExactly_TheKnownSetwent red withMeshWeaver.Graph.ContractandMeshWeaver.Kernel.Hubnewly inside it. So the pipeline sits above the toolchain and issurface-hashed, exactly as it was while it lived in
MeshWeaver.Graph.That test is green again: the full-MVID closure is unchanged by this split. The two new
assemblies join
ContentSurfaceAssemblies(surface-hashed), which is what the tester closurecomputes.
The four seams that had to be cut
Everything else is a pure move. None of these changes behaviour:
NodeTypeBuildState(new) takesTryCreateReleaseNodeand the compile-state predicates offMeshDataSourceExtensions— the couplingMeshWeaver.Graph.csprojalready flagged as "trackedfor retirement". They are extension methods and keep the
MeshWeaver.Graphnamespace, soevery call site binds unchanged; the two qualified sites (
NodeTypeBatchBake,NodeTypeLayoutAreas) are re-pointed.ICompileFailureNotifierinverts the pipeline's one call intoNotificationService, whichreads the
Notification*node types the pipeline must not depend on. Registered inAddGraph;resolved optionally, so a hub composed without
AddGraphkeeps a missing bell rather than afaulted compile.
GraphNodeTypeNamesholds the four node-type name literals the pipeline writes and reads(
Activity,CompletionMemory,Release,ReleaseSegment). The registration classes derivetheir consts from it, so each string still has exactly one definition.
(
SyncedQueryDataSourceExtensions,SyncedQueryMeshNodes) hoist toGraph.Contract.What is deliberately NOT in this diff
MeshWeaver.Graph,MeshWeaver.Graph.Configuration), so no in-mesh plugin source and no sibling repo sees an APIchange. feat(#1707): extract the NodeType compile toolchain into MeshWeaver.Compiler #1712 renamed namespaces and swept the fleet; that is not needed here and would put
every plugin's in-mesh C# at risk for no architectural gain.
IVTgrants thatfollow the moved internals, and doc-comment
crefs demoted to<c>where they would now cross anunreferenced assembly.
Tests
Assignment is by subject, not by whether a test spins a mesh: each file is scored on which
project declares the types and members it exercises, plus a filename→subject match. That is what
puts
FrameworkBuildIdentityTestnext toFrameworkBuildIdentity, which had been separatedfrom its own subject — it pins the framework identity every published module binds against, and it
is green.
Both projects are in
MeshWeaver.slnx(a project assigned to a shard but absent from the solutionis built by nothing and reports nothing — the core#2966 defect).
shard-assign.sh:MeshWeaver.Graph.Test69 → 64 and the new suite at 5. 🚨 These are estimatesscaled from one local run (59 s / 3 s), not the three-green-CI-runs the table asks for —
re-measure from the
[CI] <name> exit=markers after this lands. Shards stay balanced(378/378/377/377/377/377); the new suite goes to shard 3.
Verification
-c Release -warnaserror: 0 warnings, 0 errors.MeshWeaver.Graph.Test1,054 passed,MeshWeaver.Compiler.Pipeline.Test568 passed,0 failed, 0 skipped — reconciling exactly to the 1,622 before the split.