DOCS · GUIDES
Build and ship
What the build station does with an approved spec, the three guarantees it enforces, and how to read the result.
On this page
The build station takes an approved spec and produces a pull request. Everything it is not allowed to do is enforced rather than requested.
Starting a build
From the spec drawer in the app, or over the API:
POST /projects/:slug/board/specs/:specId/buildThe three guarantees
- The gate is re-checked at the point of use
- Not consulted once at dispatch and trusted afterwards. An unapproved spec gets the same 409 the CLI gets, at the moment agent output would first reach code.
- The agent gets editing tools only — never a shell
- It cannot run arbitrary commands. specd runs your repository's own verify command itself, so "the tests passed" is a statement specd made, not one the agent reported about itself.
- It never touches your working tree
- Local builds use a throwaway git worktree; hosted builds use a shallow clone in a scratch directory. The branch survives; the workspace does not. You can keep working while a build runs.
What comes out
- A branch named
spec/<id>-<slug>— which is also how the merge webhook matches the delivery back to the spec. - One commit per task, in the order the spec listed them.
- A pull request (or merge request) you review and merge. specd never merges.
- The as-built spec, filed into
knowledge/specs/by the last task — and appended by specd itself if the model omitted it.
Reading the verify result
Verification distinguishes two outcomes that are usually collapsed into one — and they belong to different people:
| Result | Means | Whose problem |
|---|---|---|
| failed | Your tests ran, and did not pass. | The change is wrong. Read the diff. |
| could not run | The toolchain was missing, so nothing was proved either way. | The environment is wrong. Fix the runner or the image. |
| passed | Your repository's own verify command exited zero. | Review the pull request as normal. |
Where the build runs
On the server, or on a paired runner — a machine of yours that claims jobs and drives its own local Claude Code. The runner path matters for builds specifically: a dispatched build clones and pushes with the runner machine's own git credentials. specd sends no VCS token, and push access is checked before the first model call rather than discovered at the end of an expensive run. See Self-hosted runners.
Building from your own agent instead
You do not have to use the build station. Pull the approved spec and hand it to whatever agent you already use:
specd spec pull CRM-131 > spec.md # approved only — the gate is server-sideIf that agent is Claude Code, the plugin does the same thing with the gate checked automatically, plus a hook that blocks edits on a spec branch whose spec is not approved.