Spec-driven agent orchestration

Code generation is solved. Context isn't.

shipd focuses AI coding agents on a spec before they write code — a plan, testable requirement deltas, a mechanical task list — so they build what you meant instead of drifting off-scope. Then an adversarial validator and a semantic review try to break every scenario, catching the regressions, edge cases, and spec violations agents typically ship, before anything merges. What got built and what was asked for are the same document, in your repo.

Install
$curl -fsSL https://shipd.now/install | shcopy
getting started →
Focus
DEVELOP
MANAGE
The core loop

One change, from /s:plan to shipped.

Keep scrolling — the panel follows the change.

$ /s:plan add a --json flag to export
investigating src/export/ · 14 files read
memory ✓ · oracle ✓ · you: 1 genuinely open question
? keep --format=json as an alias, or new flag only?
→ worktree .worktrees/export-json-flag · status: draft
stopped — no code written. you review a spec, not a diff
plan.md
idea, non-goals, binding decisions
spec.md
requirement deltas · WHEN/THEN scenarios
tasks.md
7 tasks, each [req:]-tagged
$ spec_gate.py export-json-flag
checking the plan against the real codebase…
every file the plan cites exists
every requirement has testable scenarios
every task carries a [req:] tag
no unanswered questions remain
PASS → status: ready · implementation may begin
a fail parks the plan rejected with findings written into plan.md — deterministic, LLM-free, never skipped silently
$ /s:build export-json-flag
gate ✓
build ●
refute
review
merge
orchestrator (strongest model) designs · executors one tier down
agent-1 claims 1.1 thread --json through ExportWriter
agent-2 claims 1.2 single-document stdout contract
agent-3 claims 2.1 scenario tests from the delta spec
tasks claimed atomically — the checklist is the coordination
☕ export-json-flag · active · 3/7 — live on your statusline
validator · independent · adversarial
#### Scenario: JSON output is machine-consumable
- WHEN export runs with --json
- THEN stdout is a single JSON document
✗ refuted: progress line leaks onto stdout → back to the executors
✓ confirmed on rerun — against the real, running code
7/7 scenarios confirmed · status: verified
the validator's job is to break the change, not to approve it — trust comes from surviving refutation
gh pr checks 212
ci ✓ pass
semantic-review AST-aware · 3 cohorts · summary + inline comments
disposition: accepted — on record, never skipped silently
✓ PR #212 merged · branch deleted · worktree removed
verified/export/spec.md ← delta merged into the capability library
completed/2026-08-23-export-json-flag/ ← archived, immutably
$ shipd board
the shipd delivery board — unplanned, ready, building, review, and shipped columns, specs grouped by epic
77 specs · 13 epics · 78 shipped this week — live from shipd's own repo
01 · PLAN

State intent. Get a spec.

Describe the change in prose. shipd investigates your codebase first, asks only what it genuinely can't infer, and compiles your intent into three reviewable artifacts — then stops. No code yet. A wrong assumption costs one markdown edit, not a rework.

$ /s:plan add a --json flag to export
investigating src/export/ · 14 files read
memory ✓ · oracle ✓ · you: 1 genuinely open question
? keep --format=json as an alias, or new flag only?
→ worktree .worktrees/export-json-flag · status: draft
stopped — no code written. you review a spec, not a diff
plan.md
idea, non-goals, binding decisions
spec.md
requirement deltas · WHEN/THEN scenarios
tasks.md
7 tasks, each [req:]-tagged
02 · GATE

No code before the gate.

A deterministic, LLM-free gate checks the spec against your actual codebase. Pass promotes it to ready. Fail parks it with the gaps written into the plan — the system stops rather than build on a guess.

$ spec_gate.py export-json-flag
checking the plan against the real codebase…
every file the plan cites exists
every requirement has testable scenarios
every task carries a [req:] tag
no unanswered questions remain
PASS → status: ready · implementation may begin
a fail parks the plan rejected with findings written into plan.md — deterministic, LLM-free, never skipped silently
03 · BUILD

Orchestrated, not prompted.

An orchestrator on the strongest model designs; execution agents one tier down claim tasks atomically in a dedicated worktree. The spec — not the chat transcript — is the single source of context every agent works from.

