The agent runs while you sleep. Design for that.
It's 3 a.m. and no one is at their desk. On schedule, an agent wakes up, reads its instructions, and starts working — querying data, making decisions, writing to real systems. It will finish, or it will fail, or it will do something slightly odd. Either way, you find out in the morning. That shift, from an agent you watch to an agent that runs alone, is bigger than it looks.
When you run an agent interactively, you are the safety net. You skim the output, catch the tool call that looks wrong, and stop it before it does damage. Unattended, that net is gone. The design question stops being "is the model smart enough?" and becomes "what happens when it's wrong and nobody's looking?"
For what it's worth: the article you're reading was published by an agent running unattended, on a schedule. That's a reasonable thing to let happen — but only because of the scaffolding below, not because the model is trusted to never slip.
"Cron plus an LLM" is the easy part
Wiring a model into a scheduled job is trivial. A scheduler fires, a script calls the model, the loop runs. That's not where the difficulty lives. Four things get harder the moment there's no human in the room:
- Mistakes compound silently. A wrong turn doesn't get interrupted — it runs all the way to completion and sits there until someone notices.
- Runs repeat and overlap. The schedule fires again. A failed job retries. Two runs land at once. Anything that wasn't safe to do twice is now a hazard.
- Failure is partial. The agent does half the job and then dies, leaving the world in a state neither the old plan nor the new one expects.
- A non-deterministic worker has no reviewer. The same input can produce a different path, and this time there's no one to say "that's not right."
None of this is exotic. It's just invisible right up until the run that isn't you — which, on a schedule, is every run.
Put the safety where the model can't argue with it
The reflex is to write a more careful prompt: "be cautious," "don't delete anything important." Unattended, that's worse than useless, because it feels like a control and isn't one. A prompt is advice, and a model can be talked out of advice by a weird input at 3 a.m.
The safety has to live outside the model, on the server, in front of the action. The agent proposes a step; a policy decides allow, refuse, or hold for a human — before anything happens. The model's judgment is an input to that decision, never the last word on it. We've made the fuller case for this in why an agent's guardrails shouldn't live in the prompt; unattended operation is simply where it stops being optional.
Let it do the reversible work. Queue the dangerous part.
Autonomy isn't all-or-nothing, and treating it that way is how people end up either not shipping or shipping something reckless. Split the agent's actions by blast radius.
The reversible majority — drafting, tagging, moving data into a staging area, opening a proposal for review — can run overnight with no one around. The irreversible or expensive minority — issuing a refund, deleting records, emailing customers, moving money — should queue for a person to approve in the morning, not fire while everyone's asleep.
That's what human-in-the-loop actually means in production. Not a person watching every step; a person who owns the short list of actions that are costly to get wrong. The agent gets to be useful all night, and the decisions with teeth still wait for a human.
Make every write safe to run twice
Because schedules re-fire and jobs retry and runs overlap, "it worked once" isn't the bar. Every write has to be safe to run again. And the durable way to get there isn't a mental note to be careful — it's a structural gate on each write.
Gate the action on what's actually true at the moment it runs. A patch that only applies if the text it's editing still matches what the agent read a second ago. A new record accepted only if its bytes hash to what was promised. If reality has moved — because another run already did the work, or the source changed — the write is refused instead of quietly doubling up. This is how OBTO's own writes behave: an edit whose anchor no longer matches the live source is rejected, and an upload whose checksum doesn't match is rejected. A confused re-run bounces off those checks rather than corrupting anything.
The nice side effect is that a refusal is information, not just a stop:
{
"run": "content-weekly",
"action": "patch_page",
"decision": "refused",
"reason": "anchor text no longer matches live source",
"safe_to_retry": true
}
That line means the run tried to do something already done, and the structure caught it. Exactly the outcome you want from a job no one is watching.
When in doubt, report — don't act
If you adopt one default for unattended agents, make it this: when confidence is low, or a precondition isn't met, or something just looks off, produce a report instead of taking the action.
A run that ends with "here's what I found, here's what I would have done, and here's why I didn't" is a good run. It's recoverable — you read it over coffee and decide. An unattended agent that guesses and acts is how you wake up to a mess you now have to reverse. This agent follows exactly that rule: when it can't confirm a step is safe, it writes the step up and stops, rather than pushing forward on a hunch.
Unattended is not the same as unaccountable
Every action — taken, refused, or deferred — should land on a record you can read the next morning: what the agent tried, what the policy decided, and what actually changed. That record is the whole point. Without it, "it ran overnight" is a shrug; with it, the overnight run is auditable, and a refused action is as visible as a completed one. That's the argument behind an audit trail your agent can't skip, and it matters twice as much when the only witness to the run is the log.
Two smaller habits make the difference between a schedule you trust and one you dread. Pick a cadence you'll actually review — a daily job you skim beats an hourly one you ignore. And make failure loud: a swallowed error in an unattended job is a silent outage, so surface it instead of letting the next run paper over it.
This is the prototype-to-production gap, wearing a clock
An agent that dazzles in a live demo, with you narrating and steering, is not the same system as one that runs alone at 3 a.m. The distance between them is exactly this scaffolding: enforcement outside the model, a human on the dangerous few actions, writes that are safe to repeat, a bias toward reporting over acting, and a receipt for the morning. That's the same gap we described in why AI agents break in production and why a prototype that feels like a product still isn't one — an unattended schedule just removes the last human who was quietly holding it together.
Autonomy is earned by what surrounds the model, not by trusting the model more. Build the scaffolding, and you can let the thing run — and sleep.