<?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: Agentik</title>
    <description>The latest articles on DEV Community by Agentik (@agentiknet).</description>
    <link>https://dev.to/agentiknet</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%2F4021451%2F95f66238-d258-4b44-80a9-624afdc31df3.png</url>
      <title>DEV Community: Agentik</title>
      <link>https://dev.to/agentiknet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agentiknet"/>
    <language>en</language>
    <item>
      <title>Your coding agent runs a shell on your machine. I audited mine.</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 21 Jul 2026 23:40:08 +0000</pubDate>
      <link>https://dev.to/agentiknet/your-coding-agent-runs-a-shell-on-your-machine-i-audited-mine-a1g</link>
      <guid>https://dev.to/agentiknet/your-coding-agent-runs-a-shell-on-your-machine-i-audited-mine-a1g</guid>
      <description>&lt;p&gt;A coding agent that can run &lt;code&gt;bash&lt;/code&gt; on your laptop is a remote shell on localhost. It has that threat model whether or not anyone designed for it — browser drive-bys, DNS rebinding, &lt;code&gt;curl | bash&lt;/code&gt;, the twenty years of localhost-daemon mistakes the web already made and wrote down.&lt;/p&gt;

&lt;p&gt;Last week wren.wtf published a teardown of opencode: &lt;a href="https://wren.wtf/shower-thoughts/stop-using-opencode/" rel="noopener noreferrer"&gt;&lt;strong&gt;Stop using opencode&lt;/strong&gt;&lt;/a&gt;. Read it in full. The headline was a real CVE — a default HTTP server with permissive CORS and an endpoint that ran arbitrary shell commands, so any website you visited could take the machine.&lt;/p&gt;

&lt;p&gt;I maintain &lt;strong&gt;agentproto&lt;/strong&gt;, an open runtime that does the same dangerous thing on purpose: a local daemon that lets agents run commands, read files, and open tunnels on the user's machine. So I read the teardown as a checklist and pointed it at my own code. Below is what I found, what I changed, and — the part that transfers — the methodology, so you can run it on whatever agent tool you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one idea
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Textual command filtering is thoughts and prayers." — the teardown&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That line is the whole game. Most agent tools try to make &lt;code&gt;bash&lt;/code&gt; safe by parsing the command string and blocking the bad ones. It doesn't work, and the article lists why: pipe to &lt;code&gt;bash&lt;/code&gt;, base64-decode, &lt;code&gt;env git&lt;/code&gt;, a heredoc, &lt;code&gt;python3 -c&lt;/code&gt;, an absolute path. Every one walks past a string filter.&lt;/p&gt;

&lt;p&gt;The fix is not a better regex. It's two boundaries a string never touches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What the process is allowed to do&lt;/strong&gt; — OS-level rights.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who is allowed to ask&lt;/strong&gt; — the network posture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything that follows is one of those two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run these four questions on your own tool first
&lt;/h2&gt;

&lt;p&gt;You can answer them in five minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does it bind a TCP port — to &lt;code&gt;127.0.0.1&lt;/code&gt;, or &lt;code&gt;0.0.0.0&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Can a random website &lt;code&gt;fetch()&lt;/code&gt; that port and read the response? Open devtools on any page and try.&lt;/li&gt;
&lt;li&gt;When it says "allow bash", what does the allow check — the command string, or the binary?&lt;/li&gt;
&lt;li&gt;Does it reach a remote model &lt;em&gt;before&lt;/em&gt; you chose one?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you don't like your answers, you're where I was.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I found, by threat class
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Threat&lt;/th&gt;
&lt;th&gt;The mistake&lt;/th&gt;
&lt;th&gt;The fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser drive-by RCE&lt;/td&gt;
&lt;td&gt;loopback-bypassed auth + reflected CORS on a command endpoint&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Origin&lt;/code&gt; gate, no bypass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-origin read exfil&lt;/td&gt;
&lt;td&gt;transcripts + a live event stream readable by any page&lt;/td&gt;
&lt;td&gt;same gate on read routes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS rebinding&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Host&lt;/code&gt; header never checked&lt;/td&gt;
&lt;td&gt;reject non-loopback &lt;code&gt;Host&lt;/code&gt; on the loopback path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supply chain&lt;/td&gt;
&lt;td&gt;`curl \&lt;/td&gt;
&lt;td&gt;bash` with no checksum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interpreter escape&lt;/td&gt;
&lt;td&gt;allowlisting &lt;code&gt;bash&lt;/code&gt;/&lt;code&gt;node&lt;/code&gt; = arbitrary read&lt;/td&gt;
&lt;td&gt;opt-in OS sandbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phoning home&lt;/td&gt;
&lt;td&gt;remote model by default&lt;/td&gt;
&lt;td&gt;loopback bind, user-chosen model, gated tunnel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The browser drive-by&lt;/strong&gt; was the sharpest. The endpoint that runs commands was gated by an auth check with a &lt;em&gt;loopback bypass&lt;/em&gt; — there to let local clients through without a token. But a browser's &lt;code&gt;fetch()&lt;/code&gt; to &lt;code&gt;127.0.0.1&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; loopback. With reflected-origin CORS, any page could drive it.&lt;/p&gt;

&lt;p&gt;The signal that separates a real local client from a drive-by is one header the page cannot forge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A browser always sends Origin on a cross-origin request.&lt;/span&gt;
&lt;span class="c1"&gt;// Native clients (the CLI, curl, an editor) send none.&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;allowlisted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A page at &lt;code&gt;evil.com&lt;/code&gt; sends &lt;code&gt;Origin: https://evil.com&lt;/code&gt;, which isn't allowlisted, and gets a 403 — from loopback, in the default config. Native clients send no &lt;code&gt;Origin&lt;/code&gt; and keep working untouched. One header closed the class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reading is exfiltration too.&lt;/strong&gt; The same daemon served conversation transcripts and a live event stream over &lt;code&gt;GET&lt;/code&gt; — readable cross-origin, no shell required. The Origin gate went on the read routes as well. If a route leaks state, gate it like it writes state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS rebinding&lt;/strong&gt; is the follow-up: a page rebinds &lt;code&gt;evil.com&lt;/code&gt; to &lt;code&gt;127.0.0.1&lt;/code&gt;, and now &lt;code&gt;Origin&lt;/code&gt; is only half the story. So the loopback path also validates the &lt;code&gt;Host&lt;/code&gt; header — a rebinding request still carries its own hostname, and anything that isn't a loopback &lt;code&gt;Host&lt;/code&gt; is refused.&lt;/p&gt;

&lt;h2&gt;
  
  
  The command-filter myth, and what replaces it
&lt;/h2&gt;

&lt;p&gt;agentproto never parsed command strings. It spawns with &lt;code&gt;shell: false&lt;/code&gt; and a verbatim &lt;code&gt;argv&lt;/code&gt;, against a default-deny allowlist of &lt;em&gt;binaries&lt;/em&gt;, not strings. That structurally kills every bypass in the teardown — there is no shell to inject into.&lt;/p&gt;

&lt;p&gt;The residual is honest: if you allowlist an interpreter — &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;node&lt;/code&gt;, &lt;code&gt;python3&lt;/code&gt; — you have allowlisted arbitrary code, and a working-directory anchor won't stop it reading &lt;code&gt;~/.ssh/id_rsa&lt;/code&gt;. The article's own recommendation is the right one: confine at the OS, not the string. So command execution gained an opt-in sandbox — macOS Seatbelt, Linux bubblewrap — that bounds what the process can read and write, and in strict mode whether it has a network at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prove the boundary; don't ship a guessed profile
&lt;/h2&gt;

&lt;p&gt;This is the part I hold hardest. A sandbox you haven't watched deny something is a comment, not a control.&lt;/p&gt;

&lt;p&gt;So before writing a line of the sandbox, I made it deny something in a real process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS Seatbelt&lt;/strong&gt; — a workspace read succeeds; &lt;code&gt;cat ~/.ssh/id_rsa&lt;/code&gt; returns &lt;code&gt;Operation not permitted&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux bubblewrap&lt;/strong&gt;, in a container — the workspace is bound and visible; &lt;code&gt;~/.ssh&lt;/code&gt; is never mounted, so the read is &lt;code&gt;ENOENT&lt;/code&gt;; with &lt;code&gt;--unshare-net&lt;/code&gt;, a socket connect returns &lt;code&gt;ENETUNREACH&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only then did the code get written — with the flags I had watched work — and a test that runs the real sandbox where it exists. The confinement ships with evidence, not a hope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not calling home
&lt;/h2&gt;

&lt;p&gt;The teardown's other thread: opencode connects to a remote model by default, pulls the default model's URL from a third party, and starts reading your files with a shell already open.&lt;/p&gt;

&lt;p&gt;The posture I hold agentproto to is the opposite, and it's boring on purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The daemon binds &lt;code&gt;127.0.0.1&lt;/code&gt;, not &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It contacts no remote model on its own. The model is whatever adapter &lt;em&gt;you&lt;/em&gt; point it at — local or hosted, your key, your call.&lt;/li&gt;
&lt;li&gt;Going public is one explicit verb, it mints a bearer token, and the tunnel is gated. A passthrough tunnel the daemon can't gate now says so, in its own result, out loud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Local-first is not a feature you add later. It's a default you refuse to trade away.&lt;/p&gt;

&lt;h2&gt;
  
  
  The methodology, in five lines
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treat an agent runtime as a remote shell on localhost. It is one.&lt;/li&gt;
&lt;li&gt;Deny by default. The allowlist gates &lt;em&gt;which&lt;/em&gt; binary; the OS gates &lt;em&gt;what it can touch&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Split "who can ask" from "what runs" — a page can't forge &lt;code&gt;Origin&lt;/code&gt;, and can't forge a loopback &lt;code&gt;Host&lt;/code&gt;. Use that.&lt;/li&gt;
&lt;li&gt;Reading is exfiltration. Gate reads like you gate writes.&lt;/li&gt;
&lt;li&gt;Prove the boundary in a real process before you trust it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where it landed
&lt;/h2&gt;

&lt;p&gt;Eight pull requests, all public. Every finding from the teardown is closed, and both sandbox backends were validated in real processes before they shipped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/agentproto/ts/pull/570" rel="noopener noreferrer"&gt;#570&lt;/a&gt; — gate &lt;code&gt;/mcp&lt;/code&gt; against the browser drive-by&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/agentproto/ts/pull/571" rel="noopener noreferrer"&gt;#571&lt;/a&gt; — block cross-origin reads, tighten CORS, redact tokens from logs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/agentproto/ts/pull/572" rel="noopener noreferrer"&gt;#572&lt;/a&gt; — refuse unverified &lt;code&gt;curl | bash&lt;/code&gt; installers in non-interactive contexts&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/agentproto/ts/pull/573" rel="noopener noreferrer"&gt;#573&lt;/a&gt; — harden the loopback signal, flag unauthenticated tunnels&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/agentproto/ts/pull/578" rel="noopener noreferrer"&gt;#578&lt;/a&gt; + &lt;a href="https://github.com/agentproto/ts/pull/581" rel="noopener noreferrer"&gt;#581&lt;/a&gt; + &lt;a href="https://github.com/agentproto/ts/pull/585" rel="noopener noreferrer"&gt;#585&lt;/a&gt; — the interpreter footgun: warn, then confine (macOS Seatbelt, Linux bubblewrap)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/agentproto/ts/pull/582" rel="noopener noreferrer"&gt;#582&lt;/a&gt; — the DNS-rebinding &lt;code&gt;Host&lt;/code&gt; guard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one thing the runtime already did right — &lt;code&gt;argv&lt;/code&gt; and a binary allowlist instead of string filtering — is the reason the worst class never applied.&lt;/p&gt;

&lt;p&gt;Read &lt;a href="https://wren.wtf/shower-thoughts/stop-using-opencode/" rel="noopener noreferrer"&gt;the original teardown&lt;/a&gt;. Then run the four questions against whatever agent runs commands on your machine. You'll find something.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
    </item>
    <item>
      <title>agentproto 0.8.0 — the daemon makes decisions so you don't have to</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Sun, 19 Jul 2026 14:14:50 +0000</pubDate>
      <link>https://dev.to/agentiknet/agentproto-080-the-daemon-makes-decisions-so-you-dont-have-to-1fop</link>
      <guid>https://dev.to/agentiknet/agentproto-080-the-daemon-makes-decisions-so-you-dont-have-to-1fop</guid>
      <description>&lt;p&gt;0.8.0 released 2026-07-17 · npm i -g @agentproto/cli · source · Apache-2.0&lt;/p&gt;

&lt;p&gt;If you've been running an agent daemon you've hit the wall. The agent finishes&lt;br&gt;
its work, runs the tests, everything passes — and then it stops. Not because it's&lt;br&gt;
done. Because it's waiting for you to click "Approve."&lt;/p&gt;

&lt;p&gt;0.8 is about tearing that wall down.&lt;/p&gt;

&lt;p&gt;No breaking changes in this one. Upgrade and the daemon gets smarter; your&lt;br&gt;
existing config stays intact.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;permissions watch&lt;/code&gt;: your agent stopped asking permission
&lt;/h2&gt;

&lt;p&gt;When an agent pauses mid-turn to ask "should I run this command?", the daemon&lt;br&gt;
parks it in a durable inbox. Until 0.8, someone — you, or a supervising agent —&lt;br&gt;
had to answer explicitly. That's the right default. But after the hundredth&lt;br&gt;
&lt;code&gt;npm install&lt;/code&gt; you've approved in a row, it stops being safety and starts being&lt;br&gt;
noise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agentproto permissions watch &lt;span class="nt"&gt;--rule&lt;/span&gt; &lt;span class="s1"&gt;'command:npm:*:allow'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                             &lt;span class="nt"&gt;--rule&lt;/span&gt; &lt;span class="s1"&gt;'command:git:status,diff,log:allow'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A watch is a persistent rule that auto-resolves matching permission requests&lt;br&gt;
before they ever surface in the inbox. The agent pauses for exactly as long as it&lt;br&gt;
takes the daemon to check the rule — sub-millisecond. You never see the prompt.&lt;/p&gt;

&lt;p&gt;The rule grammar is &lt;code&gt;kind:adapter:action:decision&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow all git reads, deny force-pushes
&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;:&lt;span class="n"&gt;git&lt;/span&gt;:&lt;span class="n"&gt;status&lt;/span&gt;,&lt;span class="n"&gt;diff&lt;/span&gt;,&lt;span class="n"&gt;log&lt;/span&gt;,&lt;span class="n"&gt;show&lt;/span&gt;,&lt;span class="n"&gt;branch&lt;/span&gt;:&lt;span class="n"&gt;allow&lt;/span&gt;
&lt;span class="n"&gt;command&lt;/span&gt;:&lt;span class="n"&gt;git&lt;/span&gt;:&lt;span class="n"&gt;push&lt;/span&gt;.*&lt;span class="n"&gt;force&lt;/span&gt;:&lt;span class="n"&gt;deny&lt;/span&gt;

