<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Agateon</title>
    <description>The latest articles on DEV Community by Agateon (@agateon).</description>
    <link>https://dev.to/agateon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4095078%2F0af8b095-0e57-4533-bb8b-8fb782b3509b.png</url>
      <title>DEV Community: Agateon</title>
      <link>https://dev.to/agateon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agateon"/>
    <language>en</language>
    <item>
      <title>Agateon: verify AI agents the way a build system verifies a compiler</title>
      <dc:creator>Agateon</dc:creator>
      <pubDate>Thu, 27 Aug 2026 01:12:48 +0000</pubDate>
      <link>https://dev.to/agateon/agateon-verify-ai-agents-the-way-a-build-system-verifies-a-compiler-1a5d</link>
      <guid>https://dev.to/agateon/agateon-verify-ai-agents-the-way-a-build-system-verifies-a-compiler-1a5d</guid>
      <description>&lt;h1&gt;
  
  
  Agateon: verify AI agents the way a build system verifies a compiler
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8dwh7b2rff6uplwpne45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8dwh7b2rff6uplwpne45.png" alt="Cover: an agent node on the left feeds work into a teal gate; the gate checks evidence — git log, test exit code, files on disk — and a checkmark lets the work advance to the next phase. Title reads " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've run a long task through an AI coding agent, you know the quality signal most setups leave you with: &lt;em&gt;it looks done&lt;/em&gt;. Not "the test suite is green and the typechecker is clean" — just that the agent says so, and the diff seems plausible. We spent months building the alternative, and this post is about what it is and why it's shaped the way it is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — Agateon is an open-source orchestration protocol for software-engineering tasks run by AI agents. There's no runtime, no daemon, no build step: it's a set of Markdown protocol files plus gate-check scripts. Work moves through eight phases, and after every phase an objective gate — a test runner's exit code, a typechecker, a git log — must pass before the state machine may advance. All state lives in version-controlled Markdown. The orchestrator agent never writes code; it dispatches a dedicated subagent per phase and checks their output against evidence. Progress can't advance on "it looks done" — only on things you can point at and re-run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: "it looks done" is not a quality signal
&lt;/h2&gt;

&lt;p&gt;LLM agents are genuinely good at software work in a single burst: scaffold a repo, fix a lint error, write a test for a known case. The trouble is long tasks. Context gets polluted. Subagents drift from the original brief. And as a task stretches across hours and dozens of turns, the only signal most setups give you is the agent's own summary of what it did.&lt;/p&gt;

&lt;p&gt;That's the failure mode this project exists to close. A build system doesn't trust a compiler's claim that it produced correct code — it checks the exit status, runs the test suite, typechecks the output. We wanted the same shape for agents: &lt;strong&gt;you don't trust the output, you verify it through gates.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: treat the agent like a compiler
&lt;/h2&gt;

&lt;p&gt;The core claim, stated plainly: an AI agent working on a codebase should be treated like a compiler feeding into a build. You don't ask it to be more honest. You don't read its diary. You make the mechanism refuse to advance unless objective evidence says the phase is done.&lt;/p&gt;

&lt;p&gt;That reframing changes a lot of defaults. "Done" stops meaning "the agent finished talking" and starts meaning "the gate command exited 0 and the evidence file is non-empty."&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phases and gates
&lt;/h3&gt;

