{"skill":{"slug":"openclaw-msg-delivery-guide","displayName":"OpenClaw Msg Delivery Guide","summary":"Ensure later replies actually reach the user in OpenClaw. Use when the user asks for reminders, scheduled checks, follow-up notifications, completion updates...","description":"---\nname: openclaw-msg-delivery-guide\ndescription: Ensure later replies actually reach the user in OpenClaw. Use when the user asks for reminders, scheduled checks, follow-up notifications, completion updates, recurring monitoring, or any task where execution and user-visible delivery happen in different steps. Default to cron for scheduled or notification-critical tasks, use subagent completion for background-result handoff, use direct reply when finishing now, and avoid heartbeat unless the user explicitly wants a soft, low-precision follow-up.\nmetadata:\n  openclaw:\n    requires:\n      bins: [\"openclaw\"]\n      config: [\"~/.openclaw/cron/jobs.json\"]\n      note: \"This skill may inspect and modify local OpenClaw cron configuration, run openclaw cron commands, manually trigger jobs for verification, and send test notifications while validating delivery behavior against the local scheduler store.\"\n---\n\n# OpenClaw Message Delivery Guide\n\n## Core problem\n\nPrevent this failure mode:\n\n- work starts\n- the agent promises a later reply\n- no real delivery path is bound\n- the user never receives the result\n\nTreat **execution** and **delivery** as separate things.\nStarting work is not the same as binding a later user-visible message.\n\n## Core rules\n\n### Rule 1: never promise a later reply without a delivery path\n\nBefore saying things like:\n\n- \"reply in 5 minutes\"\n- \"watch this task and tell me if there is progress\"\n- \"send it later\"\n- \"check this every hour and notify me\"\n\nbe able to answer all 3:\n\n1. What event counts as completion or reportable progress?\n2. Who sends the later message?\n3. Which mechanism actually delivers it?\n\nIf any answer is unclear, resolve the delivery path first: choose the mechanism, bind the target, and only then promise the follow-up.\n\n### Rule 2: choose mechanism by delivery need\n\nDefault map:\n\n- **Direct reply**: result will be sent now\n- **Cron**: exact time or repeated schedule; notification matters\n- **Subagent**: background task that should report back when finished\n- **Heartbeat**: soft, low-precision check-in only; avoid by default and use only when the user explicitly accepts a soft follow-up\n- **`message` send**: visible result already sent by tool\n\n### Rule 3: scheduled + notify => cron\n\nFor anything like:\n\n- \"reply in 5 minutes\"\n- \"remind me in 20 minutes\"\n- \"check this every hour and notify me if it changes\"\n- \"send a report every day at 9\"\n\nprefer:\n\n- **one-shot cron** with `--at` for a single future reply\n- **recurring cron** with `--cron` for repeated checks\n- **`--session isolated`** when the run should execute independently and deliver its own result\n- explicit delivery fields derived from current session metadata\n\nDo not default to cron main-session runs unless the user explicitly wants main-session / heartbeat-style behavior.\n\n### Rule 4: background exec does not imply notification\n\nStarting `exec` / `process` / a long-running task only means work has started.\nIt does **not** mean the user will later receive an update.\nIf the user expects a later message, bind a real follow-up path.\n\n## Key examples\n\n### 1. \"reply in 5 minutes\"\n\nUse **one-shot cron**, not heartbeat.\n\n```bash\nopenclaw cron add \\\n  --name \"Reply in 5 minutes\" \\\n  --at \"5m\" \\\n  --session isolated \\\n  --message \"Reply to the user with the requested follow-up. If nothing meaningful changed, say that clearly.\" \\\n  --announce \\\n  --channel <channel> \\\n  --to <destination>\n```\n\n### 2. \"run this in the background and tell me when it is done\"\n\nUse **subagent** when the main need is background execution plus completion report.\n\nRequired behavior:\n\n- start the task\n- tell the user the task has started\n- when the subagent completion announce is handed back to the requester session, deliver that result to the user immediately\n\n### 3. \"check this site every hour and notify me if it changes\"\n\nUse **recurring cron isolated + explicit delivery**.\n\n```bash\nopenclaw cron add \\\n  --name \"Hourly site check\" \\\n  --cron \"0 * * * *\" \\\n  --session isolated \\\n  --message \"Check the target site. Notify only when there is a real change; otherwise stay silent.\" \\\n  --announce \\\n  --channel <channel> \\\n  --to <destination>\n```\n\n### 4. visible result already sent via `message`\n\nIf the user-visible result has already been delivered via `message(action=send)`, do not send a duplicate normal reply; return only:\n\n`NO_REPLY`\n\n## Bad cases\n\n- Promise a later reply without naming the delivery path\n- Use heartbeat for exact reminders or required notifications\n- Start background `exec` and assume completion will surface automatically\n- Create cron jobs without explicit delivery when the user expects a visible notification\n- Bind only a final completion path when the user actually asked for progress updates\n\n## Test and verification\n\n### Cron\n\nAfter add/edit:\n\n1. confirm the job exists in `openclaw cron list`\n2. verify stored fields in `~/.openclaw/cron/jobs.json`\n3. run the job once manually\n4. confirm the notification reached the intended chat\n\nFor recurring jobs, do not rely on the schedule before doing this manual trigger once.\n\nVerify at least:\n\n- schedule kind (`at` vs `cron`)\n- session target\n- payload message\n- delivery mode\n- delivery channel\n- delivery target\n\nDo not require model verification here; use the default model unless the user explicitly asked for a model override.\n\nWhen changing a cron job, do not trust CLI output alone; verify the stored job.\n\n### Background-task follow-up\n\nVerify:\n\n1. the task actually started\n2. the user knows whether the current turn already delivered a result or not\n3. the completion path is explicit\n\n## Extra guidance\n\n### Progress mode\n\nFor long-running work, classify the expected update style before promising follow-up:\n\n- **result-only**\n- **stage updates**\n- **fixed-interval updates**\n\n### Silent-if-no-change\n\nFor recurring checks, prefer:\n\n- notify on real change\n- otherwise stay silent\n\n### Current-chat delivery\n\nWhen the result should come back to the same chat, derive delivery target from current session metadata instead of hardcoding user-specific identifiers.\n","tags":{"latest":"1.0.6"},"stats":{"comments":0,"downloads":256,"installsAllTime":10,"installsCurrent":0,"stars":1,"versions":7},"createdAt":1773149266906,"updatedAt":1778491807445},"latestVersion":{"version":"1.0.6","createdAt":1773384366580,"changelog":"Declare cron store path with ClawHub config metadata so security scans can match the documented runtime behavior.","license":"MIT-0"},"metadata":{"setup":[{"key":"~/.openclaw/cron/jobs.json","required":true}],"os":null,"systems":null},"owner":{"handle":"sonicrang","userId":"s17edey53cakw6ysv87v5w8g2d83g5br","displayName":"wurang","image":"https://avatars.githubusercontent.com/u/5936153?v=4"},"moderation":null}