Show HN: Octomind Routines – scheduled agents on persistent cloud machines Octomind launched Routines, a feature enabling scheduled agents on persistent cloud machines, addressing common failures such as silent skips, cost overruns, and timezone issues. The system stores times with IANA timezones, recomputes next fire times after each run, and logs every non-run as a row to ensure auditability. There is a specific kind of disappointment that comes from scheduled agents, and it always arrives the same way. You set one up. It works when you test it. Three weeks later you notice it hasn't done anything in eleven days, and there's nowhere to look to find out why. We shipped Routines this week — a standing instruction with a trigger attached. Pick an agent, pick when, and it wakes a computer in the cloud, does the work, and tells you what came of it. Nothing of yours has to be switched on. That description fits about a dozen products. What follows is the part that doesn't. The four ways this goes wrong Before building anything we went looking for what people actually hit with scheduled agents. The complaints cluster hard. It didn't run and nobody said so. This is the top one, and it's a category error in the design rather than a bug: the config file says what should run and has no opinion about what is running. Claude Cowork's scheduler has an open issue https://github.com/anthropics/claude-code/issues/33586 where tasks skip on a timezone offset and simply don't appear. Nothing failed loudly. Nothing appeared at all. It ran, spent money, produced nothing. "Silent failure" is its own recurring complaint in agent communities — no crash, no signal, no value, just a charge. Telerik has a whole taxonomy https://www.telerik.com/blogs/when-status-ok-still-failure-taxonomy-silent-ai-agent-breakage-how-detect of the ways an agent returns status: ok having done nothing useful. Cost runs away. Context accumulation compounds on every scheduled run. An agent loop costs roughly 3.2× a chatbot turn at five steps and over 30× at fifty https://leanopstech.com/blog/agentic-ai-cost-runaway-token-budget-2026/ , and a polling schedule pays full price on every run where nothing happened. Time is the only trigger. If something breaks at 15:00 and your check runs at 23:00, you find out at 23:00. Every one of those became a constraint. Here's what came out. A routine is a sentence Scheduling is the single thing in this product a non-technical person is most likely to want, and a cron field is a literacy test. So the form is a sentence you complete, and the expression is generated underneath. Every weekday at eight. Every Monday at nine. Every day at two in the morning. If you already think in cron, there's a custom option that takes the raw expression and tells you back, in words, what it thinks you meant — because the failure mode of a cron field is not rejection, it's silently scheduling something else. Times are stored with an IANA timezone, never an offset, and the next fire is recomputed after each run rather than incremented . That is the whole reason daylight saving doesn't drift: a local time that doesn't exist in spring fires at the next real instant, and a local time that happens twice in autumn fires once, on the first. Both are pinned by tests with fixed clocks, because this is precisely where the competition breaks. Pick who does it, not just when A routine runs as one of the specialist agents, the same roster your tasks use. "Research this every Monday" and "sweep this repo every night" are not the same job and shouldn't get the same worker. If you don't want to choose, Assistant works out who you needed. Every non-run is a row This is the design decision the rest hangs off, and it's the one we'd defend hardest. A fire request that gets refused — because the routine was off, the account was out of budget, the machine was in cold storage, the previous run was still going — is not dropped . It becomes a run row with a status that says which. The queue is the audit trail of everything that wanted to happen, not just everything that succeeded. So the history reads in plain sentences. Done. Nothing to report. Didn't run — machine was in cold storage. Hit its cost cap. A status that renders as a blank cell is the silent-skip bug wearing our own colours, so every status we can write has a sentence, and the fallback still says something specific. Each row also carries what it cost and how long it took, and the header totals them: 7 runs · $0.63 · typically 3m 8s . Those are the two questions a standing instruction raises once it's been running a while, and the two you cannot answer from a list of dates. The list view compresses the same thing into a heartbeat — one tick per recent run, coloured by outcome. You can see at a glance which routines are healthy and which one has been failing without telling you. The last one there turned itself off: after five consecutive failures, a routine disables itself and tells you, because a broken routine must not bill forever. Not spending your money on nothing Three things, in order of how much they save. A fresh conversation each run, by default. Context accumulation is the dominant driver of scheduled-agent cost runaway — a continued thread pays for every previous run's context, forever. There's a checkbox to keep one long conversation when the thread genuinely is the value, and it's labelled honestly: keeps context between runs, costs more over time . An optional check command that costs zero tokens. A shell command runs on the machine before the agent does. Exit non-zero and the run ends as "nothing to do" without a single model call. git fetch && git log --oneline @..@{u} | grep . is a complete, honest change detector, and you can read it. We deliberately did not make this a natural-language condition: an LLM condition costs a model call to decide whether to make model calls. A per-run cost cap. Crossing it ends the run, keeps what was spent, and shows it — that's the "Hit its cost cap" row above. There's also a minimum interval per plan, which is the honest version of a rate limit: every run wakes a real computer, and that costs real compute whether or not the model does anything. State is a file, not a vendor black box Every routine gets ~/routines/