{"slug": "i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didn-t-mean-what-i", "title": "I copied a \"minimal\" coding agent. Then I read it — and minimal didn't mean what I thought.", "summary": "A developer who built a coding agent from scratch to compare it against the minimal harness pi discovered that pi's minimalism is about disciplined scope, not line count. The developer found that pi's core remains four tools with a ~12,600-line agent core, and its refusals of features like MCP and subagents hold, while its depth grows through subsystems like compaction and an eval suite. The developer also identified a real bug in their own harness: pi refuses all tool calls when output is truncated, a safeguard the developer had not implemented.", "body_md": "A month ago I started building a coding agent from scratch, with one rule: **build first, then read.** I'd picked [pi](https://github.com/earendil-works/pi) as my reference precisely because it was described as the smallest serious harness — four packages, four tools, a system prompt under a thousand tokens, and competitive benchmark scores anyway. Build each piece myself, then open pi's version and diff the decisions. Reading first turns study into copying.\n\nLast week I finally opened it. The premise I'd chosen it on was gone.\n\n| pi (v0.84) | mine | |\n|---|---|---|\n| packages | 10 |\n1 |\n| tools shipped | 8 |\n5 |\n| agent core | ~12,600 lines | ~300 |\n| iteration cap | none |\n20 |\n| compaction | yes |\nnone |\n\nThe edit tool alone is 443 lines. There's a compaction subsystem, session branching, an extension system, and its own eval suite. My first note to myself was blunt: *the minimalism thesis has eroded.*\n\nThat note was wrong twice over, and both ways are the interesting part.\n\npi is known for what it leaves out: no MCP, no subagents, no to-do tool, no plan mode, no background bash. Each omission is an argument — background bash means managing processes you can't see; subagents mean decisions made where you can't inspect them.\n\nI grepped for all five. Two came back present. *There it is*, I thought — the project grew up and quietly took the features back.\n\nThen I looked at what the matches actually were. Both were inside a **vendored highlight.min.js**: the \"MCP\" hits were the string\n\n`mcpy`\n\nin a language list, the \"TODO\"s were comments in third-party source.**All five refusals hold.** I had a paragraph half-written arguing the opposite.\n\nThe same correction applies to the tool count. pi ships eight tools, but one line decides what the agent actually gets:\n\n``` js\nconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n```\n\nThe original four. `ls`\n\n, `grep`\n\n, `find`\n\nand `truncate`\n\nare opt-in. The default context surface — what an ordinary session puts in front of the model — never grew.\n\nThat's the principle I keep coming back to: **do less, and do more of what's left.** Not less effort — fewer things, each taken further. pi is the cleanest example of it I've read.\n\nIt didn't grow scope. It grew depth. The edit tool is 443 lines because it handles multiple disjoint edits in one call, matches each against the original file rather than incrementally, detects and restores line endings, and serialises concurrent mutations. Compaction arrived because long sessions genuinely need it. The eval suite arrived because you can't improve a harness you can't measure. Every one of those is the *same capability set*, done properly — while the list of things it says no to hasn't moved in a year.\n\nSo \"minimal\" was never about line count. A four-tool agent whose tools are shallow isn't minimal, it's unfinished. An eight-tool agent that has said no to twenty others is disciplined. I'd been treating small as the virtue; small was the side effect.\n\npi ships an eval package. I built one separately, without looking. Both isolate each run in a temp directory, persist the session as an artifact, index runs in a JSONL file, compare configurations against each other, and pin the provider and model into the results. Two people solving unattended agent evaluation independently produced the same five primitives — stronger evidence the design is right than either implementation alone.\n\nOne surprise: pi's \"judge\" isn't an LLM. `createJudge()`\n\nis a deterministic multi-criteria scorer. For all the talk of LLM-as-judge, a mature harness still grades its agent with code.\n\npi checks whether the model's output was cut off by the token limit, and if so refuses *every* tool call in that message — truncated output means possibly-truncated arguments, and half a JSON argument still parses sometimes. My harness records that stop reason in three places and branches on it in none. A real bug I hadn't found, in a family that had already bitten me twice.\n\n(The other: pi's graders assert on tool calls — name, arguments, status, return value — not just the final answer. Mine grades the end state, so it can tell me a task succeeded but not that the agent got there acceptably.)\n\nBuild-first paid off in a way I didn't anticipate. Because I'd already made every decision myself, the diff wasn't a list of things pi does — it was a list of places where my reasoning and theirs parted, each with a *why* attached. Reading first, I'd have copied the structure and learned none of it.\n\nAnd the most valuable thirty seconds was checking what a grep actually matched before believing it. I've now been wrong that way six times on this project: a metric that reported zero problems, twice; a regex that silently matched nothing; a grader so lenient it reported 100% while quality collapsed to zero. Every time, the number was confident and the number was wrong.\n\nThe rule I keep relearning: **a measurement that says everything is fine is a hypothesis, not a result.**\n\n*Built as a learning project on agent harnesses and evaluation. Comparison notes and the harness are in zachzwy/agentloop. I'm Wenyu — github · linkedin.*", "url": "https://wpnews.pro/news/i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didn-t-mean-what-i", "canonical_source": "https://dev.to/wenyu_zhang/i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didnt-mean-what-i-thought-55g4", "published_at": "2026-08-23 12:08:41+00:00", "updated_at": "2026-08-23 12:13:35.620087+00:00", "lang": "en", "topics": ["artificial-intelligence", "developer-tools", "ai-agents"], "entities": ["pi", "earendil-works"], "alternates": {"html": "https://wpnews.pro/news/i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didn-t-mean-what-i", "markdown": "https://wpnews.pro/news/i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didn-t-mean-what-i.md", "text": "https://wpnews.pro/news/i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didn-t-mean-what-i.txt", "jsonld": "https://wpnews.pro/news/i-copied-a-minimal-coding-agent-then-i-read-it-and-minimal-didn-t-mean-what-i.jsonld"}}