# How a release's facts, change record and fingerprints are worked out

This is the detail behind [What a release shows](the-public-registry.md#what-a-release-shows),
[The changelog](the-public-registry.md#the-changelog), [Search](the-public-registry.md#search) and
[The verifier](the-public-registry.md#the-verifier): what `jadpo package check` prints above its
bar, and what `jadpo package verify --json` writes.

> **The facts cover what the code can do.** An operation of a resource the
> package keeps to itself reaches the host and can change something there
> as much as a public one does, so `hosts` and `changing_calls` list every
> operation, and a hostile release can't hide a call behind a public
> action. `hosts` are the provider's `hosts:` and each `asks` host, or "the
> service Jadpo runs" and "the address its connection gives" where it names
> none. Each marked field is listed for each host it reaches, with its
> operation and categories, and `decided_only` when the value only decides
> what is sent. `storable_types` are every public type of a library
> package, and of a provider's only the plain values, never an object or
> an enum. `standard_candidates` are `package.standard_candidate`'s
> findings on the package's types, which a package that compiles has
> declined. `last_contract_run` and the Jadpo releases it works with are
> the registry's to add, so `verify` writes `null` for the first and leaves
> out the second.
>
> **The change record.** It compares the surface with the last release's:
> a new entry is `added`, one gone `removed`, a new `fails` line
> `new_failure`, a new host `new_host` on `provider`, and any other change
> to an entry's facts one `retyped`, whose `detail` says what it says now
> and what it said (`max_length: 30, was max_length: 20`). Descriptions,
> files, sources and recordings alone aren't changes. Comparing the two
> releases' facts gives `personal_data_sent`, once per field and host. A
> last release this Jadpo can't compile has no facts, so everything now
> sent counts as new. `jadpo package check` writes `CHANGELOG.md`'s list
> from these entries, a line each, and a first release's list is "first
> release".
>
> **The previous release's examples and tests** run in a scratch app of
> their own: the new package's files without its own tests, and the last
> release's `.test.jadpo` files and description examples placed beside
> them. A release at a tag is read from git; `verify` is given its folder.
> Each one that fails is a `behaviour_changed` entry, whose `detail` is its
> name and whose declaration is the public call it makes, on the line that
> failed if it can tell. One that no longer compiles has failed too, so a
> release can't hide a change by removing a helper an old test leans on.
> Recordings aren't run again: the new package's own are, by the bar.
>
> **A fix** is a line beneath the new version's list in `CHANGELOG.md`,
> ``Fix `uk.parse`: why it had to change``, naming the entry's declaration.
> It says why as well, so it needs no other text, and its reason is the
> entry's `why`. A mark with no reason is no mark. Without one, the bar's
> `behaviour` row fails with `publish.behaviour_changed`. While the version
> row itself is refused the behaviour row waits, since a breaking change
> usually fails those examples too.
>
> **A new major version** is compared with the newest release of any label
> of the package's name in code, so `Postcodes.v3`'s first release shows
> what changed since `Postcodes.v2`'s last. Its version is still the one its
> label names, nothing in the change record refuses it, and its behaviour
> row says "a new major".
>
> **`jadpo package verify <folder> [--previous <folder>]`** is this bar on a
> commit as it stands: it writes nothing, and reads no git tags. A
> `surface` row checks the committed `surface.jadpo_record` against the
> code, and the `changelog` row checks the list under the version's heading
> against the change record, each `publish.stale_files` when it differs.
> The previous folder's version is the one its committed surface says, and
> it has to be a release of the same name in code. With no `--previous` it
> is a first release. Its JSON holds `package`,
> `version`, `passed`, `bar`, `surface` (the record's text), `facts`,
> `change_record`, `fingerprints`, `previous` (`since`, `ran`, each `failed`)
> and `jadpo`, the release it was checked with. Its screen is `check`'s,
> without the `Wrote` line or the hint, and its footer counts the
> fingerprints.
>
> **Fingerprints.** Each public declaration has `source`, the SHA-256 of its
> tokens as the formatter writes them, leaving out its description,
> comments, visibility, `decline` lines and its own name. A function's or
> action's parameters and variables are named by their position, as the
> similar-helper check names them, so a renamed and reformatted copy has the
> same `source`. A type's fields keep their names, since they are what it
> is. Each operation, action and function also has `shape`: `inputs` and
> `output` reduced to standard types and their constraints (`Text {
> max_length: 20, min_length: 5 }`, `{ note: Text?, outward: Text }`,
> `Enum { england, wales }`, with `…` where a type comes round to itself),
> `failures` reduced to their kinds, `effects` (`calls`, `changes`), and a
> `digest` of those for an exact match. A recipe has none: it isn't part of
> the compiled package.
>
> What `check` prints, for a provider package with a release behind it:
>
> ```text
> $ jadpo package check
> Facts
>   kind      provider
>   hosts     https://api.acme-pay.example
>             https://sandbox.acme-pay.example
>   changes   customers.create
>   erasure   not declared
>   storable  CustomerId
>   failures  none
>   contract  1 of 2 operations confirmed
>
> Personal data sent
>   to https://api.acme-pay.example
>   to https://sandbox.acme-pay.example
>   customers.create  CustomerRequest.notes  health, sensitive
>
> Changes since 1.0.0
>   + new host       provider          https://sandbox.acme-pay.example
>   + personal data  customers.create
>     CustomerRequest.notes to https://sandbox.acme-pay.example
>
> Publishing bar
> ...
> ```
>
> A row is left out only where the package's kind can't have it, so a
> library's block is its kind, what an app may store and what can fail, and
> `standard` shows only when there is one. `jadpo package show` prints the
> same block, and `--json` holds every fact whole, with each host's
> operations.
