### A third party's hop has a signed record: what was sent, what came back, and what the provider bills

- **The third-party hop record** ([extensions/route-record.md](extensions/route-record.md) §6.2, §7.2 step 9),
  `wai-route-third-party-hop`: a hop a router sends to a third party's endpoint states who it called (`provider`,
  `origin`), on whose account (`operator` or `customer`, never the key), the provider's id for the work, each exchange
  (method, URL, times, status, and the body sent and received by SHA-256 and length, the response kept where it was
  JSON), the outputs by name and content hash, what the provider bills (`usage`) and what it reported charging
  (`charge`, its own figure in its own terms, never added to anything). It holds no secret: no header has a member, and
  no URL states its query, a provider's signed link being a bearer token; `route_record::third_party::kept_response`
  and `url_without_query` make a response and a URL what a record may state. It is signed by the router under its own
  domain and named by its digest.
- **It is bound to its hop.** A verification document may have `third_party`, the records' texts, beside its receipts: a
  record is held to the route record's signer and job, to its attempt's endpoint, receipt, outcome, error and times, to
  that endpoint's candidate's provider and unit, and when it served, its outputs to what the hop's receipt names and
  the attempt's count (`third_party_invalid`, `third_party_mismatch`, `third_party_output_mismatch`). No route record
  changes: the record names the receipt the route record already names. A document without `third_party` reads exactly
  as before, and its outcome has no such member.
- **The corpus.** Routes 126 → 236 vectors: nine accepted (served on the operator's account, with the provider's charge
  and job id, a failure the provider bills beside a served hop, one it does not bill, records given out of order, the
  customer's account, under a route record of version 2, a response as a record keeps it, and none given) and 101
  controls of one defect each, every form and bound of §6.2 among them. `live-conformance/route_record_verify.py`
  verifies each from this text, and stops a mutated copy at its first failure, since it only asks whether one fails.
- **Breaking:** `api:rust:wai::route_record::Accepted::third_party`: what the records state, `None` when the document has
  none. A struct literal of `Accepted` needs it.
- **Breaking:** `api:rust:wai::route_record::Document::third_party`: the records' texts, `None` when the document has
  none. A struct literal of `Document` needs it.
- **Breaking:** `api:rust:wai::route_record::Reason::ThirdPartyInvalid`, `api:rust:wai::route_record::Reason::ThirdPartyMismatch`
  and `api:rust:wai::route_record::Reason::ThirdPartyOutputMismatch`: three reasons, which an exhaustive match over `Reason`
  needs.
- **Breaking:** `api:rust:wai::route_record::Reason::ALL`: the list of §8's codes holds those three, an array of 25. A
  use that names its length needs the new one.

