Build & Ship
A run is an agent building one task. Runs happen in isolated git worktrees — each task builds off a fresh copy of the project's base branch (main unless you've set another) in its own directory, so runs never touch your working tree or each other's. You watch the whole pipeline on one Build Board and accept the finished work — branches or PRs — from its Review column.
One task
$ ptln work "add a dark-mode toggle to the navbar"Runs a single task autonomously in a sandboxed worktree and leaves a branch for you to review. It uses read/edit tools only by default and never pushes — a human merges.
Flags: --worktree <name> · --thread <id> (attach a Context Thread) · --allow-bash (let it run shell commands) · --engine <e> (defaults to the repo's registered engine — which engine builds) · --model <m> · --timeout 20m.
A backlog
$ ptln crank --file backlog.txt --thread checkoutDrives a backlog one task at a time, each in its own worktree, all sharing one context thread. It halts on a cap, a token budget, or a run of failures, and prepares N branches for review — nothing is pushed or merged by default.
Flags: --thread <id> · --max N (stop after N tasks) · --max-tokens N · --halt-on-fail K (stop after K failures) · --timeout 20m · --allow-bash · --engine <e> · --model <m> · --resume · --literal (every non-blank worklist line is a task, # included) · --max-repairs N (0–5 in-run repair rounds; defaults to 2).
Fleet mode claims tasks from the run store (dispatched from the board) instead of a file:
$ ptln crank --claim --run <id> --workers 3The board
You don't have to type commands. Promote a task from a planning session and it's dispatched to the daemon on the right machine — in the right project directory — with one click. Everything then moves left to right across one Build Board (Build in the nav), six lanes:
- Planning — the planning sessions still in flight, so work is visible before it's buildable. A card is either
● session open(click it to rejoin, or to reopen one that ended) or⏸ N items need answers— plan leaves scored below the readiness floor.✕on a needs-answers card dismisses just those below-floor drafts. Ended sessions live under History. - Backlog — promoted, waiting. Drag to reorder, or drag a card onto Building to start it now. This lane has no sort control on purpose: its order is the execution queue.
- Building — an agent on it. The card streams the run's state; its page shows every step.
- Blocked — a run that stopped and needs a decision.
- Review — passed the gates, waiting on you. Each card carries its PR link and the reviewer's grade (A–F). When your team's review gate is on, the PR opens as a draft: Accept marks it ready to merge (and arms auto-merge if the policy says so); Decline closes the PR and asks whether to re-run the task or send it back to the backlog; Discard archives the card without touching git. Multi-select to Retry or Discard several at once, or drag a card onto Shipped to accept it.
- Shipped — done and merged.
Every lane except Planning and Backlog has a sort caret — newest-first by default, click for oldest-first — and every lane header has a « that tucks the lane away into a thin rail showing its count and one tick per card. Empty lanes rail themselves automatically; the ones you collapse by hand are remembered across visits, and the board renders at the right widths on the first paint rather than snapping after load. Filter by machine, project, status, or owner, and group cards within lanes. On a phone the board shows one lane at a time with arrows to step between them.
Promote a whole feature as a chain: its tasks run one at a time in order, halting if one fails. Making a chain applies immediately — the cards snap into contiguous execution order under one ⛓ container rather than waiting for a reload, so you can't accidentally scatter a chain you just created. The PRs are stacked — each task builds on the previous task's branch and opens its own PR against it, so every task sees the work of the ones before it (no blind conflicts) and each PR shows just that task's diff. Merge them in order: as each PR lands, GitHub retargets the next one to your base branch. The chain is a single container on the board — a sequence of small, focused PRs, not one giant one.
Readiness is a warning, not a wall
Tasks carry a readiness score from the Planning agent, and 4/5 is the floor for starting one. Below the floor, the Start button stays enabled — it reads ▶ Start · 3/5 — and clicking it asks you to confirm rather than refusing:
Start this before it's fully specified? Readiness 3/5 — below the 4/5 floor, so the plan may still owe an answer. The agent will build from the spec as written. If something genuinely is unresolved, reopen the plan instead — but a stale score is not a reason to be stuck.
Start anyway proceeds. The same confirm covers a multi-select batch start. A stale score shouldn't be able to strand work you know is fine.
One path hasn't caught up: dragging a below-floor card onto Building is still refused outright, with a toast saying the item isn't ready. Use the card's Start button (or a batch start) when you want the override.
The Git panel
A run's page carries a Git panel listing the branch each task produced — with its pull request link, or a local only — on <machine> badge and the git checkout line when the branch was never pushed. A project's page has the same inventory across its recent runs, under Branches. Both are built from what the control plane already knows (run_tasks branches and PR urls); neither asks a machine anything, so there's no ahead/behind count and no check that the worktree still exists.
A run's page also keeps the full record: the tamper-evident event ledger grouped into attempts (newest first — retries stay legible), the verify and review output in full, honest spend — fresh tokens (new input + output, never the cache-inflated total) and the provider's own dollar cost — and Continue / Restart controls, including an automatic pause-until-reset when the model provider rate-limits mid-run. Need a second opinion later? Request review re-runs the independent reviewer on demand — on the machine that built the run, or (on the latest CLI) any other machine with the project when the builder is offline and the work is already pushed as a PR.
Which engine builds
Every phase — plan, build, review — runs the engine you pick, resolved in order: a per-run override (the Start control's engine · model disclosure, or --engine) → the project's phase setting (project settings) → the machine's registered engine (ptln daemon add-project --engine) → claude. The set is closed: claude · codex · gemini · opencode · goose · antigravity.
Each engine runs at the strongest permission posture it can actually enforce, and anything an engine can't do is logged on the run, never silent. On non-claude engines today: no live streaming (output is buffered), no session resume (an interrupted task restarts in its worktree), and build workers don't get context-thread remember/recall tools yet.
The hard limits:
- antigravity is interactive/planning-only. It has no enforceable headless mode — its only headless knob is a full permissions bypass, which partyline never passes — so build, review, and one-shot describe jobs refuse it, fail-closed. Interactive sessions and party/planning launches work (deny-by-default).
- codex builds require
--allow-bash(or bash enabled on the run) — codex can't separate file edits from shell, so without it the run refuses with an actionable error. - gemini needs the project directory trusted — it refuses headless tools in untrusted folders. Trust it once interactively, or set
GEMINI_CLI_TRUST_WORKSPACE=true. - opencode models are provider-scoped (
provider/model); blank falls to your opencode config's default. Needs a daemon on CLI ≥ 0.25.0 (older daemons refuse it fail-closed). - goose resolves provider and model from its own config (
GOOSE_PROVIDER/GOOSE_MODEL); read-only runs are refused (goose can't enforce that posture). Needs CLI ≥ 0.25.2. - Build/review engine choice needs CLI ≥ 0.10.0 on the daemon — older daemons ignore the field and run claude.
Whatever builds, the trust gates' evidence verifier and the visual verify layer deliberately run your local claude — the verifier is never the producer.
Worktrees
Every run gets its own worktree so nothing collides. List and clean them up:
$ ptln wtWhat happens to a finished task
That's the merge policy (set per run; the board defaults to pr):
- manual — leave a reviewable branch, push nothing. The default for local
ptln crank/ptln work. - pr — push the branch and open a pull request. With the review gate on, it opens as a draft — Accept on the board is what marks it ready.
- auto — open a PR and enable GitHub auto-merge, but only when the base branch gates on required status checks; otherwise leave the PR open.
Whatever the policy, a task only reaches it after clearing the trust gates — your tests plus an independent reviewer. A failure is quarantined for a human, never shipped.
Next: Trust gates · Projects · Context Threads.