<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Agent Architecture on AIBussin — AI applications, systems and books</title>
		<link>https://aibussin.com/categories/agent-architecture/</link>
		<description>Recent content in Agent Architecture on AIBussin — AI applications, systems and books</description>
		<generator>Hugo</generator>
		<language>en-US</language>
		
		
		
		
			<lastBuildDate>Mon, 05 Oct 2026 09:00:00 +0100</lastBuildDate>
		
			<atom:link href="https://aibussin.com/categories/agent-architecture/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>The Loop You Are Writing For</title>
				<link>https://aibussin.com/books/pi/01-chapter/</link>
				<pubDate>Thu, 01 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/01-chapter/</guid>
				<description>&lt;p&gt;You are going to write an extension. Before that, you need to know what it is&#xA;extending.&lt;/p&gt;&#xA;&lt;p&gt;This is the step most people skip. They install Pi, run a task, get something&#xA;nearly right, and start writing code against a mental model built from&#xA;observation. The model is usually close enough to work and wrong in a few named&#xA;places, and those places are where every interesting bug lives.&lt;/p&gt;&#xA;&lt;p&gt;Why &amp;ldquo;wrong in a few places&amp;rdquo; is worse than &amp;ldquo;wrong everywhere&amp;rdquo; is worth one&#xA;sentence of its own, because it explains the shape of the rest of the book. A&#xA;model that is wrong everywhere fails loudly: you stop and read the&#xA;documentation. A model that is nearly right fails as a &lt;em&gt;symptom&lt;/em&gt;. The model&#xA;ignores your instructions. Your tool never appears. Your injected content&#xA;vanishes after a compaction. Your handler fires at the wrong moment. Each of&#xA;those observations is compatible with several different causes — some in your&#xA;code, some in Pi&amp;rsquo;s, some in the way you assembled the request — and the&#xA;observation alone cannot tell them apart. What tells them apart is knowing the&#xA;exact mechanism the symptom passed through. That mechanism is the loop.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Models and Thinking Level</title>
				<link>https://aibussin.com/books/pi/03-chapter/</link>
				<pubDate>Thu, 01 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/03-chapter/</guid>
				<description>&lt;p&gt;Something is not working. The agent is not using your tool. It is ignoring an&#xA;instruction. It stops halfway. Before you go looking in your extension, check&#xA;which model is running and what thinking level it is set to.&lt;/p&gt;&#xA;&lt;p&gt;This is not a joke about blaming the model. It is a description of how the&#xA;system is layered: model choice and thinking level sit &lt;em&gt;underneath&lt;/em&gt; every&#xA;mechanism in this book, and they change behaviour in ways that look exactly&#xA;like bugs in the layer above.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The Context Window Is a Budget</title>
				<link>https://aibussin.com/books/pi/04-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/04-chapter/</guid>
				<description>&lt;p&gt;You are halfway through a refactor. Pi has read forty files, run the test suite twice,&#xA;and rewritten the same module three times because each attempt turned out to conflict&#xA;with the last. The session is still on disk, but the request has grown too large. If Pi&#xA;compacts it, older messages are represented by a summary rather than sent in full.&lt;/p&gt;&#xA;&lt;p&gt;Most people meet this as a mood: Pi got worse at the task. It is easier to reason about&#xA;as a budget. Each request consumes a varying number of tokens within the model&amp;rsquo;s context&#xA;window, across components you can inspect and, in several cases, change.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Sessions and Where They Live</title>
				<link>https://aibussin.com/books/pi/05-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/05-chapter/</guid>
				<description>&lt;p&gt;When you want to reconstruct what Pi recorded, start with its session file. It is plain JSONL that you can read with a text editor: the first line is a header, and subsequent entries describe messages, settings changes and other session events. Entries with IDs and parent IDs form a tree, but not every recorded entry is a message sent to the model.&lt;/p&gt;&#xA;&lt;p&gt;That tree is the reason Pi can offer &lt;code&gt;/tree&lt;/code&gt;, &lt;code&gt;/fork&lt;/code&gt; and &lt;code&gt;/clone&lt;/code&gt;, and it carries the&#xA;book&amp;rsquo;s most-repeated distinction: &lt;strong&gt;a session is a tree; the model&amp;rsquo;s context is one&#xA;path through it.&lt;/strong&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>Skills</title>
				<link>https://aibussin.com/books/pi/13-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/13-chapter/</guid>
				<description>&lt;p&gt;&lt;code&gt;/review&lt;/code&gt; from &lt;a href=&#34;https://aibussin.com/books/pi/12-chapter/&#34;&gt;chapter 12&lt;/a&gt; expands when you invoke it. The problem it solves has a sibling: work that the model should recognise as relevant to a task without you naming a command first. Skill selection is model-driven, not a guaranteed trigger.&lt;/p&gt;&#xA;&lt;p&gt;That is a skill, and the entire mechanism turns on one field you are tempted to rush.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-a-skill-actually-is&#34;&gt;What a skill actually is&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;skills.md&lt;/code&gt; opens with the definition: skills give Pi specialized instructions and supporting files for a particular kind of work. Pi advertises each eligible skill by name and description. The model may then read its &lt;code&gt;SKILL.md&lt;/code&gt; when it considers the skill relevant; Pi does not automatically execute the skill on a matching task.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Skills That Carry Files</title>
				<link>https://aibussin.com/books/pi/14-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/14-chapter/</guid>
				<description>&lt;p&gt;The review guard&amp;rsquo;s checklist is forty items. Three screens of Markdown in &lt;code&gt;SKILL.md&lt;/code&gt; would load all forty every time the skill fires, including for the small reviews where only three apply.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;skills.md&lt;/code&gt; offers a better arrangement: skills can bundle scripts, references, and assets alongside their instructions. The body stays short and names the files; those files are not included automatically in the model context. The agent must explicitly read or execute them when needed.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Events and the Extension Lifecycle</title>
				<link>https://aibussin.com/books/pi/16-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/16-chapter/</guid>
				<description>&lt;p&gt;The review guard can suggest running the checks. It cannot stop a &lt;code&gt;git push --force&lt;/code&gt; that the model decides to run while fixing a conflict.&lt;/p&gt;&#xA;&lt;p&gt;A &lt;code&gt;tool_call&lt;/code&gt; handler can block a matching invocation of a tool before its body runs. That makes it a useful extension-level guard, not an unconditional prohibition: commands can reach the same effect through other tools or paths the handler does not inspect. Getting this right requires knowing the lifecycle, because handlers run in registration order and a return value only matters for events declared to accept one.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Changing What Pi Knows</title>
				<link>https://aibussin.com/books/pi/18-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/18-chapter/</guid>
				<description>&lt;p&gt;The guard works. Pi asks before a force push, &lt;code&gt;run_checks&lt;/code&gt; runs the project&amp;rsquo;s own tests, and the failing-test tool answers with structured data.&lt;/p&gt;&#xA;&lt;p&gt;What still goes wrong is quieter. Pi reviews a diff using &lt;code&gt;npm test&lt;/code&gt; instead of &lt;code&gt;run_checks&lt;/code&gt;, despite the tool being declared to the model. The tool description makes it available; it does not guarantee selection. A reminder placed only in conversation history can also disappear from the request after compaction, leaving the model without that guidance on a later turn.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Extension State and Persistence</title>
				<link>https://aibussin.com/books/pi/19-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/19-chapter/</guid>
				<description>&lt;p&gt;Your &lt;code&gt;guard&lt;/code&gt; extension blocks some writes to protected paths. It works on Monday. On Tuesday you run &lt;code&gt;/reload&lt;/code&gt;, and the block count in &lt;code&gt;/guard-blocks&lt;/code&gt; reads zero. On Wednesday you resume the session from disk and it reads zero again.&lt;/p&gt;&#xA;&lt;p&gt;Nothing is broken. The count was never persisted. It lived in a &lt;code&gt;let&lt;/code&gt; captured by the extension factory, and a reload or a new process creates a new instance. The fix is not necessarily to invent a separate storage file: Pi already provides a durable, branch-aware place for state in persistent sessions. An ephemeral session, however, does not survive process exit.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Slash Commands and Custom UI</title>
				<link>https://aibussin.com/books/pi/20-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/20-chapter/</guid>
				<description>&lt;p&gt;Your &lt;code&gt;guard&lt;/code&gt; extension logs blocked writes. The reader wants to see them. The obvious move is a &lt;code&gt;/guard&lt;/code&gt; command that opens a picker. You write it, then invoke the command in print mode on a CI machine. There is no UI to show the picker, so a command written only for interactive mode cannot complete that interaction.&lt;/p&gt;&#xA;&lt;p&gt;The absence of a UI is expected, but silent failure is not a useful design. Handle modes explicitly before opening a dialog. This chapter covers the available UI surfaces and the mode rules that constrain them.&lt;/p&gt;</description>
			</item>
			<item>
				<title>MCP Servers</title>
				<link>https://aibussin.com/books/pi/21-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/21-chapter/</guid>
				<description>&lt;p&gt;The &lt;code&gt;guard&lt;/code&gt; extension intercepts &lt;code&gt;write&lt;/code&gt; and &lt;code&gt;edit&lt;/code&gt;. It blocks those calls as intended. Then someone on the team installs a Jira MCP server, and the model closes a ticket through &lt;code&gt;mcp__jira__transition_issue&lt;/code&gt; without that guard blocking the call. The MCP call has a different tool name, so a guard limited to &lt;code&gt;write&lt;/code&gt; and &lt;code&gt;edit&lt;/code&gt; does not match it.&lt;/p&gt;&#xA;&lt;p&gt;It was not consulted because the guard never claimed that path was its responsibility — and, more importantly, because whether it &lt;em&gt;is&lt;/em&gt; covered turns out to be a real question with a documented answer. This chapter is about registering MCP servers, controlling how their tools reach the model, and the one thing a permission extension can and cannot learn from them.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Compaction</title>
				<link>https://aibussin.com/books/pi/23-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/23-chapter/</guid>
				<description>&lt;p&gt;Two hours into a refactor, the footer says you are at 87% context. Nothing is wrong. Then it says the agent compacted, and the model asks you to re-explain the schema it was told about an hour ago.&lt;/p&gt;&#xA;&lt;p&gt;That re-asking is one possible consequence of compaction, not necessarily a defect in your prompt. The original entries remain in the session file, but the older portion selected for compaction no longer reaches the next model request as individual messages. Pi sends a generated summary in its place and keeps the more recent messages. The summary may be produced by the current model, and it can omit details that the earlier conversation contained.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Branching and Forking</title>
				<link>https://aibussin.com/books/pi/24-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/24-chapter/</guid>
				<description>&lt;p&gt;The agent picked a schema you did not want, edited eleven files, and is confidently three steps into an approach you have already decided against. You press Escape. Now what?&lt;/p&gt;&#xA;&lt;p&gt;There are three answers for the &lt;em&gt;conversation&lt;/em&gt;: &lt;code&gt;/tree&lt;/code&gt; moves within the current session, &lt;code&gt;/fork&lt;/code&gt; starts a new session from an earlier user message, and &lt;code&gt;/clone&lt;/code&gt; copies the active branch into a new session. The distinction decides where the conversation history lives and which part of it the model sees next. None of these commands undoes the eleven edits already made on disk. If you also want the repository back in its earlier state, inspect and restore those working-tree changes separately, using version control or a backup.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Steering, Queuing, and Changing Direction</title>
				<link>https://aibussin.com/books/pi/25-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/25-chapter/</guid>
				<description>&lt;p&gt;The agent is eleven tool calls into migrating your schema. You can see it is going to be wrong in about three more steps. Aborting would stop the current run, but it would not erase the conversation or undo tool calls that have already completed. You want to preserve the useful investigation while correcting what happens next.&lt;/p&gt;&#xA;&lt;p&gt;You type. You press Enter. And the message waits — because Pi was not going to interrupt mid-tool-call, and the moment it delivers your instruction is a specific, documented point in the loop.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Message Types</title>
				<link>https://aibussin.com/books/pi/26-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/26-chapter/</guid>
				<description>&lt;p&gt;You write an extension that renders tool results. It works with streaming events, fails when replaying a saved session, and fails differently when inspecting a provider request. The difficulty is that a streaming message, a persisted session entry, a projected conversation, and a provider request are not interchangeable representations. One field in particular is not what its name suggests.&lt;/p&gt;&#xA;&lt;p&gt;This chapter is the reference for the shapes themselves.&lt;/p&gt;&#xA;&lt;h2 id=&#34;one-union-four-surfaces&#34;&gt;One union, four surfaces&lt;/h2&gt;&#xA;&lt;p&gt;&amp;ldquo;Pi uses &lt;code&gt;AgentMessage&lt;/code&gt; values in SDK state, lifecycle events, RPC responses, and persisted session message entries.&amp;rdquo;&lt;/p&gt;</description>
			</item>
			<item>
				<title>The Session File Format</title>
				<link>https://aibussin.com/books/pi/27-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/27-chapter/</guid>
				<description>&lt;p&gt;You open a session file to find out what the agent actually saw. There are four hundred lines. Somewhere in them is the system prompt, most of a conversation that has been summarized away, a branch you abandoned last week, and a &lt;code&gt;custom&lt;/code&gt; entry from an extension storing its own counter.&lt;/p&gt;&#xA;&lt;p&gt;Which of those reached the model is not obvious from the file. This chapter is about the file and the rule that decides.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Context Admission Is Application Policy</title>
				<link>https://aibussin.com/books/pi/28-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/28-chapter/</guid>
				<description>&lt;p&gt;Compaction summarized away the schema you explained, and the model asks you to&#xA;restate it. You will not restate it. The fix is a file, because loaded instructions&#xA;travel with every request while a conversation gets compressed. &lt;a href=&#34;https://aibussin.com/books/pi/23-chapter/&#34;&gt;Chapter 23&lt;/a&gt; ended&#xA;there.&lt;/p&gt;&#xA;&lt;p&gt;But &amp;ldquo;put it in a file&amp;rdquo; is the start of the question, not the end. A file on disk can&#xA;be ignored, replaced, filtered out, or supplied by someone other than you. This chapter&#xA;is about the four separate facts hiding in the sentence &lt;em&gt;the model read my AGENTS.md&lt;/em&gt;,&#xA;and about who decides each one.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Failures, Retries, and Recovery</title>
				<link>https://aibussin.com/books/pi/29-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/29-chapter/</guid>
				<description>&lt;p&gt;The provider returns 529 overloaded. Pi waits two seconds and tries again. Twice more. Then it stops and tells you the model is unavailable.&lt;/p&gt;&#xA;&lt;p&gt;That is correct — and it is the &lt;em&gt;least&lt;/em&gt; interesting failure Pi handles. There are three responses to a failed request, they are not interchangeable, and picking the wrong one is how an agent ends up retrying a request that could never succeed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;three-responses-three-meanings&#34;&gt;Three responses, three meanings&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Retry.&lt;/strong&gt; The failure was transient. The request was fine; the server was not. Repeat it.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The Interface Is Not the Agent</title>
				<link>https://aibussin.com/books/pi/31-chapter/</link>
				<pubDate>Fri, 02 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/31-chapter/</guid>
				<description>&lt;p&gt;You have spent thirty chapters mostly in a terminal, and it is easy to come away&#xA;thinking the terminal is Pi. It is not. The terminal is one way to drive the agent,&#xA;alongside print mode, JSON, RPC and the SDK. Switching interfaces preserves the&#xA;underlying agent architecture, but can change how work is submitted, what a person&#xA;can approve, and how results and failures are reported.&lt;/p&gt;&#xA;&lt;p&gt;That is a claim about architecture, and this part of the book ends by testing it.&#xA;Chapters 32 to 35 take the interfaces one at a time. This chapter states what they&#xA;share, shows that the sharing is real, and names the one place where an interface&#xA;does leak into what an extension is allowed to assume.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Model Access Without the Coding Agent</title>
				<link>https://aibussin.com/books/pi/36-chapter/</link>
				<pubDate>Sun, 04 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/36-chapter/</guid>
				<description>&lt;p&gt;Everything so far has run inside a coding agent. You have been using a tool that&#xA;reads files, runs commands and keeps a session, and you have been attaching to&#xA;it. That is the right place to start, because Pi&amp;rsquo;s host is where most people meet&#xA;Pi.&lt;/p&gt;&#xA;&lt;p&gt;It is the wrong place to stop, because most of what an application needs from a&#xA;model is not an agent. It is one question and one answer: &lt;em&gt;is this claim&#xA;supported by this evidence?&lt;/em&gt; One input, one typed result, nothing to run, nothing&#xA;to remember.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The Agent Core on Its Own</title>
				<link>https://aibussin.com/books/pi/37-chapter/</link>
				<pubDate>Sun, 04 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/37-chapter/</guid>
				<description>&lt;p&gt;The claim checker from &lt;a href=&#34;https://aibussin.com/books/pi/36-chapter/&#34;&gt;chapter 36&lt;/a&gt; has a limit. Given the evidence you handed it,&#xA;it can produce a schema-valid assessment, including &lt;code&gt;insufficient&lt;/code&gt; when the evidence&#xA;is inadequate. It cannot independently fetch more evidence in that single call,&#xA;and the model may still judge the evidence incorrectly.&lt;/p&gt;&#xA;&lt;p&gt;Looking for more is a loop: the model asks for something, you run it, you give&#xA;the result back, and the model decides again. You have seen that loop for thirty-six&#xA;chapters, from the outside. This chapter runs it from the inside, in about forty&#xA;lines, using the same class the coding agent is built on.&lt;/p&gt;</description>
			</item>
			<item>
				<title>A Stochastic Step Is a Typed Function</title>
				<link>https://aibussin.com/books/pi/38-chapter/</link>
				<pubDate>Sun, 04 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/38-chapter/</guid>
				<description>&lt;p&gt;An unconstrained agent may finish with prose, and prose is a fragile interface&#xA;between software components.&lt;/p&gt;&#xA;&lt;p&gt;You can pass a paragraph to another function, but branching on its meaning&#xA;requires interpretation or parsing whose behavior you must define and test.&#xA;An ordinary agent can stop after deciding it is finished, without producing the&#xA;structure a downstream function expects. This chapter puts a validated value at&#xA;that boundary instead.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://aibussin.com/books/pi/36-chapter/&#34;&gt;Chapter 36&lt;/a&gt; fixed this for a single call. This chapter fixes it for a loop. The&#xA;result is the most reusable idea in the book, and it fits in one function.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Seams, Hooks, and Irreversible Decisions</title>
				<link>https://aibussin.com/books/pi/39-chapter/</link>
				<pubDate>Sun, 04 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/39-chapter/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://aibussin.com/books/pi/01-chapter/&#34;&gt;Chapter 1&lt;/a&gt; ended on a sentence that has been quietly organising the book since:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;An extension point is a real architectural seam only for decisions it can&#xA;intercept before those decisions become irreversible.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;It was stated there as a finding about forks of the coding agent, and it was&#xA;argued from three cases. This chapter tests it on something you can run. The agent&#xA;core has nine function-shaped options that run around a request or a tool call, and for each one the useful question is not &lt;em&gt;what&#xA;does it give me&lt;/em&gt; but &lt;em&gt;what can I still decide by the time it fires&lt;/em&gt;.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Composing Agent Operations</title>
				<link>https://aibussin.com/books/pi/40-chapter/</link>
				<pubDate>Sun, 04 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/40-chapter/</guid>
				<description>&lt;p&gt;The tempting next move is to make every part of the pipeline an agent. One agent&#xA;retrieves, another assesses, another summarises, and they talk. That may be useful&#xA;when the tasks genuinely require independent decisions or work, but it introduces&#xA;more model calls, coordination and failure paths than this claim checker needs.&lt;/p&gt;&#xA;&lt;p&gt;This chapter is the argument against doing that by default, made with a&#xA;pipeline you can run. The rule it demonstrates:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Testing Stochastic Software</title>
				<link>https://aibussin.com/books/pi/41-chapter/</link>
				<pubDate>Sun, 04 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/41-chapter/</guid>
				<description>&lt;p&gt;The tests in chapters 36 to 40 all passed. They tell you less than you might hope,&#xA;and it is worth being exact about what.&lt;/p&gt;&#xA;&lt;p&gt;They show how your &lt;em&gt;code&lt;/em&gt; handles the model responses you scripted. They cannot&#xA;establish how often a real model will produce those responses. A scripted provider&#xA;can simulate refusals, rambling answers and wrong tool calls, but only when you&#xA;write those cases into the script. If you stop at green tests, you have not yet&#xA;measured the stochastic part.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Authority, Isolation, and What Makes an Agent Worth Building</title>
				<link>https://aibussin.com/books/pi/42-chapter/</link>
				<pubDate>Mon, 05 Oct 2026 09:00:00 +0100</pubDate>
				<guid>https://aibussin.com/books/pi/42-chapter/</guid>
				<description>&lt;p&gt;Everything so far has been a mechanism. Tools, extensions, events, sessions, modes, protocols. This chapter is about the one question that turns a set of mechanisms into something you would let near a production repository, and about what you are then able to claim.&lt;/p&gt;&#xA;&lt;p&gt;Two claims carry the chapter. &lt;strong&gt;Capability is not authority:&lt;/strong&gt; Pi can do almost anything the account that started it can do, and several documented mechanisms bear on whether it &lt;em&gt;should&lt;/em&gt; do a particular thing. Those mechanisms matter, but none by itself is a sandbox. And &lt;strong&gt;a prohibition on what the agent can reach needs enforcement outside the agent&amp;rsquo;s ability to override it.&lt;/strong&gt; That may be an operating-system restriction, a credential with limited scope, or a remote service that independently denies an operation. A prompt, an in-process gate and a tool allowlist can still provide useful controls, but they must not be mistaken for containment of the whole process.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
