Part of Fourteen Automations That Run Without Me.

People ask the autonomy question in the wrong form. They ask how much they trust the model. Trust is not a property you can schedule against, and it does not survive a model upgrade. The useful form of the question is mechanical: after this task runs, is there a cheap and certain way to know whether it worked? If the answer is yes, the task can run unattended. If the answer is no, the task's job is to prepare a decision for a human, and nothing more.

I run a daemon built around exactly that test. It wakes early in the morning, after the other scheduled jobs have finished, looks at the state of my systems, proposes small bounded projects, runs the ones it can prove, and asks me about the rest. This post is the design.

Trust is not schedulable. A check is.

The loop

Five stages, in order: observe, score, propose, act, receipt.

Observe reads signals that already exist. It does not go looking for work in the abstract; it looks at specific files and services whose state means something. A quality gate's exit status on a named piece of writing. The open section of a citations file. Counts of issues carrying particular labels. The state file another daemon writes at the end of its cycle. The recency of a third job's logs. How stale the decisions log has become. Every one of these is a cheap read, and every one answers a question I would otherwise ask myself on a Monday.

Score turns each observation into a number. Propose turns numbers above a threshold into candidate projects drawn from a template file. Act sorts each candidate into one of three tiers. Receipt writes what happened into a state file, because a job that cannot prove what it did is a job you will eventually stop believing.

Three tiers, one test

TierPolicyAdmission test
A Run it now, unattended. A named command exists whose exit code proves the result.
B Open a tracked issue, send one line to my phone. A human must judge the outcome. No mechanical proof exists.
C Never, by construction. Publishing, sending mail, touching secrets, destructive deletes.

Tier C deserves attention because of how it is implemented. It is not a rule the daemon checks at runtime. It is the absence of a template. The daemon can only propose projects that exist in its configuration file, and that file contains no template that publishes, mails, or deletes. A job cannot decide to do something it has no vocabulary for. Deny-lists are checked and can be wrong; a missing capability cannot be reasoned around.

What a Tier-A project looks like

Each template in the configuration carries five parts: a trigger, a tier, a base priority, the command to run, and the check that proves it. Concretely, one of mine says: when a named quality gate is not green for a given piece of writing, run that gate's script against that piece, and treat exit code zero as proof. Another says: when a third job's logs have not been written for seven days, run that job's self-test.

Notice what these two have in common. The proof is not "the model said it was fine". The proof is an exit code from a program that was written to be run by a machine, by a person who was thinking about failure. That is the entire distinction between Tier A and Tier B. It is not about difficulty or importance. A trivial task with no check is Tier B. A consequential task with a real check can be Tier A.

The check kinds I use are deliberately few: an exit code, a file that must exist, a count that must not increase. Anything more elaborate becomes a thing that itself needs checking.

The caps matter more than the scoring

The configuration sets hard ceilings that have nothing to do with how confident the scoring is:

I tuned the scoring weights twice. I have never regretted the caps. When an automated system misbehaves, the damage is almost always proportional to volume, and volume is the one thing you can bound in advance without understanding the failure.

The done rule

This is the part most people skip, and it is where self-directed systems quietly rot. My rule has three clauses:

  1. Tier A is done when the check exits zero and the linked tracker issue is closed. If this is the first green run and no issue exists, the daemon creates one and closes it in the same breath — so there is a durable record that the work happened, not just a log line.
  2. Tier B is done when the issue is open and I have been pinged. I am the verifier. The daemon does not get to mark my work complete.
  3. Nothing is ever asserted done without a receipt written to the state file.

Clause three exists because of a specific failure pattern: a job that reports success from the fact that it reached the end of its own script. Reaching the end of a script proves the script ended. A receipt records what was checked, what the check returned, and when. If the receipt is missing, the answer to "did it work?" is no, regardless of what the log says.

Applying the test to your own list

Take whatever you were about to automate and ask the question honestly.

TaskIs there a cheap check?Tier
Reformat a config fileYes — the parser either accepts it or does not.A
Rename a variable across a repositoryYes — the test suite passes or fails.A
Renew an expiring tokenYes — a probe request returns 200 or 401.A
Summarise the week's messagesNo — "good summary" has no exit code.B
Decide which of three suppliers to useNo.B
Reply to a clientNot applicable — outward communication.C

The interesting rows are the ones that move. "Summarise the week's messages" is Tier B today. It becomes Tier A the moment you can state a mechanical property the summary must have — every thread in the input appears in the output, no names appear that were not in the source, the length is under a bound. Writing that check is usually more valuable than improving the prompt, and it is the only route by which a task graduates to running alone.

That is the practical advice hidden in the tier table. You do not expand autonomy by trusting the model more. You expand it by building checks, one at a time, and letting tasks graduate.

What it refuses, and why that is the point

My daemon will not publish a post, send an email, touch a credential, or delete anything. Those are the four capabilities that would make it dramatically more useful, and they are the four that would make a bad morning unrecoverable. Every automation I have regretted crossed one of those lines. Every one I still run stays behind them.

A system that proposes work all day and acts on a narrow slice of it is not a compromise. It is the shape that survives contact with its own mistakes.

Read next: Review What Actually Runs applies the same test to code review, where the check is a compiler and the auto-fix reverts itself.