Raised from Systemorph/MeshWeaver.Plugins#1271, which closes as a pointer to this one — the decision belongs to the core pack lane (module-owned-platform.sh / ModuleClosureAccounting), not to a satellite.
The gap
BakeHost.ShippedByHostProblem (#3175) refuses a module that is composed with --module AND shipped by the platform host — it checks the host's /app directory and its surface manifest. It does not check whether a second module bundle carries a copy of the same assembly name.
That case is live. Since Plugins#1268 removed MeshWeaver.Markdown.Collaboration.dll from the portal image's app closure, the AI bundle rides a copy of it as a module-owned sibling (ModuleClosureAccounting: a module-owned MeshWeaver.* sibling rides). So the assembly has two module-side producers:
- Essentials declares
MeshWeaver.Markdown.Collaboration as its module (Essentials/index.json);
- AI carries a copy of the same DLL as a riding sibling.
The Chat bundle already has this exact shape with MeshWeaver.AI.dll today, so this is a pre-existing accepted pattern, not a regression from #1268 — nothing is known to be broken by it right now.
Why it is worth deciding rather than leaving implicit
The failure mode #3175 exists to prevent is a dependency-record mismatch at adoption: records naming one build (mvid:…) while the consumer resolves another (ref:…, or a different mvid:), which DECLINES every NodeType binding the name. The guard closes the host-vs-module case. The module-vs-module case is closed only by the accident that both copies happen to be built from the same source in the same wave — a property of the current CD wave, not an invariant anyone asserts.
So the question is not "is it broken today" (it is not) but "what closes it when the wave stops being uniform" — which is exactly the shape of failure #3175 was written for.
The decision
Should a sibling that is itself another package's declared module ride into a second bundle, or should the closure rule exclude declared modules and let the landing resolve them from their owning package?
If the answer is "it should not ride", the guard extension is the same shape as #3175: refuse a bundle that carries an assembly another package declares as its module. That is a guard which can refuse an existing caller (Chat/MeshWeaver.AI today), so by the working agreement it lands with its caller sweep or in grace mode — never on its own.
Surfaced while landing Plugins#1268 (Closes Plugins#1262). No action taken there.
Raised from Systemorph/MeshWeaver.Plugins#1271, which closes as a pointer to this one — the decision belongs to the core pack lane (
module-owned-platform.sh/ModuleClosureAccounting), not to a satellite.The gap
BakeHost.ShippedByHostProblem(#3175) refuses a module that is composed with--moduleAND shipped by the platform host — it checks the host's/appdirectory and its surface manifest. It does not check whether a second module bundle carries a copy of the same assembly name.That case is live. Since Plugins#1268 removed
MeshWeaver.Markdown.Collaboration.dllfrom the portal image's app closure, the AI bundle rides a copy of it as a module-owned sibling (ModuleClosureAccounting: a module-ownedMeshWeaver.*sibling rides). So the assembly has two module-side producers:MeshWeaver.Markdown.Collaborationas its module (Essentials/index.json);The Chat bundle already has this exact shape with
MeshWeaver.AI.dlltoday, so this is a pre-existing accepted pattern, not a regression from #1268 — nothing is known to be broken by it right now.Why it is worth deciding rather than leaving implicit
The failure mode #3175 exists to prevent is a dependency-record mismatch at adoption: records naming one build (
mvid:…) while the consumer resolves another (ref:…, or a differentmvid:), which DECLINES every NodeType binding the name. The guard closes the host-vs-module case. The module-vs-module case is closed only by the accident that both copies happen to be built from the same source in the same wave — a property of the current CD wave, not an invariant anyone asserts.So the question is not "is it broken today" (it is not) but "what closes it when the wave stops being uniform" — which is exactly the shape of failure #3175 was written for.
The decision
Should a sibling that is itself another package's declared module ride into a second bundle, or should the closure rule exclude declared modules and let the landing resolve them from their owning package?
If the answer is "it should not ride", the guard extension is the same shape as #3175: refuse a bundle that carries an assembly another package declares as its module. That is a guard which can refuse an existing caller (Chat/
MeshWeaver.AItoday), so by the working agreement it lands with its caller sweep or in grace mode — never on its own.Surfaced while landing Plugins#1268 (
ClosesPlugins#1262). No action taken there.