# Widget Envelope Convention Every rendered widget in inter-hub wraps its HSX in the `widgetEnvelope` helper from `Application.Helper.View`. This injects a stable set of `data-*` attributes that enable client-side event capture without coupling to implementation details. ## Usage ```haskell import Application.Helper.View (widgetEnvelope) -- In any view: widgetEnvelope widget [hsx| |] ``` ## Emitted HTML ```html
Annotate
``` ## Attributes | Attribute | Source | Purpose | |-----------|--------|---------| | `data-widget-id` | `widget.id` | Stable identity for event capture | | `data-widget-type` | `widget.widgetType` | Semantic role of the widget | | `data-hub-id` | `widget.hubId` | Which hub owns this widget | | `data-capability-ref` | `widget.capabilityRef` | Link to hub capability | | `data-view-context` | `widget.viewContext` | Logical location in the UI | | `data-policy-scope` | `widget.policyScope` | Governance policy boundary | | `data-widget-version` | `widget.version` | Version at render time | ## Rules 1. **Every interactive hub element** that participates in governance must be wrapped. 2. The `data-widget-id` is the capture key — the event capture endpoint uses it as `widget_id`. 3. Do not add or remove `data-*` attributes without updating both this convention doc and the event capture client script. 4. The "Annotate" control is always rendered. It links to the full annotation thread for the widget.