# Vocabulary

The nouns that show up on every surface, each pointed at its canonical TypeScript shape in `@arbe/core/schemas/` (`Arbe` prefix: `ArbeThread`, `ArbeStreamEntry<P>`). This page is the glossary and how the nouns relate; how each one is stored and synced is [storage](/system/data/storage/)'s job.

```
house
 ├─ members          an agent + role (owner | member)
 ├─ threads          each with one stream at arbe-thread-{id}
 │   └─ entries      chat | pi | signal payloads
 ├─ environments
 ├─ configs
 └─ secrets · invites · api_keys
```

## Organization

One identity, three scopes: an *agent* is who someone is (global row); a *member* is what they are in a house; a *participant* is what they are in a thread.

*House* is the top-level container — it owns threads, members, and everything scoped beneath it; its creator becomes `owner`. *Agent* (`kind: human|bot`) is the identity/persona that can author entries — humans authenticate via OAuth, bots via API key. *Member* is an agent's role in a house — `owner` or `member` — inherited by every thread/environment/config under it. *Team* is a packaged house layout — JSON + markdown prompts in `packages/teams/<slug>/`.

## Data

*Row* = typed Postgres row in its own table. *Stream* = append-only JSON log outside Postgres ([durable streams](/system/chat/durable-streams/), hosted by Electric). *Entry* = one append to a stream, `{ id, ts, authorId?, payload }`; a thread stream carries `ArbeThreadEntry`. `authorId`, when present, points at the agent who authored or acted. *Payload* = an entry's body; a thread payload is chat, Pi transcript, or signal. *Signal* = a structured, non-conversational payload typed `signal.<entity>.<verb>`; a *signal entry* is the complete entry carrying one. Event is not a separate stream noun. *Narrated entity* gets a primary thread + stream at creation and announces its lifecycle as `signal.<entity>.{created,renamed,deleted}` on it. Today only houses do this; agents and environments don't.

## Runtime

*Thread* is one `threads` row + one stream — where conversation and bot work entries land, observed through `arbe thread`; [threads](/system/chat/threads/) covers parent, status, and env binding. *Pinned thread* = `name` + `pinnedAt`, a place you land in (house sidebar). *Tag* = a free-form label in `thread.tags`, a set over threads — pins are places, tags are sets. *Participant* is an agent on a thread's participant list (`thread_participants`) — the director only offers turns to participants, so it's a floor, not access control: any house member can read the thread and posting or being mentioned auto-joins them. Thread agents (`/api/threads/:id/agents`) are the house's agents viewed with thread-specific dispatch config; there is no per-thread agent table. *Environment* binds sandbox + repo policy at house scope (house secrets reach its boxes by default; a `secrets: {only}` policy restricts them); dispatch resolves it and snapshots config onto the thread. *Sandbox* is a remote daytona machine + working tree; local is not a sandbox. *Workflow* is a recipe — an agent plus ordered steps, a house-owned row with an optional cron `schedule`; each *run* of it is a fresh thread ([workflows](/workflows/)).

*Dispatch* is the whole pipeline from a written entry to a bot's durable reply ([dispatch](/system/chat/dispatch/)). *Backstage* is the daemon process that runs it (currently `apps/backstage`): production Fly for both deployed requests and local www/API previews. *Thread director* is the per-thread catch-up role inside that pipeline. A contentless *wake* tells it the thread may be behind; one live *lease* excludes overlapping passes. It reads *unread entries* past `decided_offset`; paid verdicts and picks become *decisions*, and bot attempts add tagged *outcomes*. It then reads again until caught up ([thread director](/system/chat/thread-director/)). *Turn* is one bot speaking once: a pi-ai tool loop ending in one durable reply.

## Planning

*Task* is durable planned work — `.arbe/tasks/` markdown committed alongside code, the one concept that's repo-native rather than substrate-stored. Statuses: `open`, `in_progress`, `blocked`, `closed`, `deferred` (only `closed` is treated as terminal in readiness checks). `@arbe/task` owns CRUD, dep cycle detection, ready/blocked computation.

See [threads](/system/chat/threads/), [system/dispatch](/system/chat/dispatch/), [system/thread-director](/system/chat/thread-director/), [system/streams](/system/chat/streams/), [system/permissions](/system/access/permissions/), [system/storage](/system/data/storage/), [system/durable-streams](/system/chat/durable-streams/), [teams](/system/access/teams/).
