Repository navigation
feat(modules): the modules/ publish layout, step 1 — probing, compile surface, fingerprint (#1644) - #1653
Conversation
… surface, fingerprint (#1644) All additive; modules keep riding their ProjectReferences (double-shipped), so the image is byte-for-byte unchanged. What lands: - Publish layout: both hosts import memex/MeshModulesPublish.targets — each listed module lays its own outputs under modules/<Name>/, pruned of same-identity files the app output carries. Deliberately THIN: a full per-module Publish was measured to drag ~1400 shared-framework package assemblies a filename prune cannot see; closure layout is per-module step-2 work when its reference flips. Verified: 12 modules laid out, everything pruned in the double-ship state, modules/ keeps 0 files. - Probing: Modules:Assemblies entries resolve through the new MeshBuilder.ResolveModulePath — modules/<name>/<name>.dll wins, app folder is the fallback. - Compile surface: InstallAssemblies records every loaded module as an InstalledModuleAssembly DI singleton; MeshNodeCompilationService composes its references as the TPA baseline + the mesh's modules, so a module leaving the app closure stays visible to in-mesh source. - Fingerprint: every successful compile stamps CompiledModulesHash (InstalledModulesFingerprint — sorted module MVIDs) beside CompiledFrameworkVersion. Recorded, not yet decisive: while modules ride the image the framework MVID already invalidates on rebuild; it joins the usable-build check at step 2, with null grandfathered as MATCH. - Docs: new Architecture/Modules page — the module lane end to end with the full Modules:Assemblies inventory and each module's config section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds the first (additive) slice of the “modules/ publish layout” lane (#1644): publish-time module layout scaffolding, runtime probing for Modules:Assemblies, and wiring so in-mesh compilation can reference boot-loaded module assemblies and stamp a modules fingerprint alongside framework version.
Changes:
- Introduces
modules/<name>/probing for module assemblies viaMeshBuilder.ResolveModulePath, with BaseDirectory fallback. - Records installed module assemblies in DI and composes Roslyn references as
TPA + installed modules; successful compiles now stampCompiledModulesHash. - Adds
MeshModulesPublish.targets(imported by both hosts), plus docs and tests pinning probing + fingerprint behavior.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/MeshWeaver.Graph.Test/InstalledModulesTest.cs | New tests covering module fingerprint stability, stamping semantics, and modules/ probing behavior. |
| src/MeshWeaver.Mesh.Contract/MeshBuilder.cs | Adds ResolveModulePath; records installed module assemblies in DI during InstallAssemblies. |
| src/MeshWeaver.Mesh.Contract/InstalledModuleAssembly.cs | New record representing one installed module assembly (including MVID). |
| src/MeshWeaver.Hosting/NodeTypeBatchBake.cs | Batch bake stamps CompiledModulesHash from InstalledModulesFingerprint when available. |
| src/MeshWeaver.Graph/Configuration/NodeTypeDefinition.cs | Adds CompiledModulesHash to the node type definition schema. |
| src/MeshWeaver.Graph/Configuration/NodeTypeCompilationHelpers.cs | Extends ApplyCompileSuccess to stamp/preserve CompiledModulesHash and wires it into activation-driven write-back. |
| src/MeshWeaver.Graph/Configuration/MeshNodeCompilationService.cs | Composes compile references as baseline TPA references plus installed module assembly references (deduped by path). |
| src/MeshWeaver.Graph/Configuration/InstalledModulesFingerprint.cs | New mesh-scoped fingerprint (SHA-256 over sorted installed module MVIDs). |
| src/MeshWeaver.Graph/Configuration/GraphConfigurationExtensions.cs | Registers InstalledModulesFingerprint as a singleton. |
| src/MeshWeaver.Documentation/Data/Architecture/Modules.md | New architecture documentation for the end-to-end module lane. |
| memex/MeshModulesPublish.targets | New publish target laying out per-module outputs under modules/<name>/ and pruning duplicates. |
| memex/Memex.Portal.Shared/MemexConfiguration.cs | Uses MeshBuilder.ResolveModulePath for Modules:Assemblies resolution. |
| memex/Memex.Portal.Monolith/Memex.Portal.Monolith.csproj | Imports MeshModulesPublish.targets. |
| memex/aspire/Memex.Portal.Distributed/Memex.Portal.Distributed.csproj | Imports MeshModulesPublish.targets. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Test Results (shard 0)913 tests 912 ✅ 11m 52s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Test Results (shard 4)1 541 tests 1 535 ✅ 6m 30s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Test Results (shard 3) 11 files 11 suites 6m 6s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Test Results (shard 5)1 367 tests 1 366 ✅ 5m 48s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Test Results (shard 1)2 178 tests 2 075 ✅ 7m 26s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Test Results (shard 2)2 363 tests 2 359 ✅ 7m 29s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Test Results 65 files 65 suites 45m 13s ⏱️ Results for commit 3f66a00. ♻️ This comment has been updated with latest results. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Step 1 of #1644 (maintainer-approved to proceed), fully ADDITIVE — modules keep their ships-the-bits ProjectReferences, so the image is byte-for-byte unchanged while all the machinery goes live.
What lands
memex/MeshModulesPublish.targets— each listed module (the 12-module inventory) lays its own outputs undermodules/<Name>/beside the app, pruned of same-identity files the app output already carries. Deliberately thin: a full per-modulePublishwas measured to drag ~1400 shared-framework package assemblies that a filename prune cannot see (the app resolves them from the shared framework; a class library's standalone publish rolls them in) — exactly the same-identity trap-door class in publish-time form. Closure layout is therefore per-module step-2 work, done when that module's reference flips and its private deps are known. Verified on a real publish: 12 modules laid out, everything pruned in the double-ship state,modules/keeps 0 files, target costs ~7s. Escape hatch:-p:PublishMeshModules=false.Modules:Assembliesentries resolve through the newMeshBuilder.ResolveModulePath—modules/<name>/<name>.dllwins, the app folder is the fallback.InstallAssembliesrecords every loaded module as anInstalledModuleAssemblyDI singleton;MeshNodeCompilationServicecomposes its reference set as the static TPA baseline + the mesh's installed modules (deduped by path) — so a module leaving the app closure stays visible to in-mesh source (the CornerstoneMapControlcase).CompiledModulesHash(InstalledModulesFingerprint— SHA-256 over sorted installed-module MVIDs; empty string = no modules) besideCompiledFrameworkVersion, on both write-back paths (activation-drivenApplyCompileSuccessand the batch bake). Recorded, not yet decisive — while modules ride the image, any module change rebuilds Graph and rule 3 already invalidates everything; the hash joins the usable-build check at step 2 when module-only updates become possible, withnullgrandfathered as MATCH (a null-hash build predates modules in the compile surface and referenced none). This sequencing keeps the rule-3-adjacent change zero-risk now.MeshNodeProviderAttributehooks, theModules:Assembliesinventory with each module's configuration section, the publish layout, probing, compile-surface and fingerprint story (the all-waves config reference the maintainer asked for).Gate parity (design §5)
Unchanged in this PR by construction: the thin layout keeps every module in the image's app closure, so
fetch-refs.py/compile-check.pyin the Plugins repo keep seeing the exact prod surface. Themodules/sweep lands there together with the first step-2 flip.Verification
Mesh.Contract,Graph,Hosting,Portal.Shared,Portal.Monolithbuild clean-c Release -warnaserror;MeshWeaver.Graph.Test1163/1163 (new pins: fingerprint empty/stable/order-independent/deduped, stamp preserves a recorded hash, probing prefers the modules folder and falls back);DocumentationLinkIntegrityTestgreen; realdotnet publishof the Monolith exercised the target end to end.No What's New entry: platform/deployment machinery, no user-visible change.
🤖 Generated with Claude Code