Problem
Display-only component elision drops a component's module (and its customElements.define) from the browser when the analyser judges it purely presentational. That is safe in isolation, but it has a real, undetected correctness hole: cross-module observation of an elided component's registration.
If component A is elided, its tag never registers on the client. Any OTHER shipping code that observes A's tag then breaks silently:
customElements.whenDefined('a-tag') never resolves
- a CSS
a-tag:defined { ... } rule never matches
- an
instanceof AClass check is always false
- an upgraded-member read off
document.querySelector('a-tag').someProp is undefined
- a vendor package that self-registers via
customElements.define at import top level, pulled in through a binding import on an elided module, never runs
This is acknowledged in packages/server/src/component-elision.js (around the importsSideEffectNonCorePackage comment), in agent-docs/components.md, and in packages/server/AGENTS.md invariant 7, but it is NOT statically detected (dynamic tag strings and external CSS are unanalyzable) and NOT tested at any layer. Today it relies entirely on author discipline.
Design / approach
The bias must stay conservative (ambiguous ships), so close the hole by SHIPPING when an observation is detectable, never by eliding more:
- Conservative detection: when scanning the shipping module set, if any module references a known component tag via
whenDefined('<tag>'), an instanceof <Class>, or a CSS selector <tag>:defined, mark that tag's component as must-ship (do not elide). This catches the statically-visible cases (string-literal tags, imported classes, authored CSS) and is verdict-safe (it only ever ships more).
- The residual unanalyzable cases (dynamic tag strings, external stylesheet
:defined) stay an author-facing caveat, but should at least be pinned by a test that documents the failure so the boundary is explicit.
- Self-registering vendor packages reached through an elided binding import: detect a top-level
customElements.define in a bare-package's entry where feasible, or document the .server.{js,ts} / interactivity-signal fix and test it.
Acceptance criteria
Problem
Display-only component elision drops a component's module (and its
customElements.define) from the browser when the analyser judges it purely presentational. That is safe in isolation, but it has a real, undetected correctness hole: cross-module observation of an elided component's registration.If component A is elided, its tag never registers on the client. Any OTHER shipping code that observes A's tag then breaks silently:
customElements.whenDefined('a-tag')never resolvesa-tag:defined { ... }rule never matchesinstanceof AClasscheck is always falsedocument.querySelector('a-tag').somePropis undefinedcustomElements.defineat import top level, pulled in through a binding import on an elided module, never runsThis is acknowledged in
packages/server/src/component-elision.js(around theimportsSideEffectNonCorePackagecomment), inagent-docs/components.md, and inpackages/server/AGENTS.mdinvariant 7, but it is NOT statically detected (dynamic tag strings and external CSS are unanalyzable) and NOT tested at any layer. Today it relies entirely on author discipline.Design / approach
The bias must stay conservative (ambiguous ships), so close the hole by SHIPPING when an observation is detectable, never by eliding more:
whenDefined('<tag>'), aninstanceof <Class>, or a CSS selector<tag>:defined, mark that tag's component as must-ship (do not elide). This catches the statically-visible cases (string-literal tags, imported classes, authored CSS) and is verdict-safe (it only ever ships more).:defined) stay an author-facing caveat, but should at least be pinned by a test that documents the failure so the boundary is explicit.customElements.definein a bare-package's entry where feasible, or document the.server.{js,ts}/ interactivity-signal fix and test it.Acceptance criteria
whenDefined('<tag>'),<tag>:definedCSS rule, orinstanceof <Class>referencing an elidable component forces that component to ship (not elided)agent-docs/components.md+packages/server/AGENTS.mdinvariant 7 updated to describe what is now detected vs still author-discipline