Ship: Design
You ARE the planner. You read code, investigate, write spec and plan. You must read the code yourself — delegating investigation loses the context needed to write a good plan. A peer agent investigates independently and produces its own spec for adversarial comparison.
Runtime Resolution
See ../.shared/runtime-resolution.md for the host/peer concept and
dispatch commands. In /ship:design, the peer plays two roles:
investigator (Phase 2) and drill agent (Phase 6). Both use the
same dispatch pattern from the shared reference.
Scope Mode
The prompt may specify Scope mode: full (default) or
Scope mode: refactor. It controls how much adversarial validation runs:
| Phase | full | refactor |
|---|---|---|
| 1 Init | ✅ | ✅ |
| 2 Investigate (host + peer) | ✅ | ✅ |
| 3 Write spec | ✅ | ✅ (behavior-contract template) |
| 4 Diff & verify | ✅ | ✅ |
| 5 Write plan | ✅ | ✅ |
| 6 Execution drill | ✅ | ⏭ skipped |
Why refactor mode skips Phase 6: for behavior-preserving changes (refactor, simplify, rename, extract, dedupe), the plan steps are usually small, mechanical code movements. The drill's "is every step implementable" check earns little here while adding a full peer round-trip. Peer investigation and diff stay on because they catch the real refactor failure mode — "moved complexity instead of removing it."
If no scope mode is specified (e.g. standalone /ship:design invocation),
default to full.
Process Flow
Phase 1 Init resolve task_id, create .ship/tasks/<id>/plan/
Phase 2 Investigate dispatch peer (parallel) ─┐
you read the code │
↓ │
Phase 3 Write spec write host spec.md ←─── peer writes peer-spec.md
vague? ask user → re-investigate
↓
Phase 4 Diff & verify compare specs → resolve each divergence
disagree? → debate peer (max 2 rounds)
still open? → escalate to user
critical gap? → re-investigate (max 1 loop)
↓
Phase 5 Write plan write plan.md with executable tasks
self-review against spec
↓
Phase 6 Execution drill dispatch peer (fresh session) to validate plan
BLOCKED step? → escalate
UNCLEAR step? → revise plan (max 1 loop)
all CLEAR → ready for execution
Roles
| Phase | Who | Why |
|---|---|---|
| Investigation (read code, trace paths) | Host + peer (parallel) | Independent investigation catches different blind spots |
| Write spec (host version) | You | Investigation context must not be lost |
| Write spec (peer version) | Peer agent | Independence requires separation |
| Diff & verify divergences | You | You have the context + code access to judge |
| Write plan.md | You | Spec context must flow into plan |
| Execution Drill | Peer agent (fresh session) | Fresh eyes test implementability |
Quality Gates
| Gate | Condition | Fail action |
|---|---|---|
| Investigation → Spec | All claims trace to file:line you read | Re-investigate |
| Spec → Diff | spec.md has flexible sections scaled to complexity, self-reviewed | Revise |
| Diff → Plan | Zero escalated items (resolved by evidence or debate, or user resolved them) | Ask user |
| Plan → Drill | plan.md has TDD tasks, checkbox steps, complete code, no placeholders | Revise |
| Drill → Ready | Zero BLOCKED steps, zero UNCLEAR steps | Revise plan (max 1 loop) |
No artifact passes to the next phase without meeting its gate.
Progress Tracking
Use TodoWrite to track your own progress through the design phases.
After Phase 1 (init), create todos that reflect the actual work ahead.
Adapt the items to what you discover — skip items for phases that don't
apply, add items for loops you enter (re-investigation, drill revision).
Principle: one todo per major phase the user would care about.
Update activeForm to reflect what's happening within a phase.
Example (full run with peer available):
TodoWrite([
{ content: "Investigate codebase (host + peer)", status: "in_progress", activeForm: "Investigating codebase" },
{ content: "Write spec", status: "pending", activeForm: "Writing spec" },
{ content: "Diff host vs peer specs", status: "pending", activeForm: "Diffing specs" },
{ content: "Write implementation plan", status: "pending", activeForm: "Writing implementation plan" },
{ content: "Execution drill", status: "pending", activeForm: "Running execution drill" }
])
Adaptations (not exhaustive — use judgment):
- Peer unavailable → drop "Diff" item, rename "Investigate" to reflect self-produced peer spec
- Upstream spec already exists → drop "Write spec", start with "Validate existing spec"
- Re-investigation needed → re-mark "Investigate" as
in_progress - Drill revision needed → keep "Execution drill" as
in_progress
Red Flag
Never:
- Cite files you haven't opened
- Let the peer see your spec before producing its own
- Resolve divergences by reasoning instead of code evidence (max 2 debate rounds, both cite file:line)
- Trust prior conversation over disk artifacts
- Mark plan ready when drill has BLOCKED or UNCLEAR items
- Skip the drill because "the plan looks solid"
- Delegate investigation to a sub-agent — read the code yourself
- Claim "function X is not called" without tracing all callers
- Propose a fix without searching for existing defenses
- Propose to create a file without checking if it already exists
- Change a value without grepping tests that assert the old value
- Write plan.md with vague steps or placeholders (TBD, TODO, "similar to Task N")
Phase 1: Init
- Resolve task_id, create
.ship/tasks/<task_id>/plan/directory. - If resuming, read existing artifacts and determine current state.
- Collect branch name and HEAD SHA.
Task ID
- If invoked by /ship:auto, the task_id is provided.
- If invoked standalone, generate a concise deterministic task slug:
TASK_ID=$(printf '%s' "<description>" \ | tr '[:upper:]' '[:lower:]' \ | sed 's/[^a-z0-9]/-/g' \ | sed 's/--*/-/g' \ | sed 's/^-//;s/-$//' \ | cut -c1-60)
Artifacts go to .ship/tasks/<task_id>/plan/. The Write tool creates
directories automatically — no mkdir needed.
Existing spec.md detection
Check if spec.md already exists with content:
[ -s .ship/tasks/<task_id>/plan/spec.md ] && echo 'SPEC_EXISTS' || echo 'NO_SPEC'
If SPEC_EXISTS:
- Read
spec.md. This was written by an upstream skill (e.g. refactor). - Check if spec records a HEAD SHA. If it does and it differs from
current HEAD, treat spec as stale — proceed as
NO_SPEC. - Do not overwrite it. Use it as your investigation input.
- Your job narrows: investigate to validate the spec's claims, then
produce only
plan.md. You may append an## Investigationsection to the existing spec if it lacks one, but preserve all existing sections. - Peer investigation and diff still run — the peer validates the
upstream spec independently. Execution drill runs per Scope Mode
(always in
full, skipped inrefactor).
If NO_SPEC: proceed to Phase 2.
Phase 2: Investigate (Parallel)
This is the most important phase. Do not rush it.
Step A: Dispatch peer investigation
Kick off the peer investigation before you start investigating. The peer works in parallel while you read code.
Read independent-investigator.md for the dispatch pattern and
prompt template. Fill in the task description, task_id, and repo root.
Dispatch the resolved peer runtime and save the returned thread or
session id as INVESTIGATION_THREAD_ID