From a804d234cd95d40b05f86321d50a19b47d46c4a2 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 30 Mar 2026 17:31:29 +0900 Subject: [PATCH] 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 --- docs/automation/cron-jobs.md | 8 ++++---- docs/automation/cron-vs-heartbeat.md | 22 +++++++++++----------- docs/automation/tasks.md | 21 +++++++++++---------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/docs/automation/cron-jobs.md b/docs/automation/cron-jobs.md index 136f756d1d5..9c540b36bcf 100644 --- a/docs/automation/cron-jobs.md +++ b/docs/automation/cron-jobs.md @@ -14,10 +14,10 @@ title: "Cron Jobs" Cron is the Gateway’s 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) diff --git a/docs/automation/cron-vs-heartbeat.md b/docs/automation/cron-vs-heartbeat.md index cbb02a65c37..f96c68f6910 100644 --- a/docs/automation/cron-vs-heartbeat.md +++ b/docs/automation/cron-vs-heartbeat.md @@ -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:` 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:` 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 diff --git a/docs/automation/tasks.md b/docs/automation/tasks.md index f6341829e9e..a766febc3af 100644 --- a/docs/automation/tasks.md +++ b/docs/automation/tasks.md @@ -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. -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. ## 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).