Execution (2): Building a Product with Agents#

Small robots passing a product box along a conveyor through design, assembly, inspection, and approval stages, with one person watching a control panel at the end

Once you have chosen an idea, it is time to build. This chapter covers the process of building a product alone with coding agents. It is not about which language or framework to use. It is about where a person should stand in an era when agents write the code, what to leave behind and what to review, and what you should not build yourself. It draws on the debates I went through while reworking the development process at my company, and on the decisions I made in my own personal projects.


When the Cost of Building Falls, the Bottleneck Moves Elsewhere#

The first thing you notice when coding agents arrive is that “code comes out fast.” A few weeks later, you discover something else: the things that need reviewing pile up just as fast. The volume of change an agent produces easily outpaces the speed at which a person can read it line by line. In a one-person startup, that person is the founder alone.

So product development in the agent era is not a question of “how do we build faster” but of “what do we review, and what do we guarantee automatically?” Everything in this chapter flows from that one sentence.

BeforeSpecWritten intentHuman buildsSlow but clearHuman reviewLine by lineNowHuman: sets intent, standards, contractsWhat is correct, what merges automaticallyAgent: produces an executable draftFast, but does not preserve intentHarness: guarantees what is specifiedTypes · tests · contracts · visuals · stagingHuman: reviews only contracts & risksBottleneck: how fast people build↓Bottleneck: how fast people reviewReview does not go away;what gets reviewed changes
Once the bottleneck moves from "building" to "reviewing," the person's place splits in two: setting standards at the top and watching for risk at the bottom.

The Boundary Between Executable Drafts and Production#

Let me start with a case from my company. A product manager became able to use a coding agent to make screen changes and add features directly in the frontend project. On a separate branch, they implemented a redesign direction themselves: parts that could use existing APIs worked for real, and parts that needed API changes were built with fake data. It is a very powerful way of working. Instead of stopping at a written spec, you can produce a screen that actually moves.

But problems appeared at the same time. Engineering concerns such as reusing internal modules, consistency with the existing structure, API boundaries, and state management were not reflected, and the volume of code change grew beyond what a person could reasonably review. And there was a more fundamental problem. Code does not preserve intent. A screen shows “what changed,” but it cannot tell you “why it changed that way,” “what alternatives there were,” “what was given up,” or “what counts as correct behavior.” A description the agent writes by looking at the changed code tends to become a plausible after-the-fact interpretation of a result that already exists, rather than the original intent. Developers were not handed intent; they had to reverse-engineer it from the diff. It was closer to archaeology than collaboration.

Does this problem disappear in a one-person startup where you work alone? If anything, it shows up more subtly. Since the planner and the developer are the same person, there seems to be no intent-handoff problem, but you three weeks from now are a different person. Once dozens of changes pile up where you told the agent “change it like this” and simply accepted the result, even you cannot remember which decisions were final and which were temporary, or why you chose that structure. The agent does not remember (it forgets when the session ends), and it is not written in the code.

So the first principle I set was to treat the agent’s output as an “executable draft.” The draft is built quickly and used to validate intent, and there is a separate promotion path that raises it to production quality. That path has at least the following steps.

  1. Product intent review: which user flows does this change affect?
  2. Design consistency review: does it fit the existing structure, modules, and design system?
  3. API and data contract cleanup: which APIs are needed, and what changes from the current ones?
  4. Fake data removal plan: where does temporary data remain?
  5. Harness verification: types, tests, contract checks, visual regression, staging
  6. Deployment and rollback plan

When you work alone, these steps are not meetings but a checklist. Instead of telling the agent “implement this,” ask it “before implementing, first lay out the user flows this change affects, the API changes required, where temporary data lives, and which decisions are final versus still open.” You then get an intent document alongside the draft. That document is the spec you send to yourself three weeks from now.


Review Does Not Disappear; It Changes#

The important question in agent-based development is not “do we review or not” but “what do we review?” Having a person read every diff does not last long. Review has to move from being code-centered to being centered on intent, contracts, risk, and harness results. What a person should examine looks like this:

  • Which user flows does this feature change?
  • Which APIs are needed, and what differs from the existing APIs?
  • Which data states and tables does it affect?
  • Does it affect authentication, authorization, or billing?
  • Where does temporary data remain?
  • Can it be rolled back if it fails?
  • What do the tests, type checks, end-to-end tests, and visual regression actually guarantee?

There is an opposing view: trust the harness more, merge first, and fix what turns out to be wrong. There is real truth in it, since the premise that a person must understand and approve all code is itself the bottleneck. But it rests on a precondition. A harness verifies only what has been specified. Tests cannot invent the correct answer on their own. Someone has to define first what correct behavior is and which data states must never break. If you go “merge first, improve later” while that definition is weak, the harness does not get stronger; you get tests that lock in wrong behavior as normal.

So the principles for the transition period are these.

  • Split large changes by user flow, page, or API. If splitting costs too much, reimplement in smaller units instead.
  • Record intent, priorities, edge cases, and success criteria alongside every agent change.
  • List temporary data explicitly and turn it into real implementation tasks.
  • Redefine review as examining system contracts and risk points, not inspecting all the code.
  • Gradually move the judgment criteria people used in review into tests, skills, documents, and contracts. This is the core work of the transition: making the harness see tomorrow what a person saw today.

