### `wai.sink.energy`: what decoding cost at the sink, per segment, and one session split by hop

- **Sink energy profiles** ([energy-measurement](extensions/energy-measurement.md) §9). For each
  kind of platform: the counter a sink reads for its decode, the fabrics it covers (`cpu`,
  `gpu`, `media`, `npu`) and what else it sums, whether the reading is the sink's own (`task`:
  the operating system's account of the sink's processes, `ri_energy_nj + ri_billed_energy −
  ri_serviced_energy` on macOS) or a counter every user shares, from which the figure is §3's
  bracket over the whole decode and no fabric's share, and the shortest window. No counter is
  ever divided among its users by their busy time; a whole rail is one user's only where that
  user was its sole user, at least 99% of the busy time (`rail`). `macos-task` is the kernel's
  per-process energy with the work billed to the process (`proc_pid_rusage`,
  `RUSAGE_INFO_V6`); `macos-gpu` is IOReport's `GPU Energy`; `linux-rapl` is the powercap
  package zone; `linux-nvml` is the NVIDIA total energy counter behind a plausibility rule.
  All are `OnChipCounter` with filtering `Unknown`, and none is ever `HwShunt`. On the
  reference macOS sink every other `Energy Model` channel was frozen for an unprivileged
  reader, and no channel names the video decoder, so a hardware decode path is `Partial`: it
  does not cover the media engine. Platforms with no rail (phones, a page) state an
  `Estimator` by `estimator-cpu-time/1` with its inputs and a stated uncertainty; the display
  is an `Estimator` of its own, `estimator-display/1`, from the panel's declared on-mode power
  and its luminance setting, never added to a decode figure.
- **The extension** ([sink-energy](extensions/sink-energy.md)) registers the record
  `wai.sink.energy` with three JSON records signed with Ed25519 over RFC 8785:
  - a **decode table** (§4): one figure per registered capability, decode path and profile,
    per completion of a stated work item, from an odd number of bracketed rounds (at least
    seven), each opened from rest. Every round's values are in the record and every counter
    reading is in a readings file the record binds by digest, so a verifier recomputes each
    round, each round's figure and least declaration (energy-measurement §6.2), the median,
    the range, the row's verdict and its declaration, which also covers the rounds' spread.
    A row with no decoder, no work item, no hardware path or no live counter is absent and
    says which. The procedure `wai-sink-table/1` (§4.4) is the binary `wai_sink_table`;
  - a **segment receipt** (§5) per segment of each stream, chained, whose figure is
    `measured` over a bounded window (exactly the segment's decode, so no completion-count
    term), taken from the sink's own table (`ModelBased`) or another key's (`Estimator`),
    estimated, or `unmetered` with its reason;
  - a **session receipt** (§6): the per-hop split over the hop roles a stream log uses
    (stream-termination §2 and §3.5: 1 origin, 2 relay, 3 sink decode, 4 display), one table
    with its hop entries. Each hop is a figure with its own class, the unmetered marker where
    the sink knows it took place and has no figure (with the reason), or absent where the sink
    states nothing. An origin or relay entry restates a hop's record (a live-metering `WMH1`
    for a relay) with its class only where the session was the hop's sole user, at least 99%
    of its busy time; a shared hop is the marker `hop_shared`, never divided by time. The
    sink-decode entry is composed from the segment receipts, each of which is that hop's
    figure for its segment, and no total is stated across classes.
- **Corpus and verifiers.** `live-conformance/sink-energy/` holds accepted and refused tables,
  segments, chains and sessions (every reason of §8 refuses at least one) and the measured
  tables of the reference sinks under `tables/`, each with its readings and its procedure.
  The corpus regenerates byte for byte (`wai_sink_energy_vectors`), and its second
  implementation, `live-conformance/sink_energy_verify.py`, written from the text, recomputes
  every round, row, segment and split in integers and requires every mutated copy to fail.
  CI runs the integer checks in `wai-conformance.yml`, and the procedure on the `macos` and
  `linux-hw` runners in `energy-hardware.yml`, where a runner with no live counter reports
  the measurement as skipped, never as passed.
- `browser-sink` §6: a page may take its `energy` measurement from a `figure` row of its
  sink's decode table.

