Skip to content

Availability confirms a CONSISTENT sealed set; the bake refuses a doubly-produced module (#3175) - #3187

Merged
meshweaver-cloud[bot] merged 1 commit into
mainfrom
fix/3175-one-maps-build-per-identity
Sep 3, 2026
Merged

meshweaver-cloud[bot] merged 1 commit into
mainfrom
fix/3175-one-maps-build-per-identity

Conversation

@rbuergi

@rbuergi rbuergi commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Availability must confirm a CONSISTENT sealed set — one producer per (module, identity)

Closes #3175

Maps is a Plugins module only (maintainer, 2026-09-03: "all maps should be in plugins and removed from core — move 100% to plugins").

Root cause (measured 2026-09-03 07:21–07:33Z)

Every satellite release-follow gate failed its consumption postcondition — Reinsurance run 33727661313 adopted 236 of 240 … 4 DECLINED, Manufacturing 33727661850 97 of 102 … 5 DECLINED:

Prebuilt assembly for AppleMaps/Gallery DECLINED: dependency record mismatch —
  'MeshWeaver.Maps' built against mvid:4d04617292154b2d9b7a3aa5e9b6a815,
  live is ref:1D8FDE5B7D25D8F515066B7D925ACF33D46910F6EB75E2D8DD169671B1FC8F15

ref: is the surface-manifest scheme: the gate host — the portal's /app — SHIPS MeshWeaver.Maps.dll and lists it in its manifest. mvid: is the module scheme: the Plugins bake COMPOSED Maps with --module (the id resolver puts modules first). Two producers of one assembly for one identity: the portal host in MeshWeaver.Plugins (Memex.Portal.Gui.csproj) had kept a direct ProjectReference to src/MeshWeaver.Maps from before Maps became a Store module (core #2941 / Plugins #1057). Core itself already carried no Maps project, no reference and no ContentSurfaceAssemblies entry — only stale comments and a self-test fixture claiming otherwise. Nothing had changed in any repo; no satellite could seal; memex-cloud held at ci.7652 ("no sealed content bake").

The same morning memex-cloud (ci.7621) declined SocialMedia/Post|PostsHub|Profile — 'MeshWeaver.Markdown.Collaboration' built against mvid:A, live is mvid:B — because the availability gate checked PRESENCE of a sealed bundle, not CONSISTENCY of the set (#3175's finding).

What this PR does (core half)

  1. The bake refuses a second producer by name — BakeHost.ShippedByHostProblem, applied under --app and in-process: a --module whose simple name the host also ships in its app directory or lists in its surface manifest fails the bake RED ("two builds of one assembly name in one bake … remove the assembly from the platform host's closure or stop composing it"). Pinned by BakeAgainstPlatformHostTest.AComposedModuleTheHostAlsoShips_IsRefusedByName.
  2. Availability asserts the SET — PublishedBundleCatalogue.ArtifactsForIdentity now reads, for the candidate identity, every complete source's sealed module set (each module bundle's entry assembly → MVID, PE header only) and every sealed bundle's per-NodeType dependency records (manifest only). ReleaseAvailability.IsUpdatable then holds with the new PackageAvailabilityKind.SealedSetInconsistent when a record names a module build the set does not carry, or two sources sealed one module at two MVIDs — naming bundle, NodeType, module and both builds. An unreadable module set is Indeterminate (hold, named); a module outside the set is not judged. Consumed unchanged by the self-update poll, CD's post-promote assertion and /api/plugins/is-updatable. Pinned by SealedSetConsistencyTest (8 cases, both failure directions).
  3. Maps remnants in core rewritten to past tense / neutral fixture: Memex.Portal.Shared.csproj (the "DIRECT ON PURPOSE" block described a reference that no longer exists and would have sent the next reader to re-add it), compose-gate-host.sh self-test fixture, node-repo-gate.yml, GateHostCheck.cs, BuildPluginCommand.cs error text.
  4. Docs: ModuleBuildArchitecture.md → "One producer per (module, framework identity)" (the incident table, the two controls, and what the gate still cannot see); CandidateReleaseProtocol.md → "Availability is a CONSISTENT sealed set". What's New Category: Fix.

Deliberately not in this PR

  • The second producer in time for MeshWeaver.AI / MeshWeaver.Markdown.Collaboration: core CD's plugins-modules rebuilds them per release to feed the Plugins seal while the registry's package endpoint serves the Plugins lane's content-versioned build — the bytes a portal installs. Core holds no registry credential (MW_REGISTRY_KEY is not among its secrets), so its bake cannot compose the registry's bytes today; the alternative is the instance adopting module bytes for its identity from the sealed publication. The new gate now HOLDS on the set it can see rather than rolling; the remaining gap is documented in ModuleBuildArchitecture.
  • Seal-time (bash) MVID verification in publish-bake-bundles.sh: a single bake's set is consistent by construction against its own composed modules once (1) refuses the double; cross-source consistency is asserted by (2).

Counterpart

Counterpart (independent halves, either order merges cleanly): Systemorph/MeshWeaver.Plugins#1242 — drops the MeshWeaver.Maps project reference from Memex.Portal.Gui / MeshWeaver.AI.Test and makes AppleMaps/GoogleMaps/OpenStreetMap/Cornerstone require Maps. No public type leaves core in this PR.

Acceptance

The next Reinsurance release-follow gate after both halves are in the promoted set adopts N of N (seed: adopted 240 of 240 — the control arm was run 33623801785). Verified locally: Memex.Portal.Shared.Test 622/622, MeshWeaver.PluginTester.Test 319/319, MeshWeaver.Documentation.Test 239/239, all -c Release -warnaserror.

🤖 Generated with Claude Code
Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj

…bly-produced module (#3175)

Every satellite release-follow gate declined four map galleries on 2026-09-03
("'MeshWeaver.Maps' built against mvid:4d04617…, live is ref:1D8FDE5B…"): the
portal host shipped MeshWeaver.Maps.dll in /app (ref:) while the Plugins bake
composed it as a module (mvid:) — two producers of one assembly for one
identity, no diff in any repo, nothing sealed, memex-cloud holding. The same
morning memex-cloud rolled to ci.7621 on a presence-only verdict and declined
SocialMedia at adoption ('MeshWeaver.Markdown.Collaboration' mvid:A vs mvid:B).

Maps is a Plugins module only (maintainer, 2026-09-03: "move 100% to plugins").

- BakeHost.ShippedByHostProblem: a --module the host also ships in its app
  directory or surface manifest fails the bake RED by name, under --app and
  in-process (BakeAgainstPlatformHostTest.AComposedModuleTheHostAlsoShips_…).
- PublishedBundleCatalogue.ArtifactsForIdentity reads each sealed source's
  module set (entry assembly MVID, PE header only) and every sealed bundle's
  dependency records (manifest only); ReleaseAvailability.IsUpdatable holds
  with PackageAvailabilityKind.SealedSetInconsistent when a record names a
  module build the identity's set does not carry or two sources sealed one
  module twice; an unreadable set is Indeterminate (SealedSetConsistencyTest).
- Stale Maps remnants in core rewritten (Memex.Portal.Shared.csproj "DIRECT ON
  PURPOSE" block, compose-gate-host.sh fixture, gate lane, tester, CLI text).
- Docs: ModuleBuildArchitecture "One producer per (module, framework
  identity)"; CandidateReleaseProtocol "Availability is a CONSISTENT sealed
  set"; What's New (Fix).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj
Copilot AI lite review requested due to automatic review settings September 3, 2026 08:44
@meshweaver-cloud
meshweaver-cloud Bot enabled auto-merge September 3, 2026 08:44
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

341 tests  +1   339 ✅ +1   37s ⏱️ -8s
  3 suites ±0     2 💤 ±0 
  3 files   ±0     0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The core logic changes are coherent, regression-tested, and align with the stated incident/acceptance criteria; remaining notes are minor doc/perf nits.

Pull request overview

This PR hardens the plugin bake and release-availability gate to treat “availability” as a consistent sealed set: for a target framework identity, every sealed bundle’s dependency records must match the exact module builds sealed for that same identity, and the bake refuses producing a bundle when the host also ships an assembly with the same simple name (preventing “two producers” mismatches like the Maps incident).

Changes:

  • Refuse bakes where a composed --module assembly name is also shipped by the bake host (by surface manifest or app directory), preventing doubly-produced assemblies from being sealed.
  • Extend the release-availability observation to read the sealed module set (module bundle entry assembly → MVID) and per-NodeType dependency records, and gate updates on set consistency.
  • Add targeted regression tests and update docs/fixtures to reflect the “one producer per (module, identity)” invariant.
File summaries
File Description
tools/MeshWeaver.PluginTester/TreeBake.cs Applies the “two producers” refusal in in-process mode before baking.
tools/MeshWeaver.PluginTester/GateHostCheck.cs Updates explanatory comment to remove stale Maps reference.
tools/MeshWeaver.PluginTester/BakeHost.cs Introduces and enforces ShippedByHostProblem for both --app and in-process hosts.
test/MeshWeaver.PluginTester.Test/BakeAgainstPlatformHostTest.cs Pins the “composed module the host also ships” refusal and avoids assembly-name reuse across tests.
test/Memex.Portal.Shared.Test/SealedSetConsistencyTest.cs New suite pinning sealed-set consistency and indeterminate behavior.
src/MeshWeaver.PluginCatalog/ReleaseAvailability.cs Adds set-consistency evaluation, new verdict kind, and supporting records (SealedModuleSet, BundleDependencyRecord).
src/MeshWeaver.PluginCatalog/PublishedBundleCatalogue.cs Observes sealed bundles + module set + dependency records; reads module MVIDs from module bundles.
src/MeshWeaver.Cli/BuildPluginCommand.cs Adjusts error text to remove stale Maps/.AI/.Indexing mention.
memex/Memex.Portal.Shared/Memex.Portal.Shared.csproj Rewrites Maps-related comment to reflect post-move reality and the double-producer failure mode.
.github/workflows/node-repo-gate.yml Updates workflow comment to clarify “portal-only assembly” examples over time.
.github/scripts/compose-gate-host.sh Updates self-test fixture to avoid Maps-specific naming and keep intent intact.
src/MeshWeaver.Documentation/Data/WhatsNew/2026-09-03-an-update-is-held-when-its-packages-do-not-fit-together.md Adds a user-facing “Fix” entry describing the new hold behavior.
src/MeshWeaver.Documentation/Data/Architecture/ModuleBuildArchitecture.md Documents the invariant, the two controls, and the remaining “second producer in time” gap.
src/MeshWeaver.Documentation/Data/Architecture/CandidateReleaseProtocol.md Updates protocol docs to define availability as a consistent sealed set.
Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/MeshWeaver.PluginCatalog/PublishedBundleCatalogue.cs
Comment thread src/MeshWeaver.PluginCatalog/PublishedBundleCatalogue.cs
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

243 tests  ±0   243 ✅ ±0   2m 9s ⏱️ +11s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    4 files  ±0      4 suites  ±0   1m 30s ⏱️ +4s
1 322 tests +8  1 322 ✅ +8  0 💤 ±0  0 ❌ ±0 
1 323 runs  +8  1 323 ✅ +8  0 💤 ±0  0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

448 tests  ±0   448 ✅ ±0   1m 4s ⏱️ +4s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

2 188 tests  ±0   2 188 ✅ ±0   2m 28s ⏱️ -5s
    3 suites ±0       0 💤 ±0 
    3 files   ±0       0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

578 tests  ±0   386 ✅ ±0   2m 37s ⏱️ -1s
  3 suites ±0   192 💤 ±0 
  3 files   ±0     0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Test Results

   15 files  ±0     15 suites  ±0   10m 27s ⏱️ +6s
5 120 tests +9  4 926 ✅ +9  194 💤 ±0  0 ❌ ±0 
5 121 runs  +9  4 927 ✅ +9  194 💤 ±0  0 ❌ ±0 

Results for commit 3b903d6. ± Comparison against base commit e7f1d69.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants