I ran the automation layer that kept an agent fleet alive.
Keepalives, cross-machine watchdogs, a git-backed memory sync, and recurring briefing jobs — the scheduled plumbing under a three-machine fleet. Then I audited it hard enough to prove a local LLM couldn’t hold a production cron, and routed that work back to a model that could.
An autonomous fleet doesn't stay healthy on its own.
Browser sessions expire. Gateways crash. Memory drifts. Status has to be reported on a cadence.
All of it repetitive, all of it time-sensitive — the kind of maintenance that quietly rots a system if nothing owns it.
I needed a scheduled layer that did this maintenance automatically across three Mac minis — and a way to prove each job was actually running, not silently failing behind a green checkmark.
And when cost pressure pushed me to move jobs onto a cheaper local model, I refused to move first and verify later. I wanted a reliability standard a job had to clear before I’d trust it in production.
Two schedulers, one reliability bar.
I ran OpenClaw crons for machine-level automation and Paperclip routines for recurring agent work, with macOS LaunchAgents handling OS-level sync and tunnels.
Every job had a defined schedule, an owner, and an output target — a Slack alert, a vault commit, or a notifications post. Roughly two dozen scheduled things ran across the fleet.
The discipline was the real work. When I migrated crons to a local model to cut cost, I ran a side-by-side audit instead of trusting the checkmarks: deterministic jobs could go local, judgment-heavy and Slack-facing jobs stayed hosted until individually proven, and the browser keepalive got a deterministic wrapper so its success never depended on an LLM improvising.
I didn't ship automation to save money. I proved a local model couldn't hold a production cron — with a root cause — and made the routing call accordingly.
— Reliability doctrine · prove, don't assumeThe schedule topology.
Three schedulers feed a three-machine fleet. Deterministic jobs route to a local LLM; judgment and Slack-facing jobs stay on a hosted model; the keepalive runs through a deterministic wrapper. Outputs land in Slack, GitHub, and the notifications channel.
Three schedulers — OpenClaw crons, Paperclip routines, and macOS LaunchAgents — feed a three-machine fleet. From there, jobs split by reliability class: deterministic work flows to a local Ollama-hosted model, judgment and Slack-facing work stays on a hosted model, and the browser keepalive runs through a deterministic wrapper with no LLM in the loop. Outputs land in Slack, a git-backed GitHub vault, and the notifications channel.
Schedulers
Runtime
Models
Job Types
Sync / Tunnel
I/O
Roughly two dozen scheduled things.
Inventory snapshot & audit · verified from the Slack record.
Prove-don’t-assume over green checkmarks: the standout was the local-LLM reliability audit — intermittent cron failures root-caused to the 4b model’s inconsistent tool execution, plus Ollama’s single-lane concurrency (OLLAMA_NUM_PARALLEL:1) and an outdated version. A 9b model timed out (>120s) on both cron and direct tests. The routing call followed the evidence, not the cost pressure.
What it produced — and what it honestly is.
A scheduled maintenance layer that kept an autonomous fleet running unattended, plus a documented reliability standard that survived a real cost-driven migration. This is iterated infrastructure, not a frozen product.
An unattended fleet that stayed alive.
- Sessions held via keepalives; gateways watched by a cross-machine watchdog.
- Memory vault synced to GitHub on a cadence via vault-sync.push on both machines.
- Briefing / debrief / triage / health-sweep jobs firing on schedule.
- Local-model cron failures root-caused to model determinism + Ollama single-lane concurrency + an outdated version.
- Deterministic jobs routed local; judgment / Slack-facing jobs held hosted until proven.
- Residual client crons removed and verified — zero matching entries left in jobs.json.
Continuously migrated and re-verified.
- The layer was re-worked across the period — Qwen migration, Ollama version bumps, watchdog cleanup, client-cron removal.
- Parts stayed on the hosted model precisely because the audit said the local one wasn’t ready.
- The exact total is honestly “roughly two dozen” scheduled things, not a confirmed fixed count.
The highlight here is judgment, not flawless uptime: a reliability audit that produced a root cause and drove a routing decision — the opposite of shipping unreliable automation to save money.
Two calls, at a glance.
How a cheap migration got audited.
Cost pressure pushed the OpenClaw crons onto a local qwen3.5-instruct:4b model. The migration verified “green” — all five crons routed local.
Instead of accepting the checkmarks, I ran the same jobs against local and hosted models in parallel — and caught the local model failing production crons intermittently.
Failures traced to the 4b model’s inconsistent tool execution, Ollama’s single-lane concurrency (OLLAMA_NUM_PARALLEL:1), and an outdated Ollama version. A 9b model timed out over 120s.
Deterministic jobs stayed local; judgment and Slack-facing jobs held on the hosted model until individually proven. The keepalive got a deterministic wrapper so it never depended on the LLM.
Removed residual client crons and verified zero matching entries remained in jobs.json on either machine.
I set the schedule and the reliability bar.
I owned the automation layer end to end — I directed the cron inventory, set the migration policy, and ran the audit that caught the local model failing.
I made the routing decision, required the deterministic keepalive wrapper so a maintenance job didn’t depend on an LLM’s mood, and directed the client-separation cleanup with verification. The agents executed the jobs; I designed the schedule, set the standard, and made the call.