“Merge first and deal with it later” must not become the default principle. That approach does not increase speed; it defers review cost and incident cost to the production environment, and when too many changes land at once, it becomes hard to tell where things went wrong. Experiment freely, but manage production merges in small, clear units.


Design Is a Matter of Defaults, Not Ability#

Hand screen design to a coding agent and you get reasonably decent results. But they look vaguely familiar and the details are clumsy. This is not because the agent lacks ability. Without direction, an LLM produces the most probable answer. The mode of “a decent button” is a particular font, a purple gradient, a card grid, and a white background. That is why all AI-generated designs look alike. A vague request like “make it prettier” just summons the vague average again.

The solution is not to add ability but to deliberately steer the model away from its defaults. After surveying design tools and comparing mockups I generated myself, the structure I settled on has three layers.

LayerRoleExample
Guidance pack / skillChanges the agent’s judgment and taste (divergence)A skill that names clichés and bans them, and makes the agent decide colors, fonts, and signature elements before writing code
Design documentFreezes the adopted direction (convergence)A DESIGN.md at the root: colors, typography, spacing, component rules, a banned list
Verification loopWires up the build → look → fix loopInstructions to take screenshots via a browser MCP and self-correct against the design document

The generator (the skill) produces direction, but it is stateless, so it yields slightly different results every time. It does not remember that “we decided on this.” So you write the adopted direction into a design document and reference that document from the instruction file the agent always reads. The generator is the art director; the design document is the brand guideline the director signed off on. It is the single point of consistency that makes the fifth and the twentieth page still look like the same product.

The last layer is the one most often missing. Having a tool installed is different from having that tool wired into the loop. Even with a browser MCP configured, without an instruction that says “after building the screen, take a screenshot, look at your own result, and fix it against the design document,” the agent builds with its eyes closed. The diagrams in this book were made the same way. The agent wrote the SVG, served it on a local server, took screenshots to check, and ran a loop fixing whatever was broken.


What You Should Not Build Yourself#

The temptation a one-person startup falls into most easily is the thought that “the core is important, so I have to build all of it myself.” This is especially true when building a product that contains an AI agent. There is a question I ran into while sketching out an AI-agent-based web service: “If this service’s agent is really going to do work, where should its coding ability come from?”

At first it is easy to think you can just attach a model API, build a file-editing feature, run shell commands, and run tests. But dig a little deeper and you find repository checkout, file reading and editing, command execution, tests and builds, diff and PR preparation, secret injection, network restrictions, time and cost limits, retries after failure, and log collection. “An agent that codes well” does not come from one smart model. It becomes usable only when the execution environment, tools, approval structure, isolation, and observability are all there together.

My conclusion is that implementing coding ability itself from scratch is, for a solo developer, mostly irrational. It is more realistic to take an existing coding agent runtime (the CLI-style and service-style agents from the earlier chapter) as the execution engine, and have the product own the control plane (operations layer) on top of it.

What the product owns (Control Plane · operations layer)User experienceApproval structureTeam workflowWork historyCost policySecurity · isolation policyDomain knowledge · data▼ Goals and policies go down; results and logs come back up ▲What the product borrows (Execution Engine · execution plane)Coding agent runtime (loop · files · shell)Isolated workspace (container · per-task runner)Must be replaceable. The product only knows "spin up a workspace," not what runs behind it.
Good coding runtimes keep multiplying. What the product must hold onto is the policy and structure that bind those runtimes together.

In this setup, the first use case should be narrow. Connect a repository, pick one issue, fix it in an isolated environment, show the test results and the diff, and create a PR when the user approves. If that one flow works well, it is a strong enough starting point. On top of it you can add a reviewer agent, cost policy, and long-term memory one at a time. The infrastructure does not need to be grand from the start either. Begin with the simplest configuration, one independent container per task, and look into more sophisticated scheduling only when concurrent work grows. The premise is to keep state, logs, and artifacts outside the container, and to design the control plane so that it knows as little as possible about the details of the execution environment.


A Checklist for the Solo Builder#

Compressed into a checklist, this chapter looks like the following. This is the order in which I set up the harness when starting a new project.

  1. Instruction files first: put project rules, structure documents, and the design document in the repository and make the agent always read them. (Chapters 3 and 4)
  2. Define the end first: for each feature, write down “the standard for correct behavior” as tests or a checklist. Run the agent until it passes that standard.
  3. Separate draft from production: the agent’s output is a draft. Keep the promotion path (intent review → contract cleanup → harness verification → staging → deployment) as a checklist.
  4. Preserve intent: before implementation, have the agent lay out the user flows, API changes, temporary data, and what is final versus open.
  5. Split small: do not create a change you cannot review in one sitting.
  6. Change what gets reviewed: look at contracts and risk points, not individual lines of code. What a person saw today moves into the harness the next day.
  7. Freeze design in a document: set the direction with a generator, lock it in a design document, and verify it with a screenshot loop.
  8. Borrow the loop: do not build the coding agent loop, sandbox, or execution environment yourself. The product owns the control plane.

The next chapter covers the choices involved in putting AI features inside the product you built this way: cost structure, caching, model placement, and how to bring your product into the user’s agent.