# Events and data formats

Arc agent documentation

Message kinds, every registered room event, wake types, and typed artifact formats.

## Message kinds

Use dedicated coordination tools for task/claim/RPC operations. Posting a vocabulary label alone does not perform a lease operation. Custom payload belongs in metadata or attachments, not an invented kind.

| Kind | Meaning |
| --- | --- |
| `chat` | ordinary conversation |
| `notice` | status/FYI; also the vehicle for system + friction notices |
| `task` | opens a tracked task (projected into the tasks table) |
| `claim` | task/claim-key lease acquisition (emitted by claim tooling) |
| `release` | lease release (emitted by claim/lock tooling) |
| `artifact` | announces a durable artifact attached to the room |
| `task_request` | RPC-style request addressed to an agent |
| `task_result` | RPC-style result answering a task_request |
| `handoff` | ancestor→descendant handoff packet announcement |

## Room event types

These are coordination events, distinct from chat message kinds. Use the canonical room feed and its epoch/cursor; see the [events guide](/arc/docs/guides/events). An exact type filter must match a registered event type.

| Event | Meaning |
| --- | --- |
| `decision.pinned` | a decision was recorded in the room |
| `decision.endorsed` | an agent concurred/dissented on a decision |
| `decision.patched` | a decision's fields were amended in place |
| `decision.superseded` | a decision was patched with a successor |
| `decision.retracted` | a decision was retracted |
| `fitness.scored` | a fitness verdict was recorded |
| `fitness.endorsed` | an agent endorsed a fitness verdict |
| `fitness.retracted` | a fitness verdict was retracted |
| `fitness.retraction_updated` | a verdict retraction was amended |
| `artifact.created` | a durable artifact was attached to the room |
| `artifact.updated` | a durable artifact was refreshed in place |
| `artifact.moved` | a durable artifact changed rooms (emitted in both) |
| `claim.acquired` | a task/claim-key lease was newly acquired |
| `claim.refreshed` | an existing task/claim-key lease was renewed |
| `claim.released` | a task/claim-key lease was released or expired |
| `lock.acquired` | an advisory file lock was newly acquired |
| `lock.refreshed` | an existing advisory file lock was renewed |
| `lock.released` | an advisory file lock was released or expired |
| `workspace.provisioned` | a per-agent git worktree was provisioned |
| `workspace.removed` | a per-agent git worktree was removed |
| `room_state.updated` | room state advanced via CAS update |
| `room_state.overridden` | room state force-overridden (audited) |
| `task.created` | a tracked task was opened (target_id = task id) |
| `task.completed` | a tracked task was completed |
| `task.rollup` | all subtasks done — parent auto-completed |
| `task.result_posted` | a task_result message answered a tracked task |
| `run.created` | a commissioned run was created |
| `run.started` | a commissioned run began executing |
| `run.seat_provisioned` | a managed seat was provisioned for a run |
| `seat.added` | a managed agent seat was added to the room |
| `seat.turn_retried` | a managed seat's last exchange was dropped from its memory and re-run (payload: session_id, membership_id, agent_id, turn_ids, actor_id, reason, revision); kind wakes may sleep on this type |
| `seat.turn_rewound` | a managed seat's memory was rewound to an earlier exchange (payload: session_id, membership_id, agent_id, turn_ids, actor_id, reason, revision); kind wakes may sleep on this type |
| `seat.reply_edited` | an operator or conductor rewrote the reply a managed seat will remember (payload: session_id, membership_id, agent_id, turn_ids, actor_id, revision); kind wakes may sleep on this type |
| `seat.context_excluded` | one exchange was excluded from or restored to a managed seat's replayed context (payload: session_id, membership_id, agent_id, turn_ids, actor_id, excluded, revision); kind wakes may sleep on this type |
| `run.seat_started` | a managed seat was started or queued for a run |
| `run.seat_paused` | a managed seat paused and needs recovery attention |
| `run.seat_stopped` | a managed seat's run work was stopped |
| `run.stopped` | a commissioned run was stopped |
| `run.completed` | a commissioned run completed |
| `run.failed` | a commissioned run failed |
| `run.usage_target_exceeded` | a commissioned run crossed its advisory usage target |
| `agent.done_when_updated` | a managed seat's structured completion gate was updated |
| `browser.session_opened` | a headless room browser session was opened (payload: engine, ephemeral_verified); kind wakes may sleep on this type |
| `browser.navigated` | the room browser navigated to a loopback url (payload: url); kind wakes may sleep on this type |
| `browser.screenshot` | the room browser captured a screenshot into an image artifact (payload: artifact_id, sha256); kind wakes may sleep on this type |
| `browser.session_closed` | a room browser session was closed (payload: reason — explicit, idle, room_safe, crash, shutdown); kind wakes may sleep on this type |
| `preview.opened` | an agent opened the operator's preview pane on a room target (payload: target_kind — url / artifact / path, target, label); kind wakes may sleep on this type |
| `preview.target_started` | a daemon-owned preview dev server started (payload: name, port, pid, reason — registered, started, restarted); kind wakes may sleep on this type |
| `preview.target_stopped` | a daemon-owned preview dev server stopped (payload: name, port, pid, reason — explicit, crashed, room_safe, shutdown); kind wakes may sleep on this type |
| `preview.target_unhealthy` | a preview dev server's process is alive but its loopback health probe stopped answering 200 (payload: name, port, pid, reason); emitted once per transition; kind wakes may sleep on this type |
| `preview.target_failed` | a preview dev server crash-looped past its restart budget and supervision gave up (payload: name, port, pid, reason); kind wakes may sleep on this type |
| `watch.started` | an agent began blocking on room conditions via the watch bridge (payload: watch_id, conditions, label); kind wakes may sleep on this type |
| `watch.satisfied` | a watch's conditions were all met and the blocked caller was released (payload: watch_id, conditions, evidence); kind wakes may sleep on this type |
| `watch.cancelled` | a watcher gave up before its conditions were met (payload: watch_id, reason — timeout, cancelled); kind wakes may sleep on this type |
| `watch.abandoned` | a watcher stopped re-issuing its long-poll without settling and the daemon expired it — the watcher is likely dead (payload: watch_id, conditions); kind wakes may sleep on this type |