$ /s:build export-json-flag
gate ✓
build ●
refute
review
merge
orchestrator (strongest model) designs · executors one tier down
agent-1 claims 1.1 thread --json through ExportWriter
agent-2 claims 1.2 single-document stdout contract
agent-3 claims 2.1 scenario tests from the delta spec
tasks claimed atomically — the checklist is the coordination
☕ export-json-flag · active · 3/7 — live on your statusline
04 · REFUTE

A second agent tries to break it.

An independent validator takes every WHEN/THEN scenario in the spec and tries to refute it against the real, running code. Refuted goes back to the executors; confirmed moves on. Done means verified, not "seems done".

validator · independent · adversarial
#### Scenario: JSON output is machine-consumable
- WHEN export runs with --json
- THEN stdout is a single JSON document
✗ refuted: progress line leaks onto stdout → back to the executors
✓ confirmed on rerun — against the real, running code
7/7 scenarios confirmed · status: verified
the validator's job is to break the change, not to approve it — trust comes from surviving refutation
05 · REVIEW & MERGE

Two gates, on record.

CI plus an AST-aware semantic review that must be explicitly dispositioned. Then the PR auto-merges — one change, one branch, one PR — and the deltas join the verified capability library, so the next plan starts better-informed.

gh pr checks 212
ci ✓ pass
semantic-review AST-aware · 3 cohorts · summary + inline comments
disposition: accepted — on record, never skipped silently
✓ PR #212 merged · branch deleted · worktree removed
verified/export/spec.md ← delta merged into the capability library
completed/2026-08-23-export-json-flag/ ← archived, immutably
06 · SHIPPED

It's on the board.

The change archives immutably and appears on the delivery board with everything else this pipeline has shipped — 175 changes and counting, in shipd's own repo. What got built and what was asked for are the same document.

$ shipd board
the shipd delivery board — unplanned, ready, building, review, and shipped columns, specs grouped by epic
77 specs · 13 epics · 78 shipped this week — live from shipd's own repo
For the people running the work

One workspace. Every repo. Every decision, once.

A job rarely lives in one repository. shipd's workspace layer makes the whole job portable, keeps delivery status live across every member repo, and captures each decision the first time it's made — so nobody is asked twice.

/s:workspaceone job, many repos
shipd boardlive delivery status
/s:epicdecompose big features
/s:autopilotepics, shipped unattended
/s:askdecisions, made once
$ /s:workspace clone git@…/ws-docs-linking.gitone clone stands up a cross-repo job
workspace repo — tracked
the job itself, travels with git clone
.shipd-config.json — manifest: members, clone urls, focus
.shipd/wiki/ — the job's LLM wiki, auto-committed
initiatives/ — goals & per-project context
MEMBER REPOS — ONE JOB ACROSS THREE CODEBASES, NEVER TRACKED, NO SUBMODULES
documents/ focus repo · worktree of your local cloneinstant
tasks/ clone --reference, borrows local objectsseconds
incentives/ full clone from the manifest urlfresh machine only
cheapest rung first, per machine · drift is reported, never "repaired"
/s:ask answers from:job wikibase wikispec surfacesqueued for you· /s:teach promotes job-independent answers to base — every future job inherits them
$ shipd boardthe delivery board, full-screen in your terminal
the shipd delivery board — unplanned, ready, building, review, and shipped columns, specs grouped by epic
77 specs · 13 epics · 78 shipped this week — specs grouped by epic, epics tagged to initiatives · shipd metrics turns the archive into throughput numbers · every read verb takes --json for your own dashboards
$ /s:epic a full export CLI — json, csv, streaminga feature, decomposed before anything is planned

Bigger than one change? /s:epic investigates the codebase, asks one batched round of what it can't infer, records the epic's binding Decisions and Design, and emits a stub table of member changes with complexity ratings — then stops. Members are planned later, one at a time, via /s:plan, each inheriting the epic's decisions. And when the feature needs grounding first, /s:research turns the open question into a cited report — bounded sub-questions, web search, a numbered source list — that the epic links as its evidence base.

EPIC: export-cli · MEMBERSCOMPLEXITYSTATE
export-json-flagsimpleplanned
export-csv-writersimplestub
streaming-exportmoderatestub
export-auth-scopescomplexstub
decisions are made once, at the epic — member plans cite them instead of re-asking · epics tag to exactly one initiative, so cross-repo goals roll up on the board · approve the epic and /s:autopilot takes it from here
$ /s:autopilot export-clian approved epic, delivered unattended

