Writing a good agent

What goes in a prompt, what AgentCron adds for you, and the five rules that separate a useful overnight agent from an expensive one.

An agent is four things: a CLI, a prompt, a schedule, and the gates it must pass through. The schedule is trivial and the gates come from the template. The prompt is where all the difference is.

What AgentCron already tells the agent

Do not repeat any of this in your prompt — it is appended to every run automatically, and duplicating it costs tokens and makes the instructions fight each other.

  • Where to write its run notes, its reports, its queue items and its screenshots, as both paths and environment variables.
  • How to report status, progress, a summary and a link, so the UI updates live while it works.
  • How to ask you a question with options and block until you answer.
  • How to request approval before anything irreversible, and that a timeout or an unreachable app both mean no.
  • That its commands are recorded, so it should not paste terminal output into its narration to prove work happened — and, on a CLI without a hook API, that routing a command through the wrapper is what puts it on the record.
  • The verification contract: leave proof a human can check without re-running anything.
  • Do not commit. Leave the work uncommitted for a human to review and commit.

Two more blocks are added only when they apply: the isolated-environment instructions when your project defines a setup script, and the per-hunk explanation contract when the working directory contains a git repo.

The five rules

1. One item per run

The single biggest difference between an agent that produces reviewable work and one that produces a mess. An overnight agent that picks up three things produces a diff nobody can review, because the three changes are interleaved.

Tell it: one item, and if it notices something else, file it rather than fixing it.

2. Give it permission to do nothing

A run that finds nothing worth doing and says so clearly is a good run. Without that permission, an agent will invent work to justify the run, and invented work is exactly the work you will reject.

If nothing qualifies, stop immediately with a one-line summary of why.

3. Make it declare a plan before it starts

Three to seven steps, declared up front, then stepped through. A long run has to show where it is, not merely that it is alive — and a plan you can read at 2am tells you whether to let it continue.

4. Tell it what to do when it is unsure

The default behaviour of every agent is to guess. Guessing at 3am produces a diff you throw away at 9am, which costs more than the eight hours of waiting would have.

If the item is ambiguous in a way that changes the design, ask with two options rather than guessing.

5. Write the guardrails as refusals, not preferences

"Never widen the change to make a test pass." "Never edit a test, a fixture, a timeout or a snapshot to make the suite green." "Never re-run a job to check whether it passes this time."

Agents follow specific refusals far better than they follow general encouragement. Every guardrail worth having is one you wrote after an agent did the thing.

A shape that works

ROLE
One paragraph. What this agent is, and the one thing it is for.

PICK
How to choose what to work on. What to do when there is nothing.

WORK
Where to work (its own worktree, never the main checkout).
What "done" means here — tests, lint, build.
Keeping its status current so a human can see it at a glance.

STOP AND ASK
The specific conditions under which it should ask rather than decide.

REPORT
The one-line summary, and what goes in a queue item.

GUARDRAILS
The refusals. Specific, absolute, and each one earned.

Before you enable it

Press Run once and watch. Read the command log while it works rather than afterwards — you will see it try things you did not anticipate, and each of those is a guardrail worth adding.

Then check what that run cost. An agent that costs more per night than the work is worth is a thing you want to discover on night one, not in a monthly bill. The app has a cost view per agent per day that also reports how many runs it was able to price — but until that coverage is good on your setup, your CLI's own usage dashboard is the number to trust.