Repository navigation
fix: a dependency record's module entry is a FLOOR, not an MVID pin (#3934) - #3946
Conversation
…3934) A compiled NodeType's dependency record compared each installed module by raw MVID — an exact build. An MVID moves on every compilation BY CONSTRUCTION, and Roslyn's deterministic MVID also hashes the ABSOLUTE SOURCE PATHS, so two lanes of one publication compiling identical source at two paths fork it with identical version attributes. Every NodeType binding such a module was declined at adoption, compiled in-portal into `latestAssemblyCollection: "local"` on whichever replica served, and each replica then invalidated the other's stamp. Measured on memex 2026-09-10: 22 of 272 entries declined on ONE entry each (`mvid:798f92a0…` recorded, `mvid:825581836a…` live, all eight `ref:` surfaces and `!toolchain` agreeing); `/Posts/SavThankYou` returned HTTP 200 rendering nothing for the whole day — every view `SocialMedia/Post` declares absent — while the NodeType's own record read `compilationStatus: Ok`. A recycle was measured not to fix it. Platform owner's decision, in four clauses: there is no incompatibility (two builds of one module name are ONE assembly identity, so `Assembly.LoadFrom` returns the already-loaded copy); a record states a floor; a moved MVID never triggers a runtime recompile; and an unmet floor must be VISIBLE. What changes - A module resolves `min:<version>` over `InstalledModuleAssembly.Version` (its `AssemblyInformationalVersion`, build metadata stripped) — the ONE reader both the portal's resolver and the bake host go through. A module stating no version keeps the exact `mvid:` pin: inconclusive stays on the rebuild side. - `CompiledDependencies.Satisfies` is the one comparison, ordering with `NuGetVersionComparer` (MeshWeaver.Compiler now references MeshWeaver.Plugin.Packaging rather than re-implementing the fold). It REFUSES to compare across schemes, which is the safety property. - `Validate`/`ValidateAfterReevaluation` answer a `DependencyRecordOutcome` — Satisfied / Drifted / FloorNotMet / NotChecked — modelled on `NodeDiagnosticsOutcome` (#3912/#3916), never a fourth way to say "I could not check". `FindMismatch` is a projection of it, so the two cannot disagree. - `LiveContentKeyOf` folds a SATISFIED entry at its recorded value, so the toolchain demotion survives a module rebuilt above its floor. - Clause 4: a recorded build whose bytes this process cannot resolve now overlays the existing `AssemblyUnavailable` diagnosis instead of silently binding the default configuration — the path that turned this into a blank page rather than a message. The overlay keeps the fail-fast NACK. Deliberately NOT relaxed: `!toolchain`, `!input`, `ref:` platform surfaces and `absent` are all still ordinal. `ReleaseAvailability`'s sealed-set gate now enumerates the module lane by `IsModuleLaneId` so it keeps firing on floors — only its exact-build comparison retires, and only for a floor-shaped id. `FullMvidAssemblies` gains MeshWeaver.Plugin.Packaging: a LEAF (no project references of its own) at 3 commits/60d, against a union already carrying Mesh.Contract (190/30d) and Messaging.Hub (135/30d) — and the membership is correct, since the comparer now decides which builds are adopted. Controls run both directions: the old pin's decline asserted verbatim as the falsification arm, a record below its floor still declining with the exact sentence, and separate arms for each of the four things that did not move. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S25PJZbVeCbkWhCfMub9P7
There was a problem hiding this comment.
🟢 Approval recommended
Changes appear coherent and well-tested for the new floor contract; the only remaining feedback is a minor performance/consistency nit in DependencyIdResolverOf.
Pull request overview
This PR implements issue #3934 by changing NodeType dependency records so a module dependency expresses a version floor (min:<version>) instead of an exact build pin (mvid:<guid>), preventing benign module rebuilds from causing prebuilt-bundle declines and runtime recompilation loops.
Changes:
- Introduces
min:module-floor IDs and SemVer ordering viaNuGetVersionComparer, with a newDependencyRecordOutcome/ValidateAPI to make “satisfied vs drifted vs floor-not-met vs not-checked” explicit. - Updates all major readers (adoption, bake probing, seeding, availability gating) to use the unified comparison semantics and to keep gates firing for floor-shaped module entries.
- Replaces a “silent default config” fallback on missing compiled bytes with an explicit overlay diagnosis + self-heal, and adds focused tests + documentation for the new contract.
File summaries
| File | Description |
|---|---|
| tools/MeshWeaver.PluginTester/TreeBake.cs | Adds module-version projection/resolver so the bake host can stamp min: floors consistently with the portal. |
| tools/MeshWeaver.PluginTester/BakeHost.cs | Wires the new 4-arg CreateIdResolver and updates messaging to describe min: floors vs mvid: pins. |
| test/MeshWeaver.Compiler.Pipeline.Test/FrameworkBuildIdentityTest.cs | Updates the full-MVID closure expectation to include MeshWeaver.Plugin.Packaging due to SemVer ordering dependency. |
| test/MeshWeaver.Compiler.Pipeline.Test/DependencyRecordFloorTest.cs | Adds comprehensive tests pinning the new floor semantics, non-relaxations, and reader behavior. |
| test/Memex.Portal.Shared.Test/SealedSetConsistencyTest.cs | Ensures the sealed-set gate still enumerates module-lane entries under min: and that only the intended check is retired. |
| src/MeshWeaver.PluginCatalog/ServedModuleBytes.cs | Documents that min: floors intentionally don’t select an exact sealed module build for serving bytes. |
| src/MeshWeaver.PluginCatalog/ReleaseAvailability.cs | Updates module-lane detection to include min: and retires the exact-build mismatch hold only for floor-shaped IDs. |
| src/MeshWeaver.Mesh.Contract/InstalledModuleAssembly.cs | Adds the single canonical reader for a module’s ordered version (stripped informational version). |
| src/MeshWeaver.Graph/Configuration/NodeTypeEnrichmentHelpers.cs | Replaces default-config fallback on missing bytes with an AssemblyUnavailable overlay + gated self-heal. |
| src/MeshWeaver.Documentation/Data/WhatsNew/2026-09-10-a-rebuilt-module-no-longer-makes-a-pages-views-disappear.md | Adds a user-facing Fix entry explaining the blank-page symptom and the resolution. |
| src/MeshWeaver.Documentation/Data/Architecture/ModuleOwnedSiblingsRide.md | Updates architecture guidance to reference the new floor semantics as the consumer-side remedy. |
| src/MeshWeaver.Documentation/Data/Architecture/ModuleAdoptionPolicy.md | Notes the dependency-record floor change without altering the higher-level adoption policy. |
| src/MeshWeaver.Documentation/Data/Architecture/DependencyRecordFloor.md | New architecture page defining the floor contract, rationale, non-relaxations, and controls. |
| src/MeshWeaver.Compiler/NodeSetCompiler.cs | Minor doc comment adjustment for CreateIdResolver cref formatting. |
| src/MeshWeaver.Compiler/MeshWeaver.Compiler.csproj | Adds a reference to MeshWeaver.Plugin.Packaging to reuse the repo’s canonical SemVer ordering. |
| src/MeshWeaver.Compiler/DependencyRecordOutcome.cs | Introduces DependencyRecordOutcome and DependencyRecordStatus to make “what was established” explicit. |
| src/MeshWeaver.Compiler/ContentKeyReevaluation.cs | Doc comment adjustment for CreateIdResolver cref formatting. |
| src/MeshWeaver.Compiler/CompiledDependencies.cs | Implements min: scheme, Satisfies, outcome-based validation, and module-lane predicate helper. |
| src/MeshWeaver.Compiler.Pipeline/PrebuiltAssemblySeeder.cs | Switches decline logic to outcome-based Validate and logs the status + reason explicitly. |
| src/MeshWeaver.Compiler.Pipeline/NodeTypeCompilationHelpers.cs | Uses the new floor-aware resolver and adds module-version mapping for the live environment. |
Review details
- Files reviewed: 20/20 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| internal static Func<string, string?> DependencyIdResolverOf(IMessageHub hub) | ||
| { | ||
| var versions = ModuleVersionsOf(hub); | ||
| return Compiler.CompiledDependencies.CreateIdResolver( | ||
| FrameworkBuildIdentity.ProcessSurfacePairs, |
Test Results (shard 0)254 tests 254 ✅ 2m 37s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
Test Results (shard 1)496 tests 496 ✅ 45s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
Test Results (shard 3)389 tests 389 ✅ 59s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
Test Results (shard 4)1 908 tests 1 908 ✅ 3m 24s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
Test Results (shard 5) 6 files 6 suites 4m 59s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
Test Results (shard 2)1 267 tests 1 265 ✅ 3m 39s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
Test Results 17 files 17 suites 16m 26s ⏱️ Results for commit e8ba5e9. ♻️ This comment has been updated with latest results. |
… map `ArchitectureTopicMapTest.EveryArchitecturePage_IsListedInTheTopicMap` caught it — a working URL alone does not make a page discoverable. Filed under "Node types", beside the Toolchain Re-evaluation Lane it interacts with. Local: MeshWeaver.Documentation.Test 373 passed (the whole project this time, not just DocumentationLinkIntegrityTest — which is what let this reach CI). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S25PJZbVeCbkWhCfMub9P7
…line that names how it was answered #3221 asks whether a sibling that is ITSELF another package's declared module should ride into a second bundle. It is a design question, and everything that made it hard has since moved: #3732/#3933 gave a publication ONE compilation, #3934/#3946 made a record's module entry a FLOOR rather than an MVID pin, and #3962/#3973 corrected the guard's stated reason. This settles it, measured. THE ANSWER — it rides, IFF the platform host does not already ship it. Being another package's declared module is not a reason to exclude it: exclusivity was never available (AI `requires [Store]` while Essentials, which DECLARES the assembly, `requires [AI, …]` — a package cycle) and would break a supported install. What makes the ride safe is not exclusivity but ONE BUILD per name per publication, asserted by the producer at compose time and again by the consumer over the whole sealed set. MEASURED 2026-09-11, with denominators: * Reference graph, MeshWeaver.Plugins main @ d6fa0338 — 79 index.json scanned, 37 declare a content.module, 148 csproj under src/. 18 of 37 declared modules transitively reference another package's declared module; 4 of 37 are RIDDEN (Markdown.Collaboration ×14, AI ×13, Maps ×4, Import ×1). That is the upper bound, not the answer. * What is actually PACKED — run 34563887604, success: job 103155487545 (MeshWeaver.AI): "closure: MeshWeaver.Markdown.Collaboration.dll does NOT ride — the platform ships it (measured off …/platform-refs)" => the exact pair this issue names no longer rides at all. job 103155487593 (MeshWeaver.Northwind.Application): "closure: MeshWeaver.Maps.dll RIDES — module-owned" "closure: MeshWeaver.Import.dll RIDES — module-owned" => the shape IS live today, on two names, in one bundle of 37. * The verdict on the composed sets — Plugins publish-bake 103160836446 and gate shard 103159059393; MeshWeaver.Crm publish-bake 103166073109, which composes ai.module.nupkg and essentials.module.nupkg side by side (the pair the 2026-09-08 hold named): "module set: 5 … 0 carried by more than one bundle, 0 carried at more than one BUILD" / "module set: 4 … 0 … 0" CORRECTION — the page said the refusal was INERT until each satellite moves its pin. Measured over every `uses: Systemorph/MeshWeaver/.github/workflows/…` line in all six node repos: FIVE consume node-repo-gate.yml and node-repo-publish-bake.yml at @main (Plugins, Reinsurance, SocialMedia, Manufacturing, Crm), so they took the refusal the hour it merged; only MeshWeaver.Education pins a sha (67cbbe0…) and the verdict is absent from that file at that sha. Both directions off the LOGS, not inferred from the ref: Plugins run 34563887604 and Crm run 34567369849 print the verdict line; Education's publish-bake for run 34487980275 composes the same four bundles and prints none. THE ONE CODE CHANGE — node-repo-module-pack.yml's witness line printed its path TWICE ("measured off /tmp/app/tmp/app"), because `${PLATFORM_APP:+measured off $PLATFORM_APP}${PLATFORM_APP:-declared by …}` expands `:-` to the VALUE when the variable is set. That is the branch that matters — it is the one saying the answer came from the image rather than from a hand-maintained list — and it is quoted verbatim in the page above. Stated once in a `witness` variable instead. CONTROL, both directions, executed against the REAL workflow file (the two assignment lines and the echo extracted by content, never copied): before: MEASURED … the platform ships it (measured off /tmp/app/tmp/app); … ← defect DECLARED … the platform ships it (declared by src/platform-shipped.txt); … after: PASS MEASURED … (measured off /tmp/app) [asserts "/tmp/app/tmp/app" ABSENT] PASS DECLARED … (declared by src/platform-shipped.txt) [asserts "measured off" ABSENT] VERIFIED YAML parses — node-repo-module-pack 6 jobs check-workflow-timeouts.py 84 jobs, 2 exempt, 0 violations check-workflow-shell.py 0 live findings check-workflow-yaml-keys.py 34 files, 0 violations check-abbreviated-shas.py 34 files, 0 abbreviations check-workflow-permission-pairing.py 2 pairs, 0 violations MeshWeaver.Documentation -c Release -warnaserror 0 Error(s), 0 Warning(s) MeshWeaver.Documentation.Test -c Release -warnaserror 0 Error(s), 0 Warning(s) DocumentationLinkIntegrityTest + ArchitectureTopicMapTest 5/5 passed (doclinks.trx) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…line that names how it was answered #3221 asks whether a sibling that is ITSELF another package's declared module should ride into a second bundle. It is a design question, and everything that made it hard has since moved: #3732/#3933 gave a publication ONE compilation, #3934/#3946 made a record's module entry a FLOOR rather than an MVID pin, and #3962/#3973 corrected the guard's stated reason. This settles it, measured. THE ANSWER — it rides, IFF the platform host does not already ship it. Being another package's declared module is not a reason to exclude it: exclusivity was never available (AI `requires [Store]` while Essentials, which DECLARES the assembly, `requires [AI, …]` — a package cycle) and would break a supported install. What makes the ride safe is not exclusivity but ONE BUILD per name per publication, asserted by the producer at compose time and again by the consumer over the whole sealed set. MEASURED 2026-09-11, with denominators: * Reference graph, MeshWeaver.Plugins main @ d6fa0338 — 79 index.json scanned, 37 declare a content.module, 148 csproj under src/. 18 of 37 declared modules transitively reference another package's declared module; 4 of 37 are RIDDEN (Markdown.Collaboration ×14, AI ×13, Maps ×4, Import ×1). That is the upper bound, not the answer. * What is actually PACKED — run 34563887604, success: job 103155487545 (MeshWeaver.AI): "closure: MeshWeaver.Markdown.Collaboration.dll does NOT ride — the platform ships it (measured off …/platform-refs)" => the exact pair this issue names no longer rides at all. job 103155487593 (MeshWeaver.Northwind.Application): "closure: MeshWeaver.Maps.dll RIDES — module-owned" "closure: MeshWeaver.Import.dll RIDES — module-owned" => the shape IS live today, on two names, in one bundle of 37. * The verdict on the composed sets — Plugins publish-bake 103160836446 and gate shard 103159059393; MeshWeaver.Crm publish-bake 103166073109, which composes ai.module.nupkg and essentials.module.nupkg side by side (the pair the 2026-09-08 hold named): "module set: 5 … 0 carried by more than one bundle, 0 carried at more than one BUILD" / "module set: 4 … 0 … 0" CORRECTION — the page said the refusal was INERT until each satellite moves its pin. Measured over every `uses: Systemorph/MeshWeaver/.github/workflows/…` line in all six node repos: FIVE consume node-repo-gate.yml and node-repo-publish-bake.yml at @main (Plugins, Reinsurance, SocialMedia, Manufacturing, Crm), so they took the refusal the hour it merged; only MeshWeaver.Education pins a sha (67cbbe0…) and the verdict is absent from that file at that sha. Both directions off the LOGS, not inferred from the ref: Plugins run 34563887604 and Crm run 34567369849 print the verdict line; Education's publish-bake for run 34487980275 composes the same four bundles and prints none. THE ONE CODE CHANGE — node-repo-module-pack.yml's witness line printed its path TWICE ("measured off /tmp/app/tmp/app"), because `${PLATFORM_APP:+measured off $PLATFORM_APP}${PLATFORM_APP:-declared by …}` expands `:-` to the VALUE when the variable is set. That is the branch that matters — it is the one saying the answer came from the image rather than from a hand-maintained list — and it is quoted verbatim in the page above. Stated once in a `witness` variable instead. CONTROL, both directions, executed against the REAL workflow file (the two assignment lines and the echo extracted by content, never copied): before: MEASURED … the platform ships it (measured off /tmp/app/tmp/app); … ← defect DECLARED … the platform ships it (declared by src/platform-shipped.txt); … after: PASS MEASURED … (measured off /tmp/app) [asserts "/tmp/app/tmp/app" ABSENT] PASS DECLARED … (declared by src/platform-shipped.txt) [asserts "measured off" ABSENT] VERIFIED YAML parses — node-repo-module-pack 6 jobs check-workflow-timeouts.py 84 jobs, 2 exempt, 0 violations check-workflow-shell.py 0 live findings check-workflow-yaml-keys.py 34 files, 0 violations check-abbreviated-shas.py 34 files, 0 abbreviations check-workflow-permission-pairing.py 2 pairs, 0 violations MeshWeaver.Documentation -c Release -warnaserror 0 Error(s), 0 Warning(s) MeshWeaver.Documentation.Test -c Release -warnaserror 0 Error(s), 0 Warning(s) DocumentationLinkIntegrityTest + ArchitectureTopicMapTest 5/5 passed (doclinks.trx) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements #3934 — the platform owner's decision, not a proposal: a dependency record's module entry states a floor, not an MVID pin.
The chain this dissolves, measured on memex 2026-09-10
CompiledDependencies.CreateIdResolverresolved a module tomvid:<guid>— an exact build, checked first. An MVID moves on every compilation by construction, and Roslyn's deterministic MVID also hashes the absolute source paths, so twobuild-workspacelanes of one publication compiling identical source at$GITHUB_WORKSPACEand/repofork it with byte-identical version attributes. No producer agreement can fix that.PrebuiltAssemblySeederdeclined 22 of 272 entries at one identity, across 3 module names, on one entry each:MeshWeaver.Markdown.Collaborationrecordedmvid:798f92a0…, livemvid:825581836a…, with all eightref:surfaces and!toolchainagreeing.socialmediawas 20/26, all six declines that one assembly.latestAssemblyCollection: "local", whichFileSystemAssemblyStoredocuments as "the bytes live in the local filesystem cache only; cross-silo readers must recompile". memex runs 2 replicas, so each declined the other's stamp and recompiled — two forced re-activations 2 seconds apart with identical inputs.https://memex.meshweaver.cloud/Posts/SavThankYoureturned HTTP 200 rendering nothing for the whole day —Preview,Write,PostCardall absent — while the NodeType readcompilationStatus: Ok.recyclewas measured not to fix it.What the floor is, and how a consumer compares it
A module resolves
min:<version>overInstalledModuleAssembly.Version— itsAssemblyInformationalVersionwith+<sha>stripped. That is the one reader, and both the portal's resolver (NodeTypeCompilationHelpers.DependencyIdResolverOf) and the bake host's (mw-plugin-test'sBakeHost.InProcess/ResolveDirectory) go through it, so a floor is never compared against a value nobody else computes.CompiledDependencies.Satisfiesis the comparison: ordinal equality, plus exactly one relaxation — twomin:values order byNuGetVersionComparer, and live at-or-above stamped satisfies.MeshWeaver.Compilernow referencesMeshWeaver.Plugin.Packagingfor that comparer rather than re-implementing the fold (check-module-platform-floor.py's own header: "two call sites computing the same fold differently either never converge or never fire, and both are silent"). A module stating no version keeps the exactmvid:pin — an environment that cannot state a version has no floor to offer, and inconclusive stays on the rebuild side.Relation to what already exists: this is the same instinct as
ModuleAdoptionPolicyR2 ("a different build commit or MVID is not evidence of incompatibility") one layer down, and unlikeminMeshVersionit is measured, not authored — the version of the module the producer actually compiled against.ModuleVersionCompatibility's same-MAJOR stale-but-serving rule is a different question (may an already-adopted build keep serving over moved source) and is untouched.Every reader changed
CompiledDependencies.Compare(the one comparison behindFindMismatch,FindMismatchAfterReevaluation,Validate,ValidateAfterReevaluation)min:; everything else ordinalLiveContentKeyOfCreateIdResolvermoduleVersionOf; the 3-arg one delegates with "no version" (kept, so no public removal)PrebuiltAssemblySeeder.SeedDetailedValidate(...)and logs the status plus the sentenceNodeTypeCompilationHelpers—HasUsableBuild,HasStaleFrameworkBuild, the stale-build kickoffModuleVersionsOfNodeTypeBakeStatus.Classify/ClassifyDetailed(bake probe + sweep)mw-plugin-testTreeBake/BakeHost(producer)ModuleVersionsOf/ModuleVersionResolverOf;ShippedByHostProblem's wordingReleaseAvailability.SealedSetProblem(roll gate)IsModuleLaneIdso it keeps firing on floorsServedModuleBytes.RecordedFor(registry #3244)What I deliberately did NOT relax
!toolchain— the PROXY still invalidates every record on a toolchain change. A module floor met with room to spare licenses nothing there.!input— the direct observation is still exact.ref:platform surfaces andabsent— still ordinal.min:never compares toref:, which keeps Release availability must confirm a CONSISTENT sealed set (dependency records match), not bundle presence — memex-cloud rolled to ci.7621 and then DECLINED SocialMedia at adoption #3175's one-producer rule intact: the bake reports NotChecked rather than quietly matching.ModuleVersionCompatibility, the framework identity,PrebuiltAssemblySeeder.DeclineReason(framework MVID equality), and R2's link probe: untouched.Clause 4 — an unmet floor is visible
Validateanswers aDependencyRecordOutcome(Satisfied/Drifted/FloorNotMet/NotChecked) modelled onNodeDiagnosticsOutcome(#3912/#3916) — not a fourth way to say "I could not check".FindMismatchis a projection of it, so the string and status forms cannot disagree, andIsSatisfiedis false forNotChecked.And the silent-default path is gone: a recorded build whose bytes this process cannot resolve now overlays the existing
AssemblyUnavailablediagnosis — the same one the pinned-release branch beside it already used, with the same version-gated self-heal — instead of binding the default configuration and rendering "Area not found". The overlay keeps the fail-fast contract (UnhandledMessageNack), so a typed request gets a terminalDeliveryFailurenaming the NodeType rather than being ignored.Controls, both directions
DependencyRecordFloorTest— a test that only proved acceptance would also pass for "adopt everything", so every relaxation arm is paired:'MeshWeaver.Markdown.Collaboration' built against mvid:798f92a0, live is mvid:825581836a'MeshWeaver.Markdown.Collaboration' needs at least 1.6.0 — this environment has 1.5.0, below the recorded floormin:3.0.0vs a moved build at the same version answersDependencyRecordOutcome.Satisfied!toolchain,!input,ref:andabsentdid not moveLiveContentKeyOfreproduces the stamped key when a module moved above its floor, and does not when belowClassifyDetailedasserted to report the floor sentenceSealedSetConsistencyTestgains three arms: a floor-shaped record is still held by a set conflict, still Indeterminate on an unreadable set, and not held merely because the sealed build differs (the one retired check, pinned so "retired" is distinguishable from "quietly stopped firing")FullMvidAssembliesgainsMeshWeaver.Plugin.Packaging— its ratchet caught it, which is what it is for. Cost measured before taking it: a LEAF (zeroProjectReferences, so it pulls no subtree behind it) at 3 commits/60d, against a union already carryingMesh.Contract(190/30d) andMessaging.Hub(135/30d); and the membership is correct, not merely cheap, since the comparer now decides which builds are adopted.Would a portal now adopt the bundle that produced the SavThankYou outage?
Yes. All three builds of
MeshWeaver.Markdown.Collaborationin that publication carry oneInformationalVersion(core pins it to$(PlatformVersion)underCIRun; Plugins#1604 carries the same pin), so record and live both resolvemin:3.0.0,Satisfiesanswers true, and the bundle is adopted instead of declined. Nothing then setslatestAssemblyCollection: "local", so neither replica compiles, neither invalidates the other, and the type's declared views register.Verification
Release +
-warnaserror, one project per invocation, all0 Error(s): MeshWeaver.Compiler, Compiler.Pipeline, Graph, PluginCatalog, Hosting, Documentation, PluginTester, and the test projects Compiler.Pipeline.Test, Graph.Test, Memex.Portal.Shared.Test, PluginTester.Test, Hosting.Test, Hosting.Orleans.Test.Tests: Compiler.Pipeline.Test 839 passed, Graph.Test 1516 passed, PluginTester.Test 361 passed, Memex.Portal.Shared.Test sealed-set/release filter 58 passed, Hosting.Test
PrebuiltAdoptionPolicyTest14 passed,DocumentationLinkIntegrityTestpassed.Doc:
Doc/Architecture/DependencyRecordFloor, cross-linked fromModuleOwnedSiblingsRide(whose "agreement is cheaper than exclusivity" remedy this replaces) andModuleAdoptionPolicy. What's New entry,Category: Fix.Pairs-with: none — nothing public was removed. The diff adds public surface only (
MinVersionScheme,Satisfies,IsModuleLaneId,Validate,ValidateAfterReevaluation,DependencyRecordOutcome,InstalledModuleAssembly.Version); the pre-existingCreateIdResolver,FindMismatchandFindMismatchAfterReevaluationsignatures are all kept, and the only external caller found —MeshWeaver.Plugins'ShippedPrebuiltBundlesTest, which calls the 3-argCreateIdResolverpositionally with an empty module map — is unaffected, as is itsmvid:some-other-builddecline assertion.🤖 Generated with Claude Code
https://claude.ai/code/session_01S25PJZbVeCbkWhCfMub9P7