# Wire encodings, decoders and retries

This is the detail behind [Decoding](decoding.md) and
[Calling](calling.md): the encodings a provider's fields can be sent in, a
package's own decoders, which fields are decoded, and how `retry:` and
`timed_out:` work.

- **The built-in encodings** are ten, by these names: `unix_seconds` and
  `unix_milliseconds` (an `Instant` as a whole number), `iso_8601` (an
  `Instant` with any offset from UTC, which the contract refuses, since it
  writes only `Z`), `day_month_year` (a `CalendarDate`, the encoding
  [Jobs and events](jobs-and-events.md) and the
  [Standard library](standard-library.md) name for file rows, here
  built for providers), `text` (an `Int` or a `Decimal` as text),
  `comma_separated` (a list of single values), `base64` (`Text` as the
  Base64 of its UTF-8), `json_text` (any value's JSON in a string),
  `minor_units` (`Money` in the one currency its type's `currency:`
  fixes, which `Wire.minor_units` needs) and `number` (an `Int` or a
  `Decimal` as a JSON number, its digits kept as written both ways). The
  contract writes a `Decimal` as text and reads no number for one, so
  without `number` a provider sending `2.50` could not be read at all,
  not even by a package's own decoder.
- **Where they apply.** On the provider's wire only: a call's input, its
  answer and a webhook's event. `json.write`, a route's answer
  and an event's payload write the field as the contract writes its
  type, so an app's clients never see a provider's encoding, where a
  field's `wire_name:` is its spelling everywhere. In the
  plan a field that says how it is sent has a codec of its own, holding
  its type's contract codec and how the provider sends it.
- **What each refuses.** `wire:` holds `Wire.<name>` naming one of the
  ten, on a field of a type that encoding holds; outside a provider
  package, beside `decode:` or `encode:`, or naming anything else, it is
  `package.wire_invalid`. A value the provider sends that its encoding
  can't read is a fault naming the operation, the field and the rule
  (`type`, `format`, `max` for an instant past the years an `Instant`
  holds), and a list item holding a comma, which `comma_separated` would
  split, is the fault `comma_separated` when the call is sent.
- **A field's own functions.** `decode:` and `encode:` come together,
  each `library.function` in the package's own `libraries/`, internal or
  public. `decode:` takes one value, the field as the provider sends it,
  and gives the field's type; it may fail, which is a fault. `encode:`
  takes the field's type and gives what `decode:` takes, and may not
  fail. Either named but not the package's, or of another shape, is
  `package.wire_invalid`; they count as the functions' use. That the
  pair round-trips, and that they read every recording, is checked under
  "Recordings".
- **An operation's whole decoder.** `wire_output:` and `decode:` come
  together, with `output:` (`package.operation_invalid` otherwise):
  `decode:` takes the `wire_output:` type and gives the `output:` type.
  The answer is read from `output_at:` as `wire_output:`, its own
  fields' encodings applied, and given whole to `decode:`.
- **Run at the call's site.** The runtime asks the executor to run each
  package function where the call is made; a
  field decoder that fails is the problem `decode` on that field, and an
  operation's decoder that fails names how it ended (its failure's code
  or its fault's classification), never a value.
- **Only the fields read.** Worked out per call site from its action's
  body: when the call's value, or its `attempt`'s, is a variable's and
  every use of that variable is a field read, only those top-level fields
  are decoded and checked; the others hold `none`, which no code can
  read. Fields inside a read field are decoded with it. Rules across the
  type's fields are checked only when every field is read. An operation
  decoded whole is read whole.
- **Numbers as written.** An answer is parsed with Jadpo's own reader,
  so a number keeps the digits the provider wrote and an
  answer naming a member twice isn't JSON; a request's body and query
  are written with each number's digits as the input's codec wrote them.
- **`retry:`** takes `attempts:`, 1 to 10, and `within:`, a duration up
  to 5 minutes, each defaulting to 3 and 30 seconds;
  `connection.value_invalid` otherwise. A call is sent again when it
  never left or the provider said it did nothing (`408`, `429`, its
  `in_use:` code), whatever it changes, and when it may have acted (a
  server's error, no whole answer, no answer in time) only if it changes
  nothing or takes its key, under the same key. Waits are 200
  milliseconds doubled before each further attempt, drawn evenly from
  zero (full jitter, from the host's randomness), or a `408` or `429`'s
  `Retry-After` in seconds; a wait past `within:` stops the retrying. A
  host with no timer, as a test's, sends again at once and measures
  nothing. Each attempt goes through the capability seam and is logged,
  recorded and replayed as a call of its own.
- **`timed_out:`** The driver tells an answer that didn't come within
  `timeout:` apart from other missing answers. Where
  the call's `attempt` maps `timed_out:` and the operation is safe to
  send again, the last attempt's timeout is the runtime's `timed_out`
  failure (kind `timed_out`, 504), mapped to the app's failure with it
  as the cause; anywhere else it is `unavailable` or `outcome_unknown`,
  as "How provider calls are made" says. `timed_out:` on an operation that changes something without
  a key is `failure.unknown_mapping`, to a failure that isn't
  `unavailable` `failure.mapping_kind`; an operation listing no failures
  may still be attempted for `timed_out:` alone.
- **What reviewers see.** The package's surface writes an operation's
  `wire_output X decode Y`, so the answer as sent shows beside its
  output, and `jadpo package show` gives it as "sent as"; the manifest
  gives a field's `wire`.
