docs: fix incorrect claim that main-session cron jobs don't create tasks

Source code verified: tryCreateCronTaskRun() in src/cron/service/timer.ts
is called unconditionally for ALL cron job executions (both main-session
and isolated). Main-session cron tasks use silent notify policy by default.

Fixed in:
- automation/tasks.md: update table, TL;DR, Note callout, cron section
- automation/cron-vs-heartbeat.md: fix distinction callout and comparison table
- automation/cron-jobs.md: fix intro and main-session section
This commit is contained in:
Vincent Koc 2026-03-30 17:31:29 +09:00
parent ad2c3f28bd
commit a804d234cd
3 changed files with 26 additions and 25 deletions

View File

@ -14,10 +14,10 @@ title: "Cron Jobs"
Cron is the Gateways built-in scheduler. It persists jobs, wakes the agent at
the right time, and can optionally deliver output back to a chat.
Cron does **not** mean every scheduled event becomes a background task:
All cron executions create [background task](/automation/tasks) records. The key difference is visibility:
- `sessionTarget: "main"` schedules a system event for the main session and heartbeat flow.
- `sessionTarget: "isolated"` or `sessionTarget: "session:..."` runs detached work that shows up in `openclaw tasks`.
- `sessionTarget: "main"` creates a task with `silent` notify policy — it schedules a system event for the main session and heartbeat flow but does not generate notifications.
- `sessionTarget: "isolated"` or `sessionTarget: "session:..."` creates a visible task that shows up in `openclaw tasks` with delivery notifications.
If you want _“run this every morning”_ or _“poke the agent in 20 minutes”_,
cron is the mechanism.
@ -160,7 +160,7 @@ They must use `payload.kind = "systemEvent"`.
This is the best fit when you want the normal heartbeat prompt + main-session context.
See [Heartbeat](/gateway/heartbeat).
Main-session cron jobs do **not** create [background task](/automation/tasks) records.
Main-session cron jobs create [background task](/automation/tasks) records with `silent` notify policy (no notifications by default). They appear in `openclaw tasks list` but do not generate delivery messages.
#### Isolated jobs (dedicated cron sessions)

View File

@ -14,10 +14,10 @@ Both heartbeats and cron jobs let you run tasks on a schedule. This guide helps
One important distinction:
- **Heartbeat** is a scheduled **main-session turn** — no task record created.
- **Cron (main)** is a scheduled **system event into the main session**no task record created.
- **Cron (isolated)** is a scheduled **background run** — tracked in `openclaw tasks`.
- **Cron (main)** is a scheduled **system event into the main session**creates a task record with `silent` notify policy.
- **Cron (isolated)** is a scheduled **background run**creates a task record tracked in `openclaw tasks`.
Only detached background runs (isolated cron, ACP, subagents) appear in the [task ledger](/automation/tasks). Heartbeat turns and main-session cron reminders stay in session history.
All cron job executions (main and isolated) create [task records](/automation/tasks). Heartbeat turns do not. Main-session cron tasks use `silent` notify policy by default so they do not generate notifications.
## Quick Decision Guide
@ -229,14 +229,14 @@ See [Lobster](/tools/lobster) for full usage and examples.
Both heartbeat and cron can interact with the main session, but differently:
| | Heartbeat | Cron (main) | Cron (isolated) |
| -------------------------- | ------------------------------- | ------------------------ | ----------------------------------------------- |
| Session | Main | Main (via system event) | `cron:<jobId>` or custom session |
| History | Shared | Shared | Fresh each run (isolated) / Persistent (custom) |
| 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](/automation/tasks) | No task record | No task record | Tracked in `openclaw tasks` |
| | Heartbeat | Cron (main) | Cron (isolated) |
| -------------------------- | ------------------------------- | ------------------------ | ------------------------------------------------- |
| Session | Main | Main (via system event) | `cron:<jobId>` or custom session |
| History | Shared | Shared | Fresh each run (isolated) / Persistent (custom) |
| 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](/automation/tasks) | No task record | Task record (silent) | Task record (visible in `openclaw tasks`) |
### When to use main session cron

View File

@ -17,13 +17,13 @@ ACP runs, subagent spawns, isolated cron job executions, and CLI-initiated opera
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.
<Note>
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.
Not every agent run creates a task. Heartbeat turns and normal interactive chat do not. All cron executions, ACP spawns, subagent spawns, and CLI agent commands do.
</Note>
## 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.
- ACP, subagents, all cron jobs, and CLI operations create tasks. Heartbeat turns do not.
- 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.
@ -54,17 +54,18 @@ openclaw tasks audit
## What creates a task
| 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 |
| Source | Runtime type | When a task record is created | Default notify policy |
| ---------------------- | ------------ | ------------------------------------------------------ | --------------------- |
| ACP background runs | `acp` | Spawning a child ACP session | `done_only` |
| Subagent orchestration | `subagent` | Spawning a subagent via `sessions_spawn` | `done_only` |
| Cron jobs (all types) | `cron` | Every cron execution (main-session and isolated) | `silent` |
| CLI operations | `cli` | `openclaw agent` commands that run through the gateway | `done_only` |
Main-session cron tasks use `silent` notify policy by default — they create records for tracking but do not generate notifications. Isolated cron tasks also default to `silent` but are more visible because they run in their own session.
**What does not create tasks:**
- 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
@ -211,7 +212,7 @@ A sweeper runs every **60 seconds** and handles three things:
### 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 do not.
A cron job **definition** lives in `~/.openclaw/cron/jobs.json`. **Every** cron execution creates a task record — both main-session and isolated. Main-session cron tasks default to `silent` notify policy so they track without generating notifications.
See [Cron Jobs](/automation/cron-jobs).