Shipwright
Working private toolA workflow system for coding agents that refuses to call anything done without evidence, and makes the bet explicit before any code gets written.
At a glance
- Outcome: Agent work runs through a shaped, gated lifecycle instead of a chat that drifts: frame the problem, shape the work, make the bet explicit, then execute against acceptance criteria that have to be witnessed before anything is called done.
- Status: Working private tool, built over June–July 2026 and in use on my own projects since.
- Role: Solo.
- Stack & libraries: TypeScript. A harness-agnostic core package holds the state machine, renderers, and the on-disk format; a Pi extension, a Codex drive CLI, and an MCP server shared with the Claude Code edition are bindings on top of it. A read-only local viewer serves the spine for human review.
- Source: Private. Seven repositories: the Pi package with the harness-agnostic core inside it, a Claude Code edition, and five companion packages.
- Limitations: Built around one person’s workflow, and the port story is half-finished rather than absent. The core is harness-agnostic and a test enforces it, but the conformance suite checks serialized bytes rather than replaying each port end to end, and some help text still uses Pi’s command idiom. There are several repos because each variant grew where its harness lives.
Where this sits
Project knowledge stacks up: code, symbols, systems, decisions, invariants, goals.
Indexers own the bottom. An LSP or a repo map answers what the code says. Nothing owns the top, so the decisions, the invariants and the goals live in whoever’s head was in the session, and the model gets handed more code instead of better-shaped context.
Shipwright owns the top, plus the bookkeeping a model won’t do for itself: which files are in play, which assumptions are live, and what has already been tried and failed. It never becomes an indexer; it points at one when there is one.
The idea
Coding agents are good at producing work and bad at knowing when they’re done. Left alone they will declare victory, and the failure is rarely the code. It’s that nobody wrote down what “working” meant before starting.
Shipwright borrows from Shape Up and BMad: shape the right work, bring in expert thinking only where it’s useful, then execute with ruthless verification.
Nine phases are the vocabulary, not the itinerary: Frame, Shape, Bet, Elaborate, Plan, Execute, Verify, Retro, Ship. The track picked at Frame decides how many run: tiny runs three (Frame, Execute, Verify), small five, medium seven, large all nine. The model recommends the track; the person decides.
The gates move with it. Large stops hard at Bet and at Ship. Medium collapses Bet into a persisted gate on the way into Plan and still stops at Ship. Tiny and small carry no persisted gate at all. They proceed unless the person objects, because a two-file bugfix shouldn’t cost a ceremony.
The spine
The thing Shipwright actually invented is the spine: a directory of plain files that is the workflow.
State, the phase ledger, the checkpoint, the task graph, and every phase artifact live on disk in a format pinned by golden fixtures. A conformance suite reproduces the exact bytes, and bumping a schema version fails the build until a migration fixture exists.
Modeling the workflow as a format rather than as harness code is what buys everything else: the same cycle runs under Pi, Codex, or Claude Code; the viewer can read it without an API; and a crashed process resumes from files rather than from memory. A test scans every source file in the core package for a harness SDK import and fails the build on one, so the boundary can’t silently recouple.
The details that make it work
- “Done” is a computed value, not a claim. Each acceptance criterion is paired
with a command, the command is executed through the harness, and its exit code is
recorded. The result is an evidence bundle listing what changed, what was verified
with its exit code, what failed, and what wasn’t run with the reason. The status
reads
verifiedonly when there was at least one check and every check exited 0 without being killed or skipped. A missing command, a killed process, or an empty check list all land onverification_incomplete. - A cancelled gate is not consent. If a gate is dismissed, the pending gate survives in state and gets re-presented on resume. This one rule is most of the value, because the common failure mode is an approval that never happened being treated as one.
- The ledger is a delta, not a running total. Crossing a phase boundary appends one structured entry for the phase just left: files touched split into primary, supporting, and test; commands first run; decisions recorded; what changed in the assumptions, open questions, and failed approaches; and the verify outcome. Re-entering a phase isn’t a boundary, so nothing double-appends. The next session reads the ledger instead of replaying the work that produced it.
- The loop has a spend limit. Between gates, Shipwright drives itself: after each agent turn it re-prompts from the checkpoint and asks one function whether to go again. Five things stop it: verification witnessed, a gate waiting on the person, an open question only the user can answer, the budget spent, or a stall. The budget is set at Frame and scales with the track (3, 5, 8, 12). A stall is detected by fingerprinting the working set, the failure memory, the open questions, and an in-loop activity counter; three identical fingerprints in a row means the agent is spinning, and the loop escalates instead of burning the rest of the budget. Every stop prints its reason as one line.
- Review is read-only. The artifact viewer serves the current workflow spine for a human to read. It cannot make gate decisions, edit tasks, or mutate artifacts, so “I looked at it” and “I approved it” stay separate acts.
The wider set
Around the core sit five companion packages, each standalone and each with its own tests: pi-distill (structured extraction of command output), pi-archetypes (a curated code-patterns library), pi-crew (a subagent spawner that runs prompts in nested processes), pi-flight (a local flight recorder, one compact JSONL line per event, never leaving disk), and pi-blueprint (a static-HTML visual companion that renders the ledger).
The guiding principle across all of them: don’t give the model more context, give it better-shaped context. With a corollary for verification: prefer selecting machine-readable output over parsing human output.
Clankkers grew out of this work. When the question shifted from shaping one workflow to supervising many agent processes durably, the event log and the gate model came with it.