Tasks
Tasks are the main coordination primitive. They live in thetasks table and support statuses (todo, in_progress, blocked, done, cancelled, missed), priorities, due dates, streams, recurrence, labels, comments, entity links, and deliverables.
Subtasks
Tasks support one-level nesting. A subtask is a regular task row with itsparent_id set to the parent task’s ID. There is no deeper nesting — subtasks cannot themselves have subtasks.
The main task list filters out subtasks by default (.is("parent_id", null)), so they only appear within their parent’s detail panel. In the detail panel, the subtask section shows:
- A progress summary (done/total) and a visual progress bar.
- An inline list of subtasks with status icons, assignee, and due date.
- A status toggle button to mark subtasks done or reopen them directly from the list.
- An inline input to create new subtasks without leaving the parent task.
stream_id at creation time. List and board views show a subtask progress chip on parent tasks so the operator can see completion at a glance.
The Task type includes subtask_count and subtask_done_count fields populated via a batch-fetch query for efficient rendering in list views.
Task relations
Thetask_relations table links tasks with typed dependencies:
When a blocking task transitions to
done or cancelled, the notify_blocker_resolved database trigger creates an inbox item for the unblocked task’s assignee so they know the dependency has cleared.
Overdue escalation
Aescalate_overdue_tasks pg_cron job runs every minute. It finds tasks past their due_date that are still in an active status and transitions them to missed. For each escalated task, the job creates an inbox item for the assigned agent (or a notification for a human assignee). The task form shows a missed-task banner with a reopen action.
The two queues
Commands
agent_commands — consumed by the runner. Handles lifecycle and operations: provision, update, remove, provider auth, gateway restart, and pairing approval.Inbox
agent_inbox_items — consumed by agents. Represents background work from task assignments, comment @-mentions, routines, and other workspace events.How it flows
How the dispatcher wakes agents
When a new inbox item arrives (via Realtime or the periodic reconciliation sweep), the dispatcher calls:--model and --thinking flags are included when the inbox item’s context contains per-task overrides. This lets individual tasks run with different reasoning depth without changing the agent’s default configuration.
For task_assignment events, the dispatcher enriches the message with unresolved blocker information from task_relations. If the assigned task has active blocked_by dependencies (blocking tasks not yet done or cancelled), a note is appended to the summary so the agent knows what dependencies exist before starting work.
This is fire-and-forget — the dispatcher doesn’t wait for the agent to respond. Before waking, the dispatcher checks:
- The agent is not paused or hibernating
- No active lease already exists for this agent (it’s not already processing)
- The agent’s budget hasn’t hit a hard cutoff
- There’s actually actionable work (
pendingor retryablefaileditems) - The cooldown period has elapsed since the last wake
RECONCILE_INTERVAL seconds, default 120) acts as a safety net and wakes any agents with pending work that were missed.
See Command lifecycle for the command state machine and Inbox dispatch for full dispatcher details.
