Launch offer: the first 1,000 users get Settl free for a year*Claim your spot
settlbuilding in public

The plan-first pattern + a copy-paste planning prompt

The most expensive thing an AI produces is confident code built on a wrong assumption. I build Settl, an expense-splitting app, solo with Claude, and the habit that cut my rework the most was refusing to let any nontrivial task start with code. Ask for the plan, correct the plan, then build.

Why message one is the wrong time for code

You are paying for the rewrite either way. The only question is whether you pay one sentence before the build or an hour after it.

The planning prompt

Copy-paste this, fill in the task, send it before anything else:

Before writing any code, give me a plan for this task:

[describe the task in 2 to 5 sentences]

The plan must cover:
1. Files: every file you will create or modify, one line each on what changes.
2. Approach: how it works end to end, in 3 to 6 sentences.
3. Dependencies: any new packages, and why existing ones do not cover it.
4. Assumptions: what you are assuming about the current code. Be explicit.
5. Risks: what could break, and what you will deliberately NOT touch.

Do not write any code until I approve the plan.

The two load-bearing parts are 4 and the last line. Assumptions is where wrong guesses surface while they are still cheap. The stop condition is what keeps the plan from arriving welded to an implementation.

What a good plan answer looks like

Say the task is "add password reset" to a generic Node/React app. A plan worth approving reads like this:

Files:
- src/api/auth/reset-request.ts (new): POST /auth/reset-request, creates a
  single-use token, emails the link
- src/api/auth/reset-confirm.ts (new): POST /auth/reset-confirm, validates
  the token, updates the password hash
- src/db/schema.ts: add password_reset_tokens (token hash, user id, expires_at)
- src/web/pages/ResetPassword.tsx (new): the form
- src/lib/mailer.ts: add a sendPasswordReset template

Approach: the request endpoint returns 200 whether or not the email exists,
to avoid account enumeration. Tokens are random 32 bytes, stored hashed,
expire in 30 minutes, deleted on first use.

Dependencies: none new. Existing crypto and mailer cover it.

Assumptions: passwords are hashed with bcrypt in src/lib/password.ts, and
the mailer is already configured for transactional email.

Risks: the login rate limiter keys on route, so both new endpoints need
their own limits. I will not touch the session logic.

Notice what makes it approvable: concrete file paths you can sanity-check, a security decision stated out loud, and assumptions you can veto in one line. A plan without assumptions is not a plan, it is a promise.

How to push back on a bad plan

Bad plans come in three flavors: vague ("I will update the auth files"), bloated (a new dependency for something the standard library does), or built on a wrong assumption. Push back at the plan level, one sentence per problem:

That is the entire economic argument in miniature: catching the argon2 assumption here costs ten words. Catching it after the build costs a rewrite of both endpoints and their tests.

One more failure mode: "sure, I will plan first" followed by code in the same message. Reject it and point at the stop condition. Hold that line once or twice and it sticks for the rest of the session.

When to skip planning

Planning is pure overhead when the diff is smaller than the plan:

Rule of thumb: if you could review the entire diff in under a minute, just ask for the change. If the task touches three or more files, involves data or auth, or you cannot name the files it will touch, plan first. When unsure, plan. The cost is one message.

Run this on your codebase

Paste this into a Claude session in your repo, with your actual next task:

I want to work plan-first in this repo. Here is the next task on my list:

[describe your next feature or fix in 2 to 5 sentences]

Give me only the plan:
1. Every file you will create or modify, one line each on what changes.
2. The approach end to end, in 3 to 6 sentences.
3. Any new dependencies, and why existing ones do not cover it.
4. The assumptions you are making about the current code.
5. The risks, and what you will deliberately not touch.

Do not write any code until I approve or correct the plan.

A plan is a hypothesis, not proof

"Think step by step" can make an answer easier to read. It does not create a hidden verifier. The model is still generating the next likely token, so a detailed explanation can be wrong in a more convincing way.

Add an evidence column to the plan:

For every important assumption in this plan, give:
- the repository file and line that support it;
- the command or test that will prove the change works;
- the expected result before and after;
- what result would force us to replan.

Do not claim you ran a command unless you include its real output.

Before approval, open the named files and reject assumptions that are not grounded in the current repository. After implementation, compare results with acceptance criteria, not with the model's description of what it intended to do.

This turns planning into a testable claim: "changing this function should make this failing test pass without changing these other behaviours." If the evidence disagrees, replan. Do not explain around it.

Download the runnable pack

Get the next one in your inbox