diff --git a/docs/automation/cron-vs-heartbeat.md b/docs/automation/cron-vs-heartbeat.md
index 7c11813906f..34228d1b74f 100644
--- a/docs/automation/cron-vs-heartbeat.md
+++ b/docs/automation/cron-vs-heartbeat.md
@@ -236,7 +236,7 @@ Both heartbeat and cron can interact with the main session, but differently:
| Context | Full | Full | None (isolated) / Cumulative (custom) |
| Model | Main session model | Main session model | Can override |
| Output | Delivered if not `HEARTBEAT_OK` | Heartbeat prompt + event | Announce summary (default) |
-| Tasks UI | No task run | No task run | Visible in `openclaw tasks` |
+| [Tasks](/automation/tasks) | No task record | No task record | Tracked in `openclaw tasks` |
### When to use main session cron
diff --git a/docs/automation/tasks.md b/docs/automation/tasks.md
index 2ea2fd09395..7135033e1a3 100644
--- a/docs/automation/tasks.md
+++ b/docs/automation/tasks.md
@@ -9,26 +9,44 @@ title: "Background Tasks"
# Background Tasks
-Background tasks track work that runs **outside your main conversation session**: ACP runs, subagent spawns, isolated cron job executions, and CLI-initiated operations.
+> **Cron vs Heartbeat vs Tasks?** See [Cron vs Heartbeat](/automation/cron-vs-heartbeat) for choosing the right scheduling mechanism. This page covers **tracking** background work, not scheduling it.
+
+Background tasks track work that runs **outside your main conversation session**:
+ACP runs, subagent spawns, isolated cron job executions, and CLI-initiated operations.
+
+Tasks do **not** replace sessions, cron jobs, or heartbeats — they are the **activity ledger** that records what detached work happened, when, and whether it succeeded.
-Not every agent run creates a task. Heartbeat turns and main-session cron reminders stay in main-session history. Only **detached** work (isolated cron, ACP, subagents, CLI operations) appears in the task ledger.
+Not every agent run creates a task. Heartbeat turns and main-session cron reminders stay in main-session history. Only **detached** work appears in the task ledger.
+## TL;DR
+
+- Tasks are **records**, not schedulers — cron and heartbeat decide _when_ work runs, tasks track _what happened_.
+- Only detached work creates tasks: ACP, subagents, isolated cron, CLI operations.
+- Each task moves through `queued → running → terminal` (succeeded, failed, timed_out, cancelled, or lost).
+- Completion notifications are delivered directly to a channel or queued for the next heartbeat.
+- `openclaw tasks list` shows all tasks; `openclaw tasks audit` surfaces issues.
+- Terminal records are kept for 7 days, then automatically pruned.
+
## Quick start
```bash
# List all tasks (newest first)
openclaw tasks list
-# Show details for a specific task
-openclaw tasks show
+# Filter by runtime or status
+openclaw tasks list --runtime acp
+openclaw tasks list --status running
-# Cancel a running task
-openclaw tasks cancel
+# Show details for a specific task (by ID, run ID, or session key)
+openclaw tasks show
-# Change notification policy
-openclaw tasks notify state_changes
+# Cancel a running task (kills the child session)
+openclaw tasks cancel
+
+# Change notification policy for a task
+openclaw tasks notify state_changes
# Run a health audit
openclaw tasks audit
@@ -36,179 +54,180 @@ openclaw tasks audit
## What creates a task
-| Source | Runtime | When a task is created |
-| ---------------------- | ---------- | -------------------------------------------------------------------------- |
-| ACP background runs | `acp` | Spawning a child ACP session |
-| Subagent orchestration | `subagent` | Spawning a subagent via `sessions_spawn` |
-| Isolated cron jobs | `cron` | Each execution of a `sessionTarget: "isolated"` or custom-session cron job |
-| CLI operations | `cli` | Background CLI commands that run through the gateway |
+| Source | Runtime type | When a task record is created |
+| ---------------------- | ------------ | -------------------------------------------------------------------------- |
+| ACP background runs | `acp` | Spawning a child ACP session |
+| Subagent orchestration | `subagent` | Spawning a subagent via `sessions_spawn` |
+| Isolated cron jobs | `cron` | Each execution of an isolated or custom-session cron job |
+| CLI operations | `cli` | Background CLI commands that run through the gateway |
-**Not tracked as tasks:**
+**What does not create tasks:**
-- Heartbeat turns (main-session; see [Heartbeat](/gateway/heartbeat))
-- Main-session cron reminders (`sessionTarget: "main"`; see [Cron Jobs](/automation/cron-jobs))
+- Heartbeat turns — main-session; see [Heartbeat](/gateway/heartbeat)
+- Main-session cron (`sessionTarget: "main"`) — see [Cron Jobs](/automation/cron-jobs)
- Normal interactive chat turns
+- Direct `/command` responses
## Task lifecycle
-```
-queued ──→ running ──→ succeeded
- ├──→ failed
- ├──→ timed_out
- └──→ cancelled
-
- (any active state) ──→ lost
+```mermaid
+stateDiagram-v2
+ [*] --> queued
+ queued --> running : agent starts
+ running --> succeeded : completes ok
+ running --> failed : error
+ running --> timed_out : timeout exceeded
+ running --> cancelled : operator cancels
+ queued --> lost : session gone > 5 min
+ running --> lost : session gone > 5 min
```
-| Status | Meaning |
-| ----------- | -------------------------------------------------------------------- |
-| `queued` | Created, waiting to start |
-| `running` | Actively executing |
-| `succeeded` | Completed successfully |
-| `failed` | Completed with an error |
-| `timed_out` | Exceeded the configured timeout |
-| `cancelled` | Cancelled by the operator (`openclaw tasks cancel`) |
-| `lost` | Backing session disappeared (detected after a 5-minute grace period) |
+| Status | What it means |
+| ----------- | ---------------------------------------------------------------------------- |
+| `queued` | Created, waiting for the agent to start |
+| `running` | Agent turn is actively executing |
+| `succeeded` | Completed successfully |
+| `failed` | Completed with an error |
+| `timed_out` | Exceeded the configured timeout |
+| `cancelled` | Stopped by the operator via `openclaw tasks cancel` |
+| `lost` | Backing child session disappeared (detected after a 5-minute grace period) |
-Tasks automatically transition from `running` to their terminal state when the associated agent run ends.
+Transitions happen automatically — when the associated agent run ends, the task status updates to match.
## Delivery and notifications
-When a task finishes, OpenClaw can notify you through two mechanisms:
+When a task reaches a terminal state, OpenClaw notifies you. There are two delivery paths:
-### Direct delivery
+**Direct delivery** — if the task has a channel target (the `requesterOrigin`), the completion message goes straight to that channel (Telegram, Discord, Slack, etc.).
-If the task has a `requesterOrigin` (channel target), the completion message is delivered directly to that channel (Telegram, Discord, Slack, etc.).
+**Session-queued delivery** — if direct delivery fails or no origin is set, the update is queued as a system event in the requester's session and surfaces on the next heartbeat.
-### Session-queued delivery
-
-If direct delivery fails or no origin is set, the update is queued as a system event in the requester session and delivered on the next heartbeat.
+
+Task completion triggers an immediate heartbeat wake so you see the result quickly — you do not have to wait for the next scheduled heartbeat tick.
+
### Notification policies
-Control how much you hear about a task:
+Control how much you hear about each task:
-| Policy | Behavior |
-| --------------------- | ---------------------------------------------------- |
-| `done_only` (default) | Notify only when the task reaches a terminal state |
-| `state_changes` | Notify on every state transition and progress update |
-| `silent` | No notifications at all |
+| Policy | What is delivered |
+| --------------------- | ----------------------------------------------------------------------- |
+| `done_only` (default) | Only terminal state (succeeded, failed, etc.) — **this is the default** |
+| `state_changes` | Every state transition and progress update |
+| `silent` | Nothing at all |
-Change the policy for a running task:
+Change the policy while a task is running:
```bash
-openclaw tasks notify state_changes
+openclaw tasks notify state_changes
```
-## Inspecting tasks
+## CLI reference
-### List all tasks
+### `tasks list`
```bash
-openclaw tasks list
+openclaw tasks list [--runtime ] [--status ] [--json]
```
-Output columns: Task ID, Kind (runtime), Status, Delivery status, Run ID, Child Session, Summary.
+Output columns: Task ID, Kind, Status, Delivery, Run ID, Child Session, Summary.
-Filter by runtime or status:
-
-```bash
-openclaw tasks list --runtime acp
-openclaw tasks list --status running
-openclaw tasks list --json
-```
-
-### Show task details
+### `tasks show`
```bash
openclaw tasks show
```
-The lookup token can be a task ID, run ID, or session key. Shows full task record including timing, delivery state, and terminal summary.
+The lookup token accepts a task ID, run ID, or session key. Shows the full record including timing, delivery state, error, and terminal summary.
-### Cancel a task
+### `tasks cancel`
```bash
openclaw tasks cancel
```
-For ACP and subagent tasks, this kills the child session. The task status transitions to `cancelled`.
+For ACP and subagent tasks, this kills the child session. Status transitions to `cancelled` and a delivery notification is sent.
-## Task audit
-
-The audit surfaces operational issues with background tasks:
+### `tasks notify`
```bash
-openclaw tasks audit
-openclaw tasks audit --json
+openclaw tasks notify
```
-| Finding | Severity | Condition |
-| ------------------------- | -------- | ------------------------------------------------- |
-| `stale_queued` | warn | Queued for more than 10 minutes |
-| `stale_running` | error | Running for more than 30 minutes |
-| `lost` | error | Status is `lost` (backing session gone) |
-| `delivery_failed` | warn | Delivery failed and notify policy is not `silent` |
-| `missing_cleanup` | warn | Terminal but no cleanup timestamp set |
-| `inconsistent_timestamps` | warn | Timeline violations (ended before started, etc.) |
+### `tasks audit`
-Task audit findings also appear in `openclaw status` output when issues are detected.
+```bash
+openclaw tasks audit [--json]
+```
-## Task pressure (status integration)
+Surfaces operational issues. Findings also appear in `openclaw status` when issues are detected.
-The task system reports an "at a glance" summary in `openclaw status`:
+| Finding | Severity | Trigger |
+| ------------------------- | -------- | ------------------------------------------------------------- |
+| `stale_queued` | warn | Queued for more than 10 minutes |
+| `stale_running` | error | Running for more than 30 minutes |
+| `lost` | error | Backing session is gone |
+| `delivery_failed` | warn | Delivery failed and notify policy is not `silent` |
+| `missing_cleanup` | warn | Terminal task with no cleanup timestamp |
+| `inconsistent_timestamps` | warn | Timeline violation (for example ended before started) |
+
+## Status integration (task pressure)
+
+`openclaw status` includes an at-a-glance task summary:
```
Tasks: 3 queued · 2 running · 1 issues
```
-This includes:
+The summary reports:
-- **active**: count of `queued` + `running` tasks
-- **failures**: count of `failed` + `timed_out` + `lost` tasks
-- **byRuntime**: breakdown by `acp`, `subagent`, `cron`, `cli`
+- **active** — count of `queued` + `running`
+- **failures** — count of `failed` + `timed_out` + `lost`
+- **byRuntime** — breakdown by `acp`, `subagent`, `cron`, `cli`
## Storage and maintenance
-### Where tasks are stored
+### Where tasks live
-Task records persist in SQLite at `$OPENCLAW_STATE_DIR/tasks/runs.sqlite`. The registry loads into memory at gateway start and syncs writes to SQLite for durability across restarts.
+Task records persist in SQLite at:
-### Automatic cleanup
+```
+$OPENCLAW_STATE_DIR/tasks/runs.sqlite
+```
-A maintenance sweeper runs every 60 seconds:
+The registry loads into memory at gateway start and syncs writes to SQLite for durability across restarts.
-1. **Reconciliation**: checks if active tasks' backing sessions still exist. If a session is gone for more than 5 minutes, the task is marked `lost`.
-2. **Cleanup stamping**: terminal tasks get a `cleanupAfter` timestamp set to 7 days after completion.
-3. **Pruning**: records past their `cleanupAfter` are deleted.
+### Automatic maintenance
-**Retention**: terminal task records are kept for **7 days** for historical inspection, then automatically pruned.
+A sweeper runs every **60 seconds** and handles three things:
+
+1. **Reconciliation** — checks if active tasks' backing sessions still exist. If a child session has been gone for more than 5 minutes, the task is marked `lost`.
+2. **Cleanup stamping** — sets a `cleanupAfter` timestamp on terminal tasks (endedAt + 7 days).
+3. **Pruning** — deletes records past their `cleanupAfter` date.
+
+**Retention**: terminal task records are kept for **7 days**, then automatically pruned. No configuration needed.
## How tasks relate to other systems
### Tasks and cron
-- A cron job **definition** lives in `~/.openclaw/cron/jobs.json`.
-- Each **execution** of an isolated cron job creates a task record.
-- Main-session cron jobs (`sessionTarget: "main"`) do **not** create task records.
-- See [Cron Jobs](/automation/cron-jobs) for scheduling and [Cron vs Heartbeat](/automation/cron-vs-heartbeat) for choosing the right mechanism.
+A cron job **definition** lives in `~/.openclaw/cron/jobs.json`. Each **execution** of an isolated cron job creates a task record. Main-session cron jobs do not.
+
+See [Cron Jobs](/automation/cron-jobs).
### Tasks and heartbeat
-- Heartbeat runs are main-session turns — they do **not** create task records.
-- When a detached task completes, it can enqueue a system event and trigger an immediate heartbeat wake so you see the result quickly.
-- See [Heartbeat](/gateway/heartbeat) for configuration.
+Heartbeat runs are main-session turns — they do not create task records. When a task completes, it can trigger a heartbeat wake so you see the result promptly.
+
+See [Heartbeat](/gateway/heartbeat).
### Tasks and sessions
-- A task may have an associated `childSessionKey` (the session where work happens).
-- The `requesterSessionKey` identifies who initiated the task (the parent session).
-- Sessions are conversation context; tasks are activity tracking records.
+A task may reference a `childSessionKey` (where work runs) and a `requesterSessionKey` (who started it). Sessions are conversation context; tasks are activity tracking on top of that.
### Tasks and agent runs
-- A task's `runId` links to the agent run executing the work.
-- Agent lifecycle events (start, end, error) automatically update task status.
+A task's `runId` links to the agent run doing the work. Agent lifecycle events (start, end, error) automatically update the task status — you do not need to manage the lifecycle manually.
## Related