Summary
OpenClaw cron currently supports systemEvent and agentTurn, but it has no provider-free execution style for deterministic host-local chores. This forces users to wrap tiny local jobs in isolated LLM runs. In practice that means provider latency/failures can cause false cron timeouts for work that is otherwise fast and deterministic. I’m proposing a minimal localCommand/hostCommand cron payload so these jobs can stay inside OpenClaw instead of escaping to launchd/systemd.
Problem to solve
Some recurring background tasks are fundamentally deterministic host work, not model work: local health checks, outbox flushers, tiny Apple Mail scans, compact sync/cleanup helpers, and similar maintenance jobs. Today cron can only run those through agentTurn, so the end-to-end run inherits model/provider failure modes and agent-turn timeout behavior even when the real host-side script only needs a few seconds. When that happens, users get false negatives (timeout/no delivery), and the practical workaround is to move scheduling out of OpenClaw entirely into launchd/systemd. That hurts portability, because a workflow that conceptually belongs in OpenClaw is now split across two schedulers.
Proposed solution
Add a new isolated cron payload for deterministic host-local execution, for example payload.kind = "localCommand". A minimal first version could execute an argv list directly on the gateway host without going through an LLM turn. Suggested properties: argv: string[] (required), optional cwd, optional timeoutSeconds, and maybe a very small output contract such as summary from trimmed stdout / last stdout line. I would keep the first version intentionally narrow: local host only, no remote node execution, no shell-by-default, and delivery.mode = none by default unless the operator explicitly opts into delivery. This would let OpenClaw remain the single scheduler for deterministic background jobs while keeping model-backed jobs on agentTurn.
Alternatives considered
- Increase
timeoutSeconds for the existing agentTurn jobs. This reduces the symptom rate but does not remove provider coupling; a 3-second local script can still fail because the surrounding LLM turn stalls or the provider errors. 2. Keep using launchd/systemd for deterministic chores. This works operationally, but it pushes users out of OpenClaw’s built-in scheduler and makes cross-machine migration harder because one logical workflow now lives partly in OpenClaw and partly in the host scheduler. 3. Recast everything as systemEvent + heartbeat. That still routes through model execution and does not solve provider-free deterministic execution.
Impact
This would make OpenClaw cron a more complete portability layer. Users could keep deterministic maintenance tasks inside OpenClaw instead of having to create OS-specific scheduler glue. It would also reduce false timeout/no-delivery incidents for jobs that do not actually need a model at all. From an architecture perspective, it creates a clean separation: agentTurn for model work, systemEvent for main-session wakeups, and localCommand for trusted host-local deterministic chores.
Evidence/examples
Concrete example from a recent local workflow: a daily Apple Mail heartbeat and a tiny retry/outbox helper both behaved as deterministic host-side scripts when run directly (python3 ...retry_guard.py finished in ~3.2s; python3 ...heartbeat_prepare.py finished in ~10.3s). But the same workflows timed out as OpenClaw cron agentTurn jobs at exactly their outer cron limits (90s and 420s), because the gateway currently has to wrap them in an isolated agent run. That is a strong signal that the missing primitive is not "more timeout" but "a provider-free cron execution style for deterministic local jobs".
Additional information
I realize this touches the command/tool execution surface, so I’d keep the scope narrow and security story explicit: argv execution only (no implicit shell), local gateway host only, normal cron timeout enforcement, and no default delivery. Also, since this repo currently does not appear to have GitHub Discussions enabled, I’m filing this as a feature request issue as the closest Discussion/RFC fallback suggested by CONTRIBUTING. If this direction sounds reasonable, I’m happy to turn it into a focused PR rather than a giant architecture dump.
Summary
OpenClaw cron currently supports
systemEventandagentTurn, but it has no provider-free execution style for deterministic host-local chores. This forces users to wrap tiny local jobs in isolated LLM runs. In practice that means provider latency/failures can cause false cron timeouts for work that is otherwise fast and deterministic. I’m proposing a minimallocalCommand/hostCommandcron payload so these jobs can stay inside OpenClaw instead of escaping to launchd/systemd.Problem to solve
Some recurring background tasks are fundamentally deterministic host work, not model work: local health checks, outbox flushers, tiny Apple Mail scans, compact sync/cleanup helpers, and similar maintenance jobs. Today cron can only run those through
agentTurn, so the end-to-end run inherits model/provider failure modes and agent-turn timeout behavior even when the real host-side script only needs a few seconds. When that happens, users get false negatives (timeout/no delivery), and the practical workaround is to move scheduling out of OpenClaw entirely into launchd/systemd. That hurts portability, because a workflow that conceptually belongs in OpenClaw is now split across two schedulers.Proposed solution
Add a new isolated cron payload for deterministic host-local execution, for example
payload.kind = "localCommand". A minimal first version could execute an argv list directly on the gateway host without going through an LLM turn. Suggested properties:argv: string[](required), optionalcwd, optionaltimeoutSeconds, and maybe a very small output contract such as summary from trimmed stdout / last stdout line. I would keep the first version intentionally narrow: local host only, no remote node execution, no shell-by-default, anddelivery.mode = noneby default unless the operator explicitly opts into delivery. This would let OpenClaw remain the single scheduler for deterministic background jobs while keeping model-backed jobs onagentTurn.Alternatives considered
timeoutSecondsfor the existingagentTurnjobs. This reduces the symptom rate but does not remove provider coupling; a 3-second local script can still fail because the surrounding LLM turn stalls or the provider errors. 2. Keep using launchd/systemd for deterministic chores. This works operationally, but it pushes users out of OpenClaw’s built-in scheduler and makes cross-machine migration harder because one logical workflow now lives partly in OpenClaw and partly in the host scheduler. 3. Recast everything assystemEvent+ heartbeat. That still routes through model execution and does not solve provider-free deterministic execution.Impact
This would make OpenClaw cron a more complete portability layer. Users could keep deterministic maintenance tasks inside OpenClaw instead of having to create OS-specific scheduler glue. It would also reduce false timeout/no-delivery incidents for jobs that do not actually need a model at all. From an architecture perspective, it creates a clean separation:
agentTurnfor model work,systemEventfor main-session wakeups, andlocalCommandfor trusted host-local deterministic chores.Evidence/examples
Concrete example from a recent local workflow: a daily Apple Mail heartbeat and a tiny retry/outbox helper both behaved as deterministic host-side scripts when run directly (
python3 ...retry_guard.pyfinished in ~3.2s;python3 ...heartbeat_prepare.pyfinished in ~10.3s). But the same workflows timed out as OpenClaw cronagentTurnjobs at exactly their outer cron limits (90s and 420s), because the gateway currently has to wrap them in an isolated agent run. That is a strong signal that the missing primitive is not "more timeout" but "a provider-free cron execution style for deterministic local jobs".Additional information
I realize this touches the command/tool execution surface, so I’d keep the scope narrow and security story explicit: argv execution only (no implicit shell), local gateway host only, normal cron timeout enforcement, and no default delivery. Also, since this repo currently does not appear to have GitHub Discussions enabled, I’m filing this as a feature request issue as the closest Discussion/RFC fallback suggested by CONTRIBUTING. If this direction sounds reasonable, I’m happy to turn it into a focused PR rather than a giant architecture dump.