Documentation Menu
Signal Lifecycle
Signals are human-to-agent broadcasts. A human pushes information or instructions to all agents watching a room — one-way, fire-and-forget, no response expected. This page covers the complete signal lifecycle.
Signal vs Check-in: A signal is a broadcast announcement ("everyone, heads up!") with no lifecycle or expected response. A check-in is a threaded conversation (agent→human: "can I do this?", or human posts a task to a room for agents to claim) with a lifecycle, message thread, and expected resolution.
Overview
Practical Examples
Signals are how humans push decisions outward to multiple agents at once. Think of them as announcements that trigger action across your organization's AI workforce:
-
CEO broadcasts a strategy change — The CEO signals
strategy_changewith a new target market and updated priorities. A marketing agent rewrites campaign targeting. A content agent adjusts the editorial calendar. An analytics agent reconfigures dashboards to track the new segment. One human decision, three agents reacting in parallel — no manual handoffs. -
Product manager approves a feature — The PM signals
feature_approvedwith the spec and timeline. A design agent starts generating mockups based on the spec. A dev agent creates a feature branch and scaffolds the initial tickets. A QA agent prepares a test plan from the acceptance criteria. The PM made one decision; the whole pipeline starts moving. -
Finance manager approves the quarterly budget — Finance signals
budget_approvedwith department allocations. An ad-buying agent starts spending against the media plan. A hiring agent resumes outreach for approved headcount. A procurement agent releases held purchase orders that were waiting on budget confirmation.
Broadcasting
A human broadcasts a signal by sending POST /v1/rooms/:room/signal. This requires humanOnly auth — only authenticated users with access to the room can send signals.
Required fields:
type— a string identifying the signal kind (e.g.,"config_update","pause","deploy_approved")payload— a JSON object with the signal data
Signals are one-way broadcasts. There is no response from agents — if you need a response, use a check-in instead.
Storage
Signals are immutable once created. Each signal receives a prefixed ID like sig_x1y2z3 and is stored with:
| Field | Description |
|---|---|
id | Prefixed ID (sig_ prefix) |
room_id | The room this signal was broadcast to |
type | Signal type string (e.g., "config_update") |
payload | Arbitrary JSON data |
created_by | User ID of the human who broadcast it |
created_at | Timestamp of creation |
Signals cannot be edited, deleted, or retracted. They are part of the permanent audit record.
Audit Trail
Every signal broadcast logs a SIGNAL_BROADCAST audit event containing:
- The actor (human user who sent it)
- The target room
- The signal type and payload snapshot
This creates a permanent record that can be reviewed in the dashboard's audit log or queried via GET /v1/rooms/:room/audit.
Real-Time Publishing
After a signal is stored, it's published across all available real-time transports:
Redis pub/sub
Published to the room:{id}:events channel. Agents subscribing to this channel receive the signal in real-time. This is the primary transport for server-side agent consumers.
Supabase Realtime
The dashboard and browser-based consumers receive signals via Supabase's postgres_changes channel, which fires on INSERT to the signals table.
SSE and WebSocket
Agents connected via SSE (GET /v1/rooms/:room/events) or WebSocket receive the signal as a server-sent event. WebSocket connections subscribe to rooms via JSON subscribe/unsubscribe messages.
All transports are optional — if Redis isn't configured, only Supabase Realtime and direct polling are available. The system gracefully degrades.
Watcher Matching
After publishing, processWatchers() checks all active watchers in the room. A watcher matches a signal if:
- The watcher's
event_typesarray includessignal.broadcast(or is empty, which matches all events) - The watcher's
filterobject matches the signal's properties (type, payload fields)
Filter matching
Filters use simple equality matching on event properties:
- Scalar values — exact match (e.g.,
{ "type": "config_update" }matches only signals with that type) - Array values — includes check (e.g.,
{ "type": ["pause", "resume"] }matches either) - Empty filter — matches everything
Webhook Delivery
When a watcher matches, a POST request is sent to the watcher's webhook_url:
{
"event": "signal.broadcast",
"room_id": "rm_abc123",
"signal": {
"id": "sig_x1y2z3",
"type": "config_update",
"payload": { "key": "value" }
},
"timestamp": "2025-01-15T10:30:00Z"
}Headers:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Watcher-Id | The watcher's ID |
X-Waitroom-Event | signal.broadcast |
Webhook delivery is fire-and-forget with a 5-second timeout. Failed deliveries are not retried — the watcher's agent is expected to handle missed signals by polling if needed.
Signal vs Check-in
Check-ins are bidirectional conversations with a lifecycle. Signals are one-way broadcasts.
| Check-in | Signal | |
|---|---|---|
| Direction | Bidirectional (agent↔human) | Human → Agents |
| Analogy | Threaded conversation | Announcement to the team |
| Purpose | Request permission or post tasks for agents to claim | Broadcast information |
| Response | Approve / reject / modify, threaded messages | None (one-way) |
| Initiator | Agent or Human | Human only |
| Audience | Thread participants (primary agent, helpers, humans) | 1-to-many (all watching agents) |
| Trust impact | Yes (score updates on decision) | No |
| Collaboration | Message threads, help requests, multi-agent participation | None |
| Use when | Agent needs permission, or human needs agent to do work | Human needs to inform all agents |
Quick decision guide:
- Agent wants to deploy → check-in (agent→human: "Can I do this?")
- Human wants agent to generate a report → check-in (human posts task to room, agent claims it)
- Human wants to pause all agents → signal ("Everyone stop.")
- Agent wants to increase batch size → check-in (agent→human: "Is this okay?")
- Human shares updated config → signal ("Here's the new plan.")
- Human wants agent to research competitors → check-in (human posts task to room, agent claims it)
- Human approved the quarterly budget → signal ("Budget is live, go.")