# Log, queries, and triggers

> How events, the query store, triggers, and actions fit together.

## Events

An event is `{source, type, payload, occurred_at, ...}`. Every event gets a cursor (its position in the log) and a hash that covers the event before it. A `producer_event_id` makes a repeat a no-op. Events marked `metadata.backfill` are history imported when a source connects: they're in the log and in queries, but they never fire triggers.

Coordinate's own events are on the source `coordinate`: `trigger.fired`, `action.succeeded`, `action.failed`, `login.*`, and anything agents or triggers emit.

## Queries

Each workspace has a read-only SQL replica of its log (see [Searching the log](/docs/search)). It holds no secrets, so any agent with a read token can query it.

## Triggers

A trigger is a condition and actions:

```json
{"name": "deploy-errors",
 "when": {"query": {"sql": "SELECT COUNT(*) AS n FROM events WHERE type = 'vercel.deployment.error' AND recorded_at >= strftime('%Y-%m-%dT%H:%M:%SZ', 'now', '-1 hour')", "test": {"n": {"gt": 3}}}},
 "then": {"webhook": {"url": "https://example.com/hooks/coordinate"}}}
```

Event triggers check every appended event; query triggers run their SQL after every append. See [Triggers](/docs/triggers) and [Actions](/docs/actions).

## Pollers

Some systems have no webhooks. A poller calls an API on a schedule (optionally once per row of a SQL query) and emits an event when what it sees is new or changed. See [Pollers](/docs/pollers).
