Lesson 2 of 36

Plan the Release, Not the Ticket

ReadFree to read · saving needs Core24 min · Slice → Gate → Run → Wrap → Prove · Updated 2026-10-28
You end this lesson with: factory/release-slice.md — one release split into issues with a dependency map, a size cap per PR and a plan sign-off line
view

A Coinbase engineer pointed an agent at a finished design and asked for the whole feature. The agent delivered. For one frontend page, the one-shot result was a single pull request touching 85 files and adding more than 6,300 lines. For a backend domain it was one pull request of 19 files and more than 14,000 added lines (Coinbase, self-reported, observed 2026-10-28). By the company's own account the code was correct, and the backend one merged. It was also impossible to review. Nobody can hold fourteen thousand new lines in their head, so approval meant trust, not reading, and the safety the review was supposed to provide quietly disappeared. Writing the code had stopped being the slow part, and the cost reappeared at the review desk, where one person now owned a diff that nobody could judge. Nothing was wrong with the output. The failure sat upstream, in how the job was cut before the agent wrote a line. Decide now: you hold a design that will need dozens of files. How do you split it, and who looks at what before any code exists?

This lesson gives you factory/release-slice.md - one release split into issues with a dependency map, a size cap per PR and a plan sign-off line. It serves the Slice stage of the course loop: the cut you make before anything is gated, run, wrapped or proved.

What is actually going on

The failure has a name: the unit of work was wrong. An agent shrinks the cost of writing code, but review cost does not shrink with it, and review cost grows with the size of the thing a person must judge. Cut the job as one ticket and the agent hands the whole mountain to one reviewer. The release, not the ticket, is the unit you plan, because the release is the smallest thing whose parts you can order, size and test together.

Coinbase's published pattern shows the order of operations (Coinbase, self-reported, observed 2026-10-28). Phase one is a plan: the agent reads a rules document, screenshots and a reference implementation, writes a component-by-component plan, then stops. An engineer signs it before any code exists. Phase two is a scaffold: folders, permissions, routing and stubs, run through every validation gate and opened as a draft pull request. Phase three is a set of workers, one per component, each opening a small draft PR that targets the scaffold branch rather than main. The same frontend page that had produced one 85-file pull request came out as seven component-scoped ones, generated in one afternoon.

Look at what each step buys. The plan is the cheapest place to reject a mistake, because rejecting a page of text costs minutes while rejecting a merged diff costs a rewrite. Reject the mistake while it is still a paragraph. The scaffold fixes the shared decisions once, so parallel workers cannot disagree about routes or permissions; it is the join that every worker hangs from. The small PRs turn review back into a reading task. Then the batch lands in staging together, because components that pass alone can still fail as a set. Anything off comes back as a new issue on the same map, not as a patch bolted onto a finished PR.

The sequence below runs through those hand-offs. Look for the two places a human stops the line: before any code, and after staging.

diagram
drawing
A human stops the line twice, at the plan and at the staging result; everything between is small parallel work.

The diagram shows a human at the plan and at the staging result, and nowhere in between is anyone asked to read a mountain. Workers run side by side because the scaffold made them independent, and feedback returns through the planner instead of through ad hoc edits.

The rule and its condition

Use a plan gate and a sliced release when one pull request would be larger than a person can read in one sitting, or when the release has parts that can run side by side. Otherwise ship one ticket as one small PR and skip the ceremony.

Three pieces make the rule operational. First, the spec: a short document that states what the release does and which reference it copies, which a human signs before work starts. Amazon's Kiro tool turns a prompt into requirements, then a design, then a task list sequenced in dependency waves, and a human approves each artifact (The Register, secondhand, observed 2026-10-28). Meta wrote the plan for its Forum app as a machine-readable spec with a rigorous decomposition and says every shipped outcome carried an engineer's sign-off (Meta engineering, self-reported, observed 2026-10-28). Second, the size cap: a number per PR, enforced by a check, not by goodwill. Intercom's review agent refuses large pull requests and demands a split, which turns the cap into an incentive for small changes (Intercom, self-reported, observed 2026-10-28). Third, the dependency map: which issue needs which, so you know what may run in parallel.

ApproachUse whenBreaks whenWhat it costs
One ticket, one PR, no planThe change fits under your size capThe agent can write more than a person can read, which it now canReview by trust
Ticket per layer, no mapThe layers are truly independentA later ticket needs a decision an earlier one made, so workers collide or guessRework at merge (see Agent Fleets, lesson 13)
Plan gate, scaffold, small linked issuesThe release is big or splits into parallel partsThe plan is vague, bloated, or nobody reads itOne page of human attention before code
Per-unit pipelineMany independent units, each with an objective checkUnits depend on each other, or no check existsSign the pipeline once, plan a human lane for the tail

Not every release deserves a spec gate. The tree below spends the gate where it pays.

diagram
drawing
The spec gate is worth its cost only when one PR would overflow the cap; independence and novelty pick the shape.

The tree gives two exits that skip the full ceremony and two that pay for it. Notice that the first question is about size, not about how important the release feels.

Worked case

