From review of #447 (review). Confirmed still valid at HEAD. Non-blocking. Target: L1 nexum-runtime.
The Extension::subscriptions / Extension::events seam (EventSources, ExtensionEvent) is mechanically generic, but two gaps remain:
-
No duplicate-kind detection. Subscription kinds aggregate into a BTreeSet<String> (host/extension.rs:119, via extension_subscription_kinds()), which silently dedupes. Two extensions declaring the same kind string merge into one vocabulary set with no error - their event routing silently shares a kind. Harmless today (single consumer), a latent footgun once a second extension lands. Detect and reject (or namespace) the collision at boot, the way HostServices::from_extensions already bails on a duplicate service namespace.
-
Single consumer. videre-host is the seam's only real user; cow-api does not use it. "Proves the seam" is by construction, not by a second independent consumer. Landing or stubbing a second consumer would validate the generality before the seam is leaned on as shared infrastructure.
Acceptance criteria
- Two extensions declaring the same subscription
kind fail boot (or are explicitly namespaced), covered by a test.
- Optionally: a second consumer (real or a test stub) exercises the seam independently.
Also: duplicate manifest-section names (from #448 review, 2026-07-21)
The same at-least-one-vs-at-most-one gap exists on the manifest-section seam. enforce_extension_sections (supervisor.rs:358) checks a section is claimed by at least one wired extension via .any(|ext| ext.manifest_sections().contains(...)), never at most one. Two extensions claiming the same section name (e.g. both declare "venue") silently coexist; whichever parser runs first wins, undetected.
So this issue now covers three collision classes with one root fix - assert uniqueness of the extension-claimed string at boot, the way HostServices::from_extensions already bails on a duplicate service namespace:
- service namespace (already bails)
- subscription
kind (the original scope above)
- manifest section name (this addendum)
One boot-time uniqueness pass across the wired extension set should cover all three.
The
Extension::subscriptions/Extension::eventsseam (EventSources,ExtensionEvent) is mechanically generic, but two gaps remain:No duplicate-kind detection. Subscription kinds aggregate into a
BTreeSet<String>(host/extension.rs:119, viaextension_subscription_kinds()), which silently dedupes. Two extensions declaring the samekindstring merge into one vocabulary set with no error - their event routing silently shares a kind. Harmless today (single consumer), a latent footgun once a second extension lands. Detect and reject (or namespace) the collision at boot, the wayHostServices::from_extensionsalready bails on a duplicate service namespace.Single consumer.
videre-hostis the seam's only real user; cow-api does not use it. "Proves the seam" is by construction, not by a second independent consumer. Landing or stubbing a second consumer would validate the generality before the seam is leaned on as shared infrastructure.Acceptance criteria
kindfail boot (or are explicitly namespaced), covered by a test.Also: duplicate manifest-section names (from #448 review, 2026-07-21)
The same at-least-one-vs-at-most-one gap exists on the manifest-section seam.
enforce_extension_sections(supervisor.rs:358) checks a section is claimed by at least one wired extension via.any(|ext| ext.manifest_sections().contains(...)), never at most one. Two extensions claiming the same section name (e.g. both declare"venue") silently coexist; whichever parser runs first wins, undetected.So this issue now covers three collision classes with one root fix - assert uniqueness of the extension-claimed string at boot, the way
HostServices::from_extensionsalready bails on a duplicate service namespace:kind(the original scope above)One boot-time uniqueness pass across the wired extension set should cover all three.