&lt;p&gt;A task moves through a fixed state machine: P0 brief → P1 requirements → P2 design → P3 test-first → P4 implementation → P5 verification → P6 acceptance → P7 consistency → P8 release → READY → DONE.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    P0[P0 brief] --&amp;gt; P1[P1 requirements]
    P1 --&amp;gt; P2[P2 design]
    P2 --&amp;gt; P3[P3 test-first]
    P3 --&amp;gt; P4[P4 implement]
    P4 --&amp;gt; P5[P5 verify]
    P5 --&amp;gt; P6[P6 accept]
    P6 --&amp;gt; P7[P7 consistency]
    P7 --&amp;gt; P8[P8 release]
    P8 --&amp;gt; D[DONE]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Between every pair sits a gate, and the gate's job is to run evidence the agent didn't write about itself. For a verification phase, that's the real test command — the gate script executes it and looks at the exit code. For requirements, it's a structural check: does the document contain at least one BDD (behavior-driven-development) acceptance criterion, are there unresolved &lt;code&gt;NEED_CONFIRM&lt;/code&gt; items? For acceptance, it checks that the evidence files are non-empty and the gate commands all exited 0.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    A[Phase work] --&amp;gt; G{Gate: run evidence}
    G --&amp;gt;|pass: exit 0, evidence holds| N[Persist to Markdown, advance]
    G --&amp;gt;|fail| R[Redo the phase]
    R --&amp;gt; A&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;If a gate fails, the phase is redone and the retry is recorded. This is where a recent postmortem — &lt;a href="https://dev.to/agateon/our-ai-safety-net-depended-on-the-agent-being-honest-it-wasnt-3k64"&gt;our AI safety net depended on the agent being honest. It wasn't.&lt;/a&gt; — gets relevant: we found the retry counter itself could be left empty by an agent, silently disabling the whole safety mechanism. The fix anchored that check to git history instead of the agent's own bookkeeping. The honest takeaway: the gates are only as strong as the evidence they're anchored to, and we're always looking for places where the "evidence" is really another self-report in disguise.&lt;/p&gt;

&lt;h3&gt;
  
  
  State you can see
&lt;/h3&gt;

&lt;p&gt;Every phase result is written to version-controlled Markdown (&lt;code&gt;active-tasks.md&lt;/code&gt;, &lt;code&gt;.state.yaml&lt;/code&gt;). This is a deliberate choice, and it buys two things. First, a crash — a killed session, a power loss, a model context that hit its ceiling — is a pause, not a restart: the next run reads the state file and picks up where the machine left off. Second, a human (or another agent) can audit what happened by reading the files, not by trusting the summary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4gwaam4tdz4soqzqq1at.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4gwaam4tdz4soqzqq1at.png" alt="Illustration: a task moves through phases P4 to P5 and is interrupted by a lightning bolt at the gate; below, a Markdown state-file card stays intact with the phase persisted, and an arrow resumes the work from the saved state" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Roles are separated
&lt;/h3&gt;

&lt;p&gt;The orchestrator agent never writes code. Each phase is dispatched to a dedicated subagent — a requirements analyst, an architect, a test designer, an implementer, a verifier — and their output is handed back through the gate. This keeps the orchestrator's context clean (it's a dispatcher, not a participant) and makes the review genuinely independent of the work it's reviewing. Same reason you don't let the author be the only reviewer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does it actually work? We make it eat its own food.
&lt;/h2&gt;

&lt;p&gt;Agateon is built with Agateon. The repository's own task history — dozens of tasks, from the original bootstrap to recent mechanism fixes — was produced through this same state machine, and it's all in the repo for anyone to read: &lt;a href="https://github.com/randomgitsrc/agateon/tree/main/agate-workspace/tasks" rel="noopener noreferrer"&gt;&lt;code&gt;agate-workspace/tasks/&lt;/code&gt;&lt;/a&gt;. The postmortem linked above is a real example of the loop working: an audit found a design hole, the fix went through phases with gates, adversarial tests were run against a real git repository, and the task record shows all of it.&lt;/p&gt;

