Jobs are stored with a message payload and can execute in three stable user-facing modes:
### `deliver: false`
This is the default for the cron tool.
When the job fires, PicoClaw sends the saved message back through the agent loop as a new agent turn. Use this for scheduled work that may need reasoning, tools, or a generated reply.
### `deliver: true`
When the job fires, PicoClaw publishes the saved message directly to the target channel and recipient without agent processing.
The CLI `picoclaw cron add --deliver` flag uses this mode.
### `command`
When a cron-tool job includes `command`, PicoClaw runs that shell command through the `exec` tool and publishes the command output back to the channel.
For command jobs, `deliver` is forced to `false` when the job is created. The saved `message` becomes descriptive text only; the scheduled action is the shell command.
The current CLI `picoclaw cron add` command does not expose a `command` flag.
## Config and Security Gates
### `tools.cron`
`tools.cron.enabled` controls whether the agent-facing `cron` tool is registered. Default: `true`.
If you disable `tools.cron`, users can no longer create or manage jobs through the agent tool. The gateway still starts `CronService`, but it does not install the job execution callback. As a result, due jobs do not actually run; one-time jobs may be deleted and recurring jobs may be rescheduled without executing their payload. The CLI still uses the same job store.
`tools.exec.allow_remote` is still enforced by the exec tool, but cron command scheduling has its own channel gate when the job is created. In practice, reminder jobs can be scheduled from remote channels, while scheduled command jobs are limited to internal channels and configured remote channels.
This is not a hard disable switch. If you set `allow_command` to `false`, PicoClaw still allows a command job when the caller explicitly passes `command_confirm: true`.
Command jobs also require either an internal channel or a remote channel allowed by `tools.cron.command_allowed_remotes`. Non-command reminders do not have that restriction.
### `command_allowed_remotes`
`tools.cron.command_allowed_remotes` defaults to an empty list. With the default empty list, remote channels cannot schedule command jobs.
Entries can be either a channel name or a channel plus chat id:
-`telegram` allows command jobs from any Telegram chat.
-`telegram:1234567890` allows command jobs only from that exact Telegram chat id.
-`*` allows command jobs from every non-empty channel.
This setting only controls the remote-channel gate. It does not bypass `tools.cron.allow_command`, `command_confirm`, `tools.exec.enabled`, or the exec tool's command safety checks.