# Recordings

A recording is a provider's answer to one operation, its plain values
replaced by placeholders, kept in the package as
`recordings/<resource>.<operation>.json` so its decoding can be checked
without calling the provider. This is what a recording keeps,
how it is checked and how you make one.

- **What a recording keeps.** The answer as the provider sent it, only
  along `output_at:`'s path and only the members the operation's output
  type declares, written with two spaces of indentation and members in
  name order. Each text or number the type reads as a plain value is a
  placeholder naming its built-in type in braces, `"{Text}"`,
  `"{Instant}"`, `"{Int}"`, so no personal data or account detail from
  the sandbox is committed. Kept as sent: booleans and `null`, an enum's
  spellings and a map's keys, which say nothing about anyone; a field in
  a built-in encoding or with the package's own `decode:` and `encode:`,
  and the whole answer of an operation with `wire_output:`, which its
  decoders exist to read, numbers with their digits as written; and a
  value whose type's rules no generated value keeps (a pattern), which a
  placeholder couldn't stand in for.
- **Filling a placeholder** gives a generated value of the type at its
  place, as the fake's generated default makes one: the
  invocation's clock, a fresh UUID. Members a hand-written recording adds
  beyond the type are left as they are and ignored by decoding.
- **Which recordings `jadpo test` reads.** Every
  `recordings/<resource>.<operation>.json` of the app's own integrations
  in `shared/providers/`, connected or not; an installed package's were
  read when it was published, and its files are held to its digest. Each
  is a test of a fifth kind, `recording`
  ([Kinds of test](kinds-of-test.md)), named
  `<resource>.<operation>'s recording decodes`, run alone by its file;
  it reads the whole output, never only the fields code reads. A
  recording named after no operation of its package fails it too.
- **Round trips** are checked on what a recording holds: each field's
  `decode:` over the value recorded, then its `encode:` over what that
  gave, which must be the value recorded (`test.round_trip_failed`,
  showing both). Built-in encodings round-trip by construction.
- **The publishing bar** counts the recordings as its `decoders` row,
  apart from the package's own tests, and shows each failure's report.
- **`jadpo dev`** answers an unscripted call from its operation's
  recording where its package keeps one, the generated default
  otherwise; a script still comes first. Tests keep the generated
  default, so a test never depends on a recording.
- **`jadpo package record <connection> <resource>.<operation>`** runs in
  an app, through one of its connections, since a package alone has no
  credential or sandbox to call. It records into the app's own
  integration, or into a linked package's checkout, and refuses an
  installed package (`recording.refused`), whose files its digest holds.
  The operation's input is `--input`, JSON as a route's body is written,
  required when the operation takes one. It refuses before sending
  anything a connection whose environment setting chooses `live`, one
  whose credential, environment or address nothing sets (the stand-in
  `jadpo dev` gives it would reach nobody), and one with no address. A
  keyed operation takes a key derived as any call's
  ([Several changing calls in one action](several-changing-provider-calls.md)),
  from a scope of its own and this run's randomness, so recording again
  is a new request. A refusal, no answer, or an answer that doesn't
  again leaves the file as it was.

> Writing an operation's output type from a recorded answer isn't built
> yet, so recording an operation with no `output:` is
> `toolchain.not_built_yet`.
