Suede Ship
The canonical Suede DAG. One prompt in, one shipped change out, with about fifty
agents in between arranged as a graph rather than a chain.
Invoke the workflow bundled at skills/suede-ship/workflows/suede-ship.js. If
you keep a personal copy, ~/.claude/workflows/suede-ship.js works the same way.
Choose this or the fleet first
suede-ship is the surgical instrument and it is the expensive one. Roughly
fifty agents (about fifty-four when deploys is true), research-heavy and
front-loaded, billed to the Claude limit.
If the job is actually high-volume, well-specified, and splits into independent
worker-sized tasks (content batches, test generation, bulk refactors), say so
and offer suede-codex-fleet instead. That runs
on the OpenAI subscription and costs nothing against the Claude limit. Brute
force beats surgery when the work is genuinely parallel and shallow.
Parse the invocation
The argument is free-form. Extract:
- repo — required. An absolute path. Resolve a bare name against
~/code/<name>.
If no repo is named and the cwd is inside a git repo, use that repo's root.
- scope — required. What to change, in the user's own words, kept verbatim
where possible. Do not compress it into a slogan; the planner decomposes it
into lanes and the detail is what makes lanes separable.
- deploys — true if the repo has a
vercel.json, a platform project link, or
a known live URL. Check rather than assume.
- liveUrl — the production URL if you know it or can read it from
vercel.json, package.json, or the README. Optional; the release verifier
discovers it otherwise.
- vault — optional absolute path to an external decision store (a synced
notes vault, an ADR archive, a handoff directory). Omitted by default. When
present, the prior-decisions lens reads it as context, never as source truth.
If scope is missing, ask for it. Do not invent a change to a production
repo. This workflow writes code.
State the cost before launching
This is Claude-model fan-out against the weekly limit. Say so in one line before
the call, so the spend is a decision rather than a surprise.
Launch
Workflow({
scriptPath: "skills/suede-ship/workflows/suede-ship.js",
args: { repo, scope, deploys, liveUrl, vault }
})
Pass args as a real object. If the harness stringifies it the script recovers,
but an object is correct.
The graph
Nine phases, parallel wherever the edges are not real:
- Scout — fetch origin, dirty files, worktrees, deploy-time landmines. Manifest only.
- Research — multi-modal sweep. Each lens searches a different way and is blind
to the others, because one angle never finds everything. Every claim carries a
file:line, sha, PR, or doc url.
- Gaps — a completeness critic names what went unread, then one bounded fill round.
- Plan — the lane map, with explicit file ownership. High effort by design.
- Build — disjoint lanes, each pipelined straight into its own review.
- Refute — adversarial verifiers, refute-by-default, majority kills the finding.
- Gate — a real barrier: typecheck, build, and tests on the integrated worktree.
- Release — adversarial release verification: config drift, public surface,
irreversibility, live baseline.
- Handoff — the evidence record: changed files, commands run, verification, caveats.
While it runs
Do not predict results or narrate progress you cannot see. The workflow returns a
notification when it completes; /workflows shows live progress.
When it returns
Report faithfully, including the failure shapes:
halted: true, reason: "blocking hazard at scout" — a real secret in a tracked
file, or a live process holding a worktree this run would touch. Name the hazard.
halted: true, reason: "lane collision" — the lane map claimed a protected dirty
file, gave one file two owners, or hit a file held by a live sibling worktree.
Report the collisions. The fix is a re-plan, not a retry.
- Completed — lead with
shipVerdict and gatePassed, then confirmed findings, then
crossWorktree overlap (files this work will need rebasing against other branches),
then droppedConstraints (what the skeptic rejected) and unread.
Naming what went unread is most of the honesty.
Verdict is advisory
The shipVerdict changes what you report, never what you do. The single exception
is live production exposure the verifier observed independent of this change, such
as a real secret or an unauthenticated 200 that should not exist. That goes to the
user immediately.
Do not claim deployed, verified live, or released. This workflow only reads
production. Those states require a deploy that has not happened.
Iterating
Edit the script and re-invoke with the same scriptPath. Add
resumeFromRunId: "<run id>" to replay unchanged agents from cache. Changing an
agent's prompt or schema re-runs that agent and everything downstream of it.
1---2name: suede-ship3description: Canonical Suede shipping DAG: scout, multi-lens research, gap critic, lane plan with explicit file ownership, disjoint parallel build, dual-lens review, adversarial refute, integration gate, and release verification. Use for any nontrivial change to a repo that touches more than one file or surface and deserves roughly fifty agents of surgical, research-heavy fan-out. Halts on a blocking hazard (a real secret in a tracked file, a live process holding a target worktree) or a lane collision rather than plowing through. Reads production; never deploys. NOT FOR: high-volume, well-specified work that splits into independent worker-sized tasks (use suede-codex-fleet, which bills to the OpenAI subscription instead); findings-only review with no code change (use suede-code-review); CI and branch-protection wiring (use suede-ci-gate).4---5
6# Suede Ship
7
8The canonical Suede DAG. One prompt in, one shipped change out, with about fifty
9agents in between arranged as a graph rather than a chain.
10
11Invoke the workflow bundled at `skills/suede-ship/workflows/suede-ship.js`. If
12you keep a personal copy, `~/.claude/workflows/suede-ship.js` works the same way.
13
14## Choose this or the fleet first
15
16`suede-ship` is the surgical instrument and it is the expensive one. Roughly
17fifty agents (about fifty-four when `deploys` is true), research-heavy and
18front-loaded, billed to the Claude limit.
19
20If the job is actually high-volume, well-specified, and splits into independent
21worker-sized tasks (content batches, test generation, bulk refactors), say so
22and offer [`suede-codex-fleet`](../suede-codex-fleet/SKILL.md) instead. That runs
23on the OpenAI subscription and costs nothing against the Claude limit. Brute
24force beats surgery when the work is genuinely parallel and shallow.
25
26## Parse the invocation
27
28The argument is free-form. Extract:
29
30- **repo** — required. An absolute path. Resolve a bare name against `~/code/<name>`.
31 If no repo is named and the cwd is inside a git repo, use that repo's root.
32- **scope** — required. What to change, in the user's own words, kept verbatim
33 where possible. Do not compress it into a slogan; the planner decomposes it
34 into lanes and the detail is what makes lanes separable.
35- **deploys** — true if the repo has a `vercel.json`, a platform project link, or
36 a known live URL. Check rather than assume.
37- **liveUrl** — the production URL if you know it or can read it from
38 `vercel.json`, `package.json`, or the README. Optional; the release verifier
39 discovers it otherwise.
40- **vault** — optional absolute path to an external decision store (a synced
41 notes vault, an ADR archive, a handoff directory). Omitted by default. When
42 present, the prior-decisions lens reads it as context, never as source truth.
43
44If **scope** is missing, ask for it. Do not invent a change to a production
45repo. This workflow writes code.
46
47## State the cost before launching
48
49This is Claude-model fan-out against the weekly limit. Say so in one line before
50the call, so the spend is a decision rather than a surprise.
51
52## Launch
53
54```
55Workflow({
56 scriptPath: "skills/suede-ship/workflows/suede-ship.js",
57 args: { repo, scope, deploys, liveUrl, vault }
58})
59```
60
61Pass `args` as a real object. If the harness stringifies it the script recovers,
62but an object is correct.
63
64## The graph
65
66Nine phases, parallel wherever the edges are not real:
67
681. **Scout** — fetch origin, dirty files, worktrees, deploy-time landmines. Manifest only.
692. **Research** — multi-modal sweep. Each lens searches a different way and is blind
70 to the others, because one angle never finds everything. Every claim carries a
71 `file:line`, sha, PR, or doc url.
723. **Gaps** — a completeness critic names what went unread, then one bounded fill round.
734. **Plan** — the lane map, with explicit file ownership. High effort by design.
745. **Build** — disjoint lanes, each pipelined straight into its own review.
756. **Refute** — adversarial verifiers, refute-by-default, majority kills the finding.
767. **Gate** — a real barrier: typecheck, build, and tests on the integrated worktree.
778. **Release** — adversarial release verification: config drift, public surface,
78 irreversibility, live baseline.
799. **Handoff** — the evidence record: changed files, commands run, verification, caveats.
80
81## While it runs
82
83Do not predict results or narrate progress you cannot see. The workflow returns a
84notification when it completes; `/workflows` shows live progress.
85
86## When it returns
87
88Report faithfully, including the failure shapes:
89
90- `halted: true, reason: "blocking hazard at scout"` — a real secret in a tracked
91 file, or a live process holding a worktree this run would touch. Name the hazard.
92- `halted: true, reason: "lane collision"` — the lane map claimed a protected dirty
93 file, gave one file two owners, or hit a file held by a **live** sibling worktree.
94 Report the collisions. The fix is a re-plan, not a retry.
95- Completed — lead with `shipVerdict` and `gatePassed`, then confirmed findings, then
96 `crossWorktree` overlap (files this work will need rebasing against other branches),
97 then `droppedConstraints` (what the skeptic rejected) and `unread`.
98
99Naming what went unread is most of the honesty.
100
101## Verdict is advisory
102
103The `shipVerdict` changes what you report, never what you do. The single exception
104is live production exposure the verifier observed independent of this change, such
105as a real secret or an unauthenticated `200` that should not exist. That goes to the
106user immediately.
107
108**Do not claim `deployed`, `verified live`, or `released`.** This workflow only reads
109production. Those states require a deploy that has not happened.
110
111## Iterating
112
113Edit the script and re-invoke with the same `scriptPath`. Add
114`resumeFromRunId: "<run id>"` to replay unchanged agents from cache. Changing an
115agent's prompt or schema re-runs that agent and everything downstream of it.