What proves a Run worked
Almost everything Genosyn used to know about a Run came from the Run. The status said the loop returned; the transcript was the model narrating its own work; the verdict was a second model reading that narration. Checks and the Effects list are the parts no model has a say in.
Three axes, three different claims
A Run carries three independent judgements, and reading any one of them as the others is how a convincingly wrong Run passes for a good one. They never overwrite each other — a Run with failing Checks still ends completed, because that word has a narrow meaning worth keeping.
- status
- The loop returned.
completedmeans the agent finished without erroring, timing out, or being interrupted. It is a statement about the runtime, not about the work. See Runs. - checksVerdict
- The machine-verifiable bar.
passed,failed, ornot_runwhen the Routine declares no Checks. Decided by the server running assertions an operator wrote — the only axis with no model in it anywhere. - outcomeVerdict
- A restricted model graded the evidence.
achieved,unclear,off_goal, orunverified, against the Routine's acceptance criteria. Judgement, not proof — see the outcome check.
Checks
Acceptance criteria are prose, and prose is graded by a model. A Check is the opposite shape: an assertion the operator writes, that the server evaluates, and that the employee being graded cannot author, edit, or delete. There is no MCP tool that writes one. An AI Employee may read its Routine's Checks — they ride into the Run brief, so it aims at the bar rather than discovering it afterwards — and that is the whole of its access.
Checks live on the Routine's Settings → Checks panel, beside Outcome check — at most 10 per Routine, run in the order you arrange them. Each one has a name, a kind, the assertion itself, and three switches:
- required
- A required Check that does not pass fails the Run's checks verdict. A non-required one reports its result and changes nothing — the way to watch a new signal for a fortnight before letting it stop work.
- enabled
- Off keeps the row and its history without running it.
- timeoutSec
- Wall-clock ceiling for a
commandCheck — 120 seconds by default, up to 15 minutes. Always clamped further by what remains of the Run's own deadline, so Checks can never extendtimeoutSecon the Routine.
Writing an effect Check
An effect Check is a predicate over what the server recorded this Run changing — the Effects list below. It needs no shell, no sandbox, and no extra model turn, which is what keeps Checks from being a luxury only some installs get. Four fields:
action— the recorded action to count, such asmail.sendordeal.update.targetType— optional, narrows the count to one kind of record.min— how many the Run must have recorded. The usual assertion.max— optional ceiling. This is the one that catches a loop: a digest routine that sent 400 emails passes everyminever written.
{ "action": "mail.send", "targetType": "mail_thread", "min": 1, "max": 3 }The result records the arithmetic, not a verdict word — expected at least 1 mail.send, the ledger has 0 — so the person reading it later does not have to re-derive why it failed.
Writing a command Check
A command Check runs a shell command inside the same bubblewrap boundary the bash tool uses, rooted at the employee's working directory, and passes on exit 0. Anything the sandbox can run is fair game — a test suite, a git diff --exit-code, a script that curls the endpoint the Run was supposed to deploy. The exit code and the tail of the output land on the result.
The Effects list
Every mutation inside a company already writes an audit event at the write seam, after the change succeeded. Those rows now carry the runId of the Run whose token authorized them, and the Run detail view renders them as a plain Effects list beside the transcript: what changed, to what, in order.
It is not a summary of the transcript and it is not derived from one. The transcript is the model's account of its work; the Effects list is the server's, written by the code that performed each change. It is the one record of a Run the model had no hand in — which is why a Run that ends with a confident summary of six emails sent, beside an empty Effects list, is now a visibly different object from a Run that sent six emails.
The same ledger has three other readers:
- Effect Checks assert over it.
- The outcome checker is shown it alongside the transcript, labelled as server-written, so it can weigh what happened against what was claimed.
- A retrying Run opens with what earlier attempts already did — see Retries.
- AI Employees, through the two tools below.
The list a model is shown is capped at 200 entries; a bulk import says "and 9,800 more" rather than filling a prompt. The Run page renders the full history.
What an AI Employee can read
Until now there was no run-reading tool in Genosyn at all, which made a whole class of question unanswerable from inside the company: a manager asked why a colleague's work was not landing, or an employee briefed about one of its own Routines being stood down, had nothing to open. Two tools close that, and neither writes anything.
- list_runs
- Terminal Runs for one of your Routines — or your own recent Runs across all of them — with each Run's status, checks verdict, outcome verdict and token cost.
- get_run_report
- One Run's Check results, every remediation round included, plus its Effects. The first time an AI Employee can read what a Run actually did rather than what it said.
unverified is not unclear
The outcome check used to record two very different situations with one word. unclear means the checker read the evidence and honestly could not tell. unverified means no judgement was ever produced — the checker errored, timed out, or ended without submitting.
The collision was load-bearing in the wrong direction. Every consumer downstream read "we could not verify" as "nothing was wrong," so an outage in the checker earned an employee the same credit as a graded success. They are separate verdicts now, and unverified counts against earned autonomy exactly like a bad Run.
A Run whose grading never happened at all is also no longer invisible. Genosyn stamps when the check last reached a judgement of any kind, and a sweep re-grades completed Runs still missing one — a process that died inside the verdict window used to strand its Run with a null verdict forever, and a null verdict counted as clean. How stale a Run must be, and how many are re-graded per pass, are at Admin → Runtime.
Bounded remediation
When a required Check fails, the Run is not finished — but it does not get to try forever either. Genosyn briefs the employee with the failing Check's name and detail and lets it try again, for at most two further rounds, entirely inside the Routine's existing timeoutSec. There is no extra time budget and no third round.
Every round's results are kept, so the strip on the Run is honest about a Run that only went green on the second try, and the number of rounds spent shows beside the verdict. If the Check still fails, the Run finalizes with checksVerdict: failed — a real outcome, notified like any other bad Run, not a retry loop nobody watched.
What a failed Check costs
- It revokes every active Waiver the employee holds, on the spot, exactly like a Run graded off goal. See Earned autonomy.
- It writes a Lesson into the Routine's future briefs, with the failing Check as the cause the retrospective starts from. See The improvement loop.
- It counts toward the Routine's consecutive-failure streak, which is what trips the circuit breaker into a Standdown.