# The event schema

The schema on this page runs in the first body today. It is copied from the running code, not from a design document, and every type below appears in real events in the first body's log.

Every meaningful fact about the business is one row in an append-only log. A lead captured, a board generated, a message approved, a payment made: each is one typed event, and every table the business uses is a view computed from the log. If a fact matters and is not an event, that is treated as a bug in the code that should have emitted it. Events are constructed through a single function that validates the payload against the schema for its type before the event is written, so a malformed event cannot enter the log.

## 01 · The envelope

Every event is wrapped in the same envelope, and the envelope is venture-agnostic: the next body imports it unchanged and contributes its own payload types.

| field | type | meaning |
|---|---|---|
| venture | string | The slug of the body that emitted the event. The first body emits `video`. |
| ts | ISO 8601 datetime | When the event happened. |
| type | string | The event type. The shape of the payload depends on it, and every type is listed below. |
| actor | client \| agent \| human \| system | Who caused the event. |
| jobId | string · optional | Present when the event is attached to a job. |
| payload | object | The typed payload, validated against the schema for the event's type. |

## 02 · The event types

Event types are named `arm.noun.verb-past`, where the arm is the part of the business that produced the event, so `site.lead.captured` reads as: the site captured a lead. The groups below are listed in funnel order, from a visitor's first contact down to operations. A payload field ending in `?` is optional.

### Site and funnel events

| type | payload | meaning |
|---|---|---|
| site.lead.captured | email · productUrl · audience · goal · lengthTier? · source · name? · briefChars? · uploadCount? | A visitor submitted the intake form. `source` records how they arrived: organic, outbound, oss-video, referral, or direct. |
| site.lead.confirmed | email | The lead clicked the confirmation link that was mailed to them. |
| board.generated | candidateCount · generationCostUsd · wallClockMin | The body produced a board of candidate videos, and the event records the size, the cost, and the wall-clock time of the batch. |
| board.viewed | token · watchedCandidates | A lead opened their board. The token identifies which recipient's board it was. |
| candidate.watched | candidateId · watchPct | A lead watched one candidate, and the event records how much of it they watched. |
| candidate.picked | candidateId · notes? | A lead picked a candidate from the board. |
| candidate.reaction | candidateId · reaction (up \| down) · reason? | A lead gave explicit feedback on one candidate, with an optional stated reason. |
| board.feedback | verdict · note? | Feedback on the board as a whole, including from leads who never picked. The verdict is one of picked, none-fit, wrong-style, wrong-message, price, timing, or other. |
| order.paid | tier (launch \| pro \| flagship) · amountUsd | A customer paid for an order at one of three tiers. |
| video.first_cut.ready | renderCostUsd · humanMinutes | The first cut of a paid order is ready, with the render cost and the human minutes it took. |
| revision.requested | round · class (included \| change-order) | The customer asked for a revision. The class records whether the round is included in the tier or is a change order. |
| video.delivered | tier · totalCostUsd · totalHumanMinutes | The finished video was delivered, with the total cost and the total human minutes across the job. |

### Eyes events

The eyes arm is the part of the body that publishes content and watches how it performs. Published and stats are separate types because publishing happens once and readings recur.

| type | payload | meaning |
|---|---|---|
| oss.video.published | library · platform (x \| youtube) · url | The body published a video about an open-source library. |
| oss.video.stats | library · views · likes · maintainerEngaged | A later reading of that video's performance, including whether the library's maintainer engaged. |
| content.article.published | slug · cluster | The body published an article, filed under a topic cluster. |
| content.search.stats | slug · impressions · clicks | A later reading of an article's search performance. |

### Outbound events

The outbound arm is the part of the body that finds prospects and writes to them. Every outbound artifact carries a unique signed token, so a view can be attributed to the exact recipient who viewed it. The five types after teaser.generated decompose one message's funnel, so a silence can be located at the exact stage where it happened.

| type | payload | meaning |
|---|---|---|
| outbound.teaser.generated | company · token · costUsd | The body produced a personalized teaser for a prospect, and the event records what it cost. |
| outbound.send.queued | company · contact | A draft message was staged in the approval queue. |
| outbound.send.approved | company | The owner approved the exact text of a staged message. The actor of this event is always human. |
| outbound.sent | company · token | The approved message was sent. |
| outbound.viewed | company · token · watchPct | The recipient viewed the teaser, and the token attributes the view to them. |
| outbound.replied | company · sentiment (positive \| neutral \| negative) | The recipient replied, with the sentiment recorded. |

### Ops events

Ops events are about the body itself rather than the funnel. They make the machine's own behavior part of the record.

| type | payload | meaning |
|---|---|---|
| job.state.changed | from · to · reason? | A job moved between states. |
| note.recorded | file · summary | The body wrote a note to itself and logged that it did. |
| alert.raised | severity (info \| warn \| page) · message | Something needs attention, at one of three severities. |