Illustrative composite. Harbor Billing, a six-engineer team, must ship multi-currency invoices. The design touches roughly 90 files across the database, the invoice engine, a PDF template, a settings page, an accounting export and a back-fill of existing invoices. They have a fleet that can run several agents at once and one senior reviewer, Dana, who can read about 400 changed lines in a sitting.

Three plans are on the table. Plan A: one ticket, "build multi-currency invoices," one agent, one PR. Plan B: one ticket per layer, all started at once, no plan, no map. Plan C: write the release as a spec, sign the plan, scaffold, then slice into small linked issues with a dependency map and a cap.

Decide now, before reading on: which plan, and what breaks first under the one you reject?

Plan A reproduces the opening failure. The agent writes about ninety files, the result is correct, and Dana is handed a diff she cannot read. Plan B is subtler, and it fails in the middle. The export ticket needs the rounding rule that the engine ticket is still deciding, so two agents each pick a rule, and both PRs pass their own gates. The disagreement surfaces at merge, where the reconciling work belongs to the same person who was already overloaded.

Plan C is the one you build. Dana reads a one-page plan, not a diff. The scaffold issue lands first: the currency column, a feature flag, empty service stubs, route stubs and the test harness. Seven small issues hang off it. The wave structure says which run in parallel: the rounding rule is decided in the spec and written into the engine issue, so the export issue can wait for the engine instead of guessing. The back-fill, the one change that touches stored money, gets its own issue, a human-first lane and a rollback note. Here is the file, in full.

markdown

factory/release-slice.md

release: multi-currency invoices spec: docs/specs/multi-currency-invoices.md # one page: what, why, reference, non-goals integration branch: release/multi-currency # worker PRs target this, never main

Plan sign-off

Plan signed by: ______ date: ______ spec commit: ______ No worker issue starts while any of the three blanks is empty.

Size cap per PR

  • Cap: 400 changed lines and 15 files, excluding lockfiles and generated files.
  • Check: git diff --shortstat origin/release/multi-currency...HEAD in CI; over the cap fails the PR.
  • Over the cap means split the issue. Never raise the cap to fit the PR.

Issues and dependency map

idissuedepends onwavelane
I-0scaffold: column, flag, stubs, harnessnone0agent, human reviews
I-1currency table and rounding ruleI-01agent, human reviews
I-2PDF template per currencyI-01agent, human reviews
I-3settings page, stubbed APII-01agent, human reviews
I-4docs and changelogI-01agent, spot check
I-5invoice totals engineI-12agent, human reviews
I-6back-fill of existing invoicesI-12human-first, rollback note
I-7accounting exportI-53agent, human reviews

Parallel rule: issues in the same wave may run at the same time. An issue starts only when everything it depends on has merged to the integration branch.

Staging batch

When every issue has merged to the integration branch, deploy the branch to staging and run the full release checks once. A named person signs the result. One failing check blocks the whole batch.

Feedback rule

Anything staging finds becomes a new issue on this map, with its own id, dependency and size cap. No patch lands on a merged PR.

Illustrative composite. A few details in the file carry weight. The integration branch means no worker PR ever lands on main, so a half-finished release is never live, and the staging batch has one clear thing to deploy. The blank sign-off fields are checkable: a CI step can fail any worker PR while one of them is empty. The cap is stated as a number with an exact command, so "too big" is a measurement, not an argument. The back-fill sits in a human-first lane because it rewrites stored money and cannot be undone by closing a PR; its issue carries a rollback note (see Agent Fleets, lesson 16, on rollback). And I-4, the docs, is marked spot check, because a wrong sentence in a changelog is cheap to fix and not worth a full review slot. Lanes are per issue, not per release.

Illustrative composite. Trace one week through the file to see it work. On Monday Dana reads the one-page spec, asks why the PDF template is not its own release, and signs with the spec commit filled in. I-0 lands on Tuesday. Wave 1 runs in parallel on Wednesday: four agents, four PRs, none over the cap, each readable in a few minutes. I-5 and I-6 wait until I-1 has merged, because the rounding rule lives there. On Friday the integration branch goes to staging, the full release checks run once, and one check fails: the PDF shows a currency symbol after the amount where the accounting export puts it before. Nobody edits the merged PDF PR. The finding becomes issue I-8, with a dependency on I-2, the same cap and its own review. That is the loop the rule describes: plan, sign, scaffold, parallel small work, batch check, feedback as new issues.

Before you build Plan C, check what it asks of people. It asks Dana to read a plan before she reads code, and that is a real change in habit: reviewers are used to judging what exists, not what is proposed. And it asks someone to own the map, because a map that nobody updates drifts from the work within a day. In the Harbor file that owner is the person who signs the plan. Name one in yours, because an unowned map is the first thing to rot, and the whole scheme depends on it staying true.

Rejected plans cost you the following. Plan A costs a review that is trust in disguise, and a rewrite if the rounding rule turns out wrong. Plan B costs a merge-time disagreement that no gate sees coming, because each PR was internally correct. Plan C costs Dana one page of attention up front and the discipline of waiting on a dependency.

Faded case

