You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A module bundle that states no framework identity is still publishable, so the #3154 comparison has nothing to compare — part 3 of Plugins#931 #3211
The consumer half of Plugins#931 landed in #3154 (merged d51b2971, 2026-09-03): ModuleUpdateDecision.Decide now compares (version, framework identity) before answering SkipUpToDate, and the registry advertises a per-bundle frameworkMvid on /api/plugins/bundles/index.json.
That change deliberately left one blind spot open, and named where it must be closed rather than papering over it at the consumer:
an unstated served identity SKIPS — and the verdict SAYS the identity could not be checked rather than implying the two agree. […] the place to remove that blind spot is where it is created: part 3 of the agreed shape makes a bundle that cannot state what it was built against unpublishable
— ModuleUpdateDecision.Decide, bundleFrameworkMvid parameter doc
The reasoning for skipping there is sound and should not be revisited at the consumer: answering Land on an unstated served identity re-downloads every module on every reconcile, forever, on every deployment pointed at a registry that predates the field. Landing can heal an unknown on the landed side (it writes the identity back); it can never heal one on the served side.
What is still open
A module can still be published with no framework identity.ModulePublish.Accepted.FrameworkMvid is string? and ModulePublish.Validate does not refuse a manifest that states none — so the shelf entry carries null, the index advertises frameworkMvid: null, and every consumer of that bundle is permanently in the skip-and-say-so branch. The comparison exists but has nothing to compare.
Concretely:
src/MeshWeaver.PluginCatalog/ModulePublish.cs:45 — string? FrameworkMvid on Accepted, never validated.
memex/Memex.Portal.Shared/Api/PluginBundleEndpoints.cs — ShelveModule(frameworkMvid: accepted.FrameworkMvid, …) shelves whatever arrived, including null.
src/MeshWeaver.PluginCatalog/ModulePublish.cs:39 still reads:
<param name="FrameworkMvid">The framework build the producer compiled against — diagnostic only.</param>
"diagnostic only" stopped being true when #3154 merged.LandFromBundle's own doc was corrected in that PR ("Still never a LANDING gate […] but no longer merely diagnostic: ModuleUpdateDecision reads it back to tell a rebuild from a no-op"); this one was missed. It is now the input to an update decision on every installation, and a comment telling the next reader it is diagnostic is exactly how an optional field stays optional.
What this needs
Refuse a module publish that states no framework identity — a named 400 from ModulePublish.Validate, not a silent null on the shelf — with the transition thought through: every producer CI in the fleet must be emitting the field before the refusal is armed, or the refusal takes the fleet's publishes down. Worth measuring first: how many bundles currently on the memex registry shelf carry a null identity.
Doc/Architecture/ModuleBuildArchitecture → Roadmap, which records it: "Still open: making a bundle that cannot state what it was built against UNPUBLISHABLE"
Activity