Slicing the work

How features become slices, why the shape matters, and a catalog of ways to split.

Slicing sets the pace of everything else in the method. Review stays honest only when a change fits one sitting. An agent stays coherent only when a slice fits one session. Demos happen only when every slice can run end to end. And a wrong decision costs one slice only when slices are actually small. For these reasons, slicing deserves more attention than it usually gets, and this page covers the how and the why.

The unit: a question a user can now answer

A slice is defined by the question a user can answer after it ships that they could not answer before. This one definition does most of the work. It forces the slice to run end to end, because answering a question needs the whole path from input to visible output. It makes the slice demoable, which the validation gates depend on. And it produces acceptance criteria almost by itself, because a question like “which orders are still pending?” converts directly into test scenarios.

The most common mistake is slicing by technical layer instead. A plan like “backend endpoints, read model, table component, filters, integration” looks tidy, but nothing in it can be shown to a user, so all validation waits until the end, and a misunderstood intent survives the whole feature.

The sizing test

Size is a binary test, not an estimate: one human can review the change in one sitting, and one agent can build it in one session. When a candidate slice fails the test, it gets split before work starts. When it is borderline, it is kept with a flag, and the spec step must confirm or split it. Both capacities are measured over time (how long reviews really take, how often a slice overruns its session) and adjusted at retrospectives, because reviewer habits and agent generations both change.

A worked slicing session

The example team’s customer wants to upload order files from her ERP instead of typing orders in. Two drafts were rejected before the accepted one.

The first draft sliced by activity: parser, validation engine, import queue, upload UI, error report, integration. Nothing in it was demoable, the queue was speculative, and the idempotency rule from the constitution would have been tested only at the very end, where such bugs are most expensive.

The second draft was one big slice: “upload a file and see the orders, with errors reported.” It answers a question, but it fails the sizing test on both sides.

The accepted slicing, with the reason for each cut:

S1  Skeleton: upload one clean file with 3 orders; they appear;
    uploading the same file again changes nothing (idempotency
    applies from the first slice where it means something).
    No queue yet; synchronous is the smallest thing that works.
S2  Malformed rows: each rejected row is reported with a reason;
    good rows still import.               (split by scenario)
S3  Currency and amount rules enforced.   (split by rule depth)
S4  Large files: import becomes asynchronous with progress; the
    queue enters here, sized to this need. (split by scope)
S5  The subsidiary's second file format.  (split by data variation)
SPIKE before S5, half a day: the subsidiary's file encoding is
    undocumented; the deliverable is a one-page written answer,
    not code.

At the skeleton demo, the customer uploaded a real file and asked at once why order references were cut short: her export uses 24-character references and the spec had assumed 12. The fix cost one small decision, and every later slice inherited it. Under the first draft, the same discovery would have arrived at integration, after three components had each hard-coded the wrong length.

Ways to split, roughly in order of preference

  1. By scenario: happy path first, then error and edge cases.
  2. By data variation: one currency before many; one format before its dialects.
  3. By scope: one entity before all; one pilot customer before the fleet.
  4. By operation: read before write; view before edit.
  5. By rule depth: the flat calculation before the tiered one.
  6. By fidelity: correct but plain first; refinement later, if the demo asks for it.

Two cuts are never used: by layer and by activity, because both produce work that cannot be demoed. Constitution rules are also not deferrable: a rule applies from the first slice where it becomes meaningful.

Infrastructure and open questions

Infrastructure is built inside the first slice that needs it, at the size that slice needs. In the example, the queue appears in S4, not in a “messaging setup” slice at the start, because setup slices cannot be demoed and tend to get built for imagined future needs. Open technical questions are handled as timeboxed spikes whose result is a written answer, never shipped code. A simple test keeps the two apart: a slice always has acceptance criteria, and a spike never does.

Things that go wrong

Layer slicing tends to come back under schedule pressure; the test is whether a demo would require the sentence “imagine the UI on top of this”. A trailing “polish” slice sometimes collects unfinished criteria from earlier slices; criteria stay with the slice that introduced them. Slices can also become too small, to the point where demo attention and dependencies dominate; the lower bound is a question worth a minute of a human’s demo time. And review sittings inflate quietly over months, which is why review durations are measured rather than assumed.

Full treatment: Slicing the work, the deep dive behind this page. The practitioner guide on the downloads page shows a second full slicing session with its rejected drafts.