### The browser sink: routes before decode, and the frame on screen bound to its receipt

- **The extension** ([browser-sink](extensions/browser-sink.md)) says how a sink in a web page
  answers SPEC §4's "the sink advertises `cap`". For each object it builds a capability report
  and routes the object to the user agent's decoder, a native host's or WAI's own WebAssembly
  decoder. The user agent is asked only about codec strings the WebCodecs Codec Registry
  (Registry Draft, 24 September 2026) lists: a capability with no such string (`wai.video.av2`,
  `wai.video.vvc`, `wai.audio.iamf`) is never put to `isConfigSupported`, and an answer about
  one is never read. The user agent's decoder is taken only where it is exact for the tier the
  object needs: a need of `decode-equivalence` takes it only after a probe matches published
  frame digests, and otherwise falls back to wasm. Each step's refusal has a reason code.
- **Constraint sets in the page.** [capability-constraints](extensions/capability-constraints.md)
  gains its register (§3.1, the `wai:` parameters) and its evaluation, in browser-sink §5:
  enumerations, minima and maxima ORed over sets, in integers.
- **Energy beside `powerEfficient`.** A measured figure per decode is reported beside Media
  Capabilities' boolean, with its acquisition class ([energy-measurement](extensions/energy-measurement.md)
  §2) and coverage; the boolean stays the user agent's word, and a decode with no measurement is
  unmetered, never 0 J.
- **`contentBinding`.** Every frame a page decodes carries the content hash of the receipted
  object it was decoded from ([jwp-receipts](extensions/jwp-receipts.md) §2.1), the link hash of
  the group receipt that object verified under, and the tier its samples hold. The binding
  survives `clone()`, serialization and transfer, gives nothing to the bytes `copyTo()` writes,
  and does not survive re-encode. Until the WebCodecs VideoFrame Metadata Registry lists the
  member, a page keeps it in a side table keyed by decoder and timestamp, and refuses a
  timestamp given twice. The state of the frame on screen joins the binding to the receipts and
  to [live-provenance](extensions/live-provenance.md)'s verdict. A draft registry entry and
  issue text are in [`proposals/webcodecs-content-binding.md`](proposals/webcodecs-content-binding.md),
  not filed. `contentBinding` is a wire identifier of the new kind `frame-metadata`, status
  `proposed`.
- **Reference and conformance.** `wai-rs`'s `browser_sink` module (feature `browser_sink`) and
  the corpus [`live-conformance/browser/`](live-conformance/browser/) with its second
  implementation, `browser_sink_verify.py`. `wai-live-web` builds the same functions for the
  page, and with its feature `int_video` a wasm decoder that verifies a `wai.video.int_motion`
  object against its receipts and binds every frame. The room client routes each track before it
  decodes it, binds every frame its decoders output, and shows each tile's state with
  `?debug=binding`; its end-to-end scenario `binding` runs all of it in a browser.