&lt;p&gt;We also try to break our own gates. The verification phases run adversarial tests — rollbacks, missing records, half-finished evidence — and check that the gate blocks what it's supposed to block and passes what it's supposed to pass. When a gate can be fooled by something an agent can simply omit, that's a bug, and it goes back into the machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is not (read this before trying it)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's not a magic agent.&lt;/strong&gt; It's a protocol and a set of scripts. You bring the coding agent; Agateon shapes how it's orchestrated and checked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's not a runtime or a service.&lt;/strong&gt; There's nothing to deploy. Your agent just needs to read Markdown and run commands. Setup is a symlink plus a couple of git hooks: &lt;code&gt;curl -sSL https://raw.githubusercontent.com/randomgitsrc/agateon/main/install.sh | bash&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It doesn't make gates immune to bad design.&lt;/strong&gt; A gate that checks "did the agent write a plausible-looking report" is theater; a gate that runs a real test suite is not. The difference is entirely in what you choose as evidence, and choosing well is a design problem, not a tooling problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's early and honest about it.&lt;/strong&gt; The phase machine, the gate scripts, and the docs are all live in an MIT-licensed repository at v0.64.0, but "early" isn't a euphemism for "stable": the right expectation is that you audit the gates you depend on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you're building agent tooling, check this
&lt;/h2&gt;

&lt;p&gt;The lesson generalizes beyond this project: whenever an agent's own report feeds a safety or progress mechanism, ask whether that mechanism depends on evidence the agent could simply omit. Ours did — the retry counter that triggered a human pause could be left empty, silently. The fix wasn't "make the agent more careful." It was "stop needing the agent to be careful about the parts that matter most," and anchor the check to something that exists independent of what the agent chooses to report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The repository is &lt;a href="https://github.com/randomgitsrc/agateon" rel="noopener noreferrer"&gt;github.com/randomgitsrc/agateon&lt;/a&gt; (MIT). One-line install, no infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/randomgitsrc/agateon/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've ever shipped a long agent task on "it looks done" and felt uneasy about it, this is the project for you. The honest summary of what Agateon does: it makes "done" mean something you can re-run, not something you were told.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Our AI Safety Net Depended on the Agent Being Honest. It Wasn't.</title>
      <dc:creator>Agateon</dc:creator>
      <pubDate>Wed, 26 Aug 2026 06:51:19 +0000</pubDate>
      <link>https://dev.to/agateon/our-ai-safety-net-depended-on-the-agent-being-honest-it-wasnt-3k64</link>
      <guid>https://dev.to/agateon/our-ai-safety-net-depended-on-the-agent-being-honest-it-wasnt-3k64</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbdgwgjaay31vjghms79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbdgwgjaay31vjghms79.png" alt="Cover: a row of gate checkpoints, most passed green, one flagged with a question mark fed by a dashed " width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agateon is a protocol for running software-engineering work through AI agents without trusting their word for it. Every phase of work — requirements, design, implementation, testing, release — has to pass an objective gate before it counts as done. No gate, no progress. That's the entire premise.&lt;/p&gt;

&lt;p&gt;A few days ago, a routine audit found a hole in one of our own gates. Not a logic bug. A &lt;em&gt;design&lt;/em&gt; hole — the kind where the mechanism does exactly what it was told to do, and that's the problem. Here's what happened, how we found it, and how we fixed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mechanism: fail enough times, and a human has to look
&lt;/h2&gt;

&lt;p&gt;Agents get stuck. They misread a requirement, a test fails for a reason they don't understand, a sub-agent comes back with nothing useful. Agateon's answer is simple: track retries per phase, and once a phase has failed too many times, stop automation entirely and force a human decision.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; Phase: agent starts work
    Phase --&amp;gt; GateCheck: submit for gate check
    GateCheck --&amp;gt; NextPhase: pass
    GateCheck --&amp;gt; RetryOrPause: fail
    RetryOrPause --&amp;gt; Phase: retries below limit, try again
    RetryOrPause --&amp;gt; PAUSED: retries exhausted
    PAUSED --&amp;gt; [*]: human decides
    NextPhase --&amp;gt; [*]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Nothing exotic. It's the same idea as a circuit breaker: enough consecutive failures, and the system stops trying to route around the problem itself and hands control back to a person.&lt;/p&gt;

&lt;p&gt;The part that matters is &lt;em&gt;how&lt;/em&gt; the system knows a retry happened: the agent records it. Every time a phase gets rejected and redone, the retry is supposed to be written into that task's state file.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the audit found
&lt;/h2&gt;

