# The surface

A package's surface is everything it offers an app, in one file you can
read. To see a package's surface, run `jadpo package show <name>`. The
compiler works it out from the package's code and writes it to
`surface.jadpo_record`, beside `package.jadpo`. It lists:

- the package's description, licence and version;
- every public type with its fields and constraints, and every failure
  with its kind and code;
- every public library's functions, with their signatures, failures and
  descriptions;
- every recipe;
- for a provider: its operations (wire and output types both); each
  public action with the operations it calls on each path, which of them
  change something and which failures can follow an effect; its hosts or
  container, credential scheme, settings and polls; and the capabilities
  it provides.

## Read as a diff

The surface is plain text in the format of
[the public API record](the-public-api-record.md), not JSON. Like
every `.jadpo_record` file, it starts with a line saying what wrote it
([Records and manifest](records-and-manifest.md)). Installed packages
are committed, so every upgrade's pull request carries the surface diff,
and a reviewer reads "removed `bookings.cancel`, new failure
`PostcodeNotServed`" in plain text.

Every entry points at its file, such as `types/booking.jadpo`, so an agent
reads the surface first and opens only what it needs. A file is named
after what it declares, so the pointer never goes stale.

## Generated, never written by hand

`jadpo package check` writes the surface. `add`, `update` and the registry
refuse a surface that doesn't match the code. The surface of an app's own
integration is generated into `build/`.

The surface is kept out of `package.jadpo`, which a person writes. The
descriptions stay in the source as `///` comments, where the author edits
them.

## `jadpo package show`

`jadpo package show <name>` prints the description, licence, version,
kind and public surface. `jadpo package show <name> <declaration>` prints
one operation, type or function with its description and file. `--guide`
prints `GUIDE.md`, and `--json` gives tools and agents the same. It works
for installed packages and the app's own integrations alike.

## It decides the version

Publishing compares the new surface with the last release's, and refuses
a breaking change without a new major version. A breaking change is a
public name removed, a field retyped or a new failure. The upgrade plan
diffs the same two files.

> The surface is `surface.jadpo_record` (`record
> surface 1`): the package's entry (description, file, kind, version,
> licence, Jadpo version, guide), a provider's `provider` entry (protocol,
> hosts or container, credential scheme, idempotency key), each public
> resource's operations, each public library's functions, each public
> type and failure, and each recipe, every entry with its file. `jadpo
> package show` prints it, one declaration in full or the guide, for
> installed packages and the app's own integrations alike, and `jadpo
> check` writes each own integration's surface to
> `build/providers/<name>/<version>/surface.jadpo_record`. The
> `postcodes` library package's, as `jadpo package check` writes it:
>
> ```text
> // Generated by Jadpo from this package's code; update it with `jadpo package check`, never by hand.
> record surface 1
>
> package Postcodes.v2
>     /// UK postcodes: reading them as people write them.
>     file package.jadpo
>     kind library
>     version 2.0.0
>     licence mit
>     jadpo 1.0
>
> function uk.tidy
>     /// Reads a postcode in upper case.
>     file libraries/uk.jadpo
>     signature (entered: EnteredPostcode) -> UkPostcode
>     fails InvalidPostcode
>
> type EnteredPostcode = Text
>     /// A postcode as someone typed it.
>     file types/entered_postcode.jadpo
>     max_length: 20
>
> type UkPostcode = Text
>     /// A UK postcode in standard form, such as "SW1A 1AA".
>     file types/uk_postcode.jadpo
>     max_length: 8
>     min_length: 5
>
> failure InvalidPostcode
>     /// The text isn't a UK postcode.
>     file failures/invalid_postcode.jadpo
>     kind invalid_value
>     code invalid_postcode
> ```
>
> and `jadpo package show` in an app that installed it:
>
> ```text
> $ jadpo package show postcodes
> UK postcodes: reading them as people write them.
>   package   Postcodes.v2
>   kind      library
>   version   2.1.0
>   source    path ../postcodes
>   licence   mit
>   jadpo     1.0
>   folder    packages/postcodes/v2
>
> Functions
>   uk.tidy          (entered: EnteredPostcode) fails InvalidPostcode -> UkPost…
>
> Types
>   EnteredPostcode  Text { max_length: 20 }
>   UkPostcode       Text { min_length: 5, max_length: 8 }
>
> Failures
>   InvalidPostcode  invalid_value
>
> ✓ Postcodes.v2  1 function · 2 types · 1 failure
>
> → jadpo package show postcodes uk.tidy  shows one in full, with its file
> ```
>
> `add` and `update` verify the surface at install (under "Installing
> safely"); the choices are in "How the surface and the publishing bar
> work" below.
