ST 01 Self-hosted · the build floor for coding agents

Agents write the code.
Something has to check it.

VaporBuild is the part of my local AI stack that handles code once an agent has written it. It decides whether this machine can take another agent right now, tests each commit in a throwaway sandbox, checks that a port still behaves like the original, and takes a reviewed pull request through CI, merge and deploy.

Rust · SQLite · rootless Podman sandboxes · MCP server for Claude Code, Codex and Hermes · GPL-3.0-or-later

ST 02 Try it

The build floor, in your browser.

Five small working models of VaporBuild's rules, on sample data. Pick a moment, then press the yellow button. The “What to notice” box says what to look for. Nothing here talks to a server.

01

Can another agent start?

ST 03 What it does

Six stations, one floor.

Each station answers one question an agent, or I, would otherwise answer by guessing. Every page in its web view has a JSON twin, and agents reach the same operations over MCP.

01 · Repo map

What is each repository?

A scan of every repository records its languages, toolchain pins, build system, CI, license, inferred build and test commands, and declared dependencies: Cargo, npm, Python, Go and container images. It rescans every six hours.

02 · Capacity

Can this machine take another agent?

Before VaporAgent starts an agent or a review, it asks for a slot. Free slots are the smallest of a slot limit, available memory and spare CPU. A lease ends when its process exits, so a crashed agent never keeps a slot.

03 · Test runs

Does this exact commit pass?

A fresh rootless Podman sandbox at that commit: setup steps fetch dependencies with network, test steps run without it, in the image the repository's pins ask for. Results are kept by commit, so a second reviewer reads the first run instead of repeating it.

04 · Equivalence

Does the new version behave like the old?

Record what the original does for a set of command-line or HTTP cases, replay them against the candidate, and report every difference as a diff. A step is done only when the report is clean or every difference has a written reason.

05 · Porting

How do we move this to Rust?

Parse the repository, order its modules leaves first by the import graph, and propose a Rust module and crates for each step. Each step becomes a VaporAgent task, and it can only be marked verified with its own passing equivalence report.

06 · Ship queue

How does a reviewed change go live?

Catch the pull request up with its branch, wait for the builds branch protection requires, merge it, mirror the same tree to the code forge, and run the deploy inside a monitoring maintenance window. A restart resumes where it stopped.

ST 04 In the stack

Where it sits in the local AI stack.

VaporAgent tracks the work and VaporMemory holds what the agents know. VaporBuild knows the code. These are the hand-offs between them.

  1. VaporAgentVaporBuild

    Reserves a slot before it starts an agent or a review. No slot, no start: the request waits and says why.

  2. VaporBuildVaporAgent

    Keeps agents on ready issues. Once a minute it works out how many issue workers the budget allows and asks VaporAgent to start them, always leaving a slot for an agent I start myself.

  3. Reviewer agentVaporBuild

    Asks for a test run of the exact commit under review and reads the recorded result, instead of running the suite on its own.

  4. VaporBuildVaporAgent

    Files each porting step as a task with its acceptance written in: a clean or explained equivalence report attached to that step.

  5. Any agentShip queue

    Queues a reviewed pull request as itself. VaporBuild merges it under that agent's own forge account and deploys it inside a maintenance window, so the outage alerts stay quiet only for the minutes the deploy needs.

  6. AgentsVaporMemory

    Recall what they need over MCP, with every result naming its source revision. VaporBuild's own runbooks and decisions are among those sources.

ST 05 House rules

The person at the machine comes first.

The agents share a desktop I also use. While a game is running, builds, tests and sandboxes wait in line with the reason shown, and a running test is stopped and started again later. A killswitch stops everything at once, including merges and pushes.

My own agents never wait on VaporBuild: they use capacity before any background worker is budgeted, and one slot stays free for the next one I start. A full budget only stops new workers starting. A running worker is never stopped to make room.

Writes come only from local tools. The daemon listens on loopback, checks the Host header, refuses any request a browser could send, and keeps recording, comparing and porting writes out of its HTTP API altogether.

Sandbox defaults

  • Networknone, unless a setup step asks
  • Capabilitiesall dropped, no-new-privileges
  • LimitsCPU, memory and process caps
  • Toolchainimage pinned by digest
  • Build cacheper repository and image
  • Afterwardsworkspace deleted

ST 06 Limits

What it does not do.

It does not write code.

Agents write the code. VaporBuild plans, measures, tests and ships, and refuses to call a step done without evidence.

A clean report is not proof.

Equivalence covers the cases someone recorded, plus fuzzed variants of them. Behaviour no case exercises is not compared.

One machine, one operator.

It schedules work on the host it runs on, for one person's repositories. It is not a shared CI service.

Some gaps are still open.

Equivalence runs do not yet take a capacity lease, and HTTP scenarios cannot run in the sandbox yet. Both are tracked follow-ups.

The source is private because it is configured for my own estate. The demo above runs the same rules over sample data.