> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yourhq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tasks, inbox, and commands

> The queues that coordinate the UI, gateways, and agents.

HQ uses Supabase tables as durable queues. Everything the UI tells a gateway to do — and everything agents do in the background — flows through these queues.

## Tasks

Tasks are the main coordination primitive. They live in the `tasks` 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 its `parent_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.

Subtasks inherit the parent task's `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

The `task_relations` table links tasks with typed dependencies:

| Relation type | Meaning                                             | Inverse      |
| ------------- | --------------------------------------------------- | ------------ |
| `blocked_by`  | This task cannot proceed until the target completes | `blocks`     |
| `blocks`      | This task blocks the target from proceeding         | `blocked_by` |
| `relates_to`  | Informational link, no blocking semantics           | `relates_to` |
| `parent_of`   | This task is a parent of the target                 | `child_of`   |
| `child_of`    | This task is a child (sub-task) of the target       | `parent_of`  |

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

A `escalate_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

<CardGroup cols={2}>
  <Card title="Commands" icon="terminal">
    `agent_commands` — consumed by the **runner**. Handles lifecycle and operations: provision, update, remove, provider auth, gateway restart, and pairing approval.
  </Card>

  <Card title="Inbox" icon="inbox">
    `agent_inbox_items` — consumed by **agents**. Represents background work from task assignments, comment @-mentions, routines, and other workspace events.
  </Card>
</CardGroup>

## How it flows

```text theme={null}
UI writes rows  →  Daemons lease rows  →  Agents / gateway processes execute  →  Results written back to Supabase
```

<Tip>
  Commands and inbox items are never deleted — they persist as durable history. You can review them from Settings → System.
</Tip>

Both queues use atomic leasing so parallel daemons on different gateways never steal each other's work.

## How the dispatcher wakes agents

When a new inbox item arrives (via Realtime or the periodic reconciliation sweep), the dispatcher calls:

```bash theme={null}
openclaw agent --agent <workspace>/<agent-slug> [--model <model-id>] [--thinking <level>] --message "[inbox] <reason> ..."
```

The `--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 (`pending` or retryable `failed` items)
* The cooldown period has elapsed since the last wake

Inbox items are **not** leased by the dispatcher — the agent's background session leases them directly when it starts processing. The dispatcher only signals that work is available.

If the Realtime connection drops, the dispatcher's reconciliation sweep (every `RECONCILE_INTERVAL` seconds, default 120) acts as a safety net and wakes any agents with pending work that were missed.

See [Command lifecycle](/reference/command-lifecycle) for the command state machine and [Inbox dispatch](/reference/inbox-dispatch) for full dispatcher details.