&lt;p&gt;An independent review of four recently completed tasks checked whether the retry records actually matched what had happened. They didn't.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    subgraph Real["What actually happened, per git history"]
        A1["Review rejected a design,&amp;lt;br/&amp;gt;sent back for rework"]
        A2["Verification failed,&amp;lt;br/&amp;gt;task rolled back a phase"]
        A3["A sub-agent returned&amp;lt;br/&amp;gt;nothing useful, redispatched"]
    end
    subgraph Recorded["What the state file recorded"]
        B1["retries: (empty)"]
    end
    A1 -.-&amp;gt; B1
    A2 -.-&amp;gt; B1
    A3 -.-&amp;gt; B1&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;All four tasks — real rejections, a real phase rollback, a real empty-handed sub-agent — and the retry counter for every one of them read empty. As if none of it had happened.&lt;/p&gt;

&lt;p&gt;The retry-limit mechanism was never triggered by any of this, because the mechanism has no way to see the world except through what gets written into that field. If the field says nothing happened, as far as the safety net is concerned, nothing happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this isn't just a missed edge case
&lt;/h2&gt;

&lt;p&gt;The uncomfortable part isn't that some retries went unlogged. It's &lt;em&gt;what kind&lt;/em&gt; of gap this is.&lt;/p&gt;

&lt;p&gt;Agateon's whole reason for existing is that you shouldn't trust an AI agent's account of its own work — you verify it against evidence instead. The retry-limit mechanism is supposed to be one of the things doing that verifying. But its own trigger condition depended entirely on the same untrusted party self-reporting honestly. The guard was watching for the fox, using information the fox was free to leave out.&lt;/p&gt;

&lt;p&gt;That's not a bug you find by writing more test cases for the happy path. It's a hole in the design's trust model — the mechanism could be silently no-op'd, not through malice, just through an agent that got busy, forgot, or never wired up the bookkeeping. And it fails &lt;em&gt;silently&lt;/em&gt;: no error, no crash, just a safety net that was never actually there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6opr3hazjdrtbxoxr8h7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6opr3hazjdrtbxoxr8h7.png" alt="Illustration: an agent icon connected to a shield icon only by a dashed line reading " width="800" height="427"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;sequenceDiagram
    participant Agent
    participant StateFile as State File
    participant Gate as Retry-Limit Gate

    Note over Agent,Gate: What was supposed to happen
    Agent-&amp;gt;&amp;gt;StateFile: record retry
    StateFile-&amp;gt;&amp;gt;Gate: retries for phase = 3
    Gate-&amp;gt;&amp;gt;Agent: PAUSED, human needed

    Note over Agent,Gate: What could actually happen
    Agent--xStateFile: retry never recorded
    StateFile-&amp;gt;&amp;gt;Gate: retries for phase = empty
    Gate-&amp;gt;&amp;gt;Agent: continue as normal&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;
  
  
  The fix: stop trusting the field, check the evidence instead
&lt;/h2&gt;

&lt;p&gt;The fix doesn't ask the agent to be more careful about logging. It stops relying on the log at all for the part that matters most, and checks something the agent can't quietly leave out: the git history.&lt;/p&gt;