&lt;span class="c"&gt;# Allow file writes in the project tree (but nowhere else)
&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;:**/&lt;span class="n"&gt;src&lt;/span&gt;/**:&lt;span class="n"&gt;allow&lt;/span&gt;
&lt;span class="n"&gt;write&lt;/span&gt;:/&lt;span class="n"&gt;etc&lt;/span&gt;/**:&lt;span class="n"&gt;deny&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A watch is a live daemon session you start once and forget. It survives agent&lt;br&gt;
restarts, adapter swaps, model changes — it lives at the daemon layer, not the&lt;br&gt;
agent layer. &lt;code&gt;agentproto permissions watch --list&lt;/code&gt; shows what's active;&lt;br&gt;
&lt;code&gt;--remove &amp;lt;id&amp;gt;&lt;/code&gt; kills one.&lt;/p&gt;

&lt;p&gt;This is the feature that makes the permission-hold inbox from 0.6 actually&lt;br&gt;
usable at scale. Before, answering every prompt yourself was exhausting.&lt;br&gt;
Auto-approving everything was reckless. &lt;code&gt;permissions watch&lt;/code&gt; gives you the middle&lt;br&gt;
ground: you decide the policy once, the daemon enforces it forever.&lt;/p&gt;
&lt;h2&gt;
  
  
  Worktree isolation as policy, not convention
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agent_start&lt;/code&gt; has accepted &lt;code&gt;worktree: true&lt;/code&gt; since 0.6. It was opt-in — if you&lt;br&gt;
remembered to set it, your parallel agents couldn't collide on the working tree.&lt;br&gt;
If you forgot, they could.&lt;/p&gt;

&lt;p&gt;0.8 makes it a daemon-level policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"defaults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"worktrees"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isolation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"always"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;always&lt;/code&gt; means every root spawn gets its own worktree, no matter what the caller&lt;br&gt;
passes. A spawn that would have landed directly in your main working tree now&lt;br&gt;
lands in a fresh worktree instead. The caller can't opt out — that's the point of&lt;br&gt;
a policy.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;never&lt;/code&gt; means the opposite: worktree isolation is disabled daemon-wide, and a&lt;br&gt;
spawn that requests it is rejected rather than silently ignored. (A CI box with&lt;br&gt;
ephemeral runners has no worktree to isolate.)&lt;/p&gt;

&lt;p&gt;The default is &lt;code&gt;permissive&lt;/code&gt; — today's behaviour — so nobody's setup changes&lt;br&gt;
unless they choose to tighten it.&lt;/p&gt;

&lt;p&gt;This is the pattern: take a thing that required discipline and turn it into a&lt;br&gt;
thing that's enforced. The daemon's job isn't to suggest best practices. It's to&lt;br&gt;
make the unsafe path harder than the safe one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your CI can speak agentproto now
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agentproto/agentproto-run@v0&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pnpm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fix&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;every&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;failure,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;PR"&lt;/span&gt;
    &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-code&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-sonnet-5&lt;/span&gt;
    &lt;span class="na"&gt;worktree&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;gate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pnpm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;agentproto/agentproto-run&lt;/code&gt; is a composite GitHub Action that boots the daemon,&lt;br&gt;
spawns the agent session, waits for it to finish, runs the gate, and reports the&lt;br&gt;
result. It's the same path &lt;code&gt;agentproto run&lt;/code&gt; takes locally, wrapped in a CI step.&lt;/p&gt;

&lt;p&gt;Underneath it's the generic &lt;code&gt;agentproto-run&lt;/code&gt; lane — the same one the review-fix&lt;br&gt;
loop uses. Any adapter, any model, any gate, in CI or on your machine. The&lt;br&gt;
composite action is just the GitHub-shaped packaging of it.&lt;/p&gt;

&lt;p&gt;Why this matters: until now, putting an agent in CI meant wiring up your own&lt;br&gt;
Dockerfile with the daemon, the adapter, the credentials, the gate script, and&lt;br&gt;
the exit-code plumbing. &lt;code&gt;agentproto-run&lt;/code&gt; collapses that into one step. It's what&lt;br&gt;
lets the review-fix-demo from 0.7 reuse a session across turns on the same CI&lt;br&gt;
lane — the session stays alive, the lane re-prompts it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The LLM endpoint learned to say "try again"
&lt;/h2&gt;

&lt;p&gt;A stripped model — one whose safety layer removes the entire response — returns&lt;br&gt;
an empty completion. To the caller it looks exactly like a network timeout:&lt;br&gt;
nothing came back, retry.&lt;/p&gt;

&lt;p&gt;0.8's LLM endpoint now replays the turn once when a provider returns zero&lt;br&gt;
content. If the second attempt also comes back empty, it surfaces the emptiness&lt;br&gt;
explicitly rather than silently dropping it. The caller gets a real error instead&lt;br&gt;
of a mystifying hang.&lt;/p&gt;

&lt;p&gt;Also in this release: the Requesty gateway is a first-class preset. Route your&lt;br&gt;
calls through it the same way you route through OpenRouter or Moonshot —&lt;br&gt;
&lt;code&gt;agentproto providers set requesty $REQUESTY_API_KEY&lt;/code&gt; and it's live. The&lt;br&gt;
transparent pack is committed in the repo, so the route is auditable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills are now built, not hand-copied
&lt;/h2&gt;

&lt;p&gt;The skill directory in &lt;code&gt;~/.agentproto/skills/&lt;/code&gt; used to be a hand-maintained copy&lt;br&gt;
of what lived in the monorepo's &lt;code&gt;packages/&lt;/code&gt;. That meant the two drifted. 0.8&lt;br&gt;
adds a build step — &lt;code&gt;pnpm build&lt;/code&gt; in the skill-pack packages — that produces the&lt;br&gt;
directory from source. Hand-copied &lt;code&gt;.skills/&lt;/code&gt; is retired.&lt;/p&gt;

&lt;p&gt;This is infrastructure, not a feature you'll notice directly. But it's the&lt;br&gt;
reason the &lt;code&gt;permissions watch&lt;/code&gt; skill ships on day one instead of waiting for&lt;br&gt;
someone to remember to copy it over. Every package under &lt;code&gt;packages/&lt;/code&gt; that&lt;br&gt;
declares a skill manifest is now part of the build graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  The getting-started path works end to end
&lt;/h2&gt;

&lt;p&gt;0.8 rewrites the quickstart as one verified path: install, serve, spawn, prompt,&lt;br&gt;
read output. Every step was walked by a fresh machine with no prior agentproto&lt;br&gt;
state. If friction was found, it was removed or documented.&lt;/p&gt;

&lt;p&gt;The old quickstart assumed you already knew what an MCP server was and why you'd&lt;br&gt;
want one. The new one starts from "you have a coding agent, here's what happens&lt;br&gt;
when you give it a supervisor." That's the right frame for someone who hasn't&lt;br&gt;
been living in this repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Also in the box
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Codex model selection fixed.&lt;/strong&gt; Codex spawns now receive the model as a CLI
argument instead of ACP session config — the old path was silently ignored,
and every Codex session ran on the default model regardless of what you asked
for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-credential users get a helpful message.&lt;/strong&gt; If you don't have credentials
configured for an adapter, the daemon tells you &lt;em&gt;how&lt;/em&gt; to configure them instead
of telling you to go buy a subscription. Two very different things.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider-key env aliases.&lt;/strong&gt; &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt; is now injected alongside
&lt;code&gt;GEMINI_API_KEY&lt;/code&gt;, so providers that expect one but not the other don't fail
silently. The mapping lives in the catalog, not in every adapter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worktree NUL-byte bug fixed.&lt;/strong&gt; A literal NUL in a worktree status file made
&lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, and &lt;code&gt;file&lt;/code&gt; all treat it as binary. The fix isn't glamorous, but
a worktree that can't be &lt;code&gt;ls&lt;/code&gt;-ed is worse than no worktree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release notes don't overwrite themselves.&lt;/strong&gt; A same-day second batch of
releases no longer wipes the first one's notes. Small thing. Cost me a
changelog entry once.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The arc from 0.5 to 0.8
&lt;/h2&gt;

&lt;p&gt;Four releases in two weeks. Look at the shape:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Release&lt;/th&gt;
&lt;th&gt;Theme&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;Credentials, sandboxes, cost accounting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.6&lt;/td&gt;
&lt;td&gt;Pairing, E2E encryption, permission inbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.7&lt;/td&gt;
&lt;td&gt;Extension polish, session story, the things 0.6 got slightly wrong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.8&lt;/td&gt;
&lt;td&gt;Autonomy — the daemon resolves permission, isolates worktrees, and runs in CI without a human in the loop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;0.5 was "the daemon knows who you are." 0.6 was "the daemon reaches other&lt;br&gt;
machines securely." 0.8 is "the daemon makes decisions so you don't have to."&lt;/p&gt;

&lt;p&gt;The direction is intentional. A supervisor that needs supervision isn't one.&lt;br&gt;
Every release moves one more decision from the human to the daemon — not by&lt;br&gt;
guessing, but by enforcing a policy you declared once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrading
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @agentproto/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No breaking changes from 0.7. &lt;code&gt;permissions watch&lt;/code&gt; and worktree isolation policies&lt;br&gt;
are additive — they don't touch existing behaviour unless you activate them.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Previously: &lt;a href="https://dev.to/agentiknet/agentproto-06-07-pair-two-machines-through-a-broker-that-cant-read-your-traffic-3khf"&gt;0.6 + 0.7 — pair two machines through a broker that can't read your traffic&lt;/a&gt; · &lt;a href="https://dev.to/agentiknet/agentproto-050-credentials-sandboxes-and-cost-accounting-that-refuses-to-lie-53e7"&gt;0.5.0 — credentials, sandboxes, and cost accounting that refuses to lie&lt;/a&gt; · &lt;a href="https://dev.to/agentiknet/agentproto-040-the-daemon-grows-up-into-a-supervision-surface-37ig"&gt;0.4.0 — the daemon grows up into a supervision surface&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;agentproto is an open-source (Apache-2.0) orchestration layer that runs on top&lt;br&gt;
of your existing stack — it doesn't replace your coding agent, it supervises it.&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
    <item>
      <title>agentproto 0.6 + 0.7 — pair two machines through a broker that can't read your traffic</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Fri, 17 Jul 2026 03:07:03 +0000</pubDate>
      <link>https://dev.to/agentiknet/agentproto-06-07-pair-two-machines-through-a-broker-that-cant-read-your-traffic-3khf</link>
      <guid>https://dev.to/agentiknet/agentproto-06-07-pair-two-machines-through-a-broker-that-cant-read-your-traffic-3khf</guid>
      <description>&lt;p&gt;&lt;em&gt;0.6.0 released 2026-07-16, 0.7.0 on 2026-07-17 · &lt;code&gt;npm i -g @agentproto/cli&lt;/code&gt; · &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt; · Apache-2.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your agent daemon runs on the machine with your credentials, your repo, and your&lt;br&gt;
shell. Sooner or later you want to reach it from somewhere else — a laptop, a&lt;br&gt;
phone, a CI box. That means a relay in the middle. And a relay in the middle is&lt;br&gt;
a thing you have to trust.&lt;/p&gt;

&lt;p&gt;0.6 is mostly about not having to.&lt;/p&gt;

&lt;p&gt;Two &lt;strong&gt;breaking changes&lt;/strong&gt; in here, so read the migration note at the bottom before&lt;br&gt;
you upgrade.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pairing: the broker is deliberately stupid
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agentproto pair offer&lt;/code&gt; mints a one-time token and prints an &lt;code&gt;agentproto://pair?…&lt;/code&gt;&lt;br&gt;
URL. On the other machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# On the daemon machine&lt;/span&gt;
agentproto pair offer
&lt;span class="c"&gt;# → agentproto://pair?t=&amp;lt;token&amp;gt;&amp;amp;rv=&amp;lt;url&amp;gt;&amp;amp;fp=&amp;lt;fingerprint&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# On the client machine&lt;/span&gt;
agentproto pair accept &lt;span class="s2"&gt;"agentproto://pair?..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That triggers a &lt;code&gt;pair/v1&lt;/code&gt; ECDH handshake over the rendezvous broker, after which&lt;br&gt;
every byte is wrapped in an AEAD channel. The interesting part is what the broker&lt;br&gt;
is &lt;em&gt;allowed&lt;/em&gt; to be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The rendezvous is a dumb WebSocket splicer. It matches two sockets on the same&lt;br&gt;
one-time token, pipes bytes verbatim both ways, and &lt;strong&gt;parses nothing.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It learns the token, the IPs, message sizes, and timing. It cannot read content&lt;br&gt;
and it cannot forge it. That's not a promise about our operational discipline —&lt;br&gt;
it's a property of the protocol. The distinction matters, because "trust us with&lt;br&gt;
your plaintext, we're careful" is exactly the claim nobody should accept, ours&lt;br&gt;
included.&lt;/p&gt;

&lt;p&gt;After first pairing, the daemon auto-reconnects using &lt;strong&gt;day-scoped epoch routing&lt;br&gt;
tokens&lt;/strong&gt; derived from a shared &lt;code&gt;pairRoot&lt;/code&gt; secret — &lt;code&gt;HKDF(pairRoot, "rv-route"‖epoch)&lt;/code&gt;.&lt;br&gt;
It parks on both the current and previous epoch, so a client whose clock straddles&lt;br&gt;
midnight still finds it. (A small thing that would otherwise be a mystifying&lt;br&gt;
once-a-day bug.)&lt;/p&gt;

&lt;p&gt;Revoke with &lt;code&gt;agentproto pair rm &amp;lt;fingerprint&amp;gt;&lt;/code&gt; — the daemon stops parking on&lt;br&gt;
those tokens immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't want our broker?&lt;/strong&gt; Self-host it. A &lt;code&gt;Dockerfile&lt;/code&gt; ships with the release —&lt;br&gt;
non-root, &lt;code&gt;RENDEZVOUS_*&lt;/code&gt; env config, &lt;code&gt;/healthz&lt;/code&gt; probe. Offers default to the&lt;br&gt;
hosted rendezvous when nothing else is configured, and &lt;code&gt;pair offer&lt;/code&gt; &lt;strong&gt;says so&lt;br&gt;
explicitly&lt;/strong&gt; rather than defaulting silently.&lt;/p&gt;
&lt;h3&gt;
  
  
  The same treatment for &lt;code&gt;serve --connect&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Pairing isn't the only place you hand bytes to a middleman. &lt;code&gt;agentproto serve&lt;br&gt;
--connect&lt;/code&gt; pushes your daemon out through a tunnel, and that tunnel host has&lt;br&gt;
historically seen plaintext. 0.6 adds an opt-in E2E handshake — &lt;code&gt;tunnel-e2e/v1&lt;/code&gt; —&lt;br&gt;
so it doesn't have to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tunnel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"e2e"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's token-authenticated rather than PKI-based: the same shared secret that&lt;br&gt;
authenticates the tunnel also keys the channel, which is why there's no&lt;br&gt;
certificate story to manage. It's &lt;strong&gt;opt-in on purpose&lt;/strong&gt;, and the daemon refuses to&lt;br&gt;
silently fall back to plaintext against a host that doesn't advertise e2e — if you&lt;br&gt;
asked for encryption and can't have it, you get an error, not a quiet downgrade.&lt;br&gt;
That's the whole reason to have the flag: a security property you can't verify&lt;br&gt;
isn't one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Breaking: Claude Code spawns now demand explicit credentials
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@agentproto/adapter-claude-code@1.0.0&lt;/code&gt; and &lt;code&gt;@agentproto/driver-agent-cli@1.0.0&lt;/code&gt;&lt;br&gt;
are &lt;strong&gt;major bumps&lt;/strong&gt;, and this is why.&lt;/p&gt;

&lt;p&gt;Spawning a Claude Code session used to inherit whatever the daemon's launching&lt;br&gt;
shell happened to export. Which means a stray &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; in your&lt;br&gt;
environment could silently bill your org's API credits when you thought you were&lt;br&gt;
on your Max plan — and you'd find out on the invoice.&lt;/p&gt;

&lt;p&gt;Now the runtime resolves one of two modes at spawn time and applies it&lt;br&gt;
mechanically:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;mode&lt;/th&gt;
&lt;th&gt;sets&lt;/th&gt;
&lt;th&gt;scrubs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;subscription&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CLAUDE_CODE_OAUTH_TOKEN&lt;/code&gt; (via &lt;code&gt;claude setup-token&lt;/code&gt;) — bills your Max/Pro plan&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt;, and the Bedrock/Vertex redirect toggles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;api-key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; from the provider store&lt;/td&gt;
&lt;td&gt;the subscription credential&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scrubbing &lt;code&gt;CLAUDE_CODE_USE_BEDROCK&lt;/code&gt; / &lt;code&gt;CLAUDE_CODE_USE_VERTEX&lt;/code&gt; in subscription&lt;br&gt;
mode is the quiet hero: an ambient env var could otherwise reroute a native spawn&lt;br&gt;
to Bedrock without a word.&lt;/p&gt;

&lt;p&gt;Configure once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"defaults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"adapters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"claude-code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subscription"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;bearer-token&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or override per-spawn via &lt;code&gt;agent_start.auth&lt;/code&gt;. The same resolver now backs&lt;br&gt;
&lt;code&gt;adapter-codex&lt;/code&gt;, &lt;code&gt;adapter-claude-sdk&lt;/code&gt;, and &lt;code&gt;adapter-hermes&lt;/code&gt; — &lt;strong&gt;every&lt;/strong&gt; adapter&lt;br&gt;
uses catalog-sourced billing credentials instead of ambient env inference.&lt;/p&gt;

&lt;p&gt;Keys you set with &lt;code&gt;agentproto providers set &amp;lt;slug&amp;gt; &amp;lt;key&amp;gt;&lt;/code&gt; get injected into the&lt;br&gt;
child process at spawn time, never into your shell. The resolver looks up the&lt;br&gt;
adapter's declared provider in the catalog, maps it to an env var name&lt;br&gt;
(&lt;code&gt;providerEnvVar("anthropic")&lt;/code&gt; → &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;), and sets it there and only&lt;br&gt;
there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Worktrees grew a lifecycle — and a gc that learned restraint the hard way
&lt;/h2&gt;

&lt;p&gt;If you run agents in parallel you have too many worktrees. I certainly do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agentproto worktree new              &lt;span class="c"&gt;# provisions under worktrees.root + a provenance marker&lt;/span&gt;
agentproto worktree &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;--status&lt;/span&gt;      &lt;span class="c"&gt;# classify everything&lt;/span&gt;
agentproto worktree gc               &lt;span class="c"&gt;# dry-run plan&lt;/span&gt;
agentproto worktree gc &lt;span class="nt"&gt;--apply&lt;/span&gt;       &lt;span class="c"&gt;# execute it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ls --status&lt;/code&gt; classifies each worktree on three independent axes: &lt;strong&gt;tree&lt;/strong&gt;&lt;br&gt;
(&lt;code&gt;clean&lt;/code&gt;/&lt;code&gt;dirty&lt;/code&gt;), &lt;strong&gt;integration&lt;/strong&gt; (eleven states — &lt;code&gt;fresh&lt;/code&gt;, &lt;code&gt;merged&lt;/code&gt;, &lt;code&gt;open&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;partial&lt;/code&gt;, &lt;code&gt;pushed-no-pr&lt;/code&gt;, &lt;code&gt;unpushed&lt;/code&gt;, &lt;code&gt;local-only&lt;/code&gt;, &lt;code&gt;gone-unexplained&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;diverged&lt;/code&gt;, &lt;code&gt;detached&lt;/code&gt;, &lt;code&gt;unknown&lt;/code&gt;), and &lt;strong&gt;liveness&lt;/strong&gt; (&lt;code&gt;idle&lt;/code&gt;, &lt;code&gt;sessions&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;daemon-unreachable&lt;/code&gt;). The integration axis is squash-merge-proof — it checks SHA&lt;br&gt;
containment against &lt;code&gt;origin/main&lt;/code&gt; and caches immutable forge verdicts (a merged PR&lt;br&gt;
stays merged), so it stays honest offline without needing a registry. It never&lt;br&gt;
guesses: a cache miss while offline is &lt;code&gt;unknown&lt;/code&gt;, full stop.&lt;/p&gt;
&lt;h3&gt;
  
  
  The gc ate a live worktree on July 15th
&lt;/h3&gt;

&lt;p&gt;I'd rather tell you this than have you find it.&lt;/p&gt;

&lt;p&gt;The first cut of &lt;code&gt;gc&lt;/code&gt; had a rule that sounded safe: dirty worktrees get&lt;br&gt;
&lt;em&gt;salvaged&lt;/em&gt; (snapshotted to &lt;code&gt;~/.agentproto/worktree-salvage/&lt;/code&gt;) rather than&lt;br&gt;
reclaimed, so nothing uncommitted is ever simply deleted. On 2026-07-15 that rule&lt;br&gt;
destroyed a live worktree out from under a running agent. The mechanism: a branch&lt;br&gt;
with &lt;strong&gt;zero commits of its own&lt;/strong&gt; classified as &lt;code&gt;fresh&lt;/code&gt;, &lt;code&gt;fresh&lt;/code&gt; was treated as&lt;br&gt;
license to salvage-then-remove, and the agent's uncommitted work went with it.&lt;br&gt;
The snapshot existed — but the worktree the agent was actively writing to did not.&lt;/p&gt;

&lt;p&gt;The bug wasn't the salvage step. It was letting an axis &lt;em&gt;prove less than the code&lt;br&gt;
assumed it proved.&lt;/em&gt; &lt;code&gt;fresh&lt;/code&gt; cannot distinguish "never had commits" from "real&lt;br&gt;
commits, fast-forwarded into main." Both are consistent with &lt;code&gt;fresh&lt;/code&gt;, and only one&lt;br&gt;
of them is safe to destroy.&lt;/p&gt;

&lt;p&gt;The rule in 0.6 is narrower, and the narrowness is the point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Only &lt;code&gt;merged&lt;/code&gt; — always forge-confirmed — ever licenses destroying dirty,
uncommitted work.&lt;/strong&gt; &lt;code&gt;fresh&lt;/code&gt; never does, clean or not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A &lt;code&gt;merged ∧ dirty&lt;/code&gt; worktree written to recently holds anyway&lt;/strong&gt;, inside a
recent-write window. Someone is probably still in there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reclaim&lt;/strong&gt; (clean trees only) needs &lt;code&gt;tree=clean ∧ integration ∈ {merged, fresh}
∧ liveness ∈ {idle, daemon-unreachable}&lt;/code&gt;. &lt;code&gt;fresh&lt;/code&gt; is fine &lt;em&gt;here&lt;/em&gt; precisely
because a clean tree has nothing to lose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;gc&lt;/code&gt; re-classifies every worktree from scratch immediately before touching
it.&lt;/strong&gt; A plan you printed ten minutes ago cannot cause a deletion now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hard guarantee against losing work was never the liveness probe — it's git's&lt;br&gt;
own refusal to remove a dirty worktree without &lt;code&gt;--force&lt;/code&gt;. The probe is an&lt;br&gt;
optimization on top. We'd inverted that, and it cost a worktree.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;worktree rm&lt;/code&gt; / &lt;code&gt;archive&lt;/code&gt; replace the old blanket &lt;code&gt;--force&lt;/code&gt; with explicit&lt;br&gt;
&lt;code&gt;--discard-untracked&lt;/code&gt; / &lt;code&gt;--discard-modified&lt;/code&gt;. "Force" was one flag meaning two&lt;br&gt;
very different kinds of destruction; now you have to name which one you meant.&lt;/p&gt;
&lt;h2&gt;
  
  
  Your agent stopped guessing about permission
&lt;/h2&gt;

&lt;p&gt;When an agent pauses mid-turn to ask permission — Claude Code's&lt;br&gt;
&lt;code&gt;requestPermission&lt;/code&gt; before a shell command — the daemon now parks it in a durable&lt;br&gt;
inbox instead of timing out or auto-approving.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agentproto permissions &lt;span class="nb"&gt;ls&lt;/span&gt;              &lt;span class="c"&gt;# pending holds across all sessions&lt;/span&gt;
agentproto permissions approve &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
agentproto permissions deny &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same three operations exist as MCP tools, so a supervising agent can answer&lt;br&gt;
programmatically. &lt;code&gt;SessionDescriptor&lt;/code&gt; gains &lt;code&gt;blockedOn: "subagent" | "command" | null&lt;/code&gt;,&lt;br&gt;
so a UI can finally say &lt;em&gt;why&lt;/em&gt; a session looks stuck instead of showing a spinner.&lt;br&gt;
(The case for gating writes rather than blanket-approving: &lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;&lt;code&gt;--approve-all&lt;/code&gt; is how your agent ships the dangerous one&lt;/a&gt;.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Also in the box
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;xAI / Grok&lt;/strong&gt; is a first-class preset — &lt;code&gt;grok-4.5&lt;/code&gt;, &lt;code&gt;grok-4.3&lt;/code&gt;, &lt;code&gt;grok-4.20&lt;/code&gt;,
&lt;code&gt;grok-build-0.1&lt;/code&gt; registered in the catalog:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  agentproto providers &lt;span class="nb"&gt;set &lt;/span&gt;xai &lt;span class="nv"&gt;$XAI_API_KEY&lt;/span&gt;
  agentproto run &lt;span class="nt"&gt;--adapter&lt;/span&gt; claude-sdk &lt;span class="nt"&gt;--mode&lt;/span&gt; xai &lt;span class="nt"&gt;--model&lt;/span&gt; grok-4.5 &lt;span class="s2"&gt;"explain this codebase"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Route-aware model identity&lt;/strong&gt; — the catalog now separates a model's &lt;em&gt;product
identity&lt;/em&gt; from its &lt;em&gt;serving route&lt;/em&gt;: &lt;code&gt;openai/gpt-4o&lt;/code&gt; vs &lt;code&gt;openai/gpt-4o@openrouter&lt;/code&gt;.
Bare legacy ids still work. Custom routes register via &lt;code&gt;registerCustomRoute&lt;/code&gt; —
and only the env var &lt;em&gt;name&lt;/em&gt; lives in config, never the value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fault-tolerant fan-out&lt;/strong&gt; — &lt;code&gt;MapStep&lt;/code&gt;/&lt;code&gt;PipelineStep&lt;/code&gt; take &lt;code&gt;onError: "collect"&lt;/code&gt;,
so every item completes and you get a &lt;code&gt;Promise.allSettled&lt;/code&gt;-shaped result instead
of losing the batch to the first throw.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto policy&lt;/code&gt;&lt;/strong&gt; — completion policies are finally a CLI verb:
&lt;code&gt;attach&lt;/code&gt; / &lt;code&gt;status&lt;/code&gt; / &lt;code&gt;wait&lt;/code&gt; / &lt;code&gt;ls&lt;/code&gt; / &lt;code&gt;cancel&lt;/code&gt;. The engine existed for a while;
it had no command, which meant in practice nobody attached one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto acp&lt;/code&gt;&lt;/strong&gt; — any ACP-speaking agent, not just our adapter family, can
be registered in &lt;code&gt;config.json&lt;/code&gt; and driven directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSE with replay&lt;/strong&gt; — &lt;code&gt;GET /sessions/:id/events/stream&lt;/code&gt; replays stored events
then hands off to live delivery. Reconnect mid-session and you miss nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto.json&lt;/code&gt;&lt;/strong&gt; — declare &lt;code&gt;setup&lt;/code&gt;/&lt;code&gt;teardown&lt;/code&gt; hooks, supervised services,
and a localhost reverse proxy per worktree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto run --output-schema&lt;/code&gt;&lt;/strong&gt; — validate a run's output against a JSON
Schema and fail the command if it doesn't conform. For CI that eats agent output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto sessions story &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/strong&gt; — a readable narrative of what a session
actually did, collapsing noisy low-level events into steps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto run --model&lt;/code&gt; / &lt;code&gt;--effort&lt;/code&gt;&lt;/strong&gt; — pick the model and reasoning effort
per run, with a friendly error on unknown flags instead of a stack trace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;daemon.authToken&lt;/code&gt; + &lt;code&gt;--auth-token&lt;/code&gt;&lt;/strong&gt; — a persistent gateway bearer token, so
the daemon isn't re-authenticating from scratch every restart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terminalPresets&lt;/code&gt;&lt;/strong&gt; in &lt;code&gt;config.json&lt;/code&gt; — name a terminal setup once, reuse it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@agentproto/adapter-pi&lt;/code&gt;&lt;/strong&gt; — an AIP-45 proprietary-arm adapter for
earendil-works/pi. The adapter family keeps growing without the core knowing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;claude-opus-4-8&lt;/code&gt;, &lt;code&gt;claude-sonnet-5&lt;/code&gt;, &lt;code&gt;claude-fable-5&lt;/code&gt;&lt;/strong&gt; registered in the
pricing catalog — and &lt;em&gt;runnable&lt;/em&gt; is now decoupled from &lt;em&gt;priced&lt;/em&gt;, so a model
missing pricing data still runs (it reports &lt;code&gt;no-pricing&lt;/code&gt;, it doesn't guess).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache-2.0.&lt;/strong&gt; Every package relicensed from MIT — 92 packages, zero MIT left.
No API changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The VS Code extension stopped lying to you
&lt;/h2&gt;

&lt;p&gt;The bigger story across these two releases isn't in the CLI at all. The&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=agentproto.agentproto-vscode" rel="noopener noreferrer"&gt;VS Code extension&lt;/a&gt;&lt;br&gt;
went &lt;code&gt;0.0.1&lt;/code&gt; → &lt;code&gt;0.1.0&lt;/code&gt; (in 0.6) → &lt;code&gt;0.1.1&lt;/code&gt; (in 0.7), which is the arc from&lt;br&gt;
"technically exists" to "the thing I actually watch my agents in."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0.1.0&lt;/strong&gt; gave it a spine: structured conversation rendering instead of a wall of&lt;br&gt;
raw events, a sessions tree with filters/search/grouping, workspace autodetect on&lt;br&gt;
spawn, session restart over MCP, and &lt;code&gt;agentproto.openTerminal&lt;/code&gt; — a real&lt;br&gt;
Pseudoterminal mirror for PTY and agent-cli sessions, so you can watch a session&lt;br&gt;
in an actual terminal rather than a simulation of one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0.1.1&lt;/strong&gt; is where it stopped misrepresenting state, which is the part I care&lt;br&gt;
about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stop was painted as a crash.&lt;/strong&gt; You'd stop a session deliberately and the UI
would show you the same thing it shows when an agent dies. Tree icons and the
status bar now run on an &lt;em&gt;activity&lt;/em&gt; axis rather than a lifecycle one — a stopped
session reads as stopped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A sub-agent reaped after finishing read as "stopped" instead of "complete."&lt;/strong&gt;
It had done its job. The UI said otherwise.&lt;/li&gt;
&lt;li&gt;The sidebar auto-refreshes on a clock, unread sessions carry a read-receipt dot,
and a spawn shows up as an optimistic row instead of appearing several seconds
late.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of those first two are the same bug in different clothes, and it's the bug&lt;br&gt;
this whole project exists to fight: &lt;strong&gt;the interface asserting something about your&lt;br&gt;
agents that isn't true.&lt;/strong&gt; A panel that calls a clean stop a crash trains you to&lt;br&gt;
ignore it, and an ignored panel is worse than no panel — you've paid for the pixels&lt;br&gt;
and gained nothing.&lt;/p&gt;

&lt;p&gt;The composer also grew up in this window: a stop button, prompt history on ↑/↓,&lt;br&gt;
drag-and-drop, &lt;code&gt;@file&lt;/code&gt; mentions, attachment chips, and paste-an-image-into-the-&lt;br&gt;
transcript. (Fair warning, since I'd rather you hear it here: several of those&lt;br&gt;
landed without changesets, so they're in the shipped extension but missing from its&lt;br&gt;
changelog. The tooling that's supposed to catch that didn't.)&lt;/p&gt;
&lt;h2&gt;
  
  
  0.7.0, a day later: the polish pass
&lt;/h2&gt;

&lt;p&gt;Beyond the extension, 0.7 is exactly what a release should look like when the&lt;br&gt;
previous one was big: fixes to the things 0.6 got slightly wrong.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adapters no longer report themselves uninstalled while rebuilding.&lt;/strong&gt; A
last-known-good fallback covers the window where a package is mid-build — the
old behaviour made a perfectly healthy adapter vanish from the catalog for a few
seconds, which is a &lt;em&gt;wonderful&lt;/em&gt; way to lose an afternoon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;models.allowed&lt;/code&gt; takes structured entries&lt;/strong&gt;, fixing gateway model-mode binding
in the VS Code picker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sessions record &lt;code&gt;worktreePath&lt;/code&gt; / &lt;code&gt;worktreeId&lt;/code&gt; at spawn time&lt;/strong&gt; — so the session
and the worktree it lives in are joinable without inference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;policy ls --session &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/strong&gt; (and the matching &lt;code&gt;policy_list&lt;/code&gt; / &lt;code&gt;GET /policies&lt;/code&gt;
filter) — the policy list stops being unreadable once you have more than a
handful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--prompt&lt;/code&gt; strings get wrapped into a ContentBlock&lt;/strong&gt; before &lt;code&gt;session.send()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All CLI timeout/interval flags validate and echo their resolved duration&lt;/strong&gt;, so
&lt;code&gt;--until 15m&lt;/code&gt; tells you what it parsed rather than silently meaning something
else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;node-pty&lt;/code&gt;'s spawn-helper exec bit is fixed&lt;/strong&gt;, with PTY spawn errors that
actually say what failed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test gateways stopped writing fake session rows into the real
&lt;code&gt;~/.agentproto/&lt;/code&gt;.&lt;/strong&gt; Our own test suite was polluting real user state. Worth
naming, because it's the same class of bug as the gc one: something that only
&lt;em&gt;looks&lt;/em&gt; isolated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus docs backfill for 0.6's &lt;code&gt;policy&lt;/code&gt; / &lt;code&gt;worktree&lt;/code&gt; verbs, config keys, and&lt;br&gt;
&lt;code&gt;sessions story&lt;/code&gt; — which had shipped without their pages.&lt;/p&gt;
&lt;h2&gt;
  
  
  Migrating from 0.5 to 0.7
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;adapter-claude-code&lt;/code&gt; and &lt;code&gt;driver-agent-cli&lt;/code&gt; went to 1.0.0.&lt;/strong&gt; If you relied on&lt;br&gt;
Claude Code spawns inheriting credentials from the daemon's shell, they no longer&lt;br&gt;
do. Declare the mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"defaults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"adapters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"claude-code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subscription"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;bearer-token&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;mode: "api-key"&lt;/code&gt; to bill an API key from the provider store instead. This is&lt;br&gt;
a change you &lt;em&gt;want&lt;/em&gt;: the old behaviour is how you accidentally bill org credits&lt;br&gt;
for a session you thought was on your subscription.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @agentproto/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full notes: &lt;a href="https://github.com/agentproto/ts/releases/tag/release/2026-07-16" rel="noopener noreferrer"&gt;the July 2026 release&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go deeper
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What shipped in 0.6 / 0.7&lt;/th&gt;
&lt;th&gt;The thinking behind it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Permission inbox, explicit credential modes&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;&lt;code&gt;--approve-all&lt;/code&gt; is how your agent ships the dangerous one&lt;/a&gt; &lt;strong&gt;(hands-on)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;agentproto policy&lt;/code&gt;, completion policies&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;Kill the loop: why &lt;code&gt;while true&lt;/code&gt; is not reliability&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Route-aware model identity, xAI preset&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Cheaper per token is not cheaper per outcome&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;agentproto.json&lt;/code&gt;, lifecycle hooks&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Your Claude skill is invisible to Codex&lt;/a&gt; &lt;strong&gt;(hands-on)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session story, SSE replay, the VS Code extension&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;Your agent says the tests passed. It didn't run them.&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Why any of this matters at 5 agents&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can parallelize the typing. You can't parallelize the trust.&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Previously: &lt;a href="https://dev.to/agentiknet/agentproto-050-credentials-sandboxes-and-cost-accounting-that-refuses-to-lie-53e7"&gt;0.5.0 — credentials, sandboxes, and cost accounting that refuses to lie&lt;/a&gt; · &lt;a href="https://dev.to/agentiknet/agentproto-040-the-daemon-grows-up-into-a-supervision-surface-37ig"&gt;0.4.0 — the daemon grows up into a supervision surface&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;agentproto is an open-source (Apache-2.0) orchestration layer that runs on top&lt;br&gt;
of your existing stack — it doesn't replace your coding agent, it supervises it.&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
    <item>
      <title>agentproto 0.5.0 — credentials, sandboxes, and cost accounting that refuses to lie</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Wed, 15 Jul 2026 19:16:51 +0000</pubDate>
      <link>https://dev.to/agentiknet/agentproto-050-credentials-sandboxes-and-cost-accounting-that-refuses-to-lie-53e7</link>
      <guid>https://dev.to/agentiknet/agentproto-050-credentials-sandboxes-and-cost-accounting-that-refuses-to-lie-53e7</guid>
      <description>&lt;p&gt;&lt;em&gt;Released 2026-07-08 · &lt;code&gt;npm i -g @agentproto/cli&lt;/code&gt; · &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt; · Apache-2.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/agentiknet/agentproto-040-the-daemon-grows-up-into-a-supervision-surface-37ig"&gt;0.4&lt;/a&gt;&lt;br&gt;
turned the daemon into a supervision surface. 0.5 makes it one you can hand a&lt;br&gt;
credential to, run somewhere other than your laptop, and actually measure.&lt;/p&gt;

&lt;p&gt;37 packages went out, six of them new. Three arcs are worth your time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Arc 1 — Auth: the secret never touches your env
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@agentproto/auth@0.1.0&lt;/code&gt; implements AIP-50 end to end. Three &lt;code&gt;CredentialStore&lt;/code&gt;&lt;br&gt;
backends (Keychain, Memory, File), a full RFC 8628 device-code flow engine, and&lt;br&gt;
a &lt;code&gt;CredentialBroker&lt;/code&gt; that hands you ready-to-use headers by provider path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CredentialBroker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;KeychainStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getAuthProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;broker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CredentialBroker&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;KeychainStore&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;getProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;getAuthProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// → { Authorization: "Bearer &amp;lt;token&amp;gt;" }, refreshed silently when stale.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveHeaders&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;guilde&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The broker refreshes 60s before expiry, scopes by audience, and knows the&lt;br&gt;
difference between tokens it can serve directly (PAT / OAT / daemon) and&lt;br&gt;
assertion-style tokens that need a flow engine first.&lt;/p&gt;

&lt;p&gt;The part I like most is the companion: &lt;code&gt;@agentproto/secrets@0.1.0&lt;/code&gt; adds an&lt;br&gt;
&lt;code&gt;mcp-header&lt;/code&gt; &lt;code&gt;SecretExposure&lt;/code&gt; variant. Brokered headers get forwarded to child&lt;br&gt;
MCP servers &lt;strong&gt;at spawn time&lt;/strong&gt; — the secret never appears in env, never appears in&lt;br&gt;
config, never sits in a file the agent can read. If you've ever handed an agent&lt;br&gt;
a &lt;code&gt;.env&lt;/code&gt; and felt something die inside, this is the fix.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agentproto auth login&lt;/code&gt; is rewritten onto this engine, and&lt;br&gt;
&lt;code&gt;agentproto auth cred set|list|rm&lt;/code&gt; seeds credentials for brokered child-MCP auth.&lt;/p&gt;
&lt;h2&gt;
  
  
  Arc 2 — Sandboxes: stop running agents against your filesystem
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@agentproto/sandbox@0.1.0&lt;/code&gt; defines the AIP-36 &lt;code&gt;SandboxProvider&lt;/code&gt; interface — a&lt;br&gt;
backend-agnostic boot/connect/pause/stop lifecycle.&lt;br&gt;
&lt;code&gt;@agentproto/sandbox-e2b@0.1.0&lt;/code&gt; is the first concrete implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSandboxAgentSessionHost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/sandbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;e2bSandboxProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/sandbox-e2b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createSandboxAgentSessionHost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e2bSandboxProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sandboxHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slugs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// a full DaemonAgentSessionHost — prompt, export, stop, pause all work&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;// closes the daemon connection, then tears down the box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The runtime wires it through &lt;code&gt;agent_start.sandbox&lt;/code&gt;, so &lt;strong&gt;any&lt;/strong&gt; &lt;code&gt;AgentStep&lt;/code&gt; in a&lt;br&gt;
workflow can declare a sandbox with no bespoke plumbing. Paused boxes reconnect&lt;br&gt;
later via &lt;code&gt;provider.connect(sandboxId, …)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pair it with &lt;code&gt;@agentproto/storage-github@0.1.0&lt;/code&gt; — an AIP-35 &lt;code&gt;WorkspaceSync&lt;/code&gt; over&lt;br&gt;
git, with configurable branching (&lt;code&gt;main&lt;/code&gt; / &lt;code&gt;per-conversation&lt;/code&gt; / &lt;code&gt;per-turn&lt;/code&gt;) and&lt;br&gt;
opt-in PR creation. The token goes through &lt;code&gt;GIT_HTTP_EXTRAHEADER&lt;/code&gt;, never the&lt;br&gt;
command line, never the repo URL. Its &lt;code&gt;pairsWith: "sandbox"&lt;/code&gt; metadata is not&lt;br&gt;
decoration: sandbox + GitHub storage is the combination that lets an agent work&lt;br&gt;
on a real repo without touching your disk.&lt;/p&gt;
&lt;h2&gt;
  
  
  Arc 3 — Observability, including the honest kind
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Eval.&lt;/strong&gt; &lt;code&gt;runEval&lt;/code&gt; runs typed cases through a target, scores with bound scorers,&lt;br&gt;
aggregates a report. Four deterministic scorers ship (&lt;code&gt;exact-match&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;regex-match&lt;/code&gt;, &lt;code&gt;json-schema-valid&lt;/code&gt;, &lt;code&gt;latency-budget&lt;/code&gt;). The LLM judge is&lt;br&gt;
vendor-neutral by construction — the package carries &lt;strong&gt;no LLM SDK&lt;/strong&gt;. You inject a&lt;br&gt;
&lt;code&gt;JudgeFn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;runEval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;llmJudge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bindScorer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/eval&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runEval&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summarise-suite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;longDoc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;concise summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="na"&gt;scorers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;bindScorer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;llmJudge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quality&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;judge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;myAgentJudge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// any async fn satisfying JudgeFn&lt;/span&gt;
    &lt;span class="na"&gt;criteria&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Accurate, concise, no hallucinations?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mapOutput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}))],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;summarise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Telemetry.&lt;/strong&gt; &lt;code&gt;@agentproto/telemetry@0.2.0&lt;/code&gt; ships an OTel adapter alongside the&lt;br&gt;
existing sinks. &lt;code&gt;@agentproto/telemetry-langfuse@0.2.0&lt;/code&gt; ingests session turns into&lt;br&gt;
Langfuse as traces, with atomic-drain flush on shutdown and per-case span trees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redaction.&lt;/strong&gt; &lt;code&gt;@agentproto/redaction@0.2.0&lt;/code&gt;, zero dependencies, four composable&lt;br&gt;
redactors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chainRedactors&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;denyListRedactor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;valueScanRedactor&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt;
&lt;span class="nx"&gt;redact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redact&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer sk-ant-abc…&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use sk-live-xyz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// → { Authorization: "[redacted]", note: "use [redacted]" }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;valueScanRedactor&lt;/code&gt; is the useful one — it catches secret &lt;em&gt;shapes&lt;/em&gt; regardless of&lt;br&gt;
the key name: PEM blocks, JWTs, &lt;code&gt;sk-&lt;/code&gt; keys, AWS access key ids, GitHub and Slack&lt;br&gt;
tokens. The runtime now defaults its telemetry tracer to the &lt;code&gt;secrets&lt;/code&gt; redactor,&lt;br&gt;
so turn events are scrubbed before they leave the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost, honestly.&lt;/strong&gt; &lt;code&gt;usage_update&lt;/code&gt; events now carry &lt;code&gt;tokensIn&lt;/code&gt;, &lt;code&gt;tokensOut&lt;/code&gt;, and&lt;br&gt;
&lt;code&gt;cost&lt;/code&gt;. &lt;code&gt;deriveSessionUsage&lt;/code&gt; resolves them into a snapshot with a four-way&lt;br&gt;
&lt;code&gt;source&lt;/code&gt; tag:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;source&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;adapter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;the agent reported a real cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;computed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tokens priced against the in-repo LLM catalog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-pricing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tokens exist, model isn't in the catalog — &lt;strong&gt;no price invented&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;none&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;nothing measured&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That &lt;code&gt;no-pricing&lt;/code&gt; state is deliberate. A dashboard that shows a confident wrong&lt;br&gt;
number is worse than one that admits it doesn't know. (More on why per-token&lt;br&gt;
pricing misleads you: &lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;cheaper per token is not cheaper per outcome&lt;/a&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Also in the box
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gateway presets&lt;/strong&gt; — &lt;code&gt;moonshot&lt;/code&gt; (Kimi), &lt;code&gt;openrouter&lt;/code&gt;, &lt;code&gt;deepseek&lt;/code&gt;, usable from
both &lt;code&gt;claude-code&lt;/code&gt; and &lt;code&gt;claude-sdk&lt;/code&gt; adapters. The ambient &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;
is &lt;strong&gt;scrubbed from env&lt;/strong&gt; when a gateway &lt;code&gt;base_url&lt;/code&gt; is set, so it can't leak to
a third-party host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role registry + spawn-time privilege gate.&lt;/strong&gt; Agents spawn as &lt;code&gt;executor&lt;/code&gt; or
&lt;code&gt;supervisor&lt;/code&gt;, or a custom role from &lt;code&gt;ROLE.md&lt;/code&gt;. A &lt;code&gt;maxGrantableDelegation&lt;/code&gt; cap
stops a role pack from self-granting delegation above your ceiling — a pack
asking for more than the cap gets forced to &lt;code&gt;deny&lt;/code&gt;. Why that gate exists:
&lt;a href="https://dev.to/agentiknet/an-agent-that-can-spawn-agents-is-a-fork-bomb-with-good-intentions-2kjh"&gt;an agent that can spawn agents is a fork bomb with good intentions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worktree &lt;code&gt;linkPaths&lt;/code&gt;&lt;/strong&gt; — symlink gitignored dirs (read: &lt;code&gt;node_modules&lt;/code&gt;) from
the host repo into a fresh worktree, so &lt;code&gt;pnpm install --prefer-offline&lt;/code&gt;
resolves without a full reinstall. &lt;code&gt;AgentStep.cwd&lt;/code&gt; binds to the provisioned
path: provision → agent → gate → approval → cleanup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agentproto_terminal&lt;/code&gt;&lt;/strong&gt; — a live PTY panel over WebSocket in the MCP UI
bridge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global &lt;code&gt;defaults&lt;/code&gt; config&lt;/strong&gt; — per-adapter &lt;code&gt;skills&lt;/code&gt;/&lt;code&gt;options&lt;/code&gt; auto-applied to
every spawn, folded into each adapter's native option shape.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;adapter-kit&lt;/code&gt; → &lt;code&gt;provider-kit&lt;/code&gt; rename.&lt;/strong&gt; &lt;code&gt;@agentproto/adapter-kit@0.3.0&lt;/code&gt; is a
compat shim that re-exports everything. Old imports keep working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caption-first video ingestion&lt;/strong&gt; in &lt;code&gt;corpus import-web&lt;/code&gt; — subtitles first (fast,
free), transcription only when captions are absent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Go deeper
&lt;/h2&gt;

&lt;p&gt;Each arc in this release is an argument made in code. Here's the argument in&lt;br&gt;
prose — why the design went this way, and what it's defending against:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What shipped in 0.5&lt;/th&gt;
&lt;th&gt;The thinking behind it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Credential broker, &lt;code&gt;mcp-header&lt;/code&gt; exposure&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;&lt;code&gt;--approve-all&lt;/code&gt; is how your agent ships the dangerous one&lt;/a&gt; &lt;strong&gt;(hands-on)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Role registry, &lt;code&gt;maxGrantableDelegation&lt;/code&gt; cap, sandboxes&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/an-agent-that-can-spawn-agents-is-a-fork-bomb-with-good-intentions-2kjh"&gt;An agent that can spawn agents is a fork bomb with good intentions&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost &lt;code&gt;source&lt;/code&gt; tags, gateway presets&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Cheaper per token is not cheaper per outcome&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eval harness, LLM-judge scoring&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;Your agent says the tests passed. It didn't run them.&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telemetry, redaction, the whole observability arc&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69"&gt;You're optimizing the part of your agent you don't own&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caption-first &lt;code&gt;corpus import-web&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.to/agentiknet/a-folder-of-docs-is-not-a-knowledge-base-55b9"&gt;A folder of docs is not a knowledge base&lt;/a&gt; &lt;strong&gt;(hands-on)&lt;/strong&gt; · &lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;Your coding agent knows the internet's average&lt;/a&gt; &lt;strong&gt;(hands-on)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @agentproto/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full notes: &lt;a href="https://github.com/agentproto/ts/releases/tag/%40agentproto%2Fcli%400.5.0" rel="noopener noreferrer"&gt;the 0.5.0 release&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;agentproto is an open-source (Apache-2.0) orchestration layer that runs on top&lt;br&gt;
of your existing stack — it doesn't replace your coding agent, it supervises it.&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
    <item>
      <title>agentproto 0.4.0 — the daemon grows up into a supervision surface</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Wed, 15 Jul 2026 16:35:01 +0000</pubDate>
      <link>https://dev.to/agentiknet/agentproto-040-the-daemon-grows-up-into-a-supervision-surface-37ig</link>
      <guid>https://dev.to/agentiknet/agentproto-040-the-daemon-grows-up-into-a-supervision-surface-37ig</guid>
      <description>&lt;p&gt;&lt;em&gt;Released 2026-07-03 · &lt;code&gt;npm i -g @agentproto/cli&lt;/code&gt; · &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt; · Apache-2.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The gap between "I can start an agent" and "I can leave an agent running" is&lt;br&gt;
where most orchestration tooling quietly gives up. Starting is easy. What's hard&lt;br&gt;
is everything after: knowing when it finished, noticing when it lied, resuming it&lt;br&gt;
tomorrow, running five of them without a polling loop eating your CPU and your&lt;br&gt;
attention.&lt;/p&gt;

&lt;p&gt;0.4.0 is the release where the agentproto daemon stops being a launcher and&lt;br&gt;
becomes a &lt;strong&gt;supervision surface&lt;/strong&gt; — something that keeps running, keeps records,&lt;br&gt;
and can be scripted against.&lt;/p&gt;

&lt;p&gt;Here's what landed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Durable cron, on the daemon
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agentproto cron&lt;/code&gt; schedules agent work that survives your terminal closing. Jobs&lt;br&gt;
live on the daemon and are exposed three ways — an MCP tool, a REST route, and a&lt;br&gt;
CLI verb — so a scheduled run is reachable from an agent, a script, or your&lt;br&gt;
shell.&lt;/p&gt;

&lt;p&gt;A job can do one of three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run an allowlisted command,&lt;/li&gt;
&lt;li&gt;spawn a fresh agent session,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;re-prompt a session that's already alive&lt;/strong&gt; (&lt;code&gt;prompt-session&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That third one is the interesting one. It means a long-lived session can be&lt;br&gt;
poked on a schedule — "check the deploy every 20 minutes" — without paying to&lt;br&gt;
rebuild its context from scratch each time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scriptable wait — delete your polling loop
&lt;/h2&gt;

&lt;p&gt;If you've orchestrated agents, you've written this loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_session &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"done"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;break
  sleep &lt;/span&gt;5
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's wrong in the ways all busy-waits are wrong, and it gets worse with five&lt;br&gt;
sessions. 0.4 replaces it with a real primitive: block until a session — or a&lt;br&gt;
&lt;strong&gt;fan-in group&lt;/strong&gt; of sessions — reaches turn-end, or until a completion policy&lt;br&gt;
resolves. Available as both a REST endpoint and a CLI subcommand.&lt;/p&gt;

&lt;p&gt;One call, N sessions, no polling. (I wrote about why &lt;code&gt;while true&lt;/code&gt; isn't&lt;br&gt;
reliability &lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;over here&lt;/a&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The WorkflowRunner primitive
&lt;/h2&gt;

&lt;p&gt;The headline addition. &lt;code&gt;WorkflowRunner&lt;/code&gt; gives you ordered stages of concurrent&lt;br&gt;
steps with &lt;strong&gt;explicit barriers&lt;/strong&gt; between them — so you can say "these four run&lt;br&gt;
together, and nothing proceeds until all four land" without hand-rolling the&lt;br&gt;
synchronization.&lt;/p&gt;

&lt;p&gt;What it carries:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sessionRef&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a step reuses an earlier step's session instead of a cold one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;outputSchema&lt;/code&gt; + &lt;code&gt;maxRetries&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;validate the step's output, retry on mismatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;maxTotalCostUsd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a run-level ceiling — the run stops, it doesn't surprise you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;journal cache&lt;/td&gt;
&lt;td&gt;re-invoking replays unchanged steps instead of re-running them&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last one matters more than it sounds. Editing step 7 of a 9-step workflow&lt;br&gt;
shouldn't cost you steps 1–6 again.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WorkflowRunner.startFromFile&lt;/code&gt; and the &lt;code&gt;workflow_run_file&lt;/code&gt; MCP tool load a&lt;br&gt;
&lt;code&gt;WORKFLOW.md&lt;/code&gt; at call time, so the workflow is a file in your repo — reviewable,&lt;br&gt;
diffable, not buried in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured transcripts
&lt;/h2&gt;

&lt;p&gt;Per-session conversation export, plus a daemon-events export source and&lt;br&gt;
&lt;code&gt;GET /sessions/:id/events&lt;/code&gt; for incremental polling. The point is auditability:&lt;br&gt;
when an agent claims it ran the tests, the transcript is how you find out&lt;br&gt;
whether it did. That claim is the whole subject of&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;the supervision ladder&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tool verbs, renamed to a family-first taxonomy
&lt;/h2&gt;

&lt;p&gt;Breaking-ish, and worth it. MCP tools are now grouped by family: &lt;code&gt;agent_*&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;session_*&lt;/code&gt;, &lt;code&gt;terminal_*&lt;/code&gt;, &lt;code&gt;command_*&lt;/code&gt;, &lt;code&gt;file_*&lt;/code&gt;, &lt;code&gt;directory_*&lt;/code&gt;, &lt;code&gt;browser_*&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;policy_*&lt;/code&gt;, &lt;code&gt;routine_*&lt;/code&gt;, &lt;code&gt;tunnel_*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a model is picking from 60 tools, a name that says which family it belongs&lt;br&gt;
to does real work. Agent tools also moved into a dedicated &lt;code&gt;agent-tools.ts&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first in-process adapter (AIP-45)
&lt;/h2&gt;

&lt;p&gt;Every adapter until now spawned a subprocess. &lt;code&gt;createProprietaryProtocolArm&lt;/code&gt;&lt;br&gt;
dynamic-loads an adapter's &lt;code&gt;createAgentCliClient&lt;/code&gt;, and &lt;code&gt;createAgentCliRuntime&lt;/code&gt;&lt;br&gt;
skips the spawn entirely.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@agentproto/adapter-mastracode-inprocess&lt;/code&gt; is the first one to use it — driving&lt;br&gt;
Mastra Code in-process through its SDK (&lt;code&gt;createMastraCode&lt;/code&gt; + &lt;code&gt;runMC&lt;/code&gt;) rather than&lt;br&gt;
shelling out. Its composite &lt;code&gt;resourceId:threadId&lt;/code&gt; session id survives a process&lt;br&gt;
restart, which is the part I actually care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliability fixes worth naming
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The hermes hang.&lt;/strong&gt; A per-turn silence watchdog on the ACP client fixes
sessions that stalled without ever emitting turn-end. If you've had an agent
sit there looking alive and doing nothing, this was often why.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;agent_output&lt;/code&gt; during tool-busy turns&lt;/strong&gt; stays visible instead of going dark.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool calls render informatively&lt;/strong&gt; instead of the generic &lt;code&gt;[tool] view&lt;/code&gt; line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session liveness on the descriptor&lt;/strong&gt; — &lt;code&gt;pid&lt;/code&gt;, &lt;code&gt;lastActivityAt&lt;/code&gt;,
&lt;code&gt;processAlive&lt;/code&gt;. The dashboard now distinguishes busy, idle, and
stale-running (a session whose pid is dead but whose record says otherwise).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Silent prompt-delivery failures&lt;/strong&gt; to dead and busy sessions: fixed. They now
tell you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transcript writer&lt;/strong&gt; no longer strips newlines from text-delta events.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Onboarding
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agentproto onboard&lt;/code&gt; registers the MCP server and installs the skill pack in one&lt;br&gt;
run. &lt;code&gt;install skill/&amp;lt;slug&amp;gt;&lt;/code&gt; targets hermes, claude-code, and claude-desktop;&lt;br&gt;
&lt;code&gt;install-mcp&lt;/code&gt; does a surgical &lt;code&gt;config.yaml&lt;/code&gt; upsert for hermes and a manifest&lt;br&gt;
upsert for claude-desktop — it edits what it must and leaves the rest alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go deeper
&lt;/h2&gt;

&lt;p&gt;Most of what's in this release is an argument made in code. If you want the&lt;br&gt;
argument in prose — including why the design went this way and not the obvious&lt;br&gt;
way — these go with it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What shipped in 0.4&lt;/th&gt;
&lt;th&gt;The thinking behind it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scriptable wait, durable cron&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;Kill the loop: why &lt;code&gt;while true&lt;/code&gt; is not reliability&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structured transcripts&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;Your agent says the tests passed. It didn't run them.&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;install skill/&amp;lt;slug&amp;gt;&lt;/code&gt; across hermes / claude-code / claude-desktop&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Your Claude skill is invisible to Codex — here's how to fix it&lt;/a&gt; &lt;strong&gt;(hands-on)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool-verb taxonomy, WorkflowRunner&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69"&gt;You're optimizing the part of your agent you don't own&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Why any of this matters at 5 agents&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can parallelize the typing. You can't parallelize the trust.&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Notes before you upgrade
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;chat-tui&lt;/strong&gt; migrated off Ink/React onto &lt;code&gt;@earendil-works/pi-tui&lt;/code&gt;. If you had
custom Ink themes, re-check your rendering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routines and workflows are different primitives.&lt;/strong&gt; Routines are a flat
&lt;code&gt;RoutineStep[]&lt;/code&gt; with per-step fan-in. Workflows add staged concurrency with
explicit barriers. &lt;strong&gt;Use workflows for new orchestration code.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @agentproto/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full notes: &lt;a href="https://github.com/agentproto/ts/releases/tag/%40agentproto%2Fcli%400.4.0" rel="noopener noreferrer"&gt;the 0.4.0 release&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;agentproto is an open-source (Apache-2.0) orchestration layer that runs on top&lt;br&gt;
of your existing stack — it doesn't replace your coding agent, it supervises it.&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
    <item>
      <title>A Folder of Docs Is Not a Knowledge Base</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:49 +0000</pubDate>
      <link>https://dev.to/agentiknet/a-folder-of-docs-is-not-a-knowledge-base-55b9</link>
      <guid>https://dev.to/agentiknet/a-folder-of-docs-is-not-a-knowledge-base-55b9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; and its corpus&lt;br&gt;
tooling, which is what the walkthrough uses. The commands are real and&lt;br&gt;
checkable; the problem in the first half is one every RAG setup hits.&lt;br&gt;
Corrections welcome — file an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The advice is everywhere and it sounds complete: &lt;em&gt;give your agent your knowledge —&lt;br&gt;
just do RAG over your docs folder.&lt;/em&gt; So you point a retriever at &lt;code&gt;docs/&lt;/code&gt;, embed the&lt;br&gt;
chunks, and wire it up. The agent starts answering questions about your systems.&lt;/p&gt;

&lt;p&gt;Then you ask it something that matters, and it gives you a fluent, confident&lt;br&gt;
paragraph — and you have no idea whether it's true, because you have no idea where&lt;br&gt;
it came from. Was that from the current runbook or a design doc you abandoned in&lt;br&gt;
2024? Is that retry number the real one, or a chunk from a stale README that&lt;br&gt;
happened to score well on cosine similarity? You can't tell. Neither can the&lt;br&gt;
agent.&lt;/p&gt;

&lt;p&gt;That's the tell that you don't have a knowledge base. You have a search index over&lt;br&gt;
a pile of documents, which is a different and much weaker thing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
A folder of docs is not a knowledge base. What makes it one is &lt;em&gt;provenance&lt;/em&gt; —&lt;br&gt;
every fact knowing which source it came from, so the agent can cite it and you&lt;br&gt;
can check it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The two things a doc dump can't do
&lt;/h2&gt;

&lt;p&gt;A folder of markdown fails as a knowledge base for two structural reasons, and no&lt;br&gt;
amount of better embeddings fixes either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It retrieves prose, not facts.&lt;/strong&gt; A document is a wall of sentences about many&lt;br&gt;
things at once. Chunk it and you get arbitrary slices — half a paragraph about&lt;br&gt;
retries glued to the start of a paragraph about logging. The agent gets &lt;em&gt;near&lt;/em&gt; the&lt;br&gt;
answer and reconstructs the rest, which is exactly where confident-but-wrong comes&lt;br&gt;
from. The unit of knowledge should be a &lt;em&gt;claim&lt;/em&gt;, not a 512-token window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It forgets where everything came from.&lt;/strong&gt; Once a chunk is embedded, it's just a&lt;br&gt;
floating string. There's no thread back to "this is from &lt;code&gt;runbooks/payments.md&lt;/code&gt;,&lt;br&gt;
last touched in the April incident." So the agent can't cite, and — worse — &lt;em&gt;you&lt;/em&gt;&lt;br&gt;
can't audit. A knowledge base you can't audit is a knowledge base you can't trust,&lt;br&gt;
which means it's a liability the first time it's confidently wrong.&lt;/p&gt;

&lt;p&gt;Both problems have the same fix, and it's not a fancier retriever. It's a&lt;br&gt;
&lt;strong&gt;pipeline&lt;/strong&gt;: turn sources into atomic, sourced claims &lt;em&gt;before&lt;/em&gt; anything queries&lt;br&gt;
them. That pipeline is what separates a corpus from a folder.&lt;/p&gt;
&lt;h2&gt;
  
  
  What's your "knowledge base" actually made of?
&lt;/h2&gt;

&lt;p&gt;Place yourself before you build. Four honest answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing.&lt;/strong&gt; The agent runs on pre-training and whatever you paste. Generic by&lt;br&gt;
default. &lt;em&gt;Ceiling: it never knows one thing that isn't already public.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A docs folder + RAG.&lt;/strong&gt; You retrieve chunks by similarity. Better than nothing,&lt;br&gt;
and it's the trap this piece is about: no provenance, no dedup, no notion of a&lt;br&gt;
claim — it answers from sources it can't name. &lt;em&gt;Ceiling: confident, unverifiable,&lt;br&gt;
and stale the day a doc rots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A hand-curated wiki.&lt;/strong&gt; Real, human-maintained, often good — but it's written for&lt;br&gt;
&lt;em&gt;people&lt;/em&gt; to read, not for an agent to query claim-by-claim, and it goes stale&lt;br&gt;
between the edits nobody makes. &lt;em&gt;Ceiling: high quality, low queryability, manual&lt;br&gt;
upkeep.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A distilled, sourced corpus.&lt;/strong&gt; Sources imported with their origin attached,&lt;br&gt;
distilled to claim-level entries, each carrying its provenance, queryable by topic.&lt;br&gt;
&lt;em&gt;This is the one an agent can cite and you can audit — and it's four commands.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where are you?&lt;/strong&gt; If your honest answer is &lt;em&gt;"RAG over a docs folder,"&lt;/em&gt; you have&lt;br&gt;
the confident-but-unverifiable setup — the most dangerous kind, because it &lt;em&gt;feels&lt;/em&gt;&lt;br&gt;
like it works right up until it states a stale fact with a straight face. The&lt;br&gt;
rest of this turns the pile into a corpus.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Step 1: import, and keep the receipt
&lt;/h2&gt;

&lt;p&gt;Start by pulling your sources into a corpus workspace — and the non-negotiable is&lt;br&gt;
that each source keeps a thread back to where it came from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @agentproto/corpus-cli

&lt;span class="c"&gt;# scaffold an AIP-10 workspace (generic research preset, no seed noise)&lt;/span&gt;
corpus init house-knowledge knowledge/house &lt;span class="nt"&gt;--preset&lt;/span&gt; research

&lt;span class="c"&gt;# import your sources; --tags is what makes the corpus queryable by topic later&lt;/span&gt;
corpus import-web knowledge/house &lt;span class="nt"&gt;--urls-file&lt;/span&gt; runbooks.txt &lt;span class="nt"&gt;--tags&lt;/span&gt; runbooks
corpus import-web knowledge/house &lt;span class="nt"&gt;--urls-file&lt;/span&gt; incidents.txt &lt;span class="nt"&gt;--tags&lt;/span&gt; incidents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every imported source lands as an AIP-10 record carrying its &lt;code&gt;originalUrl&lt;/code&gt; — the&lt;br&gt;
provenance thread. An article comes in via readability; a walled page routes&lt;br&gt;
through a browser; &lt;strong&gt;a recorded incident review or an architecture talk on video&lt;br&gt;
comes in via transcription&lt;/strong&gt; — same workspace, same provenance, so a decision your&lt;br&gt;
team only ever said out loud becomes a citable source. Import is resumable: re-run&lt;br&gt;
it and it skips what's already in, so you grow the corpus instead of rebuilding it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: distill — turn documents into claims
&lt;/h2&gt;

&lt;p&gt;This is the step a folder-and-RAG setup skips entirely, and it's the one that&lt;br&gt;
matters. Distillation reads each source and emits &lt;strong&gt;atomic, claim-level entries&lt;/strong&gt;,&lt;br&gt;
roughly seven per source, each one carrying the source it came from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# cheap + strong: distill on an open model via OpenRouter (saves frontier credits)&lt;/span&gt;
corpus distill knowledge/house &lt;span class="nt"&gt;--engine&lt;/span&gt; opencode &lt;span class="nt"&gt;-m&lt;/span&gt; openrouter/deepseek/deepseek-v4-pro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the unit of knowledge is a claim, not a chunk — &lt;em&gt;"payment retries are capped at&lt;br&gt;
3 with an idempotency key, per incident 2026-04"&lt;/em&gt; is one entry with one source, not&lt;br&gt;
a slice of a paragraph that happened to embed nearby. When an agent retrieves this,&lt;br&gt;
it retrieves the fact &lt;strong&gt;and&lt;/strong&gt; its origin, which is what lets it answer &lt;em&gt;"per&lt;br&gt;
incident 2026-04…"&lt;/em&gt; instead of &lt;em&gt;"a common approach is…"&lt;/em&gt;. Provenance stops being&lt;br&gt;
metadata and becomes the answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why claims beat chunks, grounded.&lt;/strong&gt; Anthropic's context-engineering guidance is&lt;br&gt;
to keep the working context small and retrieve high-signal facts &lt;strong&gt;just in time&lt;/strong&gt;&lt;br&gt;
rather than pre-loading walls of text. You can't do just-in-time retrieval on a&lt;br&gt;
document — it's too big and says too much. You can do it on a claim. Distillation&lt;br&gt;
is what makes your knowledge &lt;em&gt;retrievable at the right grain.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Step 3: gate the corpus — a knowledge base is maintained, not filled
&lt;/h2&gt;

&lt;p&gt;A pile of docs is fill-once-and-forget. A corpus is an artifact you &lt;em&gt;keep&lt;/em&gt;, so it&lt;br&gt;
gets a quality gate before anything trusts it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;corpus validate knowledge/house    &lt;span class="c"&gt;# schema-valid sources, 0 errors&lt;/span&gt;
corpus lint knowledge/house        &lt;span class="c"&gt;# structural checks&lt;/span&gt;
corpus knowledge knowledge/house &lt;span class="nt"&gt;--tags&lt;/span&gt; incidents &lt;span class="nt"&gt;--max&lt;/span&gt; 20   &lt;span class="c"&gt;# preview what an agent would pull&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two failure modes to catch here, because they're the ones that poison a corpus&lt;br&gt;
quietly. A &lt;strong&gt;bad scrape&lt;/strong&gt; — a retriever grabbing a cookie-wall or a nav menu&lt;br&gt;
instead of the article — still gets distilled into confident-sounding entries;&lt;br&gt;
grep for self-flags (&lt;em&gt;"content does not match"&lt;/em&gt;, off-topic nouns) and quarantine&lt;br&gt;
them into a &lt;code&gt;demoted/&lt;/code&gt; folder so they never reach an agent. And &lt;strong&gt;coverage&lt;/strong&gt;: for&lt;br&gt;
each topic you care about, does the corpus actually have sourced claims, or is that&lt;br&gt;
tag empty? A gap you find now is a gap the agent won't paper over with a guess&lt;br&gt;
later.&lt;/p&gt;

&lt;p&gt;This is the discipline the doc-dump never had: &lt;strong&gt;your knowledge base is only as&lt;br&gt;
good as its worst source, so you check the sources.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: serve it — every agent, claim-level, sourced
&lt;/h2&gt;

&lt;p&gt;Now the corpus becomes a tool. Back it with a &lt;code&gt;knowledge.search&lt;/code&gt; driver pointed at&lt;br&gt;
the workspace you just built, and serve it over MCP — the full contract-and-driver&lt;br&gt;
pattern is &lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;its own walkthrough&lt;/a&gt;, but the payoff is one&lt;br&gt;
environment variable and one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CORPUS_WS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;knowledge/house agentproto serve   &lt;span class="c"&gt;# serves knowledge.search to every agent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every agent that mounts the daemon — Claude Code, Codex, a cheap local model — now&lt;br&gt;
queries the &lt;em&gt;same&lt;/em&gt; distilled, sourced corpus, and because the driver reads local&lt;br&gt;
files, &lt;strong&gt;your knowledge never leaves the machine.&lt;/strong&gt; Ask any of them your retry&lt;br&gt;
policy and the answer comes back with &lt;code&gt;incident 2026-04&lt;/code&gt; attached. That citation&lt;br&gt;
isn't decoration — it's the thing that lets a skeptical reviewer (human or agent)&lt;br&gt;
check the answer against the source instead of trusting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest edges
&lt;/h2&gt;

&lt;p&gt;A corpus is a real artifact, so it has real upkeep and real failure modes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A wrong corpus is worse than no corpus.&lt;/strong&gt; A stale claim gets retrieved with the&lt;br&gt;
same confidence as a fresh one — now &lt;em&gt;with a source attached&lt;/em&gt;, which makes it more&lt;br&gt;
persuasive and more dangerous. Provenance is what saves you: because every claim&lt;br&gt;
names its origin, a wrong answer is &lt;em&gt;traceable&lt;/em&gt; to the stale source and fixable,&lt;br&gt;
instead of an anonymous hallucination you can't hunt down. You maintain a corpus&lt;br&gt;
like you maintain docs, because that's what it is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't let the agent write your knowledge base.&lt;/strong&gt; A corpus distilled from real&lt;br&gt;
runbooks, incidents, and decisions is yours; one an agent generates about itself is&lt;br&gt;
the internet's average with your repo's name on it. Distill from sources you'd&lt;br&gt;
stand behind — the whole point is that the knowledge is &lt;em&gt;earned&lt;/em&gt;, not synthesized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And the fair comparison.&lt;/strong&gt; Managed RAG products and vendor retrieval are less&lt;br&gt;
setup — if you want "upload your docs, get a chatbot," they'll get you there faster,&lt;br&gt;
and for some teams that's the right trade. What you give up is the two things this&lt;br&gt;
whole piece is about: claim-level provenance you can audit, and a knowledge base&lt;br&gt;
that lives in your repo, on your machine, not in someone's index. If your knowledge&lt;br&gt;
is your edge, those aren't details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the corpus, not the pile
&lt;/h2&gt;

&lt;p&gt;Everyone rents the same models now, so the one part of the stack that's genuinely&lt;br&gt;
yours is what your agent &lt;em&gt;knows&lt;/em&gt; — and that's only true if what it knows is real.&lt;br&gt;
A folder of docs behind a retriever gives you fluent answers from sources you can't&lt;br&gt;
name and can't check, which is the exact opposite of what a knowledge base is for.&lt;/p&gt;

&lt;p&gt;The fix isn't a better embedding model. It's a pipeline: import your sources with&lt;br&gt;
their provenance intact, distill them into claims small enough to retrieve and&lt;br&gt;
honest enough to cite, gate the result like the artifact it is, and serve it to&lt;br&gt;
every agent you run. Four commands, and your agent stops guessing from a pile and&lt;br&gt;
starts answering from a corpus — one where every fact can tell you exactly where it&lt;br&gt;
came from.&lt;/p&gt;

&lt;p&gt;Give your agent knowledge. Just make sure it's the kind that can show its work.&lt;/p&gt;

&lt;p&gt;If you build your knowledge base a way that keeps provenance without the distill&lt;br&gt;
step — or you've made folder-RAG genuinely auditable — tell me where. I'll fix the&lt;br&gt;
piece.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0,&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;) — a local, cross-vendor daemon for&lt;br&gt;
running and governing coding agents. Same contract as our&lt;br&gt;
&lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page: dated facts, named strengths,&lt;br&gt;
corrections by issue. Got something wrong?&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>rag</category>
      <category>devtools</category>
    </item>
    <item>
      <title>An Agent That Can Spawn Agents Is a Fork Bomb With Good Intentions</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:46 +0000</pubDate>
      <link>https://dev.to/agentiknet/an-agent-that-can-spawn-agents-is-a-fork-bomb-with-good-intentions-2kjh</link>
      <guid>https://dev.to/agentiknet/an-agent-that-can-spawn-agents-is-a-fork-bomb-with-good-intentions-2kjh</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt;, one of the&lt;br&gt;
tools in this market. The primitives in the back half are real and the fields&lt;br&gt;
are checkable; the problem in the front half is everyone's. Corrections&lt;br&gt;
welcome — file an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's the multi-agent dream, and it's a good one: you hand one capable agent a&lt;br&gt;
big task, and instead of grinding through it alone, it spins up a little team —&lt;br&gt;
one sub-agent to research, two to implement in parallel, one to review — waits for&lt;br&gt;
them all, and hands you the merged result. An orchestrator that manages&lt;br&gt;
orchestrators. It works, and it's genuinely powerful.&lt;/p&gt;

&lt;p&gt;Now read that sentence again with an engineer's paranoia. &lt;em&gt;An orchestrator that&lt;br&gt;
manages orchestrators.&lt;/em&gt; If an agent can spawn agents, then the agents it spawns&lt;br&gt;
can spawn agents. And nothing in "you can spawn a sub-agent" says where that&lt;br&gt;
stops.&lt;/p&gt;

&lt;p&gt;You already know this shape. It's the oldest prank in the Unix book:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;:&lt;span class="o"&gt;(){&lt;/span&gt; :|:&amp;amp; &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;:   &lt;span class="c"&gt;# a function that calls two copies of itself, forever&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a fork bomb. It does nothing malicious — each copy just politely starts&lt;br&gt;
two more, until the process table is full and the machine is on its knees. A&lt;br&gt;
coding agent with an unbounded spawn tool is the same structure with a language&lt;br&gt;
model in the middle and your API bill underneath.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
Spawning isn't a feature you turn on. It's a privilege you grant — and a&lt;br&gt;
privilege with no depth, no breadth, and no ceiling is a fork bomb with good&lt;br&gt;
intentions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The privilege you're granting without noticing
&lt;/h2&gt;

&lt;p&gt;When you give an agent a &lt;code&gt;spawn_sub_agent&lt;/code&gt; tool, you're not just adding a&lt;br&gt;
capability. You're granting it the right to grant &lt;em&gt;itself&lt;/em&gt; the same capability,&lt;br&gt;
recursively, as many times as its reasoning talks it into. Most setups make that&lt;br&gt;
grant implicitly and totally: if the tool is in the toolset, spawning is&lt;br&gt;
unlimited — any depth, any number of children, and each child just as privileged&lt;br&gt;
as the parent.&lt;/p&gt;

&lt;p&gt;Two things make that expensive fast, and neither is hypothetical. First, cost.&lt;br&gt;
Anthropic's own guidance on sub-agents is that you isolate exploration in them&lt;br&gt;
precisely because &lt;strong&gt;each one can burn ten thousand tokens to hand back a&lt;br&gt;
five-line summary&lt;/strong&gt; — cheap when it's one, a bonfire when a confused parent&lt;br&gt;
spawns twelve and each of those spawns twelve. Second, the multi-agent reflex&lt;br&gt;
itself is usually wrong:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The receipt that should slow you down.&lt;/strong&gt; The sharpest orchestration writers&lt;br&gt;
converge on one rule: &lt;em&gt;the number of agents a job spawns is the **output&lt;/em&gt;* of&lt;br&gt;
the orchestration decision, not the input.* You don't pick a multi-agent&lt;br&gt;
workflow because you can — you pick it because the work's shape demands it. An&lt;br&gt;
agent that spawns because spawning is available has skipped the only decision&lt;br&gt;
that mattered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the problem isn't multi-agent orchestration. It's &lt;em&gt;ungoverned&lt;/em&gt; spawning —&lt;br&gt;
handing an LLM a recursive, self-replicating capability and trusting its judgment&lt;br&gt;
to not run it off a cliff. The fix isn't "don't spawn." It's "make spawning a&lt;br&gt;
metered privilege."&lt;/p&gt;
&lt;h2&gt;
  
  
  How does your setup bound spawning today?
&lt;/h2&gt;

&lt;p&gt;Place yourself honestly before you build. Four postures, each with a ceiling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unbounded.&lt;/strong&gt; Any agent holding the spawn tool spawns freely — any depth, any&lt;br&gt;
count. Powerful, and one confused reasoning loop from a runaway tree and a bill&lt;br&gt;
with a comma you didn't expect. &lt;em&gt;Ceiling: the first agent that decides the answer&lt;br&gt;
to "this is hard" is "spawn more agents."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrency-capped by hand.&lt;/strong&gt; You cap how many agents run at once, in your own&lt;br&gt;
harness code, watching a dashboard. Better — but it's your attention doing the&lt;br&gt;
capping, and it doesn't stop &lt;em&gt;depth&lt;/em&gt;, just width at one instant. &lt;em&gt;Ceiling: you,&lt;br&gt;
watching.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Worktree-isolated only.&lt;/strong&gt; You give each parallel agent its own git worktree so&lt;br&gt;
they don't stomp each other's files — the near-universal isolation trick, and a&lt;br&gt;
good one. But a worktree isolates the &lt;em&gt;filesystem&lt;/em&gt;, not the &lt;em&gt;right to spawn&lt;/em&gt;. A&lt;br&gt;
tidily-isolated agent can still fork-bomb. &lt;em&gt;Ceiling: clean files, unbounded tree.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privilege-gated.&lt;/strong&gt; Spawning is a role, capped by depth and breadth, and a child&lt;br&gt;
can never grant itself more than the parent had. &lt;em&gt;This is the one that can't run&lt;br&gt;
away, and it's the one you can declare instead of police.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where are you?&lt;/strong&gt; If your honest answer is &lt;em&gt;"any agent with the tool can spawn&lt;br&gt;
as much as it wants,"&lt;/em&gt; you don't have orchestration — you have a fork bomb that&lt;br&gt;
hasn't gone off yet. The rest of this is four bounds that make sure it never&lt;br&gt;
does.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Bound 1: spawning is a role, and most agents shouldn't have it
&lt;/h2&gt;

&lt;p&gt;The first bound is the bluntest: most agents in a tree should be &lt;em&gt;leaves&lt;/em&gt; that&lt;br&gt;
physically cannot delegate. In agentproto that's a spawn-time role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c1"&gt;// this child does the work and CANNOT spawn — the spawn tools are removed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;agent_start(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// leaf: agent_start / agent_prompt are stripped&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/abs/host/path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Implement the retry cap in src/payments/retry.ts. Do not delegate."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An &lt;code&gt;executor&lt;/code&gt; is a leaf by construction: the &lt;code&gt;agent_start&lt;/code&gt; and &lt;code&gt;agent_prompt&lt;/code&gt;&lt;br&gt;
tools are &lt;strong&gt;stripped from its toolset&lt;/strong&gt;, and asking it to become an orchestrator&lt;br&gt;
is simply ignored — no amount of clever prompting gives it back the ability to&lt;br&gt;
spawn, because the capability isn't in the room. A &lt;code&gt;supervisor&lt;/code&gt; may delegate.&lt;br&gt;
That single distinction turns "every agent is a potential parent" into "spawning&lt;br&gt;
is a named privilege that most of the tree doesn't hold."&lt;/p&gt;

&lt;p&gt;This is the same lesson the OWASP Agentic Top 10 files under &lt;strong&gt;least agency&lt;/strong&gt;:&lt;br&gt;
give an agent only the autonomy its task needs. A worker implementing a function&lt;br&gt;
doesn't need the right to raise an army. Take it away, and a whole class of&lt;br&gt;
runaway trees becomes unrepresentable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Bound 2: depth — the recursion has a floor it can't dig past
&lt;/h2&gt;

&lt;p&gt;Leaves can't spawn, but supervisors can, and a chain of supervisors is still a&lt;br&gt;
recursion. So the second bound caps how &lt;em&gt;deep&lt;/em&gt; the tree can go, and makes the cap&lt;br&gt;
one-directional.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="err"&gt;agent_start(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"supervisor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;orchestrator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;maxDepth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;maxChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// this subtree, bounded&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c1"&gt;// …&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;maxDepth&lt;/code&gt; defaults to &lt;strong&gt;3&lt;/strong&gt; and has a &lt;strong&gt;hard ceiling of 8&lt;/strong&gt; — a spawn that would&lt;br&gt;
exceed it is rejected outright, not queued. The load-bearing detail is the&lt;br&gt;
direction: &lt;strong&gt;a recursive spawn can only &lt;em&gt;lower&lt;/em&gt; the inherited cap, never raise&lt;br&gt;
it.&lt;/strong&gt; A parent at depth 3 can hand a child a budget of 2; that child cannot hand&lt;br&gt;
&lt;em&gt;its&lt;/em&gt; child a budget of 5. The fork bomb's whole trick is unbounded recursion;&lt;br&gt;
capping depth with a monotonically-shrinking budget removes the trick. The tree&lt;br&gt;
has a floor, and nothing inside the tree can dig past it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bound 3: breadth — no single agent fans out into a swarm
&lt;/h2&gt;

&lt;p&gt;Depth stops the tree going infinitely &lt;em&gt;down&lt;/em&gt;; breadth stops any one node&lt;br&gt;
exploding &lt;em&gt;sideways&lt;/em&gt;. &lt;code&gt;maxChildren&lt;/code&gt; defaults to &lt;strong&gt;8&lt;/strong&gt; concurrently-alive&lt;br&gt;
sub-agents per parent and, like depth, a recursive spawn can only lower the&lt;br&gt;
inherited quota — never raise it.&lt;/p&gt;

&lt;p&gt;That's the direct antidote to the &lt;code&gt;:|:&lt;/code&gt; in the fork bomb — the part where one&lt;br&gt;
process becomes two becomes four. Cap the branching factor and the geometric&lt;br&gt;
explosion can't start. Combined with depth, your worst case is now a &lt;em&gt;known&lt;/em&gt;&lt;br&gt;
number of agents (&lt;code&gt;maxChildren ^ maxDepth&lt;/code&gt;, and shrinking as it descends), not an&lt;br&gt;
open-ended one. You can look at a spawn config and say exactly how bad a confused&lt;br&gt;
run gets. That sentence is impossible in the unbounded world.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cost gets its own hard stop.&lt;/strong&gt; Independently of the tree shape, each session&lt;br&gt;
takes &lt;code&gt;maxCostUsd&lt;/code&gt; — a cumulative dollar ceiling; the session is stopped at the&lt;br&gt;
next turn-end once it's exceeded. Depth and breadth bound the &lt;em&gt;count&lt;/em&gt;; this&lt;br&gt;
bounds the &lt;em&gt;spend&lt;/em&gt; directly, so even a legal-sized tree of expensive turns has a&lt;br&gt;
number it can't cross.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Bound 4: a child can't out-privilege its parent
&lt;/h2&gt;

&lt;p&gt;The last bound is the subtle one, and it's what makes the other three trustworthy:&lt;br&gt;
a child can never end up &lt;em&gt;more&lt;/em&gt; powerful than the parent that made it. The daemon&lt;br&gt;
enforces a privilege lattice — a spawn made through an orchestrator may only&lt;br&gt;
create a role at or below the caller's own level, never something more privileged,&lt;br&gt;
and an explicit &lt;code&gt;tools&lt;/code&gt; allowlist can only ever &lt;em&gt;narrow&lt;/em&gt; the toolset, never widen&lt;br&gt;
it. &lt;strong&gt;A child can never grant itself scope its parent didn't have.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And the parent's view is boxed, too. The daemon mints a &lt;strong&gt;per-child scope-token&lt;/strong&gt;,&lt;br&gt;
injects a scoped sub-gateway into that child's session, and &lt;strong&gt;revokes the token&lt;br&gt;
when the session exits&lt;/strong&gt;. A parent's &lt;code&gt;session_tree&lt;/code&gt; shows only &lt;em&gt;its own&lt;/em&gt; subtree;&lt;br&gt;
it can't see, prompt, or kill sessions outside its branch. Shell, filesystem,&lt;br&gt;
remote, and import tools are &lt;strong&gt;never&lt;/strong&gt; handed to an orchestrator child at all. So&lt;br&gt;
the tree isn't just size-bounded — every node is capability-bounded to a shrinking&lt;br&gt;
box, and the boxes evaporate when the work is done.&lt;/p&gt;

&lt;p&gt;Four bounds, one property: you can hand an agent the genuinely powerful ability to&lt;br&gt;
build and run a team, and still be able to state — before it runs — the maximum&lt;br&gt;
depth, the maximum breadth, the maximum spend, and the ceiling on privilege. The&lt;br&gt;
capability stays; the fork bomb becomes unrepresentable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest edges (what bit me building this)
&lt;/h2&gt;

&lt;p&gt;Real infrastructure, real sharp corners. Four I hit live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The parent has to be Claude Code.&lt;/strong&gt; A hermes parent silently ignores the
injected orchestration gateway — it never mounts the spawn tools, so nothing
happens. Children can be any adapter (cheap Haiku for trivial work); the
&lt;em&gt;parent&lt;/em&gt; that does the orchestrating must be Claude Code. If a parent reports
"the orchestration tools aren't mounted," that's the tell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fan-in races fast children.&lt;/strong&gt; A trivial child can finish its turn &lt;em&gt;before&lt;/em&gt; the
parent has wired up its wait — and &lt;code&gt;turn-end&lt;/code&gt; is a transient event, so the wait
times out on a child that already succeeded. Teach the parent the fallback: if
the wait times out, read the child's output to confirm, or take an event cursor
&lt;em&gt;before&lt;/em&gt; spawning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Killing the parent doesn't kill the children.&lt;/strong&gt; The scope-token is revoked on
parent exit, but the child processes are full sessions of their own. Kill the
parent &lt;em&gt;and&lt;/em&gt; each child (their ids are in &lt;code&gt;session_tree&lt;/code&gt;), or you'll leak
running agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;cwd&lt;/code&gt; must be a real host path&lt;/strong&gt; for every child — the daemon runs on your
machine, and a child with no resolvable working directory just errors out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the fair comparison. Vendors do ship sub-agents — Claude Code's Agent Teams&lt;br&gt;
will run a team for you, and inside one vendor's stack it's smooth and needs none&lt;br&gt;
of this wiring. Two things a built-in team doesn't give you: the spawn tree stays&lt;br&gt;
inside that vendor (your cheap open-model executors aren't invited), and the&lt;br&gt;
governance is theirs, not a set of depth/breadth/role/cost bounds you declare and&lt;br&gt;
own. If you live entirely in one vendor and never want a mixed fleet, take the&lt;br&gt;
built-in — it's less work. If you want to spawn across vendors &lt;em&gt;and&lt;/em&gt; sleep at&lt;br&gt;
night, the bounds have to be yours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give it a team. Keep the blast radius finite.
&lt;/h2&gt;

&lt;p&gt;The instinct to stop agents from spawning is the wrong lesson — spawning a team&lt;br&gt;
is exactly the leverage that makes agents worth orchestrating. The right lesson is&lt;br&gt;
that a self-replicating capability handed to a probabilistic reasoner needs the&lt;br&gt;
same thing every other powerful capability needs: limits it can't rewrite.&lt;/p&gt;

&lt;p&gt;So grant the privilege deliberately. Make most agents leaves that can't delegate.&lt;br&gt;
Cap the depth so the recursion has a floor. Cap the breadth so no node fans into a&lt;br&gt;
swarm. Cap the spend and the privilege so a child is always smaller than its&lt;br&gt;
parent. Do that and "an agent that spawns agents" stops being a fork bomb and&lt;br&gt;
starts being what you actually wanted: a team with a foreman, and a foreman who&lt;br&gt;
can't accidentally hire the whole city.&lt;/p&gt;

&lt;p&gt;Let the agent build its team. Just make sure the tree has a floor, the branches&lt;br&gt;
have a limit, and the whole thing dies when the job's done.&lt;/p&gt;

&lt;p&gt;If your orchestrator bounds spawning a cleaner way — or you've found a runaway&lt;br&gt;
tree these four bounds wouldn't have caught — tell me where. I'll fix the piece.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0,&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;) — a local, cross-vendor daemon for&lt;br&gt;
running and governing coding agents. Same contract as our&lt;br&gt;
&lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page: dated facts, named strengths,&lt;br&gt;
corrections by issue. Got something wrong?&lt;br&gt;
&lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claudecode</category>
      <category>devtools</category>
    </item>
    <item>
      <title>'Approve All' Is How Your Agent Ships the Dangerous One</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:42 +0000</pubDate>
      <link>https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma</link>
      <guid>https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt;, one of the&lt;br&gt;
tools in this market. The primitives in the second half are real and the&lt;br&gt;
commands are checkable; the problem in the first half stands on its own.&lt;br&gt;
Corrections welcome — file an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You gave your coding agent a shell. Now you live in one of two bad houses.&lt;/p&gt;

&lt;p&gt;In the first house, every risky command stops and asks you. &lt;em&gt;Can I run&lt;br&gt;
&lt;code&gt;git push&lt;/code&gt;? Can I delete this file? Can I &lt;code&gt;curl&lt;/code&gt; this?&lt;/em&gt; You approve, approve,&lt;br&gt;
approve — and somewhere around the two-hundredth reflexive &lt;em&gt;yes&lt;/em&gt;, the one request&lt;br&gt;
that actually mattered slides through on muscle memory.&lt;/p&gt;

&lt;p&gt;In the second house, you got tired of that and ran the agent with&lt;br&gt;
&lt;code&gt;--dangerously-skip-permissions&lt;/code&gt;. Now it never asks. It also never asks before&lt;br&gt;
the &lt;code&gt;rm -rf&lt;/code&gt; in the wrong directory, or the &lt;code&gt;DROP TABLE&lt;/code&gt; against the wrong&lt;br&gt;
&lt;code&gt;DATABASE_URL&lt;/code&gt;, while you're at lunch.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
Auto-approve reads. Gate writes. The line isn't &lt;em&gt;risky vs. safe&lt;/em&gt; — it's&lt;br&gt;
&lt;em&gt;does this change state.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both houses share one bug: they treat "should the agent need approval?" as a&lt;br&gt;
property of your &lt;em&gt;attention&lt;/em&gt; — how much you're willing to click — instead of a&lt;br&gt;
property of the &lt;em&gt;action&lt;/em&gt;. Fix that, and the whole problem changes shape.&lt;/p&gt;
&lt;h2&gt;
  
  
  The line everyone draws in the wrong place
&lt;/h2&gt;

&lt;p&gt;Ask ten teams where the approval boundary goes and you'll get three wrong&lt;br&gt;
answers. By &lt;strong&gt;tool category&lt;/strong&gt;: "shell is dangerous, file-read is fine" — except&lt;br&gt;
&lt;code&gt;cat ~/.aws/credentials&lt;/code&gt; is a read that exfiltrates and &lt;code&gt;echo&lt;/code&gt; can clobber a&lt;br&gt;
file. By &lt;strong&gt;reversibility&lt;/strong&gt;: "block the irreversible stuff" — except you can't&lt;br&gt;
reliably tell at call time what's reversible. By &lt;strong&gt;vibes&lt;/strong&gt;: skip-all until&lt;br&gt;
something breaks.&lt;/p&gt;

&lt;p&gt;The boundary that actually holds is simpler and it's not about the tool at all:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Draw it at state mutation.&lt;/strong&gt; One widely-cited write-up on human-oversight for&lt;br&gt;
code agents (Niklas Heidloff) lands on the exact rule: &lt;em&gt;auto-approve only the&lt;br&gt;
commands that don't change state; gate the ones that do.&lt;/em&gt; Not by tool, not by&lt;br&gt;
reversibility — by whether the world is different afterward. A pure read can run&lt;br&gt;
free. A write waits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And here's why "just approve each one" was never going to save you, stated by the&lt;br&gt;
people who studied it: &lt;strong&gt;manual-approve, skip-all, and static allowlists all fail&lt;br&gt;
the same way.&lt;/strong&gt; Review every action and you hit approval fatigue — after hundreds&lt;br&gt;
of reflexive yeses the dangerous request gets one too. Skip everything and you've&lt;br&gt;
armed the agent. A static allowlist rots the moment the agent needs something&lt;br&gt;
new. The failure isn't your discipline; it's asking a human to be the runtime&lt;br&gt;
permission check.&lt;/p&gt;

&lt;p&gt;That's the same wall from &lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;the trust piece&lt;/a&gt;,&lt;br&gt;
wearing a different hat: you are the serial bottleneck, and "approve each action"&lt;br&gt;
just moves the bottleneck to your clicking finger.&lt;/p&gt;
&lt;h2&gt;
  
  
  How do you gate a risky call today?
&lt;/h2&gt;

&lt;p&gt;Place yourself before you build. Four honest answers, each with its ceiling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You approve each one.&lt;/strong&gt; Every gated call pings you; you click yes. Safe-ish,&lt;br&gt;
and completely unscalable — this is the approval-fatigue trap, and it caps at one&lt;br&gt;
agent you babysit full-time. &lt;em&gt;Ceiling: you, again.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You skip all of it.&lt;/strong&gt; &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt;, YOLO mode. Fast, fully&lt;br&gt;
unattended, and one hallucinated path from a very bad afternoon. &lt;em&gt;Ceiling: the&lt;br&gt;
first destructive command nobody caught.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You keep a static allowlist.&lt;/strong&gt; A file of pre-blessed commands. Better — but it's&lt;br&gt;
frozen; the agent hits something new and either stalls or you widen the list until&lt;br&gt;
it's &lt;code&gt;*&lt;/code&gt;. &lt;em&gt;Ceiling: it can't tell a read from a write, so it over- or&lt;br&gt;
under-blocks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You classify by risk and relay only the writes.&lt;/strong&gt; Read-only calls auto-approve;&lt;br&gt;
state-changing calls pause and route to a decision — a human &lt;em&gt;or&lt;/em&gt; a policy — and&lt;br&gt;
the important ones surface instead of drowning. &lt;em&gt;This is the only one that scales,&lt;br&gt;
and it's the one you can build.&lt;/em&gt; The rest of this piece wires it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where are you?&lt;/strong&gt; If your honest answer is &lt;em&gt;"skip-all, and I hope,"&lt;/em&gt; you don't&lt;br&gt;
have an autonomy setup — you have an unexploded one. Everything below moves the&lt;br&gt;
yes/no off your attention and into the architecture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Rung 1: make the tool declare its own risk
&lt;/h2&gt;

&lt;p&gt;The relay only works if a call knows whether it mutates &lt;em&gt;before&lt;/em&gt; it runs. So put&lt;br&gt;
the risk class on the tool contract, not in a human's head. In agentproto a tool&lt;br&gt;
declares what it changes; a read-only tool mutates nothing and approves itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// a read-only tool — nothing changes, so it runs free&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;knowledgeSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;knowledge.search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// …schema…&lt;/span&gt;
  &lt;span class="na"&gt;mutates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;              &lt;span class="c1"&gt;// touches no state&lt;/span&gt;
  &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// ⇒ auto-approved, never interrupts you&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// a write tool — declares the mutation, so it must be cleared&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;applyPatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs.apply_patch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// …schema…&lt;/span&gt;
  &lt;span class="na"&gt;mutates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;          &lt;span class="c1"&gt;// changes files on disk&lt;/span&gt;
  &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// ⇒ pauses for a decision before it runs&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's "auto-approve reads, gate writes" as two lines of contract instead of a&lt;br&gt;
policy you enforce by clicking. &lt;code&gt;knowledge.search&lt;/code&gt; from&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;the knowledge piece&lt;/a&gt; is literally &lt;code&gt;mutates: []&lt;/code&gt; for&lt;br&gt;
exactly this reason. The boundary is now data, so a machine can enforce it — which&lt;br&gt;
is the whole point of making approval, in the words of one human-in-the-loop&lt;br&gt;
build (Nylas), &lt;strong&gt;a first-class architectural feature, not an afterthought you&lt;br&gt;
bolt on per tool.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rung 2: the permission relay — a pause, not a wall
&lt;/h2&gt;

&lt;p&gt;Now the gated calls need somewhere to go that &lt;em&gt;isn't&lt;/em&gt; a modal blocking your&lt;br&gt;
terminal. agentproto turns a pending write into an item in a cross-session inbox:&lt;br&gt;
the agent pauses, the decision waits, and anyone — or anything — can answer it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# what's waiting on a decision right now?&lt;/span&gt;
permissions_list
&lt;span class="c"&gt;# → [{ id: "perm_9f", sessionId: "sess_42",&lt;/span&gt;
&lt;span class="c"&gt;#      tool: "fs.apply_patch", summary: "write migrations/003_add_index.sql" }]&lt;/span&gt;

&lt;span class="c"&gt;# answer it — approve once, approve-always, or deny&lt;/span&gt;
permissions_respond &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;: &lt;span class="s2"&gt;"perm_9f"&lt;/span&gt;, decision: &lt;span class="s2"&gt;"approve"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things this buys that a terminal prompt doesn't. First, it's &lt;strong&gt;out of band&lt;/strong&gt;:&lt;br&gt;
the approval isn't trapped in one attached session, so a supervisor (or you, from&lt;br&gt;
your phone) can clear it without sitting in front of the agent. Second, it's&lt;br&gt;
&lt;strong&gt;programmable&lt;/strong&gt;: &lt;code&gt;decision&lt;/code&gt; is just &lt;code&gt;approve&lt;/code&gt; / &lt;code&gt;deny&lt;/code&gt;, so the responder can be a&lt;br&gt;
human for the calls that need judgment and a &lt;em&gt;policy&lt;/em&gt; for the calls that don't.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The relay is the L2 rung, built.&lt;/strong&gt; &lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;The supervision ladder&lt;/a&gt;&lt;br&gt;
maps the whole climb from &lt;em&gt;you watch&lt;/em&gt; to &lt;em&gt;a gate decides&lt;/em&gt;; this is the L2&lt;br&gt;
"permission relay" rung as actual wiring. Read-only auto-approves (Rung 1),&lt;br&gt;
risky writes land here, and only the genuinely judgment-worthy ones ever reach a&lt;br&gt;
person. Approval fatigue dies because the reads never showed up in the first&lt;br&gt;
place.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Relaying the write to a human is fine for a &lt;code&gt;DROP TABLE&lt;/code&gt;. But for "did this diff&lt;br&gt;
actually fix the bug," a human clicking approve is just a slower version of the&lt;br&gt;
agent grading itself. Some writes need a &lt;em&gt;check&lt;/em&gt;, not a &lt;em&gt;click&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rung 3: put an external check on the write — and stage the commit behind it
&lt;/h2&gt;

&lt;p&gt;The top rung replaces the human judgment call with something that scales: a gate&lt;br&gt;
that runs &lt;em&gt;outside&lt;/em&gt; the working agent and has to say yes before the write lands.&lt;br&gt;
You attach it to the session, it fires at the end of the agent's turn, and its&lt;br&gt;
verdict — not the agent's self-report — decides what happens next.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c1"&gt;// attach a gate to the session; a green result stages a commit behind YOUR ack&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;attach_policy(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sess_42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;gate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;                              &lt;/span&gt;&lt;span class="c1"&gt;// a shell gate: exit 0 = pass&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pnpm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payments"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src/payments/retry.ts"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// stages EXACTLY these — never `git add -A`&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fix: cap payment retries at 3 (incident #2026-04)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="na"&gt;requireHumanAck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="c1"&gt;// green gate ⇒ waits for your yes&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lifecycle is the part that matters: the gate runs, and on green the policy&lt;br&gt;
doesn't commit — it moves to &lt;code&gt;awaiting-ack&lt;/code&gt; and emits &lt;code&gt;policy:commit-ready&lt;/code&gt;. The&lt;br&gt;
commit &lt;strong&gt;does not happen&lt;/strong&gt; until you call &lt;code&gt;ack_policy({ policyId, approve: true })&lt;/code&gt;,&lt;br&gt;
which stages &lt;em&gt;only&lt;/em&gt; the listed paths (&lt;code&gt;git add -- &amp;lt;paths&amp;gt;&lt;/code&gt;, never &lt;code&gt;-A&lt;/code&gt;, never a&lt;br&gt;
glob), commits, and emits &lt;code&gt;policy:committed&lt;/code&gt;. It never pushes. The agent cannot&lt;br&gt;
reach past the gate to the commit; the gate cannot reach past your ack to the&lt;br&gt;
push.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When exit codes can't judge, spawn a skeptic.&lt;/strong&gt; Swap the shell gate for&lt;br&gt;
&lt;code&gt;gate: { judge: { adapter, prompt } }&lt;/code&gt; and agentproto runs a short-lived LLM&lt;br&gt;
reviewer that ends in &lt;code&gt;VERDICT: PASS|FAIL&lt;/code&gt; — fail-safe, so a timeout or an&lt;br&gt;
unparsable answer counts as FAIL. Prompt it to &lt;em&gt;refute&lt;/em&gt;, not admire ("try to&lt;br&gt;
prove this diff did NOT fix the bug"). That's the &lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;kill-the-loop&lt;/a&gt;&lt;br&gt;
lesson in one primitive: the check has to sit outside the loop it's checking, or&lt;br&gt;
it rubber-stamps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You now have the full plane: reads run free, writes relay, load-bearing writes&lt;br&gt;
wait on an external verdict, and the irreversible act — the commit — is staged&lt;br&gt;
behind one human yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest edges (the gotchas that bit me)
&lt;/h2&gt;

&lt;p&gt;This is real infrastructure, which means it has sharp corners. Four I hit live,&lt;br&gt;
so you don't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The gate runs against an allowlist, and &lt;code&gt;test&lt;/code&gt; isn't on it.&lt;/strong&gt; Shell gates go
through the same default-deny allowlist as any command
(&lt;code&gt;.agentproto/allowed-commands.json&lt;/code&gt;). &lt;code&gt;test -f x&lt;/code&gt; fails with &lt;em&gt;not in
allowlist&lt;/em&gt; → the policy goes &lt;code&gt;blocked&lt;/code&gt;. Use an allowlisted binary — &lt;code&gt;ls x&lt;/code&gt;, not
&lt;code&gt;test -f x&lt;/code&gt;; &lt;code&gt;pnpm&lt;/code&gt;/&lt;code&gt;node&lt;/code&gt; for tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The gate's working directory is anchored to the workspace.&lt;/strong&gt; A session whose
cwd is &lt;em&gt;outside&lt;/em&gt; the workspace fails the gate with &lt;code&gt;cwd escapes the workspace&lt;/code&gt;.
If you run agents in per-feature worktrees outside the repo root, shell gates
are effectively unusable — fall back to &lt;code&gt;then: "emit"&lt;/code&gt; (milestone only) and
verify the result yourself with &lt;code&gt;git&lt;/code&gt;/&lt;code&gt;gh&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attach before the turn ends.&lt;/strong&gt; The gate fires on &lt;code&gt;turn-end&lt;/code&gt;; attach the policy
&lt;em&gt;before&lt;/em&gt; the session finishes its turn (spawn idle → attach → prompt), or you
race the event and miss it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The durable auto-supervisor is still volatile.&lt;/strong&gt; The RoutineRunner that would
babysit this across many steps is an in-memory MVP today — a daemon restart
drops in-flight runs. The pieces that survive are the ones above:
&lt;code&gt;attach_policy&lt;/code&gt;, the event bus, the ack. Don't build a control tower on the part
that isn't load-bearing yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the fair comparison, because credibility depends on it. &lt;strong&gt;Claude Code already&lt;br&gt;
ships a good version of Rung 1–2&lt;/strong&gt; — per-command permission prompts and an&lt;br&gt;
allowlist, built in, zero setup. If you live entirely in one vendor's agent,&lt;br&gt;
you may not need to wire any of this. Two things you're trading for that&lt;br&gt;
convenience: the approval dies with the session (close the terminal, lose the&lt;br&gt;
relay), and it's single-vendor — it won't clear a pending write from your Codex&lt;br&gt;
agent or a cheap local model. An approval plane that spans &lt;em&gt;every&lt;/em&gt; agent you run,&lt;br&gt;
and survives your laptop sleeping, is the part a per-tool prompt can't give you.&lt;br&gt;
The broader principle underneath all of it is OWASP's &lt;strong&gt;least agency&lt;/strong&gt;: grant the&lt;br&gt;
minimum autonomy, tools, and credential scope the task needs — and make the&lt;br&gt;
grant a decision the architecture enforces, not one you re-make by clicking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give it the keys, keep the ignition
&lt;/h2&gt;

&lt;p&gt;Autonomy was never the scary part. An agent that can read your whole codebase,&lt;br&gt;
run your tests, and draft the fix is exactly what you want. The scary part is the&lt;br&gt;
&lt;em&gt;write&lt;/em&gt; — the one command that changes something you can't un-change — landing&lt;br&gt;
because you were too tired to catch it or too far away to be asked.&lt;/p&gt;

&lt;p&gt;So stop deciding approval with your attention and start deciding it with the&lt;br&gt;
action. Auto-approve the reads; they can't hurt you. Relay the writes; a human or&lt;br&gt;
a policy clears them. Put an external check on the writes that matter, and stage&lt;br&gt;
the one irreversible act — the commit — behind a single deliberate yes. The agent&lt;br&gt;
proposes. Something outside the agent disposes. That's the whole plane.&lt;/p&gt;

&lt;p&gt;Give your agent the keys. Just keep the ignition where it can't reach it.&lt;/p&gt;

&lt;p&gt;If your setup draws the approval line somewhere smarter than state mutation, or&lt;br&gt;
you've made approve-each actually scale, tell me where — I'll fix the piece.&lt;/p&gt;




&lt;h3&gt;
  
  
  The series — &lt;em&gt;Orchestration, Honestly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Ten pieces, one argument. Start anywhere; each one cross-links the rest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;The one idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can't parallelize the trust&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Amdahl's Law: why your fifth agent slows you down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69"&gt;Harness engineering&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;you rent the model; the harness is the part you own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;The supervision ladder&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;five rungs of trusting an agent you don't watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The approval plane&lt;/strong&gt; &lt;em&gt;(you're here)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;auto-approve reads, gate writes — wire the line between&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;Kill the loop&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;why "keep going until done" compounds a wrong turn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Route by cost&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;plan expensive, execute cheap, verify independently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Files with contracts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the interop layer every agent system reinvents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;Knowledge is power&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;give your agent your knowledge, not the internet's average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/saying-hi-to-this-agent-daemon-cost-029-a-rivals-hands-on-paseo-review-e7i"&gt;Paseo, hands-on&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;a full real-session review of the daemon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk"&gt;9 orchestrators, compared&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the tool-by-tool teardown + a decision table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0, &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Same contract as our &lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page — dated facts, named strengths, corrections by issue. Got something wrong? &lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claudecode</category>
      <category>devtools</category>
    </item>
    <item>
      <title>You're Optimizing the Part of Your Agent You Don't Own</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:40 +0000</pubDate>
      <link>https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69</link>
      <guid>https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt;, one of the&lt;br&gt;
tools in this market. Every fact below is dated and sourced; the tool-by-tool&lt;br&gt;
review lives in&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk"&gt;9 coding-agent orchestrators, compared&lt;/a&gt; where&lt;br&gt;
competitors' strengths are named. Corrections welcome — file an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Open any dev feed this week and count how many arguments are about the model.&lt;br&gt;
Which one codes best. Which one dropped. Which benchmark moved two points.&lt;/p&gt;

&lt;p&gt;It's the wrong fight. Here's the receipt that should end it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The receipt.&lt;/strong&gt; LangChain took a coding agent from &lt;strong&gt;rank 30 to the top 5 on&lt;br&gt;
Terminal-Bench without changing the model&lt;/strong&gt; — the wins came from the scaffolding&lt;br&gt;
around it, not a better brain. Same weights, thirty places, harness only.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sit with that. The single biggest jump they got came from the part you can&lt;br&gt;
actually edit — and most people spend their attention on the part they can't.&lt;/p&gt;

&lt;h2&gt;
  
  
  You rent the model. You own the harness.
&lt;/h2&gt;

&lt;p&gt;You did not train the model. You can't change its weights, you can't see its&lt;br&gt;
training data, and next quarter the vendor swaps it for a new one and your&lt;br&gt;
carefully-tuned prompts quietly stop meaning what they meant. The model is a&lt;br&gt;
&lt;strong&gt;rental&lt;/strong&gt;. It's a good rental — but it's not yours, and it moves under you.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;harness&lt;/em&gt; is everything you wrap around that rental to turn a raw&lt;br&gt;
token-predictor into something that ships work: the system prompt, the tools, the&lt;br&gt;
memory, the loop, the checks, the sandbox it runs in. Anthropic's own harness&lt;br&gt;
team defines it exactly this way — the harness is "everything wrapped around a&lt;br&gt;
model that turns raw capability into completed work."&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
You rent the model. You own the harness. Stop optimizing the rental.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it turns out the harness is the bigger lever anyway. LangChain's own writeup&lt;br&gt;
is one data point; the broader pattern is that harness-only changes repeatedly&lt;br&gt;
beat model swaps. The field even has a name for the discipline now —&lt;br&gt;
"harness engineering" — with a whole awesome-list of tools for it. The model got&lt;br&gt;
commoditized while you weren't looking. The scaffolding is where the craft moved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which era are you working in?
&lt;/h2&gt;

&lt;p&gt;There's a clean way to place yourself, and it's basically the history of this job&lt;br&gt;
in three steps. Anthropic's context-engineering post lays out the first two; the&lt;br&gt;
long-running-agent writeups add the third. Find the one that sounds like your&lt;br&gt;
week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Era 1 — prompt engineering.&lt;/strong&gt; You get better results by wording the ask&lt;br&gt;
better. Few-shot examples, "think step by step," role-play framing. This still&lt;br&gt;
matters, but it's table stakes now, and it's the most fragile layer — a model&lt;br&gt;
upgrade can silently rewrite what your clever phrasing does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Era 2 — context engineering.&lt;/strong&gt; You realized the bottleneck isn't the wording,&lt;br&gt;
it's &lt;em&gt;what's in the window&lt;/em&gt;. Anthropic's framing: treat context as a finite&lt;br&gt;
attention budget, because recall degrades as the window fills — "context rot,"&lt;br&gt;
where attention spreads thinner across every added token. You curate what the&lt;br&gt;
model sees, load facts just-in-time, and keep state on disk instead of in the&lt;br&gt;
transcript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Era 3 — harness engineering.&lt;/strong&gt; You stopped tuning any single call and started&lt;br&gt;
designing the &lt;em&gt;system&lt;/em&gt; the model runs inside: the loop, the tools, the roles, the&lt;br&gt;
gates, the sandbox. The model became one swappable component in a machine you&lt;br&gt;
built.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where are you?&lt;/strong&gt; If your honest answer is &lt;em&gt;"I write really good prompts,"&lt;/em&gt;&lt;br&gt;
you're in Era 1 — doing real work on the most rented, most fragile layer. Every&lt;br&gt;
rung past here is about moving leverage into the part you keep.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most teams are stuck somewhere in Era 1, blaming the model for failures the&lt;br&gt;
harness was supposed to catch. So let's climb.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rung 1: a loop grounded in truth, and nothing more
&lt;/h2&gt;

&lt;p&gt;The minimal harness is almost embarrassingly small. Anthropic's "Building&lt;br&gt;
effective agents" reduces it to one line: an agent is a tool-using model in a&lt;br&gt;
loop, grounded in feedback from the real environment. Not a framework. A loop&lt;br&gt;
that checks reality.&lt;/p&gt;

&lt;p&gt;Start there and resist the urge to add. The same post is blunt about it: begin&lt;br&gt;
with the simplest thing and add complexity &lt;strong&gt;only when it measurably helps&lt;/strong&gt;,&lt;br&gt;
because frameworks bury the actual prompts and responses under abstraction and&lt;br&gt;
make failures harder to debug. Most "my agent is dumb" bugs are a harness that&lt;br&gt;
grew faster than it earned.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The tell.&lt;/strong&gt; If you can't name what each piece of your scaffolding is &lt;em&gt;for&lt;/em&gt; —&lt;br&gt;
which specific model weakness it patches — that piece is probably cargo. The&lt;br&gt;
loop grounded in ground truth is the only part you always need.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Rung 2: get the right things into the window, keep the rest out
&lt;/h2&gt;

&lt;p&gt;Once the loop works, the next failure is the model drowning in its own history.&lt;br&gt;
This is the Era-2 move made structural. The long-running-agent playbooks compress&lt;br&gt;
it to three verbs — &lt;strong&gt;Reduce, Offload, Isolate&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduce&lt;/strong&gt; — compact old tool calls into summaries once history crosses a
threshold, so the window stays high-signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offload&lt;/strong&gt; — write the plan, the progress, and the rules to a file on disk
(a &lt;code&gt;NOTES.md&lt;/code&gt;, a task list), not the transcript. State outside the context
window survives a reset; state inside it evaporates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolate&lt;/strong&gt; — push exploration into sub-agents with clean windows that burn ten
thousand tokens and hand back a five-line summary. The dirty context never
touches the main thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The knowledge you feed it is part of this budget too — and &lt;em&gt;whose&lt;/em&gt; knowledge&lt;br&gt;
decides how much of the internet's average you're stuck with, which is&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;its own piece&lt;/a&gt;. The rule underneath all of it:&lt;br&gt;
the best context is the &lt;em&gt;smallest&lt;/em&gt; set of high-signal tokens that lets the model&lt;br&gt;
take its next step — even when the window could hold a thousand times more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rung 3: stop letting the worker grade its own work
&lt;/h2&gt;

&lt;p&gt;Here's the harness component people skip, and it's the one that fails silently.&lt;br&gt;
An agent asked &lt;em&gt;"are you done?"&lt;/em&gt; says yes too early — models grade their own&lt;br&gt;
output too leniently, seeing a button render and calling the feature shipped.&lt;br&gt;
Anthropic's harness team found the fix isn't a smarter prompt; it's a&lt;br&gt;
&lt;strong&gt;structural split&lt;/strong&gt;, a generator-and-evaluator loop where the two roles are&lt;br&gt;
separate and the evaluator is tuned to be skeptical.&lt;/p&gt;

&lt;p&gt;The mature version splits three ways — planner, generator, evaluator — because&lt;br&gt;
each targets a &lt;em&gt;different&lt;/em&gt; failure: the planner fixes under-scoping, the generator&lt;br&gt;
does the work, the evaluator catches the lie. This is the whole spine of the&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;supervision ladder&lt;/a&gt;; the point here is narrower —&lt;br&gt;
&lt;strong&gt;the evaluator is a harness component you install, not a mood the model gets&lt;br&gt;
into.&lt;/strong&gt; Bolt it outside the working agent's loop, or it grades itself and passes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Receipt.&lt;/strong&gt; This is also why "just loop until done" isn't reliability. A loop&lt;br&gt;
gives the agent persistence, not correctness — the completion check has to live&lt;br&gt;
&lt;em&gt;outside&lt;/em&gt; the loop or it rubber-stamps a wrong turn fifty times. That argument&lt;br&gt;
has &lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;its own piece&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Rung 4: make the parts swappable
&lt;/h2&gt;

&lt;p&gt;The resilient harness treats the model as a component, not the center of gravity.&lt;br&gt;
Addy Osmani's long-running-agent writeup names the split cleanly — &lt;strong&gt;decouple the&lt;br&gt;
Brain, the Hands, and the Session&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Brain&lt;/strong&gt; — the model plus its loop. Replaceable: swap Claude for a cheap open
model on a task that doesn't need frontier reasoning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hands&lt;/strong&gt; — the ephemeral sandbox where code runs and gets thrown away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session&lt;/strong&gt; — the durable state and history, which outlives any single run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Decoupled, each part upgrades on its own clock. Your rented Brain changes every&lt;br&gt;
quarter; your Hands and Session don't have to. This is also what makes cost&lt;br&gt;
routing possible at all — plan on an expensive Brain, execute on a cheap one, and&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;the routing math&lt;/a&gt; only works because the harness let you&lt;br&gt;
swap the engine without rebuilding the car.&lt;/p&gt;

&lt;p&gt;There's an interop tax hiding here, though: today every tool speaks its own&lt;br&gt;
dialect of "agent behavior as files" — &lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;SKILL.md&lt;/code&gt;, all&lt;br&gt;
mutually invisible — so a capability you built for one Brain doesn't travel to the&lt;br&gt;
next. Fixing that with contracts instead of yet another framework is&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;a companion piece&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rung 5: the best harness engineers delete scaffolding
&lt;/h2&gt;

&lt;p&gt;Now the counterintuitive top of the ladder, and the part almost nobody says out&lt;br&gt;
loud. &lt;strong&gt;Every piece of your harness encodes an assumption that the model is bad at&lt;br&gt;
something. When the model gets good at it, that piece becomes dead weight.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Multiple harness writers land on the same warning independently — it's the Bitter&lt;br&gt;
Lesson arriving at the application layer. The context resets, the sprint&lt;br&gt;
decomposition, the elaborate verification dance: each one exists to patch a&lt;br&gt;
weakness in &lt;em&gt;this&lt;/em&gt; model generation. LangChain's own history shows it — the same&lt;br&gt;
scaffolding that lifted an agent to the top 5 becomes drag once a stronger model&lt;br&gt;
ships and no longer needs it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The move most teams miss.&lt;/strong&gt; On every model upgrade, don't just enjoy the&lt;br&gt;
bump — &lt;strong&gt;re-audit your harness and rip out the scaffolding the new model made&lt;br&gt;
pointless.&lt;/strong&gt; The harness that wins in 2026 is lighter than the one that won in&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Growing your harness forever is how you end up slower than someone running
a plain loop on a better model.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the discipline in one sentence: build the scaffolding the model needs&lt;br&gt;
today, and be ruthless about deleting it the day it doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vendors will sell you a harness. It just won't be yours.
&lt;/h2&gt;

&lt;p&gt;Here's the fair part, because the whole argument depends on it. The model vendors&lt;br&gt;
are shipping harnesses too, and they're good. Claude Code &lt;em&gt;is&lt;/em&gt; a harness. Managed&lt;br&gt;
Agents is Anthropic's hosted meta-harness — session, sandbox, and loop&lt;br&gt;
virtualized behind a stable interface, April 2026. If you want the harness to be&lt;br&gt;
someone else's problem, that is a genuine, less-work answer, and I won't pretend&lt;br&gt;
otherwise.&lt;/p&gt;

&lt;p&gt;Two things you're trading away, though, and they're exactly the two the whole&lt;br&gt;
piece has been about. A hosted harness is &lt;strong&gt;their&lt;/strong&gt; harness, wrapped around&lt;br&gt;
&lt;strong&gt;their&lt;/strong&gt; model, on &lt;strong&gt;their&lt;/strong&gt; plan — so you can't prune it (Rung 5 isn't yours to&lt;br&gt;
do), and you can't swap the Brain for a cheaper or open one (Rung 4 is off the&lt;br&gt;
table). You've rented the model &lt;em&gt;and&lt;/em&gt; the harness. The one part that was supposed&lt;br&gt;
to be yours went back to being a rental.&lt;/p&gt;

&lt;p&gt;The alternative is to own the harness as portable infrastructure — the checks,&lt;br&gt;
the contracts, the roles living in &lt;em&gt;your&lt;/em&gt; repo and running on &lt;em&gt;your&lt;/em&gt; machine,&lt;br&gt;
around any model. That's the whole design of what I build:&lt;br&gt;
&lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; is a local daemon with adapters for Claude&lt;br&gt;
Code, Codex, and open models via OpenRouter or Hermes, so the harness you tune&lt;br&gt;
travels when you swap the engine, and no vendor holds the keys. Concede the&lt;br&gt;
hosted route is less setup. Just know what you gave up to skip it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tune the car, not the rental
&lt;/h2&gt;

&lt;p&gt;So the feed has it backwards. The model you're all arguing about is the one thing&lt;br&gt;
in the whole system you can't change and won't keep. The harness — the loop, the&lt;br&gt;
context budget, the evaluator, the swappable parts, the scaffolding you're brave&lt;br&gt;
enough to delete — is the part that's yours, the part that moved a coding agent&lt;br&gt;
thirty places without a new model, and the part your competitors are ignoring&lt;br&gt;
while they refresh the benchmark leaderboard.&lt;/p&gt;

&lt;p&gt;Two questions turn this into Monday's work. When your agent fails, do you reach&lt;br&gt;
for a better prompt, or do you ask which harness component was supposed to catch&lt;br&gt;
it? And when the next model drops, do you just feel faster — or do you open your&lt;br&gt;
harness and delete what it made obsolete?&lt;/p&gt;

&lt;p&gt;Rent the best engine you can. Then go build a car worth putting it in.&lt;/p&gt;

&lt;p&gt;If your harness beats this framing — or you've found a scaffold worth keeping that&lt;br&gt;
I'd have told you to cut — tell me where. I'll fix the piece.&lt;/p&gt;




&lt;h3&gt;
  
  
  The series — &lt;em&gt;Orchestration, Honestly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Ten pieces, one argument. Start anywhere; each one cross-links the rest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;The one idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can't parallelize the trust&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Amdahl's Law: why your fifth agent slows you down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Harness engineering&lt;/strong&gt; &lt;em&gt;(you're here)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;you rent the model; the harness is the part you own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;The supervision ladder&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;five rungs of trusting an agent you don't watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;The approval plane&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;auto-approve reads, gate writes — wire the line between&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;Kill the loop&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;why "keep going until done" compounds a wrong turn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Route by cost&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;plan expensive, execute cheap, verify independently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Files with contracts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the interop layer every agent system reinvents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;Knowledge is power&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;give your agent your knowledge, not the internet's average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/saying-hi-to-this-agent-daemon-cost-029-a-rivals-hands-on-paseo-review-e7i"&gt;Paseo, hands-on&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;a full real-session review of the daemon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk"&gt;9 orchestrators, compared&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the tool-by-tool teardown + a decision table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0, &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Same contract as our &lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page — dated facts, named strengths, corrections by issue. Got something wrong? &lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claudecode</category>
      <category>devtools</category>
    </item>
    <item>
      <title>9 Coding-Agent Orchestrators, Honestly Compared (Dated, Sourced, and One of Them Is Mine)</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:37 +0000</pubDate>
      <link>https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk</link>
      <guid>https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt;, one of the&lt;br&gt;
nine tools below. Every fact is dated and pulled from each project's own docs&lt;br&gt;
or repo; where a competitor beats me, it says so in plain text. Corrections&lt;br&gt;
welcome — file an issue, I'll fix it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most "best orchestrator" roundups rank. They hand you a leaderboard, crown a&lt;br&gt;
winner, and leave you to discover three weeks later that the winner solves a&lt;br&gt;
problem you don't have.&lt;/p&gt;

&lt;p&gt;This one doesn't rank. It &lt;em&gt;places&lt;/em&gt;. Because the awesome list has grown past&lt;br&gt;
&lt;a href="https://github.com/andyrewlee/awesome-agent-orchestrators" rel="noopener noreferrer"&gt;fifty entries&lt;/a&gt; and&lt;br&gt;
half of them changed shape in the last six months — so the useful question was&lt;br&gt;
never "which is best," it's "which one fits the specific way my setup hurts."&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
A ranking tells you who won. A map tells you where you are. Two questions&lt;br&gt;
locate any orchestrator on it — &lt;em&gt;who checks the work, and who equips the&lt;br&gt;
agents&lt;/em&gt; — and almost every tool answers one while quietly dodging the other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those two questions are the ones &lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;the landscape&lt;br&gt;
piece&lt;/a&gt; ends on, and they're not&lt;br&gt;
arbitrary. They're the two halves of the bottleneck that caps every agent&lt;br&gt;
fleet: the judgment that decides "done" is true, and the plumbing that gets a&lt;br&gt;
new capability to every agent instead of one. Everything else a tool advertises&lt;br&gt;
— panes, voice, kanban swimlanes — is UX on top of how it answers those two.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Method: each project's own docs and repo, checked 2026-07-07 → 2026-07-14, plus&lt;br&gt;
hands-on sessions where noted. Supervision rungs refer to&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;the ladder&lt;/a&gt;: L0 you watch, L1 watchdogs, L2&lt;br&gt;
permission relay, L3 verifier loops, L4 external policy gates.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The two questions, and why the map has two axes instead of ten
&lt;/h2&gt;

&lt;p&gt;Strip a tool's branding and it answers two questions or dodges them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question one — who checks the work?&lt;/strong&gt; When the agent says "done," what decides&lt;br&gt;
whether that's true? This is the supervision ladder: at the bottom (L0) the&lt;br&gt;
checker is you, reading a diff; at the top (L4) it's a process the agent can't&lt;br&gt;
see or sweet-talk, holding the commit until a gate passes. The rung &lt;em&gt;is&lt;/em&gt; the&lt;br&gt;
answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question two — who equips the agents?&lt;/strong&gt; When you give one agent a new tool or&lt;br&gt;
skill, how many of the others get it for free? For almost every tool the answer&lt;br&gt;
is &lt;em&gt;zero&lt;/em&gt; — you rewire each agent by hand, which is the quiet serial tax nobody&lt;br&gt;
puts on the pricing page. The vendors equip agents, but only inside their own&lt;br&gt;
walls. Exactly one tool on this list distributes &lt;em&gt;your&lt;/em&gt; tools to &lt;em&gt;every&lt;/em&gt; agent;&lt;br&gt;
that's &lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;its own companion piece&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Plot both and the field sorts into a shape, not a ranking. Cockpits answer&lt;br&gt;
question one with your eyeballs and dodge question two. Steering tools give the&lt;br&gt;
human a nicer surface and dodge both. Only the daemon shape can even reach the&lt;br&gt;
top-right corner — and only one is standing there. Let's walk the map.&lt;/p&gt;

&lt;h2&gt;
  
  
  The daemons: the only shape that can answer both
&lt;/h2&gt;

&lt;p&gt;A daemon is a long-lived process that owns sessions behind an API. It's the only&lt;br&gt;
shape that can run &lt;em&gt;unattended&lt;/em&gt; — which is the only shape that can answer&lt;br&gt;
question one above rung L2, and question two at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  agentproto (disclosure: mine)
&lt;/h3&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%2Flto5qfq48dz66fc22x72.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%2Flto5qfq48dz66fc22x72.png" alt="agentproto homepage" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Local daemon + CLI, Apache-2.0, 0.5.0-alpha. Nine adapters under one manifest&lt;br&gt;
contract (Claude Code, Claude SDK with Anthropic/Moonshot/OpenRouter gateways,&lt;br&gt;
Codex, Hermes, opencode, Mastra Code + Agent, browser-as-agent). The three bets&lt;br&gt;
are exactly the two questions plus the safety to delegate them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Checks the work: L4.&lt;/strong&gt; A completion policy attaches to a session; at
turn-end a gate fires — a shell command (lint/tests/typecheck) or a skeptical
judge model — and the commit is staged behind a human ack. It runs &lt;em&gt;on the
daemon&lt;/em&gt;, so it survives your laptop closing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equips the agents: yes — and this is the rare one.&lt;/strong&gt; You author a tool once
(a TOOL contract + a DRIVER implementation, plain files) and the daemon serves
it over MCP to &lt;em&gt;every&lt;/em&gt; agent; external MCP servers can be imported and handed
to any agent at spawn. Write once, every agent gets it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role-gated nested orchestration:&lt;/strong&gt; executors can't spawn, supervisors can
(with depth and children caps), so an agent can safely manage a team without
fork-bombing your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Weaknesses, honestly: alpha APIs that will move under you, no mobile client, no&lt;br&gt;
voice, terminal-native UX only. And of ~52 numbered AIP specs, the daemon plus&lt;br&gt;
core adapters are operational — the rest is early scaffolding. If your&lt;br&gt;
bottleneck is steering from a phone, this is the wrong tool; keep reading.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paseo — the strongest steering tool on this list
&lt;/h3&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%2Fikr2h6lbkqvfzrproick.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%2Fikr2h6lbkqvfzrproick.png" alt="Paseo homepage" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other real daemon, and — credit where it's due — the best tool here for&lt;br&gt;
&lt;em&gt;driving agents from anywhere&lt;/em&gt;. 10.3k★ (as of 2026-07-13), AGPL-3.0, a one-man&lt;br&gt;
company. Daemon plus&lt;br&gt;
desktop / iOS / Android / web / CLI clients, QR pairing, voice control (local or&lt;br&gt;
OpenAI STT/TTS), an official Docker image, and a self-hostable web UI. Five&lt;br&gt;
first-class providers (Claude Code, Codex, Copilot, OpenCode, Pi) &lt;em&gt;plus&lt;/em&gt; custom&lt;br&gt;
ones — custom binaries, ACP agents, Anthropic-compatible endpoints like Z.AI and&lt;br&gt;
Qwen. Recurring schedules with run history. Its MCP server is opt-in&lt;br&gt;
(&lt;code&gt;daemon.mcp.enabled&lt;/code&gt;) so Claude Desktop or Code can drive it.&lt;/p&gt;

&lt;p&gt;I didn't just read the docs — I installed it and ran the permission relay end to&lt;br&gt;
end. Launch an agent in always-ask mode, watch it freeze on a &lt;code&gt;Write&lt;/code&gt;, approve&lt;br&gt;
from another terminal with &lt;code&gt;paseo permit allow&lt;/code&gt;, task completes. It works&lt;br&gt;
exactly as advertised.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Two gotchas from the actual session (2026-07-13).&lt;/strong&gt; The default Claude model&lt;br&gt;
is Opus, so our one-word &lt;code&gt;"hi"&lt;/code&gt; cost &lt;strong&gt;$0.29&lt;/strong&gt; before we'd typed a real prompt.&lt;br&gt;
And every &lt;code&gt;run&lt;/code&gt; spins up a fresh workspace unless you pass &lt;code&gt;--workspace&lt;/code&gt;. Full&lt;br&gt;
log in the &lt;a href="https://dev.to/agentiknet/saying-hi-to-this-agent-daemon-cost-029-a-rivals-hands-on-paseo-review-e7i"&gt;hands-on review&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now place it on the map. &lt;strong&gt;Checks the work: L2/L3&lt;/strong&gt; — it relays the agent's &lt;em&gt;own&lt;/em&gt;&lt;br&gt;
permission prompts to a nicer surface, plus a Ralph-loop skill with an optional&lt;br&gt;
verifier. There's no L4: no daemon-side turn-end gate, no commit staging.&lt;br&gt;
&lt;strong&gt;Equips the agents: no&lt;/strong&gt; — &lt;code&gt;injectIntoAgents&lt;/code&gt; pushes &lt;em&gt;Paseo's&lt;/em&gt; control tools&lt;br&gt;
into agents, but there's no way to write &lt;em&gt;your&lt;/em&gt; tool once and have every agent&lt;br&gt;
get it. So: unbeatable at question one's ergonomics, silent on question two. If&lt;br&gt;
your bottleneck is steering from the couch, stop here — it's excellent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cockpits: your eyeballs are the checker
&lt;/h2&gt;

&lt;p&gt;A cockpit is an interface you sit &lt;em&gt;inside&lt;/em&gt; and review from. Every one answers&lt;br&gt;
question one with "you, watching" (rung L0) and question two with "you, rewiring&lt;br&gt;
each agent by hand." That's not a knock — for exploratory work L0 is the &lt;em&gt;right&lt;/em&gt;&lt;br&gt;
rung. It's a ceiling, and the ceiling is your own attention.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The ceiling, measured.&lt;/strong&gt; Tools whose supervision model is "a human watches&lt;br&gt;
each pane" have no programmatic API, no per-turn gates, and state that&lt;br&gt;
evaporates when the app closes — &lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;the ladder piece has the exact&lt;br&gt;
wall&lt;/a&gt;. Teams then hand-roll tmux-plus-Redis&lt;br&gt;
watchdogs to compensate — reinventing a daemon badly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Claude Squad&lt;/strong&gt; — the terminal-first classic.&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%2Fvtcqsty9l0k7i6six9ag.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%2Fvtcqsty9l0k7i6six9ag.png" alt="Claude Squad" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AGPL-3.0 TUI over tmux + git worktrees, multi-agent (Claude Code, Codex, Gemini,&lt;br&gt;
Aider), &lt;code&gt;brew install claude-squad&lt;/code&gt; (needs tmux + gh). One isolated workspace per&lt;br&gt;
task, review by hand. L0 by design — you are the loop. No API, so question two&lt;br&gt;
never even comes up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conductor&lt;/strong&gt; — the most polished L0 cockpit.&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%2Fj3vgrqq5tw03u649vcug.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%2Fj3vgrqq5tw03u649vcug.png" alt="Conductor homepage" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Closed-source Mac app: clones your repo, gives each agent (Claude Code, Codex,&lt;br&gt;
Cursor) its own git-worktree workspace, with a genuinely strong diff viewer and&lt;br&gt;
PR flow. A Conductor Cloud variant exists. macOS only, no programmatic surface —&lt;br&gt;
review throughput is the whole product, and it's good at it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crystal → Nimbalyst&lt;/strong&gt; — the shape outlives the app.&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%2Fkwgbd8qbrwli9tdht7hi.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%2Fkwgbd8qbrwli9tdht7hi.png" alt="Nimbalyst homepage" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Crystal (Stravu's Electron app, the first GUI for parallel Claude Code/Codex&lt;br&gt;
sessions in worktrees) was &lt;strong&gt;deprecated in February 2026&lt;/strong&gt;; Nimbalyst is the&lt;br&gt;
successor — same model plus a session kanban, a linked task board, one-click&lt;br&gt;
worktree isolation, a per-session diff sidebar, and the &lt;em&gt;only native iOS app in&lt;br&gt;
the category&lt;/em&gt; with push-on-input. Still L0 at heart, but the mobile monitoring&lt;br&gt;
nudges it toward "watch from anywhere." Open-source, Mac/Windows/Linux + iOS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibe Kanban&lt;/strong&gt; — the cautionary data point.&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%2Fyov5ivri0nn5txnyzua4.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%2Fyov5ivri0nn5txnyzua4.png" alt="Vibe Kanban homepage" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent kanban board — and the reason "who maintains this?" is a real column&lt;br&gt;
in the table below.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The sustainability receipt, now dated.&lt;/strong&gt; Bloop, the company behind Vibe&lt;br&gt;
Kanban, &lt;strong&gt;shut down in April 2026&lt;/strong&gt;; the project survives only as&lt;br&gt;
community-maintained open source with its cloud services sunset. It's not&lt;br&gt;
alone — Opcode (formerly Claudia) is no longer actively developed, and Crystal&lt;br&gt;
became Nimbalyst. Evaluate open-source agent tools as &lt;em&gt;local tools you own&lt;/em&gt;,&lt;br&gt;
not as SaaS with a support guarantee. (Nimbalyst's own 2026 roundup of&lt;br&gt;
agent-management tools makes the same point.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The batch runner and the remote control
&lt;/h2&gt;

&lt;p&gt;Two tools that look like supervision from a distance and turn out to answer&lt;br&gt;
question one with an asterisk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code Agent Farm&lt;/strong&gt; — L1, and honest about it.&lt;/p&gt;

&lt;p&gt;MIT Python batch runner: throw dozens of Claude Code instances at a lint/type-fix&lt;br&gt;
queue (its repo demos 20+), coordinated by tmux + lock files, with an HTML&lt;br&gt;
report and a workload watchdog that auto-restarts stalled agents. That watchdog&lt;br&gt;
&lt;em&gt;is&lt;/em&gt; its answer to question one — and a watchdog keeps the process alive, it&lt;br&gt;
says nothing about whether the output is right. &lt;strong&gt;Restart twenty stalled agents&lt;br&gt;
enough times overnight and by morning you don't have correct code — you have&lt;br&gt;
twenty confident reports and one shared mistake, multiplied.&lt;/strong&gt; Claude Code only,&lt;br&gt;
by design. The right tool for exactly one job, and it doesn't pretend otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Omnara&lt;/strong&gt; — L2, plus the sharpest architecture lesson on the list.&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%2Fqmr6fif8bq84lr5owo7v.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%2Fqmr6fif8bq84lr5owo7v.png" alt="Omnara homepage" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YC S25, Apache-2.0 apps. Syncs coding-agent sessions (Claude Code, Codex, n8n)&lt;br&gt;
across terminal, web, and mobile, with notifications and human-in-the-loop&lt;br&gt;
replies — so its answer to question one is "you, from your phone" (L2). In 2026&lt;br&gt;
it pivoted to a hosted, voice-first managed-agents platform. The pivot carries a&lt;br&gt;
lesson worth more than the feature list:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't build on a CLI you don't control.&lt;/strong&gt; Omnara originally &lt;em&gt;wrapped&lt;/em&gt; the&lt;br&gt;
Claude Code CLI and had to abandon that architecture — constant upstream CLI&lt;br&gt;
changes made the wrapper unmaintainable. It rebuilt on the stable Claude Agent&lt;br&gt;
SDK. Intercepting a fast-moving interactive CLI is a losing architecture; build&lt;br&gt;
on a programmatic layer. (Per Omnara's own GitHub README.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The competitor that isn't on the awesome list
&lt;/h2&gt;

&lt;p&gt;Here's the fair part, because credibility depends on it. The biggest competitor&lt;br&gt;
to every tool above isn't a third-party tool — it's the model vendors absorbing&lt;br&gt;
orchestration natively, and their integration reaches deeper than any outsider's&lt;br&gt;
can.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What shipped, dated.&lt;/strong&gt; Claude Code Agent Teams; Dynamic Workflows (Claude&lt;br&gt;
writing its own orchestration script); &lt;strong&gt;Outcomes&lt;/strong&gt; — a grader model that&lt;br&gt;
scores work against your rubric and forces retries, a legitimate &lt;strong&gt;L3&lt;/strong&gt;;&lt;br&gt;
&lt;strong&gt;Advisor&lt;/strong&gt; — a cheap executor consulting a stronger model mid-turn; and&lt;br&gt;
Managed Agents, Anthropic's hosted meta-harness. If you're an all-Claude shop&lt;br&gt;
on a Team plan, that's a real answer to question one, closer to the model than&lt;br&gt;
I'll ever sit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So why does third-party orchestration outlive it? Two structural limits, and&lt;br&gt;
they're both about the two questions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The catch that sends you cross-vendor.&lt;/strong&gt; Every vendor stack is&lt;br&gt;
&lt;em&gt;single-vendor by construction&lt;/em&gt; — Advisor has the same single-vendor,&lt;br&gt;
encrypted-advice catch as Agent Teams; &lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;see the landscape&lt;br&gt;
piece&lt;/a&gt; for the compatibility-table&lt;br&gt;
breakdown. That rules out the exact case where checking pays off most: a cheap&lt;br&gt;
open executor judged by a stronger model. And it all lives on their plans and&lt;br&gt;
their infrastructure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That matters because open weights caught up. On SWE-bench Verified (July 2026)&lt;br&gt;
the frontier is GPT-5.6 Sol at 96.2 and Claude Fable 5 at 95 — but the best&lt;br&gt;
permissively-licensed models, GLM-5.2 (MIT, 82.8), Kimi K2.7 (78.2) and&lt;br&gt;
DeepSeek-V4 (MIT, 76.2), now match proprietary frontier from a few months back&lt;br&gt;
at a fraction of the price. The rational 2026 fleet is mixed — and a mixed fleet&lt;br&gt;
only pays off if something external, cross-vendor, catches the $0.10 model's&lt;br&gt;
mistakes before merge (&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;the routing math is its own post&lt;/a&gt;).&lt;br&gt;
The vendor stacks, by design, can't be that something.&lt;/p&gt;

&lt;h2&gt;
  
  
  The long tail (and what it's actually solving)
&lt;/h2&gt;

&lt;p&gt;amux, cmux, dmux, mux (yes, all of them), clideck, thurbox, agentbox, AGX,&lt;br&gt;
sortie, tutti… Most are cockpit or batch-runner variants — same two answers as&lt;br&gt;
their bigger cousins. The interesting outliers aren't orchestrators at all:&lt;br&gt;
coordination micro-protocols like &lt;strong&gt;gnap&lt;/strong&gt; (git-as-task-board), &lt;strong&gt;swarm-protocol&lt;/strong&gt;&lt;br&gt;
(MCP work-claiming), and &lt;strong&gt;wit&lt;/strong&gt; (AST-level function locks). They solve agent&lt;br&gt;
&lt;em&gt;collision&lt;/em&gt; — two agents clobbering the same file — not agent &lt;em&gt;supervision&lt;/em&gt;.&lt;br&gt;
Useful, but a different question than either of ours. Full zoo in the&lt;br&gt;
&lt;a href="https://github.com/andyrewlee/awesome-agent-orchestrators" rel="noopener noreferrer"&gt;awesome list&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The table (the receipt)
&lt;/h2&gt;

&lt;p&gt;Read it as a coordinate grid: the two middle columns &lt;em&gt;are&lt;/em&gt; the two questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Shape&lt;/th&gt;
&lt;th&gt;Who checks the work&lt;/th&gt;
&lt;th&gt;Who equips the agents&lt;/th&gt;
&lt;th&gt;License / status&lt;/th&gt;
&lt;th&gt;The honest catch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;agentproto&lt;/strong&gt; &lt;em&gt;(mine)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;daemon&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;L4&lt;/strong&gt; — turn-end gate, judge, commit behind ack, survives disconnect&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;your tools → every agent&lt;/strong&gt; (TOOL/DRIVER + imported MCP)&lt;/td&gt;
&lt;td&gt;Apache-2.0, 0.5.0-alpha&lt;/td&gt;
&lt;td&gt;alpha APIs, no mobile/voice, terminal-only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Paseo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;daemon&lt;/td&gt;
&lt;td&gt;L2/L3 — permission relay, Ralph loop&lt;/td&gt;
&lt;td&gt;injects &lt;em&gt;its own&lt;/em&gt; control tools only&lt;/td&gt;
&lt;td&gt;AGPL-3.0, 10.3k★&lt;/td&gt;
&lt;td&gt;no L4 gates, no user tools; Opus default is pricey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Claude Squad&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TUI cockpit&lt;/td&gt;
&lt;td&gt;L0 — you, in a pane&lt;/td&gt;
&lt;td&gt;you, by hand (no API)&lt;/td&gt;
&lt;td&gt;AGPL-3.0, community&lt;/td&gt;
&lt;td&gt;caps at 2–5 agents; dies at screen-lock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conductor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mac cockpit&lt;/td&gt;
&lt;td&gt;L0 — you, great diff viewer&lt;/td&gt;
&lt;td&gt;you, by hand (no API)&lt;/td&gt;
&lt;td&gt;closed, free&lt;/td&gt;
&lt;td&gt;macOS only, no programmatic surface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Nimbalyst&lt;/strong&gt; (ex-Crystal)&lt;/td&gt;
&lt;td&gt;cockpit + iOS&lt;/td&gt;
&lt;td&gt;L0 + mobile push-on-input&lt;/td&gt;
&lt;td&gt;you, by hand&lt;/td&gt;
&lt;td&gt;open-source&lt;/td&gt;
&lt;td&gt;Crystal deprecated Feb 2026; still eyeballs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vibe Kanban&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;kanban board&lt;/td&gt;
&lt;td&gt;L0 — you, on a board&lt;/td&gt;
&lt;td&gt;you, by hand&lt;/td&gt;
&lt;td&gt;community-maintained&lt;/td&gt;
&lt;td&gt;Bloop shut down Apr 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent Farm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;batch runner&lt;/td&gt;
&lt;td&gt;L1 — a liveness watchdog&lt;/td&gt;
&lt;td&gt;n/a (one vendor, one job)&lt;/td&gt;
&lt;td&gt;MIT, community&lt;/td&gt;
&lt;td&gt;keeps it alive, not correct; Claude Code only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Omnara&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;remote control&lt;/td&gt;
&lt;td&gt;L2 — you, from your phone&lt;/td&gt;
&lt;td&gt;n/a (hosted)&lt;/td&gt;
&lt;td&gt;Apache-2.0, YC S25&lt;/td&gt;
&lt;td&gt;pivoted to hosted; approval fatigue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Vendor-native&lt;/strong&gt; (Claude)&lt;/td&gt;
&lt;td&gt;in-product / hosted&lt;/td&gt;
&lt;td&gt;L3 — Outcomes grader, inside the walls&lt;/td&gt;
&lt;td&gt;vendor equips, per-product only&lt;/td&gt;
&lt;td&gt;proprietary&lt;/td&gt;
&lt;td&gt;single-vendor; Advisor advice encrypted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(Facts from each project's own docs/repos, 2026-07-07 → 2026-07-14. The&lt;br&gt;
vendor-native row is unpacked in&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;the state-of piece&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pick by the shape of your pain, not by a ranking
&lt;/h2&gt;

&lt;p&gt;There is no best tool, only best fits. Find your bottleneck; the map picks for&lt;br&gt;
you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steering from the couch or phone, best-in-class UX&lt;/strong&gt; → &lt;strong&gt;Paseo&lt;/strong&gt; (or
&lt;strong&gt;Omnara&lt;/strong&gt; if you'd rather it be hosted).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal cockpit, hands-on review, no lock-in&lt;/strong&gt; → &lt;strong&gt;Claude Squad&lt;/strong&gt;;
Mac-native with a great diff viewer → &lt;strong&gt;Conductor&lt;/strong&gt;; want a board + the only
native iOS app → &lt;strong&gt;Nimbalyst&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grinding a mechanical fix queue with one vendor&lt;/strong&gt; → &lt;strong&gt;Agent Farm&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All-Claude shop on Team/Enterprise, happy inside one vendor&lt;/strong&gt; → the native
stack (Agent Teams / Dynamic Workflows / &lt;strong&gt;Outcomes&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unattended runs, mixed-vendor fleets, a real check before merge, and your
own tools distributed to every agent&lt;/strong&gt; → &lt;strong&gt;agentproto&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The tie-breaker, if two rows look close.&lt;/strong&gt; Ask the two questions out loud&lt;br&gt;
against your actual week. If your pain is "I can't watch fast enough,"&lt;br&gt;
question one sorts you — climb the &lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;supervision&lt;br&gt;
ladder&lt;/a&gt;. If your pain is "I keep re-wiring the same&lt;br&gt;
tool into every agent," question two sorts you, and today almost nothing&lt;br&gt;
answers it. Steering tools answer neither; they add cockpits in front of the&lt;br&gt;
same bottleneck.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the whole map. Nine tools, two questions, one honest table — and the one&lt;br&gt;
row I built is disclosed as mine on every line. A ranking would've told you I&lt;br&gt;
won. A map tells you something more useful: exactly which pain each of us was&lt;br&gt;
built to kill, and which we quietly left on the table.&lt;/p&gt;

&lt;p&gt;If I've mis-rated where your tool sits, or a dated fact has gone stale since I&lt;br&gt;
checked, tell me where — I'll fix the piece.&lt;/p&gt;




&lt;h3&gt;
  
  
  The series — &lt;em&gt;Orchestration, Honestly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Ten pieces, one argument. Start anywhere; each one cross-links the rest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;The one idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can't parallelize the trust&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Amdahl's Law: why your fifth agent slows you down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69"&gt;Harness engineering&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;you rent the model; the harness is the part you own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;The supervision ladder&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;five rungs of trusting an agent you don't watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;The approval plane&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;auto-approve reads, gate writes — wire the line between&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;Kill the loop&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;why "keep going until done" compounds a wrong turn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Route by cost&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;plan expensive, execute cheap, verify independently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Files with contracts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the interop layer every agent system reinvents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;Knowledge is power&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;give your agent your knowledge, not the internet's average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/saying-hi-to-this-agent-daemon-cost-029-a-rivals-hands-on-paseo-review-e7i"&gt;Paseo, hands-on&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;a full real-session review of the daemon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;9 orchestrators, compared&lt;/strong&gt; &lt;em&gt;(you're here)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;the tool-by-tool teardown + a decision table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0, &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Same contract as our &lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page — dated facts, named strengths, corrections by issue. Got something wrong? &lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claudecode</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Your Coding Agent Knows the Internet's Average. Here's How to Make It Know Yours.</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:33 +0000</pubDate>
      <link>https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg</link>
      <guid>https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt;, whose&lt;br&gt;
knowledge and operator primitives are the back half of this piece. The problem&lt;br&gt;
in the first half stands on its own, and the walkthrough uses real, checkable&lt;br&gt;
commands. Corrections welcome — file an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Open Claude Code. Open Codex. Open a cheap local model in the same repo. Ask all&lt;br&gt;
three the same question about your codebase — your retry convention, your deploy&lt;br&gt;
runbook, why that one service is the way it is.&lt;/p&gt;

&lt;p&gt;You'll get three fluent, confident, near-identical answers. And all three will be&lt;br&gt;
wrong in the same way: they'll describe how a &lt;em&gt;reasonable&lt;/em&gt; team does it, not how&lt;br&gt;
&lt;em&gt;yours&lt;/em&gt; does. They're all running the same frontier weights, trained on the same&lt;br&gt;
public internet, so out of the box they all know exactly the same thing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
The weights are everyone's. Your knowledge base is the only part of the stack&lt;br&gt;
that's &lt;em&gt;yours&lt;/em&gt; — and the only thing that makes the agent yours instead of the&lt;br&gt;
internet's average.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The model stopped being the differentiator
&lt;/h2&gt;

&lt;p&gt;Here's the shift most people missed while arguing about benchmarks. The gap&lt;br&gt;
between the best model and the tenth-best is collapsing — &lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;the hub piece&lt;/a&gt;&lt;br&gt;
has the Stanford AI Index receipt (the #1-to-#10 spread fell from 11.9% to 5.4%&lt;br&gt;
in a year). When the weights converge, the weights stop being your edge.&lt;/p&gt;

&lt;p&gt;What replaces them is system design. One widely-cited 2026 essay on the evolution&lt;br&gt;
of agents put it bluntly: &lt;strong&gt;agent capability has moved from model quality to&lt;br&gt;
system design&lt;/strong&gt; — from writing a clever prompt to engineering what the model can&lt;br&gt;
&lt;em&gt;see&lt;/em&gt;. The clever prompt is a commodity now. The context isn't.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The receipt that reframes the whole market.&lt;/strong&gt; In a production-readiness&lt;br&gt;
comparison of agent frameworks, one finding held across every orchestration&lt;br&gt;
style tested: &lt;em&gt;retrieval quality dominates knowledge-agent performance&lt;br&gt;
regardless of orchestration.&lt;/em&gt; You can have the best planner-worker-judge&lt;br&gt;
topology in the world; if the agent is retrieving from the internet's average&lt;br&gt;
instead of your world, it answers like a stranger.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the interesting question stopped being "which model?" and became "what does it&lt;br&gt;
know that no one else's does?" JetBrains' framing is useful here: some agents are&lt;br&gt;
&lt;strong&gt;action-first&lt;/strong&gt; (their value is what they &lt;em&gt;do&lt;/em&gt;) and some are &lt;strong&gt;data-first&lt;/strong&gt;&lt;br&gt;
(their value is what they can &lt;em&gt;access&lt;/em&gt;). A coding agent for &lt;em&gt;your&lt;/em&gt; team is&lt;br&gt;
data-first whether you designed it that way or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The uncomfortable part: if you haven't attached your knowledge to your agent,&lt;br&gt;
you're shipping the stranger.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Which tier is your agent on?
&lt;/h2&gt;

&lt;p&gt;Run the self-diagnosis before you build anything. There are three tiers, and most&lt;br&gt;
teams are stuck on the first two without noticing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 0 — no knowledge base.&lt;/strong&gt; The agent knows what the pre-training run knew:&lt;br&gt;
public GitHub, Stack Overflow, docs up to some cutoff. Ask it about your world and&lt;br&gt;
it pattern-matches to the nearest public example. It's confident and it's generic.&lt;br&gt;
&lt;em&gt;Ceiling: it will never know a single thing that isn't already on the internet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 1 — pasted into context.&lt;/strong&gt; You dump the runbook, the conventions doc, a few&lt;br&gt;
past PRs into the prompt (or a &lt;code&gt;CLAUDE.md&lt;/code&gt;) and hope. It works — until the context&lt;br&gt;
fills up. Anthropic's context-engineering post is direct about why this caps out:&lt;br&gt;
you have to &lt;strong&gt;treat context as a finite attention budget&lt;/strong&gt;, because recall decays&lt;br&gt;
as the window grows ("context rot").&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why Tier 1 has a hard ceiling.&lt;/strong&gt; The same post prescribes the fix — &lt;em&gt;keep&lt;br&gt;
lightweight references and retrieve just-in-time&lt;/em&gt;, not pre-load everything.&lt;br&gt;
Pasting your whole knowledge base into every prompt is the exact anti-pattern:&lt;br&gt;
it's expensive, it rots, and it doesn't scale past a handful of documents. A&lt;br&gt;
KB you paste is a KB you'll soon truncate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Tier 2 — a served, queryable knowledge base.&lt;/strong&gt; Your knowledge lives in one place,&lt;br&gt;
gets indexed, and every agent &lt;em&gt;queries&lt;/em&gt; it on demand — pulling only the three&lt;br&gt;
relevant entries for the question at hand, with their sources attached. This is&lt;br&gt;
just-in-time retrieval, done properly, shared across every agent you run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The jump from Tier 1 to Tier 2 is the whole game — and it's the "who equips the&lt;br&gt;
agents" question from &lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;the files-with-contracts piece&lt;/a&gt;,&lt;br&gt;
pointed straight at knowledge.&lt;/strong&gt; Let's build it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1 — an operator that already knows where to look
&lt;/h2&gt;

&lt;p&gt;Start with the packaged shape, because it shows the target. In agentproto, an&lt;br&gt;
&lt;strong&gt;operator&lt;/strong&gt; (the AIP-9 &lt;code&gt;OPERATOR.md&lt;/code&gt;) is a persona plus policies plus a set of&lt;br&gt;
bound tools — and one of those tools is a knowledge binding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# operators/house-engineer/OPERATOR.md — persona + policies + a KB binding&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;House Engineer&lt;/span&gt;
&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;house-engineer&lt;/span&gt;
&lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Answer and act using OUR conventions and past incidents, never generic defaults.&lt;/span&gt;
  &lt;span class="na"&gt;voice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Concrete, cites the runbook or incident it's drawing from.&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;knowledge-query&lt;/span&gt;          &lt;span class="c1"&gt;# ← the bound knowledge tool&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;shell&lt;/span&gt;
&lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;policy:engineering/house-rules"&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;corpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;knowledgeViews&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;corpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;engineering&lt;/span&gt;
        &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;conventions&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;runbooks&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;incidents&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read what that &lt;code&gt;knowledgeViews&lt;/code&gt; block does: it scopes the operator to &lt;em&gt;your&lt;/em&gt;&lt;br&gt;
engineering corpus, filtered to the tags that matter. The persona decides how it&lt;br&gt;
answers; the policies decide what it's allowed to do; the knowledge view decides&lt;br&gt;
what it &lt;em&gt;knows&lt;/em&gt;. Three separate concerns, one file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is a real shape, not a mock.&lt;/strong&gt; The research operators shipped in&lt;br&gt;
agentproto's own corpus — &lt;code&gt;source-scout&lt;/code&gt;, &lt;code&gt;research-analyst&lt;/code&gt; — carry exactly&lt;br&gt;
this: &lt;code&gt;tools: [knowledge-query, ...]&lt;/code&gt; plus a &lt;code&gt;metadata.corpus.knowledgeViews&lt;/code&gt;&lt;br&gt;
binding scoped by domain and quality score. The operator is the &lt;em&gt;packaging&lt;/em&gt;.&lt;br&gt;
Underneath it is a tool, and the tool is the part that ports to any agent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;An operator is what "give the agent your knowledge" looks like when it's one&lt;br&gt;
declared file.&lt;/strong&gt; Now let's build the tool that backs it — the part that reaches&lt;br&gt;
agents that never heard of your operator format.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2 — the knowledge.search tool, authored once
&lt;/h2&gt;

&lt;p&gt;This is the exact move from &lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;the files-with-contracts piece&lt;/a&gt;,&lt;br&gt;
specialized to knowledge: split the &lt;strong&gt;contract&lt;/strong&gt; (what the tool promises) from the&lt;br&gt;
&lt;strong&gt;driver&lt;/strong&gt; (the code that answers). Here's the contract — a pure &lt;code&gt;defineTool&lt;/code&gt;,&lt;br&gt;
no execute body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// tools/knowledge-search/TOOL.ts — the contract, and nothing else&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineTool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;knowledgeSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;knowledge.search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Answer from OUR knowledge base: conventions, runbooks, past incidents. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Returns refined entries, each with the source it came from.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;([]),&lt;/span&gt;
    &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;outputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;      &lt;span class="c1"&gt;// provenance — where this knowledge came from&lt;/span&gt;
    &lt;span class="p"&gt;})),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;mutates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;                 &lt;span class="c1"&gt;// read-only → no approval gate&lt;/span&gt;
  &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the driver — the implementation, bound to the contract by &lt;code&gt;implementTool&lt;/code&gt;. It&lt;br&gt;
reads your corpus workspace off local disk and returns the matching entries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// drivers/knowledge-corpus.ts — backed by your own corpus workspace&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineDriver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;implementTool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/driver&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;knowledgeSearch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../tools/knowledge-search/TOOL.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;resolveKnowledge&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/corpus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NodeFsAdapter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agentproto/corpus/fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineDriver&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;knowledge.search.corpus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Knowledge search over your corpus workspace&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;in-process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;implementations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;implementTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knowledgeSearch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// the same resolver behind `corpus knowledge &amp;lt;ws&amp;gt; --tags … --max …`&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;resolveKnowledge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NodeFsAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CORPUS_WS&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maxResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;})),&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;egress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;     &lt;span class="c1"&gt;// reads local files → your knowledge never leaves the box&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That driver is the real corpus resolver — the same &lt;code&gt;resolveKnowledge&lt;/code&gt; call that&lt;br&gt;
sits behind &lt;code&gt;corpus knowledge &amp;lt;ws&amp;gt; --tags conventions,incidents --max 5&lt;/code&gt; on the&lt;br&gt;
command line, now exposed as a tool. The &lt;code&gt;network.egress: []&lt;/code&gt; line is doing quiet&lt;br&gt;
but load-bearing work: &lt;strong&gt;the knowledge is queried from local files, so it never&lt;br&gt;
leaves your machine.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Provenance is a feature, not decoration.&lt;/strong&gt; Every entry carries its &lt;code&gt;source&lt;/code&gt; —&lt;br&gt;
the runbook, the incident, the PR it was distilled from. That's what lets an&lt;br&gt;
external check — &lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;the supervision ladder's&lt;/a&gt; whole&lt;br&gt;
point — verify the answer later: the LLM-as-a-judge literature evaluates RAG on&lt;br&gt;
&lt;em&gt;two&lt;/em&gt; sides, context relevance going in and &lt;strong&gt;faithfulness coming out&lt;/strong&gt; (did the&lt;br&gt;
answer actually follow the retrieved source, or wander off it?). No provenance,&lt;br&gt;
no faithfulness check.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;One contract, one driver, and now every agent that mounts the daemon can answer&lt;br&gt;
from your world.&lt;/strong&gt; Serve it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3 — the same question, with and without your knowledge
&lt;/h2&gt;

&lt;p&gt;Start the daemon. It reads your &lt;code&gt;tools/&lt;/code&gt; and &lt;code&gt;drivers/&lt;/code&gt; and serves them over MCP,&lt;br&gt;
&lt;code&gt;knowledge.search&lt;/code&gt; included.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @agentproto/cli
agentproto serve                 &lt;span class="c"&gt;# serves the /mcp gateway to every agent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now spawn an agent &lt;em&gt;with&lt;/em&gt; the tool, and ask it something it could only know from&lt;br&gt;
your docs — a convention set by a past incident:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agentproto sessions start codex &lt;span class="nt"&gt;--cwd&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"What's our retry policy for the payments queue? Use knowledge.search."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ Per incident #2026-04 (double-charge on gateway timeout), payment retries are
  capped at 3 with jittered backoff, and we NEVER retry a charge without an
  idempotency key. Source: runbooks/payments-queue.md, incidents/2026-04.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the same agent, same question, &lt;strong&gt;without&lt;/strong&gt; the tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agentproto sessions start codex &lt;span class="nt"&gt;--cwd&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"What's our retry policy for the payments queue?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ A common approach is exponential backoff with 3–5 retries and a dead-letter
  queue after the final attempt…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second answer isn't &lt;em&gt;wrong&lt;/em&gt; — it's the internet's average, and it's exactly&lt;br&gt;
what you'd get from any agent, anywhere. The first answer knows about the&lt;br&gt;
double-charge you shipped in April, because it read your incident file. &lt;strong&gt;That&lt;br&gt;
delta — a real past incident it could only learn from your knowledge base — is&lt;br&gt;
the entire difference between an agent and &lt;em&gt;your&lt;/em&gt; agent.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cross-vendor, by construction.&lt;/strong&gt; That was Codex. Point Claude Code or a cheap&lt;br&gt;
local model via Hermes at the same daemon and they call the identical&lt;br&gt;
&lt;code&gt;knowledge.search&lt;/code&gt; — because it's served over MCP, not baked into one vendor's&lt;br&gt;
config. Author the KB tool once; every agent in your fleet inherits your world.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Guilde parallel: the same primitive, packaged
&lt;/h2&gt;

&lt;p&gt;Here's the honest framing, because overclaiming is how you lose a reader. In&lt;br&gt;
&lt;a href="https://guilde.work" rel="noopener noreferrer"&gt;Guilde&lt;/a&gt; — our AI-company product — attaching a knowledge&lt;br&gt;
base to an agent is &lt;em&gt;one packaged step&lt;/em&gt;: an operator ships with an attached&lt;br&gt;
corpus, and you apply it to a scope in a single command. Persona, policies,&lt;br&gt;
knowledge, done.&lt;/p&gt;

&lt;p&gt;What you just built by hand in agentproto is that same primitive, one floor down:&lt;br&gt;
an operator (Step 1) plus a served knowledge tool (Step 2). &lt;strong&gt;Guilde adds the&lt;br&gt;
one-command packaging; agentproto is the from-primitives path you can run today&lt;/strong&gt;,&lt;br&gt;
in your own repo, on your own machine, with no platform to adopt.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What agentproto does &lt;em&gt;not&lt;/em&gt; do yet, stated plainly.&lt;/strong&gt; There's no single&lt;br&gt;
&lt;code&gt;apply-knowledge-pack&lt;/code&gt; verb in the open CLI — you wire the tool, the driver,&lt;br&gt;
and the operator yourself, as three files. That's more assembly than the&lt;br&gt;
packaged version. It's also fully inspectable and fully yours, which for a&lt;br&gt;
knowledge base — the most sensitive thing you'll attach to an agent — is often&lt;br&gt;
the trade you want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The primitive is identical either way: &lt;strong&gt;an operator with a queryable knowledge&lt;br&gt;
tool.&lt;/strong&gt; One product packages it; the other hands you the parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest edges
&lt;/h2&gt;

&lt;p&gt;A knowledge base is not magic, and three caveats keep it honest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A wrong KB is worse than no KB.&lt;/strong&gt; If your knowledge base contains a stale&lt;br&gt;
convention, the agent will state it with the same confidence as a correct one —&lt;br&gt;
now with a &lt;em&gt;source&lt;/em&gt; attached, which makes it more persuasive and more dangerous.&lt;br&gt;
This is why the faithfulness check above matters: retrieval quality is the whole&lt;br&gt;
ballgame, and a KB is an artifact you maintain, not a bucket you fill once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't let the agent write its own knowledge base.&lt;/strong&gt; ETH Zurich research&lt;br&gt;
(Gloaguen et al.) found that LLM-generated &lt;code&gt;AGENTS.md&lt;/code&gt; files provided &lt;strong&gt;no&lt;br&gt;
benefit and could reduce success rates.&lt;/strong&gt; A knowledge base curated from real&lt;br&gt;
incidents, runbooks, and decisions is yours; one the agent hallucinated about&lt;br&gt;
itself is just the internet's average with your repo's name on it. Curate the&lt;br&gt;
KB like you'd curate docs — because that's what it is.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;And it's the most sensitive thing you'll attach.&lt;/strong&gt; Your incidents, your&lt;br&gt;
conventions, your internal decisions — that's exactly the data you don't want&lt;br&gt;
leaving your network. The &lt;code&gt;network.egress: []&lt;/code&gt; driver above isn't a detail; it's&lt;br&gt;
the reason this whole pattern runs locally. Your knowledge is your edge precisely&lt;br&gt;
because it's private, so the tool that serves it should keep it that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Knowledge is the part you own
&lt;/h2&gt;

&lt;p&gt;Every team in 2026 rents the same frontier weights. That was always going to&lt;br&gt;
commoditize — the models converge, the benchmarks compress, and the clever prompt&lt;br&gt;
becomes a thing anyone can copy. What doesn't commoditize is what your agent knows&lt;br&gt;
that no one else's does: your codebase's conventions, your runbooks, the incident&lt;br&gt;
that taught you never to retry a charge without an idempotency key.&lt;/p&gt;

&lt;p&gt;That knowledge is the one layer of the stack you actually own. Attaching it isn't&lt;br&gt;
a nice-to-have on top of a good model — after the models converged, &lt;strong&gt;it's the&lt;br&gt;
only move left that makes your agent yours.&lt;/strong&gt; An operator with a queryable&lt;br&gt;
knowledge tool, served locally to every agent you run. Three files, and the&lt;br&gt;
stranger becomes a colleague.&lt;/p&gt;

&lt;p&gt;So run the diagnosis one more time, honestly: does your agent know your world, or&lt;br&gt;
just the internet's average of it? If it's the average, you don't have an agent&lt;br&gt;
problem. You have a knowledge problem — and it's the good kind, because the fix is&lt;br&gt;
entirely in your hands.&lt;/p&gt;

&lt;p&gt;If your setup already attaches knowledge a cleaner way, or I've mis-described how&lt;br&gt;
your KB reaches your agents, tell me where — I'll fix the piece.&lt;/p&gt;




&lt;h3&gt;
  
  
  The series — &lt;em&gt;Orchestration, Honestly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Ten pieces, one argument. Start anywhere; each one cross-links the rest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;The one idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can't parallelize the trust&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Amdahl's Law: why your fifth agent slows you down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69"&gt;Harness engineering&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;you rent the model; the harness is the part you own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;The supervision ladder&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;five rungs of trusting an agent you don't watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;The approval plane&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;auto-approve reads, gate writes — wire the line between&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk"&gt;Kill the loop&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;why "keep going until done" compounds a wrong turn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Route by cost&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;plan expensive, execute cheap, verify independently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Files with contracts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the interop layer every agent system reinvents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Knowledge is power&lt;/strong&gt; &lt;em&gt;(you're here)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;give your agent your knowledge, not the internet's average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/saying-hi-to-this-agent-daemon-cost-029-a-rivals-hands-on-paseo-review-e7i"&gt;Paseo, hands-on&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;a full real-session review of the daemon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk"&gt;9 orchestrators, compared&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the tool-by-tool teardown + a decision table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0, &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Same contract as our &lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page — dated facts, named strengths, corrections by issue. Got something wrong? &lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claudecode</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Kill the Loop: Why `while true` Is Not Reliability</title>
      <dc:creator>Agentik</dc:creator>
      <pubDate>Tue, 14 Jul 2026 01:36:30 +0000</pubDate>
      <link>https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk</link>
      <guid>https://dev.to/agentiknet/kill-the-loop-why-while-true-is-not-reliability-59fk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure up front: I build &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt;, which runs&lt;br&gt;
checks &lt;em&gt;inside&lt;/em&gt; an agent's loop rather than only at the end. Everything about&lt;br&gt;
why that matters you can verify without me — the sources are named and dated,&lt;br&gt;
and I'll concede where the plain loop is exactly right. Corrections welcome,&lt;br&gt;
file an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You gave your agent a loop, closed the laptop, and went to bed.&lt;/p&gt;

&lt;p&gt;The whole pitch of the overnight loop is that it keeps going. &lt;code&gt;while true; do&lt;br&gt;
cat prompt.md | claude -p; done&lt;/code&gt; — it wakes back up every time it stalls,&lt;br&gt;
re-reads the plan, and grinds on until a checklist is green. You come back to a&lt;br&gt;
finished feature and a clean exit code. Sometimes that's a miracle. Sometimes&lt;br&gt;
it's a very tidy way to have built the wrong thing four hundred times.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The one idea, if you remember nothing else:&lt;/strong&gt;&lt;br&gt;
A loop gives your agent &lt;em&gt;persistence, not correctness.&lt;/em&gt; And a wrong turn, held&lt;br&gt;
with conviction and looped, is just a faster way to be wrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Persistence is not correctness
&lt;/h2&gt;

&lt;p&gt;A loop is a liveness guarantee. It promises the process will keep running; it&lt;br&gt;
promises nothing about whether the process is pointed the right way. Those are&lt;br&gt;
two different properties, and the whole overnight-autonomy genre quietly conflates&lt;br&gt;
them. "It's still going" feels like "it's still on track" at 2am. It isn't.&lt;/p&gt;

&lt;p&gt;Geoffrey Huntley named the mechanism precisely when he described the Ralph&lt;br&gt;
technique as &lt;em&gt;a deterministic loop wrapped around a non-deterministic model&lt;/em&gt; —&lt;br&gt;
the bet being that repeated attempts converge on a working solution. That bet is&lt;br&gt;
real, and often it pays. But convergence has a direction, and the loop doesn't&lt;br&gt;
supply it. The loop supplies fuel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why the direction can be wrong.&lt;/strong&gt; Each Ralph iteration starts with a fresh&lt;br&gt;
context window but inherits all prior work from the filesystem — code, commits,&lt;br&gt;
notes — which it treats as ground truth and builds on (Sid Bharath, &lt;em&gt;"the&lt;br&gt;
dumbest smart way to run coding agents,"&lt;/em&gt; 2026). That's the strength on a good&lt;br&gt;
run. On a bad one, iteration two builds on iteration one's mistake, iteration&lt;br&gt;
three trusts both, and the error stops looking like a bug and starts looking&lt;br&gt;
like the codebase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So an unsupervised loop doesn't &lt;em&gt;self-correct&lt;/em&gt;. It &lt;em&gt;self-reinforces&lt;/em&gt;. It pays&lt;br&gt;
compound interest on your first wrong turn — confidently, on a timer, with every&lt;br&gt;
pass making the mistake more load-bearing and more expensive to unwind. &lt;strong&gt;The&lt;br&gt;
scariest output of a runaway loop isn't a crash. It's a green checkmark on top of&lt;br&gt;
a bad foundation.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The check at the finish line is the check that arrives too late
&lt;/h2&gt;

&lt;p&gt;"Fine," you say, "I gated it — the loop only exits when the tests pass and it&lt;br&gt;
prints &lt;code&gt;COMPLETE&lt;/code&gt;." Good instinct, wrong position. A terminal gate fires after&lt;br&gt;
the loop has already burned the budget and stacked the tower. By the time your&lt;br&gt;
end-of-run check has an opinion, the wrong thing is built, tall, and load-bearing.&lt;/p&gt;

&lt;p&gt;And the completion signal you're trusting is more fragile than it looks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The exit condition is a suggestion, not a safety mechanism.&lt;/strong&gt; A completion&lt;br&gt;
promise is typically a static exact-match string with no OR conditions — so it&lt;br&gt;
can silently never fire if the wording drifts. The thing that actually bounds a&lt;br&gt;
runaway loop is the &lt;em&gt;iteration cap&lt;/em&gt;; long loops can plausibly cost $30–150 in&lt;br&gt;
API spend, so you never run one without one (&lt;em&gt;The AI Agent Factory&lt;/em&gt;, 2026).&lt;br&gt;
Read that again: the mechanism keeping your loop from running forever is a&lt;br&gt;
counter, not a judgment. It stops the spend. It doesn't check the work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The deeper problem is that the failures that matter most are &lt;em&gt;invisible to any&lt;br&gt;
single moment&lt;/em&gt; — including the last one. Apollo Research, whose Watcher tool&lt;br&gt;
monitors coding agents, splits agent failures into two shapes, and the split is&lt;br&gt;
the whole game.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Two failure shapes, two different checks.&lt;/strong&gt; Some failures live in a single&lt;br&gt;
action — deleting files, leaking a secret, a force-push — and must be blocked&lt;br&gt;
&lt;em&gt;synchronously, before execution.&lt;/em&gt; Others only emerge over many turns — scope&lt;br&gt;
creep, a confidently wrong diagnosis, premature "done" claims — and no single&lt;br&gt;
action reveals them; they have to be judged over the &lt;em&gt;trajectory&lt;/em&gt;&lt;br&gt;
(&lt;a href="https://watcher.apolloresearch.ai/blog/monitor-coding-agents.html" rel="noopener noreferrer"&gt;Apollo Research&lt;/a&gt;,&lt;br&gt;
2026). A terminal gate sees exactly one moment. The drift that sinks you lives&lt;br&gt;
in the shape it can't see.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Self-diagnosis: when does your loop check its work?
&lt;/h2&gt;

&lt;p&gt;Here's the one question that sorts every autonomous setup. &lt;strong&gt;When does your loop&lt;br&gt;
check its work — only at the very end, or partway through?&lt;/strong&gt; If the only&lt;br&gt;
checkpoint is the completion gate, you are blind to the exact class of failure&lt;br&gt;
that compounds: the one that builds up quietly across turns and looks fine right&lt;br&gt;
up until it's enormous.&lt;/p&gt;

&lt;p&gt;Run the honest audit on your own harness. Between kickoff and the final green&lt;br&gt;
check, how many times does something &lt;em&gt;other than the agent&lt;/em&gt; look at where it's&lt;br&gt;
going? For most overnight loops the answer is zero — the agent grades its own&lt;br&gt;
progress every iteration, and a generator grading itself is the plateau the whole&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;supervision ladder&lt;/a&gt; is built to escape.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Receipt from the trajectory list.&lt;/strong&gt; Apollo's rubric of multi-turn failure&lt;br&gt;
modes reads like a confession of every bad overnight run: premature completion&lt;br&gt;
claims without verification, ignoring user corrections, confidently wrong&lt;br&gt;
diagnoses, scope overreach, fabricated APIs, and — my favorite — &lt;em&gt;repeating a&lt;br&gt;
failing command 3+ times without changing strategy.&lt;/em&gt; A loop is a machine for&lt;br&gt;
doing that last one at scale.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your check lives only at the finish line, the loop's superpower — never giving&lt;br&gt;
up — becomes its failure mode. It will never give up on the wrong path, either.&lt;/p&gt;
&lt;h2&gt;
  
  
  The wrong fix: a watchdog that restarts you into the same groove
&lt;/h2&gt;

&lt;p&gt;The reflex, when a loop misbehaves, is to make it &lt;em&gt;more&lt;/em&gt; persistent: auto-restart&lt;br&gt;
on stall, replay the last message in a fresh session, keep it alive through&lt;br&gt;
context overflow and API errors. That's a watchdog, and it's genuinely necessary&lt;br&gt;
plumbing for unattended runs — but it is the exact wrong tool for this problem.&lt;/p&gt;

&lt;p&gt;A watchdog keeps the process breathing and says nothing about whether the process&lt;br&gt;
is right. &lt;strong&gt;It will cheerfully restart a wrong loop into producing the same wrong&lt;br&gt;
answer until sunrise&lt;/strong&gt; — the &lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;supervision ladder&lt;/a&gt;&lt;br&gt;
calls this L1, and the reason it's the lowest automated rung is that "alive" and&lt;br&gt;
"correct" are different axes. Restarting a confidently-wrong agent doesn't&lt;br&gt;
interrupt the self-reinforcement. It refuels it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Alive ≠ on-track.&lt;/strong&gt; Health-monitoring harnesses track context usage, idle&lt;br&gt;
time, and error counts, then act: clear context below a threshold, restart&lt;br&gt;
agents that stall, disable them after N consecutive errors (Claude Code Agent&lt;br&gt;
Farm, 2026). Every one of those signals is about &lt;em&gt;liveness&lt;/em&gt;. None of them asks&lt;br&gt;
the only question that matters mid-flight: is this still the right thing to be&lt;br&gt;
building?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the fix can't be "keep it going better." It has to be something that can make&lt;br&gt;
it &lt;em&gt;stop going the wrong way&lt;/em&gt; — partway through, before the tower is tall.&lt;/p&gt;
&lt;h2&gt;
  
  
  The fix: an external skeptic that runs &lt;em&gt;during&lt;/em&gt; the loop
&lt;/h2&gt;

&lt;p&gt;The check has to move two places at once: &lt;em&gt;outside&lt;/em&gt; the agent (a different&lt;br&gt;
context, ideally a different model — a generator can't be its own skeptic) and&lt;br&gt;
&lt;em&gt;inside&lt;/em&gt; the timeline (running alongside the loop, not waiting at the exit).&lt;br&gt;
That's the &lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;ladder's&lt;/a&gt; L3/L4 external-judge idea, but&lt;br&gt;
applied &lt;em&gt;continuously&lt;/em&gt; instead of only at turn-end.&lt;/p&gt;

&lt;p&gt;This is precisely what a trailing monitor does, and Apollo measured the payoff&lt;br&gt;
and its limit in the same breath.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Catch the drift early or don't bother.&lt;/strong&gt; When a trailing monitor scores a&lt;br&gt;
session over threshold on scope-overreach or premature-completion, injecting a&lt;br&gt;
short &lt;code&gt;system-reminder&lt;/code&gt;-style nudge — &lt;em&gt;"you were asked to fix the login bug but&lt;br&gt;
are now refactoring the session module"&lt;/em&gt; — generally steers the agent back.&lt;br&gt;
But &lt;em&gt;effectiveness drops the further the agent has already committed to the&lt;br&gt;
wrong path&lt;/em&gt;, so the monitor must run frequently enough to catch drift early&lt;br&gt;
(&lt;a href="https://watcher.apolloresearch.ai/blog/monitor-coding-agents.html" rel="noopener noreferrer"&gt;Apollo Research&lt;/a&gt;,&lt;br&gt;
2026). That sentence is the entire argument for killing the terminal-only gate:&lt;br&gt;
the redirect that works cheaply at turn three is nearly useless at turn thirty.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The redirect gets weaker exactly as fast as the loop's confidence gets stronger.&lt;br&gt;
Compound interest, running the other way. &lt;strong&gt;A check that only fires at the end&lt;br&gt;
isn't a safety net; it's an autopsy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And because the monitor is a separate context, it can be a separate &lt;em&gt;provider&lt;/em&gt; —&lt;br&gt;
which is a feature, not an accident.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't let the agent pick its own referee.&lt;/strong&gt; Models share blind spots with&lt;br&gt;
themselves: a monitor from the same family tends to trust the agent's reasoning&lt;br&gt;
patterns — Apollo observed Claude models being too trusting of their own&lt;br&gt;
reasoning, GPT models over-suspicious as graders. Mixing providers across the&lt;br&gt;
monitoring pipeline yields oversight that doesn't inherit the supervised&lt;br&gt;
agent's biases. The skeptic works best when it isn't the defendant's cousin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Building it: interrupt the loop, don't just watch it end
&lt;/h2&gt;

&lt;p&gt;Concretely, the difference is one structural move. Here's the naive loop&lt;br&gt;
everyone starts with — one check, at the very end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# The terminal-gate loop: blind between iterations&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;prompt.md | claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--dangerously-skip-permissions&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"COMPLETE"&lt;/span&gt; progress.md &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;break&lt;/span&gt;   &lt;span class="c"&gt;# the ONLY check, and it's last&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="k"&gt;$((&lt;/span&gt;i++&lt;span class="k"&gt;))&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 50 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;break&lt;/span&gt;              &lt;span class="c"&gt;# the counter, not a judgment&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything between kickoff and &lt;code&gt;COMPLETE&lt;/code&gt; is unsupervised. Now put a skeptic&lt;br&gt;
&lt;em&gt;inside&lt;/em&gt; the timeline — an external monitor that reads the trajectory at every&lt;br&gt;
turn boundary and can halt-and-redirect partway through, even mid-way through a&lt;br&gt;
sub-agent's run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A mid-flight monitor: runs alongside, can interrupt — not a watchdog&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sess_…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cadence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"every-turn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="c1"&gt;// not "on-exit"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"judge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"adapter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;// a DIFFERENT provider than the executor&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Score scope-overreach, wrong-diagnosis, premature-completion 0–1. Quote the turn."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"onDrift"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="c1"&gt;// trajectory failure → steer, early&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"above"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nudge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You were asked to fix the retry test, not rewrite the queue. Return to the task."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"onIrreversible"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// single dangerous action → stop, synchronously&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the reversibility split in config: single dangerous actions get blocked&lt;br&gt;
&lt;em&gt;before&lt;/em&gt; they run; multi-turn drift gets caught early, while the redirect still&lt;br&gt;
works. The monitor lives in a daemon, so it keeps checking after your screen&lt;br&gt;
locks — and because it's an external adapter, it runs on any executor: Claude&lt;br&gt;
Code, Codex, or a cheap GLM/DeepSeek model via Hermes. &lt;strong&gt;The loop keeps its&lt;br&gt;
persistence; you just stop letting it persist unsupervised.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This matters most where the money is. A mixed fleet — frontier model plans, cheap&lt;br&gt;
model executes in a loop, &lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;the routing math its own post&lt;/a&gt; —&lt;br&gt;
is where self-reinforcement is cheapest to trigger and most expensive to catch&lt;br&gt;
late. The $0.10 executor will loop confidently into a wall; something external has&lt;br&gt;
to notice before iteration thirty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kill the loop, not the iteration
&lt;/h2&gt;

&lt;p&gt;To be fair to the loop, because fairness is the point: for a low-stakes,&lt;br&gt;
disposable, sandboxed project, the plain overnight loop is &lt;em&gt;the right tool.&lt;/em&gt;&lt;br&gt;
Someone shipped a full prompt-history feature to a React Native app from an&lt;br&gt;
11-task list for about $1, exiting early at iteration 8 on the completion&lt;br&gt;
sentinel — it compiled and worked (&lt;a href="https://www.youtube.com/watch?v=nwbl9tk8vY4" rel="noopener noreferrer"&gt;demo talk, 2026&lt;/a&gt;).&lt;br&gt;
Well-scoped, throwaway, checked by real tests: loop away. The trouble starts the&lt;br&gt;
moment it's code you're accountable for — &lt;em&gt;"the loop wrote it"&lt;/em&gt; has never once&lt;br&gt;
been a defense.&lt;/p&gt;

&lt;p&gt;So "kill the loop" doesn't mean kill iteration — iteration is how these agents&lt;br&gt;
converge at all. It means kill the &lt;em&gt;unsupervised&lt;/em&gt; loop: the one whose only check&lt;br&gt;
sits at the finish line, refueled by a watchdog, grading its own homework every&lt;br&gt;
pass. Keep the &lt;code&gt;while true&lt;/code&gt;. Just put a skeptic inside it, running alongside,&lt;br&gt;
allowed to interrupt.&lt;/p&gt;

&lt;p&gt;Because a loop, on its own, is confidence with an exit code. Persistence isn't the&lt;br&gt;
same as being right, and this whole series turns on one question first asked in&lt;br&gt;
&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;the hub piece&lt;/a&gt;: when your agent says&lt;br&gt;
"done," what — other than the agent — decided that was true? A loop answers&lt;br&gt;
"nothing, but enthusiastically." The only real answer is to have something that&lt;br&gt;
isn't the agent look at where it's going &lt;em&gt;before&lt;/em&gt; it gets there.&lt;/p&gt;

&lt;p&gt;If your loop already checks itself mid-flight, or I've mis-drawn where the&lt;br&gt;
terminal gate fails you, tell me where — I'll fix the piece.&lt;/p&gt;




&lt;h3&gt;
  
  
  The series — &lt;em&gt;Orchestration, Honestly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Ten pieces, one argument. Start anywhere; each one cross-links the rest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;The one idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/you-can-parallelize-the-typing-you-cant-parallelize-the-trust-2fkd"&gt;You can't parallelize the trust&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Amdahl's Law: why your fifth agent slows you down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/youre-optimizing-the-part-of-your-agent-you-dont-own-b69"&gt;Harness engineering&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;you rent the model; the harness is the part you own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-agent-says-the-tests-passed-it-didnt-run-them-15j"&gt;The supervision ladder&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;five rungs of trusting an agent you don't watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/approve-all-is-how-your-agent-ships-the-dangerous-one-2ma"&gt;The approval plane&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;auto-approve reads, gate writes — wire the line between&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Kill the loop&lt;/strong&gt; &lt;em&gt;(you're here)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;why "keep going until done" compounds a wrong turn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/cheaper-per-token-is-not-cheaper-per-outcome-3b9b"&gt;Route by cost&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;plan expensive, execute cheap, verify independently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-claude-skill-is-invisible-to-codex-heres-how-to-fix-it-3l74"&gt;Files with contracts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the interop layer every agent system reinvents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/your-coding-agent-knows-the-internets-average-heres-how-to-make-it-know-yours-1aeg"&gt;Knowledge is power&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;give your agent your knowledge, not the internet's average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/saying-hi-to-this-agent-daemon-cost-029-a-rivals-hands-on-paseo-review-e7i"&gt;Paseo, hands-on&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;a full real-session review of the daemon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/agentiknet/9-coding-agent-orchestrators-honestly-compared-dated-sourced-and-one-of-them-is-mine-3kpk"&gt;9 orchestrators, compared&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;the tool-by-tool teardown + a decision table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Written by the maintainer of &lt;a href="https://agentproto.sh" rel="noopener noreferrer"&gt;agentproto&lt;/a&gt; (Apache-2.0, &lt;a href="https://github.com/agentproto/ts" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Same contract as our &lt;a href="https://agentproto.sh/compare" rel="noopener noreferrer"&gt;/compare&lt;/a&gt; page — dated facts, named strengths, corrections by issue. Got something wrong? &lt;a href="https://github.com/agentproto/ts/issues" rel="noopener noreferrer"&gt;File an issue.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building agentproto in the open — follow &lt;a href="https://x.com/theagentproto" rel="noopener noreferrer"&gt;@theagentproto&lt;/a&gt; and &lt;a href="https://x.com/agentik_ai" rel="noopener noreferrer"&gt;@agentik_ai&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claudecode</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
