18 Design the development path

The order in which software is built affects what can be learned and what can be discarded. A team that integrates three weeks of acquisition work before testing publication has made the publication decision expensive to revisit. A team that creates a branch for every minor step may spend more effort maintaining branch relationships than learning about the product. Both problems begin before the code is wrong.

Designing the development path means choosing boundaries where a coherent result becomes inspectable. Sometimes that boundary is a commit. Sometimes it is a disposable experiment, a pull request, or a demonstration against the actual consumer. Git can preserve the boundary, but Git topology cannot supply its purpose.

Puma identified branch planning as something to improve. The inspected standards subsequently ask what each development or integration boundary makes visible and what evidence would reopen the design; they explicitly avoid a branch-per-milestone or merge-per-slice rule. That establishes a stated direction, without establishing a measured reduction in revision cost. Development and integration boundaries.

Put the earliest useful observation first

For the running resource example, the first useful result need not contact a real download service. A controlled candidate can establish whether the consumer sees the old version before publication and the replacement afterward. This makes a risky lifecycle assumption observable with little implementation attached to it.

The next boundary can add the real acquisition adapter. Another can expose status through the actual caller. These are vertical observations: each connects a piece of production behavior to something outside that piece. Dividing the work into “all types,” “all services,” and “all interface code” may produce tidy assignments while postponing the first meaningful result until every assignment finishes.

A proposed development map could be expressed in ordinary text:

Base A: Existing consumer behavior is characterized.

Publication slice, A to B: A controlled candidate can replace the active reference; failed preparation leaves the old version usable. One integration owner accepts B.

From B, two proposals: The acquisition adapter supplies checked candidates. The interface consumes a fixed status contract. Each proposal names B as its starting contract.

Integration C: Exercise the actual caller through acquisition, checking, publication, and failure. Accept the combination only after verifying the shared meaning of completion.

The dependency shape is small enough to see at a glance:

A: existing behavior
         |
B: publication contract
       /   \
  adapter  interface
       \   /
C: combined acceptance

The letters identify observable development boundaries, not a required Git history.

This map has one deliberately serial step. The two later proposals cannot safely work independently until the status and publication contract is understandable. Starting both earlier is possible, but then their work is exploratory and may need revision. Calling the uncertainty “parallelism” does not remove it.

Give isolation a job

A worktree helps two workers edit without overwriting each other's uncommitted changes. A branch can keep an experiment out of a release candidate. Neither establishes compatibility. The interface branch may interpret completion as “bytes received,” while the acquisition branch means “consumer publication settled.” Their files can merge cleanly and their individual tests can pass.

The integration contract therefore belongs beside the branch map. In our example it says that a candidate is not available merely because checking succeeded, and that the active reference changes only at the agreed publication boundary. Both authors can test against this contract before integration.

Isolation also needs an ending. A retained branch should have a continuing purpose. A superseded experiment needs a record of what was learned and which commits, if any, remain useful. An abandoned worktree containing the only copy of unfinished work should not disappear during mechanical cleanup. Operational resources and durable explanation have different lifetimes.

There is no advantage in manufacturing these obligations for a small serial repair. If one person can make, inspect, and verify a bounded change on the allowed integration path, a separate branch may add no useful isolation. Repository rules can still require one; then the reason is institutional, not an intrinsic property of the change.

Keep a serial alternative on the table

Mitchell Hashimoto's February 2026 adoption account describes one background coding agent while he continues manual work. He distinguishes that arrangement from parallel research and triage, and avoids assigning work merely to keep agents occupied. The report is a personal workflow, not a comparative trial, but it supplies a serious alternative to a permanent implementation swarm. My AI Adoption Journey.

The architectural question is whether extra concurrency shortens the path to an accepted result. Two separable tasks with stable inputs may benefit. Two tasks repeatedly changing the same contract may benefit more from a brief serial decision followed by independent implementation. A worker who finishes quickly but waits a day for integration has improved local throughput without necessarily improving delivery.

One useful counterexample is a format-version migration. The parser, writer, and compatibility behavior may be so tightly linked that dividing them between agents creates more assumptions than capacity. A single implementation owner with a separate reviewer can preserve focus while still providing another perspective. Agent count is a resource choice, not a maturity score.

Rehearse a change in direction

Draw the proposed development path for your next substantial change. At each boundary, write the behavior someone can observe and the fact that would make you reconsider. Then introduce a plausible surprise halfway through: the consumer needs an additional file, publication behaves differently on another platform, or the intended API is unavailable.

Identify what survives, what must be redone, and which unintegrated work has become stale. If every discovery forces the whole effort to restart, look for an earlier observation or a smaller commitment. If every boundary exists only because it seemed orderly, combine some. The exercise succeeds when a reviewer can trace a changed assumption to a specific reconsideration point and see the valid work that remains.

Search the book

Type to find a passage.