# Declaring an event

An event records that something happened, so that other code can react
to it later without the action that caused it waiting. You declare it as
a type whose base is `Event`, named in the past tense, one per file in
the domain's `events/` folder.

`domains/planning/events/todo_completed.jadpo`:

```jadpo
// domains/planning/events/todo_completed.jadpo
/// A todo was marked complete.
public type TodoCompleted = Event {
    todo_id: Todo.id
    completed_at: Instant
}
```

`TodoCompleted` says a todo was completed, which todo and when. Mark an
event `public` when another domain subscribes to it.

## What an event holds

An event is written as a failure is ([Declaring a failure](declaring-a-failure.md)):
`type X = Event { ... }`, as `type X = Failure { ... }`. Its fields
follow the ordinary type rules.

Carry ids and the facts of the moment, not whole records. A subscriber
that needs more reads the current state.

## One type per event

Each event is its own type. There are no event families with variants,
such as `TodoEvent.completed`, so subscribing to an event and matching on
it never depend on a list that grows.

## An event nobody uses

An event nothing subscribes to is reported like any declaration nothing
uses.

## The event record

An event's shape is recorded, and a change to it is shown as a diff, as
an API's shape is ([The public API record](the-public-api-record.md)).
This matters because events waiting in the outbox when a new build ships
are read with the new shape. So every event is recorded, not only
`public` ones.

Each domain that declares an event keeps one record beside its events,
`domains/<domain>/events/events.jadpo_record` (written by
`jadpo records update`; never edit it by hand). It is a view in the
record format (`record events 1`), whose header says it is generated
from "the events of domain `<domain>`". There is no command of its own:
`jadpo records update` writes it, and `jadpo records` lists it.

The record holds an `event <Name>` entry for each event, marked `public`
when another domain may subscribe to it. Under each entry are its fields
as its payload carries them, in the API record's wire form
(`words: Text { max_length: 200 }`). Then comes an `object`, `enum`,
`input` or `output` entry for each type a field names, written as the API
record writes them. Events, fields and types are sorted by born name.
Descriptions are left out, as in the API record.

The record is checked as the API record is
([What is committed, and why](what-is-committed-and-why.md)).
A missing record, one whose events changed (`record.out_of_date`, naming
each entry added, changed or removed), and the record of a domain left
with no events, are all put right by `jadpo records update`. A hand edit
Jadpo couldn't have written is `record.edited`. While an event file has
errors, the record isn't compared.

Classifying a change as breaking, and accepting one, aren't built yet.
They come with the API record's [acceptances](acceptances.md).