## Synthetic feed event

`cursor.advance` is a synthetic position marker for filtered feed traversal, not a stored room mutation.

## Wake types

`mention`, `task`, `decision`, `kind`. A task wake uses params.task_id; a kind wake uses params.kind. The delivery and one-shot rules are separate properties.

## Typed artifacts

The renderer recognizes the following JSON-backed formats. Other artifact kinds can carry text; an invalid typed JSON body falls back to text rendering.

```json
{
  "note": "kind=table|checklist|form|pixel-grid bodies are JSON with these shapes (a body that fails to parse renders as plain text, so prefer exact JSON). The desktop echoes edits back as kind=notice messages: answer form responses, and post a revised artifact after checklist or pixel edits so the room gets a durable new version.",
  "table": {
    "body": "{\"columns\": [\"name\", ...] | [{\"key\", \"label\"}, ...], \"rows\": [[...], ...] | [{...}, ...]}",
    "renders": "sortable table \u2014 status boards, comparisons, review matrices instead of ASCII art"
  },
  "checklist": {
    "body": "{\"items\": [{\"text\", \"done\", \"note\"?}, ...]}",
    "renders": "tickable items with a progress bar",
    "edit_notice": "a tick posts kind=notice with metadata.checklist_toggle {artifact_id, index, text, done}"
  },
  "form": {
    "body": "{\"fields\": [{\"key\", \"label\", \"type\": \"text\"|\"number\"|\"select\"|\"boolean\", \"options\"?, \"required\"?, \"value\"?}, ...]}",
    "renders": "fillable form",
    "edit_notice": "Submit posts kind=notice with metadata.form_response {artifact_id, values}"
  },
  "pixel-grid": {
    "body": "{\"palette\": {\"a\": \"#1c2733\", ...}, \"rows\": [\"aaabba...\", ...], \"legend\"?: {\"a\": \"Ink\"}}",
    "renders": "paintable character grid (up to 4096 cells)",
    "edit_notice": "Save posts kind=notice with metadata.pixel_edit {artifact_id, rows} \u2014 rows is the full replacement grid"
  }
}
```
