piw, a container that keeps my agent off my infrastructure
• Created by: Domonkos Poór

Hindsight is 20/20. It is easy to claim you knew something after the fact. I had a suspicion years before, and I got the chance to confirm it at a previous workplace: a larger model does not automatically mean more productivity, or more intelligence in any useful sense.
In my experience, your processes matter far more than the model you run. The useful output, the work that actually gets done, depends on how you work, not on the size of the weights.
The trend to stuff more tools and capabilities into the harnesses and models we use is, I think, backfiring. This is anecdotal, but I have solved problems more accurately, and often faster, with a smaller model than a larger one. I have my suspicions about why, but that is a different note.
The conclusion I drew is simple. I want lean tools, and I want tools I control.
The tool I wanted
pi fits that description. It is an agentic coding harness built around minimalism, extensibility, and a low profile, and it is open source.
But pi has full filesystem access. Run it directly on a workstation and it can read and write anything my user can. Most of the time that is fine. When you provision servers, handle credentials, or work on live infrastructure, it is not fine. I did not want the agent to touch production, even by accident.
So I did what a DevOps engineer does in this situation. I put pi inside Docker. The first version worked, and it worked better than I expected. I kept using it after I left that workplace. Eventually I rebuilt the idea from scratch, with more thought about how other people would use it. That rebuild is piw.
What piw is
piw is a launcher and environment manager for pi. It runs the agent in a container and keeps the workspace native.
The container holds the tooling and the isolation. The workspace stays on the host and is mounted at the same path. The agent cannot change the host outside the paths you mount.
The design has four goals, in priority order:
- Isolation without friction. The agent cannot change the host by accident. The workflow still feels native, because the workspace, configuration, and skills are mounted. Every change is visible on the host at once.
- Transparency. The
piwcommand is one bash script. The Dockerfile is plain. - Leanness. The default image carries the tools that most sessions need and nothing more. You add the rest.
- Composition. Layers and store tools combine without limit.
When two goals conflict, the order decides. Isolation wins over transparency. Transparency wins over leanness. Leanness wins over composition.
How it works
Two scopes
The harness separates two kinds of files, and the boundary is visible from the repository root.
Upstream content is everything a user receives by cloning: the piw
script, the Dockerfile, the seed files, the skills, and the docs.
Local state is everything the user owns: secrets, the agent's state,
installed tools, and the user's layers. It all lives under one gitignored
directory, .local/. git status stays clean, and the private half never
leaks into a commit.
The images
piw builds two images. piw:default is the base, from the Dockerfile. It
carries Node, apt tools, mise, yq, and uv. piw:local
starts from that base and
appends one step per active layer. A launch uses piw:local.
The image carries a label with the hash of the plan that built it. That is how piw detects a stale image and refuses to launch it.
piw does not put the agent in the image. pi lives in a mount, and its extensions live in another. Both update without an image rebuild.
Layers and store tools
Two mechanisms add tools.
A layer adds tools to the image at build time. A layer directory holds up to
five files: an apt list, an archives list, a mise.toml, an install.sh
that runs as root, and a README. The user adopts a layer by name in a manifest.
The shipped layer, workstation, adds compilers, infrastructure tools, and
security and forensics tools.
A store tool is installed into .local/store, which is mounted inside the
container. Store tools survive an image rebuild, because they live in the mount
and not the image. mise resolves the spec, pins the version in a lockfile, and
checks the checksum where the backend provides one.
An install script runs as root, so a third-party layer can run any command as root. Read a layer before you adopt it. That warning is in the documentation, and it is worth repeating here.
The mounts
A launch mounts the workspace at the same path, read-write by default. It mounts the agent state, the store, the mise config, the app directory, and the skills directories. It mounts the user's git configuration read-only, so commits inside the container use the host identity.
/home/pi is not writable and does not survive the container. The store mount
is the writable, persistent home area, and every tool that writes to $HOME
points at a path under .local/.
The mounts carry the SELinux relabel flag that Fedora and RHEL need. The launch passes the host user and group ID, so files on the mount belong to the host user. The Docker socket is not exposed.
Permission modes
Three modes gate the agent: permissive, restricted, and readonly. The mode
config is mounted read-only. In readonly mode, the workspace itself mounts
read-only.
The secrets rules deny by default. The secrets file is denied outright, and the agent's authentication file is gated.
Status
piw is public under the GPLv3-or-later, at github.com/dpoorc/piw.
It is a community wrapper. It is not an official product of the pi project.