Skip to the open case if this is familiar. A different team must migrate about three thousand React test files from one testing library to another. Airbnb faced the same job and built a per-file pipeline: each file moves through a refactor step, a test run, lint and a type check, and a step is retried with the latest file and exact errors until the checks pass or an attempt cap is hit. The first bulk run migrated 75% of files in four hours, and after four days of tuning on the failing sample it reached 97%, with fewer than a hundred files left (Airbnb, self-reported, observed 2026-10-28). The last stretch went to engineers who started from the failed baseline. Note the shape: this is a per-file pipeline, not a ticket-to-merge flow, and the post does not describe pull-request review.

Same sheet, one decision left to you. You must fill in release-slice.md for this migration. What does the dependency map look like, where does the plan sign-off line sit, and what do you do with the files that resist?

Two constraints sharpen the choice. The test suite already runs on every file, so each file has an objective check before any human sees it. And the team has one reviewer who can read only a few hundred changed lines a day, so thousands of files cannot reach her as individual changes. Think about what a plan would even say per file, and whether anyone would read thousands of them. Then think about where a mistake in the pipeline itself would be cheapest to catch: before the bulk run, on a sample, or after the files have merged.

Also decide what the size cap means here. The cap in the Harbor file counted lines per pull request. A migration PR can touch many files and still be easy to read, if every file changes in the same mechanical way. Say whether your cap counts files, lines, or distinct kinds of change, and why. Finally, name the one person who owns the long tail when the pipeline stops improving. A tail with no owner stays at "almost done" for months, and the release never closes.

Open case

A team wants an agent to add saved searches to its product. The design lists a new database table, an API with four endpoints, a settings page, an email digest job that reads saved searches, and a back-fill that creates default saved searches for existing users. The design touches more than sixty files, and one engineer has volunteered to review everything. The team's draft plan is one issue per layer, all started on Monday, merged to main as each finishes, with no sign-off and no size limit.

Rewrite the plan. Say which issues run first, which wait, what the scaffold contains, what the cap does to the API issue, and where a human signs. Say what happens when staging shows that the digest emails the wrong people. The quiz grades your split.

Where this breaks

The pattern does not fit every kind of work. Coinbase says its workflow is best on forms, tables and product pages, not on novel, judgment-heavy features, and engineers still fixed edge-case business logic, spacing and beyond-happy-path tests by hand (Coinbase, self-reported, observed 2026-10-28). Its headline results table is an image the evidence read could not recover, and no defect or incident numbers are published. Treat this as a described mechanism, not a measured result.

Parallelism is not free, and not all work is shaped for it (see Agent Fleets, lesson 2, on fleet-shaped work). Coinbase's internal multi-agent tool gives each agent its own worktree, and the company reports its users merged 39.6 pull requests per engineer against 11.4 for the baseline (Coinbase, self-reported, observed 2026-10-28). The authors themselves say the comparison is confounded, since tool users were probably already high-output engineers, and they claim no causation. Use the number as a reminder to report your own selection caveat, never as a target. And Airbnb's 97% is a per-file result under objective checks, not evidence that a ticket-sized feature will behave the same way.

Specs can fail too. Thoughtworks and Martin Fowler's site describe elaborate spec workflows that generate long documents that are hard to review, and rank the strongest version, where humans edit only the spec, as the least proven (Fowler site, secondhand, observed 2026-10-28). A plan nobody reads is a gate in name only. The open-source Spec Kit toolkit structures one agent session through spec, plan and implementation, but it has no queue, merge gate or scheduling across many issues, and no outcome data exists on whether such tools reduce rework. Keep the plan to a page.

Key Takeaways

  • Split the release into small linked issues before the agent writes any code.
  • Make a human sign the plan, because rejecting a page costs minutes and a merged diff costs a rewrite.
  • Set a size cap per PR and enforce it with a check, never goodwill.
  • Draw the dependency map, then run only independent issues in parallel.
  • Batch-validate in staging, and turn every finding into a new issue on the same map.
  • Reject the mistake while it is still a paragraph.

What You Have Now

factory/release-slice.md - one release split into issues with a dependency map, a size cap per PR and a plan sign-off line. It lives in your factory/ directory next to the line map from the first lesson: that file shows the queues and gates, this one shows how a single release moves through them in pieces a reviewer can read. Keep the sign-off line unfilled until a named person has read the plan, and let your CI enforce the cap. This is the Slice stage of the course loop, and every later gate in the course assumes the diff it is handed is small enough to judge.

Further Reading

Exercises

  1. Cut one release. Take a release you have waiting and write the issue list with a one-line purpose for each. Mark each as agent, human-first or spot check.
  2. Draw the map and set the cap. Add the dependency column and the wave numbers to your list. Pick a size cap from how much your reviewer actually reads in a sitting, and write the CI check that enforces it.
  3. Rehearse the sign-off. Write the one-page spec for your release, hand it to a named person, and record what they changed. If they changed nothing, ask whether they read it. Compare the plan against Graph Engineering, lecture 5 (fans and joins) and say which issue is your join.

Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in

Check your understanding


Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in