jonnifyagile agents
jonnify / Agile Agent Workflow / A2 · Decomposition / A2.03 / A2.03.3 · Small and independent

A2.03 · INVEST · dive 3

Small and independent

Two of the six letters pull against each other. Small wants the thinnest slice; Independent wants a slice that waits on nothing.

Cut too coarse and a story fails Small; cut along technical layers and the pieces fail Independent. The resolution is to split along value. Switch the strategy on the right to see which split keeps the slices independently demonstrable. Estimability follows from smallness; the how of the split is A2.05.

Split “manage the catalogue” · by layer or by value

manage the catalogue → slices the courses table coupled the courses API coupled the courses page coupled by layer · each slice waits on another
Split by layer → 3 slices, 0 independently demonstrable. Each waits on another; all fail I.

Small pulls against Independent

Most of the six letters reinforce each other. Two do not. Small wants the thinnest possible slice; Independent wants a slice that does not wait on its neighbours. Making a story smaller can introduce a dependency: split “enrol and see the confirmation” into “enrol” then “see the confirmation”, and the second half now waits on the first.

The trap is splitting along technical layers — the table, then the API, then the page. Each layer is small, but none ships value on its own, so each fails Independent: the API waits on the table, the page waits on the API. The resolution is to split along value: cut the work so each slice is a whole capability, demonstrable by itself. “Browse the catalogue” and “enrol in a course” are both small and independent because each is a complete thing a learner can do.

Splitting along value is the subject of A2.05; this dive is the why. The rule of thumb: a slice that a user could be shown is a value slice; a slice that only another slice can use is a layer.

Estimable follows from Small

The hero shows that the right split keeps slices independent. This view proves the other half: a small story is estimable almost by definition. Drag a story's size from the whole catalogue down through the ladder rungs. At each step the figure reports whether Small passes and whether Estimable passes — and Estimable flips to pass at exactly the same step Small does.

That is not a coincidence. A slice that fits one rung has little of it to misjudge, so the cost is a guess anyone can make. A too-big story fails Small and Estimable together, because its size is exactly what makes the estimate a guess in the dark. Estimability is not a separate judgement to apply — it falls out of smallness.

Drag the size · watch Estimable follow Small

enrol
size of the story enrol in a course S Small PASS E Estimable PASS E follows S — both flip at the same size
Size: one rung (enrol) — Small: pass, Estimable: pass. E follows S.

Estimable is not a separate test — it flips exactly when Small does, because size is what makes a cost a guess.

The split on the Portal

On the Portal, “manage the whole catalogue” fails Small and Estimable. Splitting it along value yields the story ladder: browse → enrol → open a lesson → track progress. Each rung is small (one turn), estimable (small implies estimable), and independent (a whole capability a learner can be shown). The ids the rungs rest on are already minted — Portal.ID.generate/1 hands back a typed id, and Portal.ID.decode/1 reads its .type back — so no rung waits on another to define its identifiers.

Splitting along layers would have produced “the courses table”, “the courses API”, and “the courses page” — three slices that each fail Independent, because none is demonstrable on its own. Same destination, but the value split keeps every slice shippable in isolation. The mechanics of the cut are A2.05; the reason to cut along value is that it is the only split that satisfies Small and Independent at once.

# "manage the whole catalogue" — fails S and E. Split it.

# Split by VALUE → each slice is small, estimable, AND independent:
#   browse  → enrol  → open a lesson  → track progress      (4 / 4 independent)

# Split by LAYER → each slice is small but coupled:
#   courses table → courses API → courses page             (0 / 3 independent)

id = Portal.ID.generate(:course)        # ids are already minted — no rung waits on another
assert Portal.ID.decode(id).type == :course

The principle

Small and Independent pull against each other; splitting along value, not along layers, satisfies both — and estimability follows from smallness.

On the Portal

“Manage the catalogue” splits along value into browse → enrol → open → track — four small, independent, estimable rungs; splitting by layer would leave three coupled slices.

Split along value: each slice stays a whole capability, so Small and Independent hold together and Estimable comes for free.

Recap — the one tension, resolved

Small and Independent are the two INVEST letters that pull against each other: shrinking a story can couple its pieces. Splitting along value rather than along technical layers satisfies both, because each value slice is a whole capability that ships alone. Estimability is not a third thing to check — it follows from smallness, flipping to pass exactly when Small does. On the Portal, “manage the catalogue” splits along value into the four-rung ladder. That closes A2.03: a story is ready when the six tests pass, a smell names the letters when they do not, and value is the axis that keeps Small and Independent together. The mechanics of the cut are the next module.

Next module — A2.04 · Acceptance criteria with Given/When/Then — pins a ready story down with concrete examples of the behaviour that proves it done. Return to the A2.03 module hub to review the dives.

References

The story-splitting and estimation sources behind this tension, and where it connects in the course.

Sources

Related in this course