Autopilot picks up an epic's unplanned members and drives each to a shipped PR — plan → gate → build → auto-merging PR, in risk-ascending order, one worktree and branch per member. Every gate still runs; nothing is skipped because nobody is watching.

MEMBER (risk-ascending)RISKOUTCOME
export-json-flaglowPR #212 merged
export-csv-writerlowPR #213 merged
streaming-exportmedium● building 4/6
export-auth-scopeshighparked · resume pointer
open decisions go to the oracle and proceed on its recommendation — questions park for you, they never block the run · under pr-mode: draft, members land as draft PRs for human review instead of auto-merging
$ /s:ask which retention window should the queue enforce?the ask-first oracle — you are the last rung, not the first
1 · read — codebase & specs2 · oracle — memory · wiki · answered queue3 · you — asked once
ANSWER
one cited position, quoted verbatim from the wiki — nobody is interrupted
Cited: [[logging-conventions]]
INSUFFICIENT
nobody has decided this — filed as a question for a person, recommendation attached
Queued: q-queue-retention
your answer is written back to the queue — the next agent to hit that decision gets an ANSWER, and /s:teach settles it into the wiki. never answers from model knowledge: definitive evidence, or nothing.
not just a command — /s:plan consults the oracle internally before ever asking you, and an /s:autopilot run proceeds on its recommendation instead of blocking, parking the question for you to answer later.
What shipd does with context

Capture it. Gate on it. Verify against it.

The expensive failure isn't bad code — it's an agent confidently building the wrong thing. shipd guides the agent while the change is still markdown: plan mode investigates your codebase, surfaces the open questions, and lets you validate the idea in minutes. Only when the context gate confirms nothing is missing does an agent get sent in.

01 · CAPTURE

Everything becomes a spec.

Prose, a brief, even a screen recording — shipd compiles whatever you give it into the same three reviewable artifacts: a plan, testable requirement deltas, and a task list, checked into your repo. Answers you've given before are already there; they're never asked twice.

02 · GATE

Insufficient context never builds.

A deterministic gate checks the spec against your actual codebase before a line of code is written. Gaps park the plan with findings attached — you enrich it, it re-enters. The system stops rather than guess.

03 · VERIFY

Quality is checked, not assumed.

An independent validator tries to refute every scenario in the spec against the running code, then CI and a semantic review — explicitly dispositioned, on record — gate the merge. What ships is what the spec says, verified.

The spec is the product.

real artifacts from shipd-now/shipd
plan.mdplan
# oracle-qa-ledger
Status: verified
## Idea
Record every oracle consultation as a
referenceable Q<n> entry so the user can
correct the oracle's standing position.
## Implementation
The ledger is a plan.md section, not a
separate artifact — it rides every existing
read/merge/archive path for free.
specs/shipd-plan/spec.mddelta
## ADDED Requirements
Requirement: Q&A ledger
Every consultation is recorded.
#### Scenario: settled decision
- WHEN the oracle settles a decision
- THEN the plan carries a Q<n> entry
with verdict, answer, and citations
tasks.mdtasks
[x] 1.1 Ledger section grammar in emission.md
[x] 1.2 Error-level lint rule in spec_lint.py
[x] 2.1 /s:teach Q<n> reference mode
[x] 2.2 cat change completed/ fallback
4/4 · status: verified · merged

shipd builds itself. This is the board.

$ shipd board text
175
changes shipped by its own pipeline
36
verified capabilities in the library
13
epics — autopilot delivers approved ones unattended
autonomous-deliveryresearch → epic → unattended member PRscomplete
video-ingestscreen recording → cited intent briefcomplete
mikk-knowledgewiki · memory · ask-first oraclecomplete
delivery-metricsthroughput metrics over the archivecomplete
portable-workspacesdoctor-checked setup, JSON-first CLIactive
+ 8 more epics · lifecycle: draft → ready → active → complete → verified

Stop watching agents type.

$curl -fsSL https://shipd.now/install | sh
then, in your repo: /s:plan /s:build → merged PR
WHAT CAN IT DO? →