Pig: Pi in Go, a port that plans on keeping up PiG, a Go rewrite of the Pi agent harness, became open source this week as a community-owned project sponsored by HPE's Open Source Program Office, after author Michael Kinsy committed a 5,903-line scaffold in late April and ran it in production in internal HPE tooling. The repository's docs/evals measurements on Linux x86_64 with 1 CPU over 10 runs show `pig --version` at a median 21.5 ms versus 300.3 ms for Pi 0.87.1, and peak memory of 24.6 MiB versus 101.5 MiB. PiG is not officially affiliated with Earendil or the Pi project but plans to support upstream. Earlier this year, GitHub announced https://github.blog/news-insights/company-news/github-copilot-is-moving-to-usage-based-billing/ that Copilot would move to usage-based billing on June 1. Most people using the tool seriously weren't surprised. Once you fan work out across more agents doing more ambitious work, token use climbs by an order of magnitude, and a flat monthly fee starts to look like a subsidy. Copilot's subagent feature in particular made it easy to get huge usage out of one subscription. I wanted something to show for the last weeks of request-based pricing. My plan was to push a few projects far enough with agents that I could finish them later with fewer and cheaper model calls. One of them was a compiled version of the agent harness I already used every day, the program that connects a model to tools and a terminal. Soon after the announcement, at the end of April, I committed a 5,903-line scaffold of Pi https://github.com/earendil-works/pi rewritten in Go. Pi helped write it, and within a few days it compiled, ran, and passed its own tests. Getting it to the point where I could rely on it daily took most of May. By the end of May it had a name, PiG "Pi in Go" , and it was my daily harness. It has run in production in internal HPE tooling ever since. This week it becomes open source, as a community-owned project sponsored by HPE's Open Source Program Office. PiG isn't officially affiliated with Earendil or the Pi project, but it plans to support upstream in any way it can. From a scaffold to a daily driver, to production, and now to open source. Why Pi, and why Go Pi was already my daily harness. I found it while trying to understand how OpenClaw worked and ended up digging into the engine underneath instead. Mario Zechner and the Pi contributors built something small enough to follow. It has an agent loop, a terminal interface, plain session records, support for many model providers, and an extension system for adding whatever the core leaves out. I could see what went into the session and why. Mario's account of Pi's design https://mariozechner.at/posts/2025-11-30-pi-coding-agent/ explains the thinking better than I do here. I wanted that same harness as a single native binary, with no Node.js requirement and the option to compile my extensions in. The goal was never a different harness. PiG is meant to behave like Pi, and where it doesn't, the difference is a bug. The same harness, packaged as one native binary. The repository publishes its own startup and memory measurements in docs/evals https://github.com/MichaelKinsy/PiG/blob/main/docs/site/docs/evals.md . On its last run Linux x86 64, 1 CPU, 10 runs , pig --version had a median of 21.5 ms against 300.3 ms for Pi 0.87.1, and peak memory was 24.6 MiB against 101.5 MiB. For me it came down to Go or Rust, and Go won for practical reasons. We already use it in some internal AI services I work on. Its syntax is small and boring, which helps when you review a lot of generated code. And a harness spends most of its time waiting on model streams, tool processes, and the terminal, which is the kind of concurrency Go handles with less ceremony than most languages. Rust still has a place through the extension software development kit SDK , wherever measurements show it's worth the cost of crossing a process boundary. From the back of a napkin to a translation system The original plan could fit on the back of a napkin. Map every TypeScript file to a Go target, have dedicated agents translate, capture Pi's outputs as goldens reference results to compare against , and fix mismatches until the port matched. Red, green, refactor, repeat. In one day, nine parallel batches mapped roughly 250 upstream files to Go. The code looked reasonable. The missing behavior was harder to see. Long sessions ran fine for an hour and then slowed to a crawl. The terminal flickered, but only after certain resizes, which is a nice way to add surprise disorientation to your workflow. In terminal extensions, a translation could return the right values while delivering events in the wrong order during cancellation. Everything looked fine until you pressed Ctrl-C at the wrong moment. So testing became the project. Every upstream file needed a Go target, an explicit deferral, or a reason it didn't apply. Every upstream file has a row and a status. For interactive testing I built a comparison runner that gives Pi and PiG the same inputs and compares what comes out. For the terminal, it starts both programs in separate tmux terminal multiplexer sessions, sends the same keystrokes, and compares the screens. Most scenarios compare a region of the screen exactly, some including colors. Others compare it after normalizing whitespace. That caught cursor problems, stale rows, broken overlays, and resize bugs that unit tests walked past. The comparison runner. Both programs get identical keystrokes; if the compared part of the screen differs, the scenario fails and the diff is saved. Then the test system needed tests. A scenario could start both programs, wait for some text, and pass without exercising the behavior it was named for. Custom linters started rejecting scenarios that asserted too little or hid real differences behind loose comparisons. The linters had bugs too. Some of May went to fixing the thing that was supposed to tell me whether everything else was fixed. I also tried letting another model judge the patches. It was less reliable than the patches, so I removed it. Agents still write code and find problems. Tests, side-by-side comparisons, and a person reading the diff decide what ships. This process also surfaced issues that sent me to read Pi more deeply, and that reading was some of the most valuable part of the work. By late May, PiG was the default coding-agent runtime for an internal HPE AI services platform and my own daily driver. I still switch back to Pi sometimes, when I need something the port hasn't caught up on. By June the question had changed from "Can PiG replace Pi?" to "Have I stopped noticing that I switched?" That left the napkin's last step. "Repeat" turned out to be the hardest one. Pi keeps shipping, and PiG has to follow. The tooling for that grew into the PiG Porter. It started as a list of which Pi files had a Go counterpart. Then the real Pi became the judge: comparison scenarios run the pinned Pi next to PiG, so a scenario passes only when both programs agree. Then each piece of evidence started recording hashes of the upstream source, tests, and fixtures it depends on, so an upstream change reopens only the claims it touches. Now an agent, the Porter, is being built to work inside those limits. It's meant to read an upstream change, check what the real Pi does, and propose a Go change with the test that should prove it. It doesn't approve its own work, commit, or change the Pi version PiG follows; a person does. It still has gaps and is far from airtight, so manual work is still needed. Making it easier for the project to stay current is one of my main engineering goals. How PiG follows each Pi release. The agent proposes; Pi judges; a person merges. Piglets I used to keep a few Pi setups for different jobs, each with its own extensions, skills, model, and prompt. I called them pi-flavors, which I thought was clever as long as I didn't think too hard about what pie has to do with Pi . The idea turned out to be more useful than the name, and in PiG they became Piglets. A Piglet is one named agent: a PiG configuration that names its extensions, skills, built-in tools, packages, model settings, and system prompt. That makes an agent easy to share, either as a sourced configuration or as a built binary. Install one with pig piglet add npm: