The guard that works while the agent works
A judge that reads meaning, next to code checks that read facts, watching an agent while it works for days. We ran it live on long builds. Most of what went wrong was not the model. This note gives the three moments, the contract every judge needs, and the six pitfalls that cost us the most.
- Author
- Nexus Agent Team
- Published
- Sep 26, 2026
- Last revised
- Sep 26, 2026
- Reading time
- 21 min
- An agent that works for hours needs a guard that works for hours too. Nobody reads every step.
- Code checks are exact about facts. They cannot read what the owner meant. A judge like Jev can, if you ask it the right question at the right moment.
- There are three moments where a live guard can act: the owner's message, each action, and the turn end.
- We ran this on long builds, for days. Most failures sat outside the model: the agent cleared its own gates, alarms read the wrong fact, verdicts arrived too late, and judges went silent without anyone noticing.
- The fix is not a better question. It is a contract: every judge needs the decision it serves, the facts it needs, the moment it can still change the act, and proof each run that it was asked and read.
1Why a live guardrail
The owner is not reading every step. Something else has to.
An agent that builds an app, runs a migration or answers a queue does not take one action. It reads files, writes code, sends helpers off to work in parallel, pushes, deploys, and reports back.
The owner reads the replies. The owner does not read the hundreds of actions in between. That is the point of an agent, and it is also the risk. By the time the owner sees a problem,
So you put guards around the agent. The first guards everyone writes are code checks. They are fast, free and exact:
- Did the push reach the deploy branch?
- Does the test file exist?
- Has the live page been fetched since the last deploy?
Code checks are right about facts. They are blind about meaning. They cannot tell whether a reply claims work it has not shown, whether , or whether a question the agent wants to ask can be answered on one read.
That is where a judge comes in. Jev, the structured judgement model from TypeSafe, reads a state you give it and answers typed questions with a probability for each allowed answer.1 It never writes a paragraph. Your code branches on the answer. Part one explained the model. Part two showed how to wire it and measured twelve judged checks on held out cases.2
This note is about what happened next, when the same layer ran live, for days, on real builds with a real owner.
2The three moments
A guard can only act where the software around the agent gives it a moment.
The agent does not call its guards. The software around it does, at fixed points.
The owner's message. A new message arrives. This is the moment to read what the owner asked for. Is this a standing rule? Does it open new scope? Is it a request, or a reaction? What the guard learns here shapes everything the agent does next.
Each action. Before a tool runs, a guard can allow it or refuse it. This is the only moment that can stop an act. A refused push never happened. A refused question never reached the owner.
The turn end. The agent has replied. A guard can make it keep working, or leave it a note. One fact decides what this moment can do: the reply is already on the owner's screen. A turn end guard cannot hold a reply back. It can only add to it, or keep the agent going.
| Moment | What a guard can still change | What it cannot change |
|---|---|---|
| The owner's message | What the agent does next | What the agent already did |
| Each action | Whether this act happens | Acts already taken |
| The turn end | Whether the agent keeps working | The reply the owner already read |
2 Cost is not the constraint. Timing is.
3What code decides, what the judge decides
Code owns the facts. The judge owns the reading. A code fact always wins.
The division sounds obvious. Getting it right is most of the work.
Code decides anything a program can read directly:
- Which files changed, which commits landed, which branch was pushed.
- Whether the live page was fetched, and which version it served.
- Whether a test ran, and whether it passed.
- Who wrote something: the owner, the agent, or a helper.
The judge decides what only reading can settle:
- What the owner's message asks for, and whether it binds from now on.
- Whether a claim of "done" shows the work, or only says so.
- Whether a question to the owner can be answered on one read.
- Whether a reply promises something with nothing behind it.
- Code runs first. The judge is asked only what code could not prove. If code already knows a helper is running, nobody asks the judge whether anything will happen.
- A code fact beats a judgement. When both speak, the fact wins, because code is right about facts.
And one order of decisions, fixed once, in one place: a refusal beats a note, a code fact beats a judgement, and
The call itself
The call is small. You send one state and a set of typed questions. Each question has a fixed list of allowed answers. All questions are judged in parallel against the same state, and each comes back as a probability for every answer.1 This is the shape our own layer sends, trimmed to one question:
POST /v1/systemone{"model": "jev-latest","state": {"the_reply": "Done. The new screen is live.","what_the_owner_asked": "Ship the settings screen.","served_version_matches_last_deploy": false},"questions": {"done_claim": {"type": "choice","instructions": {"question": "Does the reply claim finished work, and does it show it?"},"criteria": {"shows_it": "The reply names what was done and how it was checked","claims_without_showing": "The reply says done but shows no evidence","no_claim": "The reply claims nothing finished"}}}}
The answer carries a probability for each allowed answer. Your code then applies a bar: act only when one answer is clear enough. Everything else stays with the rule you had before.
4The judge contract
Missing any one, it does harm.
This is the lesson of the whole note, so it comes before the pitfalls. Every failure in section 5 is one of these four missing.
1 ยท The decision it serves. Name the act the verdict can change. "Refuse this card." "Keep the agent working." "Open a new design round." A judge that serves no decision produces notes nobody acts on. Start from the type of work and the step, not from the last incident.
2 ยท The facts it needs. Give the judge everything the decision depends on, in full. If the question says "compare with the plan", the state must carry the plan. A blank field, or a placeholder string where the facts should be, is a bug that looks like an answer.
3 ยท The moment it can still change the act. Before the act, in the same turn. Never on the owner's next message. A verdict that arrives after the owner has already reacted is a record, not a guard.
4 ยท Proof it worked, every run. For each judge and each session: was it asked, was it fed real inputs, did it answer, and did anything read the answer? If any of the four is zero, the judge itself raises an alarm. Silence must never look like "nothing to report".
And one rule on top: a judge whose answer changes saved state that other checks enforce is a gate, even if you call it advisory. Test it as a gate.
5Typical pitfalls
Each one comes with a rounded illustration from our own live builds, and the rule that prevents it.
5.1 ยท The agent clears its own gate
A gate is only as strong as whoever can open it. If the agent can open it, it is a suggestion.
Every gate needs an exit. The owner may really want the act. The trap is an exit the agent can reach alone:
- An override word the agent types into its own command.
- A proof line the agent writes, which the gate reads as the owner's approval.
- A one time unlock code, printed in the refusal the agent receives.
- A helper type the gate does not watch.
- A "mute" file the agent can create.
In one build that ran for days, we read every refusal the main agent received, one by one. None by the owner's own words.
The same build carried A gate that held back new builders until the plan was ready was Reading the code,
This is not the agent being devious. The exit was there, the refusal often named it, and the work was urgent. Any agent under pressure will take the nearest door.
The rule: only someone else can clear a check. A refusal clears on the owner's recorded words about that refusal, or on evidence the act itself produced: a commit, a served page, a test run. Never on a line, word or file the checked agent writes. Keep the proof records and the mute switches out of the agent's reach.
5.2 ยท False alarms from reading the wrong fact
An alarm that reads a stand in for the fact will be wrong every time the two differ.
The agent's world has many neighbours of the fact you care about. A push reaches a remote, but not the deploy branch. A page gets fetched, but by a different tool than the one the check watches. A folder looks like the app, but it is a helper's working copy.
Illustrations from our live builds:
- A "nothing is live yet" alarm was wrong 94 times out of 94. It waited for one specific record that was never written. Meanwhile the live page had been fetched hundreds of times.
- A "you pushed and nothing verified it" alarm was wrong on at least 212 of 222 fires. The pushes were helpers' working branches, which never deploy.
- A "0 of 0 features" line printed 161 times out of 162. It was a parser that could not read its input, reported as a count.
Every one of these is code, not the judge. But they matter to a judge layer twice. They teach the agent to ignore alarms. And the judge often receives the same wrong fact as input.
The rules:
- Read the effect's own key: the deploy branch, the served page address, one identity for "the app" shared by every check.
- When a check cannot read its input, it says so and stays quiet on that part. Unreadable is not zero.
- Each sentence in an alarm is filled only by the test that fired. An alarm never claims something its branch did not check.
- Fire again only when the condition changes. Not on a timer.
5.3 ยท Verdicts that arrive after the owner already reacted
A right verdict, delivered late, is a wrong guardrail.
Turn end verdicts have a delivery problem. The reply is already shown. If the verdict becomes a note that rides on the next message, the next message is often the owner's own correction.
What we measured:
- A judge that checks "done" claims was right at 6 of 7 moments where the owner later said the work was not done. Each time, its verdict reached the agent on the owner's next message, which was the correction.
- One judge flags promises with nothing behind them. In one build, its notes reached the agent In another, where the owner stepped away, the median was close to 4 hours, and about three in four of its notes were never delivered at all.
- Some verdicts arrived in time and were still overridden. The agent overrode it both times. The owner then rejected exactly those two pieces of work. Another judge warned that key planning steps had been skipped.
The rules:
- Put the question at the last moment it can change the act. "Is this done?" belongs before the claim goes out, not after.
- If the turn end is the only moment, make the verdict act in that turn: keep the agent working, with the verdict as the reason. Or drop it.
- A right verdict must not be waved away by an override the agent types. See 5.1.
5.4 ยท Silent judges
A judge that is not running looks exactly like a judge with nothing to say.
This was the most repeated failure in our layer. The forms varied:
- A judge was built, tested, and never wired to the moment that should call it.
- A judge was called with placeholder text where the facts should be, and answered the placeholder.
- Verdicts were computed at every turn end and delivered to nothing. On one build,
- The judge service The failed calls said nothing.
The root cause is a design choice most teams make on day one, and we made it too: fail open. If the judge is unreachable, fall back to the old rule. That is right for the agent: work should not stop because a classifier is down. It is wrong for the guard layer, if nobody sees the fallback happen.
The rules:
- Keep a ledger per judge per session: asked, fed, answered, read. Alarm on any zero.
- Refuse to send a call with an unfilled field. Placeholders never leave the machine.
- A failed call says what it could not check. It does not go quiet.
5.5 ยท One judge per incident
When a new judge costs nothing to add, you will add one for every bad day.
Part two's main trick was to put every question for a moment into one call. The call costs the same as its slowest question, not the sum of all of them.2 That is good for latency. It also removed every reason to say no to a new question.
Our layer went from 10 judges to 22 in six days. Live, Each addition answered a real incident.
The same pattern ran through fixes. When a judge misfired, the fix was one more input field, or one more exception in its question. The class came back in the next form. Across our past review rounds, , , Each time the fix was one check at a time.
The rules:
- Start from a grid: type of work by step. One judge per cell that has a real decision. Fewer, broader judges.
- Admit a judge only under the contract in section 4.
- Every new check passes the same contract test before it ships: no exit the agent can type, fires on the act whatever helper performs it, reads the shared facts, stays quiet when blind, and proves delivery.
5.6 ยท Paperwork blocks
A turn end block that a one line note can clear is teaching the agent to write notes.
A turn end guard can keep the agent working. That is valuable. Agents stop too early, and a block that says "these tasks are ready and nobody holds them" gets real work done.
But the block has to read real movement. Ours read helper messages and a task board stamp. It could not see helpers committing code.
What we measured:
- In one build, helpers were visibly working at 136 of 147 turn end blocks. In another, at 323 of 337.
- With no repeat limit, the agent answered the same block with "Waiting."
- A turn end guard told the agent "nothing is watching this job" while a watcher on that exact job was running. Nothing in the code ever set the fact the question depended on.
The opposite failure is real too. "Block only when nothing moves" In one night run, a block led the agent to find the root cause of a broken refresh job,
The rules:
- Judge each open task, not the whole session.
- Held: its helper shows movement, such as a commit, a file write or a running job. No block.
- Parked: it names what it waits on, and who. No block.
- Neither: block, with a repeat limit.
- One more case no turn end guard can see: a turn that dies on an API error or a usage limit never reaches its turn end. Only a watcher outside the session can restart it.
6What part two got wrong
We wrote that a judgement never stops work on its own. Live, that was not true.
Part two ended on a boundary we were proud of: "In our layer a judgement never stops work on its own."2
- One judge refused an act on its verdict alone, with only an agent typed override.
- which kind of build is running, whether a new design round has opened, whether a message counts as a request. A wrong reading in the morning became a refusal in the afternoon.
- An alarm told the agent "ask the owner this question", and a judge refused the resulting question.
None of this shows on a test bench, because a bench measures one question on one case. It shows only when verdicts feed each other over days.
The rule: any judge whose answer changes state that another check enforces is a gate. It needs the code facts to back it before it writes, and it is tested as a gate.
7What held
Not everything failed. A few patterns were right in every session we read, and they are the ones we are building on.
- A refusal that demands real proof. The judge that checks task closes But it is the one judge that measurably improved the work.
- An unlock only the owner's answer can give.
- Gates with no typed exit. The only gate fixes that held across sessions.
- Deciding who wrote a message by record type, not by its words. The only false alarm fix that held.
- "These tasks are ready now" nudges. Right in every session.
8How to start
A short checklist for putting a live judge next to your own agent.
- List the three moments your agent's runtime gives you: the owner's message, each action, the turn end. Write what each can still change.
- Write the code checks first. Every fact a program can read, it reads. Use the effect's own key.
- Build one shared source of facts: which app, who acted, what is deployed, what is served, what moved. Every check reads it.
- Map decisions before questions: type of work by step. One judge per real decision.
- Fill the contract for each judge: the decision, the facts in full, the moment, proof it ran.
- Ask at the last moment the act can change. Not on the next message.
- Remove every exit the agent can reach alone. Owner words about that refusal, or evidence the act produced.
- Keep a health ledger: asked, fed, answered, read. Alarm on any zero.
- Treat state writing judges as gates, and test them as gates.
- Add an outside watcher for turns that die before they end.
- Keep a register of the owner's corrections, each paired with the check that watches it, or a written reason no check can.
9The fine print
- One team, one agent, a handful of long builds. Every number here comes from our own session logs and code, read one by one. Other agents will have other failures.
- Counts are from logs, not a controlled test. Where we say "wrong", someone read the case against what actually happened. Where a class was not read case by case, we left it out.
- The refusal breakdown in 5.1 covers the 78 refusals we classified one by one in the main agent of one build.
- Delivery delays are medians over the notes that were delivered. The share never delivered is stated separately.
- The judge service outage in 5.4 is stated by its timing only. Its cause was not investigated for this note.
- The request in section 3 is the shape our layer sends, with the state and question shortened for reading.
- TypeSafe's claims are TypeSafe's. Section 3 describes the call from its public documentation.1
Glossary
- Agent
- An AI that takes actions in steps, not just answers.
- Alarm
- A check that leaves the agent a note but does not stop anything.
- Code fact
- Something a program can read directly: a file, a commit, a served page, a test result.
- Fail open
- When a check cannot get an answer, it behaves as if it did not exist. Safe for work, dangerous if nobody sees it.
- Gate
- A check that can refuse an act.
- Judge
- A model call that answers a typed question about meaning, with a probability for each allowed answer.
- Judge question
- One question, with a fixed list of allowed answers, asked of the judge at one moment.
- Owner
- The person the agent works for, who sets the goal and approves the big calls.
- Stand in
- A neighbour of the fact you care about, read instead of the fact itself.
- Turn end
- The moment after the agent's reply is shown, before it stops.
- TypeSafe, Introducing System One models and Jev, 15 September 2026, and the TypeSafe documentation at docs.typesafe.ai. Several question types can be mixed in one call; every question is judged in parallel and in isolation against the same state; answers come back as probabilities code can branch on.
- Nexus Agent, A cheap model watching an expensive one, 18 September 2026. Part two of this series: one call per moment, the order of decisions, and
Tell us where the work piles up.
We build the first procedure with your team and run it with you.
Talk to our team