Practices

Robust Planning

Planning applies first principles thinking before the agent starts building. The engineer must know what the software should do and resolve the unknowns that could misguide the implementation. A plan can invent file paths and assumptions as easily as any generated answer and earns the same skepticism. As you learned with First Principles Thinking, each major decision should follow a stated requirement, a codebase fact, or a repeatable experiment.

Start With Behavior You Can Check

Suppose you are adding a feature to the local control panel introduced in Preview. You want to arrange the steps of a pipeline, then save it and open it again later. A pipeline carries a task through a sequence of steps; the runner is the code that executes them. This will be our working example through the Practices pages.

“Build a pipeline editor” leaves several decisions open. The agent could save only in browser memory. It could choose its own storage format or build a screen that never connects to the runner. Describe what you expect to happen when someone uses the feature and where the change ends.

Example requirements

You can give a pipeline a name, add steps, and change their order. Saving and reopening it preserves that name and order, including after a page reload.

An empty pipeline cannot be saved. If saving fails, the editor keeps your work and shows the failure. Saving a pipeline does not start a run.

These requirements give you something to verify. They also expose decisions you still need to make. Where does the data live? How is an existing pipeline identified? What happens when someone saves another pipeline with the same name?

Investigate The Parts That Matter

Before choosing an implementation, ask the agent to trace the existing path from the editor to storage and from storage to the runner. Point it toward the relevant documentation or entry files if you know them. Ask for the actual files and functions it finds. It should list unresolved questions separately from observations.

A useful finding would identify the function that loads a saved pipeline and show how the runner reads its steps. “The app probably uses a database” leaves the storage decision unresolved. If a project document describes one format and the code uses another, investigate the disagreement before putting either in the plan.

Keep this research focused on the change. Map the relevant files and their responsibilities, and note the existing test commands. This gives the next session a starting point. Update that map when the implementation changes so later work does not begin from an obsolete description.

Try The Uncertain Part

Some questions need an experiment. Suppose you cannot tell whether the runner preserves saved step order. Build a small test that saves a few distinguishable steps and loads them, then inspect the sequence passed to the runner. If dragging steps might not feel usable, try a rough editor in the browser.

Keep the experiment small enough to answer the question that prompted it. A storage experiment does not need a polished interface. Use a separate branch or scratch directory. Record what you observed and how you checked it, plus which decision changes as a result.

Bring those findings back into the plan. Treat any prototype code you intend to keep as code that still needs review and integration. A working demonstration may have skipped error handling or used sample data in place of the real storage path.

Write A Plan Someone Can Follow

Once the major unknowns are resolved, write the implementation in an order that respects its dependencies. For the editor, that could mean agreeing on the saved representation and implementing storage first. Then connect the interface and check the complete save-and-reopen path.

Record the intended change and the relevant files for each part, along with how you will verify it. Include the connection between parts. The editor must call the storage operation, and the runner must read what it saves. A list of components to create can omit those connections.

  • State the behavior the finished feature must provide and any work you have deliberately left out.
  • Record decisions that affect later steps and the evidence or requirement behind them.
  • Keep open questions visible. Name the question that blocks implementation instead of quietly choosing an answer.
  • Specify checks for normal use and invalid input, plus failures at the boundaries between components.

Read the resulting plan against your original request. Check that existing components you intend to reuse are included and that requirements discussed earlier survived into the document. You should be able to explain why the implementation is ordered this way before handing it to an agent.

Scale this effort to the uncertainty. A label correction can go directly to an edit and a visual check. A change to how saved pipelines are represented deserves more investigation. The editor, storage, and runner all depend on that representation.

Exercise 0: Write A Specification Before Building

Pick a small feature in a working project and describe it to an agent in one sentence, then save the plan it returns. Before asking again, write down how a person would check the finished feature: what happens on normal use, on invalid input, and when a save or request fails. Open a fresh session and ask for a second plan with those behaviors attached.

Compare the two plans line by line. The first plan will contain choices nobody asked for, such as where data is stored or how bad input is handled, and each one should be marked. The second plan should have turned several of those choices into questions. Any choice it still made without asking belongs in the written behavior before work starts.

September, 2026

Search the website