Files
inter-hub/contracts/core/widget-envelope-v1.md
Bernd Worsch b5d73aa18b
Some checks failed
Test / test (push) Has been cancelled
feat(WP-0009): IHF GAAF Compliance Foundation — type registries, extension manifests, architectural contracts
Implements IHUB-WP-0009: closes four GAAF-2026 gaps before domain hub work begins.
- TypeRegistry helper + controllers/views (hub_kind, hub_capability_manifest)
- HubCapabilityManifest entity with validation and registry linkage
- ARCHITECTURE-LAYERS.md + CI-enforced boundary contracts
- Alembic migration 1743724800, fitness tests (Test/Architecture/)
- GAAF spec, Operational Architecture spec, domain hub extension guide
- Updates to CLAUDE.md, SCOPE.md, Schema.sql, Routes, FrontController, Types

state_hub_sync: pending (tunnel was STALE at completion time; run fix-consistency)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:17:39 +00:00

3.2 KiB

Widget Envelope Contract

Name: widget-envelope Version: 1.0 Date: 2026-03-31 Status: Active Layer: Core Immutable: Yes — changes require v1.1 with backwards-compatible additions only


Purpose

The Widget Envelope is the metadata boundary attached to every rendered widget. It enables the IHF capture pipeline to attribute any DOM event to a governed widget without coupling to the widget's implementation.

Any UI technology that emits the required data-* attributes on a DOM element is a first-class IHF participant.


Required Attributes

Every widget root element MUST carry all of the following:

Attribute Format Example
data-widget-id UUID (RFC 4122) data-widget-id="550e8400-e29b-41d4-a716-446655440000"
data-hub-id Registered hub slug (TEXT) data-hub-id="ops-hub"
data-view-context Dot-separated path (TEXT) data-view-context="ops.incidents.list"
data-widget-type Registered name from widget_type_registry data-widget-type="chart"

Optional Attributes

Attribute Format Notes
data-capability-ref TEXT Links widget to a hub capability
data-policy-scope Registered name from policy_scope_registry Defaults to internal if absent
data-widget-version Integer as string Current widget version number
data-experiment-variant TEXT A/B experiment identifier
data-requirements-thread-ref UUID Links to an open AnnotationThread

Validation Rules

  1. data-widget-id must be a valid UUID. Non-UUID values cause the envelope to be treated as malformed.
  2. data-hub-id must match the slug of a registered hub in the hubs table. Unknown hub slugs are logged but do not block event capture.
  3. data-widget-type must exist in widget_type_registry with status = 'active' at the time of capture. Events from deprecated types are accepted but flagged.
  4. data-view-context has no format enforcement in v1.0 beyond non-empty.

Failure Mode

  • Missing required attribute: the capture pipeline logs a malformed_envelope event with the missing attribute names in metadata. The original interaction event is not stored. This is fail-safe, not fail-loud — the UI does not crash.
  • Unknown hub slug: event is stored with metadata.hub_warning = "unknown_hub_slug".
  • Unregistered widget_type: event is stored with metadata.type_warning = "unregistered_widget_type". No 422 is returned to the frontend (retroactive registration is possible).

Backwards Compatibility Rule

v1.0 is frozen. New optional attributes may be added in v1.1 without breaking existing implementations. Removing any attribute, or making an optional attribute required, requires a new major version (v2.0) with a migration window.


Implementation Reference

  • Schema enforcement: widgets.widget_type validated against widget_type_registry on create/update in WidgetsController
  • Client-side: static/ihf-annotation-launcher.js reads data-widget-id and data-hub-id from the nearest ancestor with these attributes
  • Server-side envelope rendering: widgetEnvelope HSX helper in Application/Helper/View.hs