### Routed media jobs: the route record, OER/2 minor version 1, and the operations a job names

- **`wai.route.record`** ([extensions/route-record.md](extensions/route-record.md)): what a router considered for
  one media job and why it chose. The job's request (an operation of the catalogue, a capability and a fallback, its
  quantities, hard limits and soft preferences), the price book and a named, versioned routing policy are documents
  pinned by SHA-256 over their RFC 8785 forms; from them alone come the candidates, every limit that removes one (a
  value the price book does not know counted as the most restrictive), the ranking, the order and the decision, which
  the router signs with every attempt, its hop's OER/2 job receipt and whether it was billed. The attempts follow the
  order, only the last serves, and a failed hop or one that served past the declared deadline is not billed. Feature
  `route_record` (`route`, `seal`, `verify`); the corpus `live-conformance/routes/`, written by
  `wai_route_record_vectors`, each control refused at the reason and place it declares; its second implementation
  `live-conformance/route_record_verify.py`, which verifies the hop receipts with the OER/2 reference verifier. The
  document kinds `wai-route-request`, `wai-route-pricebook`, `wai-route-policy` and `wai-route-record` are wire
  identifiers.
- **OER/2 minor version 1** ([extensions/oer-receipts.md](extensions/oer-receipts.md) §3.1): a receipt whose `oer` is
  `"2.1"` may state its figure as the unmetered marker, `energy.joules_total` `null`, which a verifier reports as
  unmetered and never as a figure, or beside its acquisition class, `energy.class`, which must support exactly the
  receipt's grade. Three reasons (`unmetered_invalid`, `class_invalid`, `class_grade_mismatch`), a third canonical
  fixture, and `oer-conformance/job_vectors.json` from the hand-declared `generate_job_vectors.py`. A receipt of minor
  version 0 reads as before: every existing vector keeps its reasons. A `job` receipt names its operation under
  `oer.job.*`, and a route record holds each hop's receipt to that name. The differential fuzzer mutates job receipts
  of minor version 1 too.
- **The catalogue**: `route.verify` (`wai route verify <document>`, a build with `route_record`); `package.build` and
  `package.verify` (`wai package build|verify`), which run the reference packager `wai-pack` as itself (found with
  `--packer`, `$WAI_PACK_BIN`, beside `wai` or on `PATH`), so a job can name its packaging by an operation of the
  catalogue. `wai/catalogue/ops.json` is regenerated.
- **`VideoReceipt::from_json`**: the inverse of `to_json`, so a holder of a `wai.video.int_motion` receipt's JSON runs
  `verify` and `verify_reconstruction_wiv1` with WAI's own code. `to_json` writes the signer id as an escaped JSON
  string, which changes nothing for an id that needs no escape.
- **`wai-pack`'s meter slot is `Send`**: `PackOpts::meter` is `Option<Box<dyn Meter + Send>>`, so a host that packs on
  a worker thread hands the packer its meter and the package receipt states the figure.
- **Breaking:** `api:rust:wai::energy_meter::CounterMeter::new`: its read and clock closures are `Send`, so the meter
  can cross threads. A caller whose closure holds an `Rc` or a `RefCell` moves its state into the closure or holds it
  in an `Arc<Mutex<_>>`.
- **Breaking:** `api:rust:wai::energy_meter::CounterMeter::calibrated_instrument`: the same, for a calibrated
  instrument's read and clock.
- **Breaking:** `api:rust:wai::energy_meter::ModelMeter::new`: the same, for the model meter's clock.

