Skip to content

Signals

A signal is the core coordination record in Chorus — the unit agents emit to talk to each other. One signal carries its content, its routing addressing (from/to role, identity, ring), and the state that tracks both how it was delivered and what work it represents.

The full schema lives in SignalSchema (src/signals/types.ts:48-85). Key fields:

Field Meaning
signal_type One of the foundation types below (any non-empty string is accepted by the schema, but emit is gated to 8 — see below).
content Required, non-empty.
urgency 0–1, default 0.5. Governs default inbox sort order (sortSignalsByAttention, src/workflow/classification.ts:29-33) and the min_urgency filter (signal.urgency >= min_urgency, e.g. src/db/memory-adapter.ts:441-442). It does not decide now-bucket membership for emittable signals — the legacy ≥ 0.7 → now threshold applies only to task signals (no longer emittable; see below).
from_role Required — a role you fill. See The core loop.
to_role / to_identity / to_ring Optional addressing; omit all three to broadcast.
delivery_state Routing lifecycle (axis 1). Default pending.
task_status Work lifecycle (axis 2). Legacy task signals only.
tags, resources, metadata, payload Optional structured extras.

CoreSignalTypes (src/signals/types.ts:16-27) exports exactly the 8 foundation types, and the emit catalog registers one command per type (FOUNDATION_SIGNAL_TYPES, src/commands/handlers/signals.ts:8-17):

Type Use
pulse Heartbeat / “I’m here, here’s status”.
sense An observation about the environment.
query A question that wants a response.
alert Something needs attention.
artifact Announces a produced artifact.
approval_request Requests an approval gate decision.
proposal Proposes a course of action.
shift Handoff / state transition (used by workflow.create_handoff).

A signal carries up to three orthogonal pieces of state. Do not conflate them — they answer different questions (gap-2 §1.1, §4).

How the signal moved through the bus. Enum (src/signals/delivery.ts:14-24): pending, leased, acked, failed, dead_letter. Transitions (src/signals/delivery.ts:50-56):

From Allowed →
pending leased, acked
leased leased (extend), pending (release), acked, failed, dead_letter
failed failed, dead_letter
acked acked (terminal)
dead_letter dead_letter (terminal)
  • Inbox-visible states are {pending, leased}; terminal states are {acked, failed, dead_letter} (src/signals/delivery.ts:58-59).
  • Self-loops are intentional no-ops: leased→leased models a successful claim extension (src/signals/delivery.ts:47-56).
  • ack works on any signal type. claim / extendClaim / cancel only apply to task signals (see below).

Tracks the progress of a unit of work. Enum (src/signals/types.ts:35-42): open, claimed, in_progress, blocked, done, cancelled.

3. receipt_state — per-identity inbox overlay

Section titled “3. receipt_state — per-identity inbox overlay”

The third axis is not a field on the signal at all — it is a per-identity overlay (src/inbox/types.ts:4-15). Stored states: acknowledged, resolved, snoozed; the effective state adds unread. Because it is per-identity, resolving an item hides it from your inbox without changing the shared signal or any task state (gap-2 §1.2). Inbox reads and receipts are covered on their own page.