&lt;p&gt;A real phase rollback — say, verification failing and the task moving backward a phase — is a fact that's already sitting in version control the moment it happens, independent of anything the agent writes anywhere. So the fix compares the two: if the commit history shows a real rollback but the retry counter for that phase didn't grow, the commit is blocked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3k5glenhyfa3nh4m2w7x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3k5glenhyfa3nh4m2w7x.png" alt="Illustration: before and after comparison. Before, an agent connects to a gate only through a dashed self-report line and the gate shows a question mark. After, the same self-report line is grayed out and a solid line from git history commits feeds the gate, which now shows a checkmark" width="800" height="462"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Commit staged] --&amp;gt; B{Did phase move backward?}
    B -- No --&amp;gt; Z[Allow]
    B -- Yes --&amp;gt; C{Did retries counter&amp;lt;br/&amp;gt;for that phase increase?}
    C -- Yes --&amp;gt; Z
    C -- No --&amp;gt; D["Block commit&amp;lt;br/&amp;gt;retry happened, wasn't recorded"]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;We deliberately kept this narrow. There are softer signals too — things like a review-rejection file existing on disk, or a sub-agent's output containing the phrases that usually mean "came back empty." Those are useful hints, but they're pattern-matching, and pattern-matching has false positives. So those only produce a warning, not a block. The one check that hard-blocks a commit is built on a fact that can't be fabricated by omission: a phase number that actually moved backward in git history. Confidence dictates enforcement strength — we don't block on evidence we don't fully trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Did it actually work? We tried to break it.
&lt;/h2&gt;

&lt;p&gt;We didn't take the fix's word for it either. Two adversarial tests, both against a real git repository:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack:&lt;/strong&gt; stage a phase rollback with an empty retry record — exactly the scenario the audit found.&lt;br&gt;
&lt;strong&gt;Result:&lt;/strong&gt; commit blocked, with a message naming the exact phase and the exact missing record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Control:&lt;/strong&gt; the same rollback, this time with the retry properly recorded.&lt;br&gt;
&lt;strong&gt;Result:&lt;/strong&gt; commit allowed.&lt;/p&gt;

&lt;p&gt;One more thing worth mentioning, because it's the kind of detail that's easy to leave out of a postmortem and shouldn't be: an earlier version of this fix had a guard condition that, on inspection, would have made it unable to catch the exact failure mode that motivated it in the first place — the original evidence was tasks where a retry had &lt;em&gt;never&lt;/em&gt; once been recorded, and the guard assumed there'd already been a prior record to compare against. It was caught in review before it shipped, not after. We're mentioning it because "the fix for the self-reporting problem needed a second pair of eyes to catch a flaw in its own logic" is a good demonstration of why we don't rely on any single check, including this one, working perfectly on the first attempt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's still open
&lt;/h2&gt;

&lt;p&gt;The heuristic checks — the ones that only warn instead of block — can still be evaded by an agent that's a bit more careful about not leaving the usual pattern-matching signals behind. We know this. We're not claiming the retry-tracking problem is now airtight; we're claiming the one path that was silently, structurally guaranteed to fail is no longer silent, and everything else stays exactly as uncertain as it honestly is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general shape of the problem
&lt;/h2&gt;

&lt;p&gt;If you're building anything where an AI agent's own report is part of what triggers a safety mechanism, this is worth checking for directly: does the trigger condition depend on evidence the agent could simply omit? If yes, that's not a hypothetical risk. Ours sat there, unnoticed, across four completed tasks, doing nothing, until an audit went looking for it on purpose.&lt;/p&gt;

&lt;p&gt;The fix isn't "make the agent more careful." It's "stop needing the agent to be careful about the parts that matter most" — anchor the check to something that exists independent of what the agent chooses to report.&lt;/p&gt;

&lt;p&gt;That's the whole idea behind Agateon: &lt;a href="https://github.com/randomgitsrc/agateon" rel="noopener noreferrer"&gt;github.com/randomgitsrc/agateon&lt;/a&gt;. The fix described here lives at &lt;a href="https://github.com/randomgitsrc/agateon/blob/main/agate/scripts/check-state-transition.py" rel="noopener noreferrer"&gt;&lt;code&gt;agate/scripts/check-state-transition.py&lt;/code&gt;&lt;/a&gt;, and the task that shipped it is &lt;a href="https://github.com/randomgitsrc/agateon/tree/main/agate-workspace/tasks/TAG0023-mechanism-checks" rel="noopener noreferrer"&gt;&lt;code&gt;TAG0023-mechanism-checks&lt;/code&gt;&lt;/a&gt; — full history included, nothing trimmed for the writeup.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>llm</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
