A practical guide for founders and business owners building with generative AI – written for people who are not software engineers but now have to make engineering-shaped decisions.
Who this is for
Something has changed in the last two years, and it has changed for our clients rather than for us.
People who have never written a line of code are now building working prototypes. Founders are testing ideas over a weekend. Business owners are producing internal tools without a development team. It works, often surprisingly well, and we think it is a good thing.
But it means that a question which used to belong to software engineers has landed on the desks of people who never asked for it:
How do I set this process up properly? I am not a technical expert. Organisationally, what am I supposed to do?
That is the question this article answers. It is not about prompts, tools or which model to use – those change every few months. It is about how to structure what you want, so that a generative model can actually build it, and so that the work survives contact with reality afterwards.
The method described here is not new and was not invented for AI. It is how we have planned and estimated software at Software Planet Group for years, and its roots go back further than that, to Extreme Programming and the early agile movement. We are describing it now because something unexpected happened: a plan that can be estimated accurately turns out to be the same artefact as a plan a generative model can build first time. Both need the same thing – small, self-contained, fully-specified units of work with an explicit definition of “done”.
Nothing about good requirements has changed. What changed is that the cost of getting them wrong is now visible immediately.
In brief
If you read nothing else:
- Aim to get each piece of work right on the first attempt. With a generative model, reworking something costs more than building it, which is the opposite of normal software development.
- Break the work into small, independent, end-to-end pieces. One piece should be something a user or the system can do, not a technical layer like “build the database”.
- Keep each piece small enough to be built in one go. Measure against a fixed reference story rather than in hours.
- Write down what “correct” means before building – as a short list of behaviours the system should exhibit.
- Decide the structural things once, up front: data model, design system, terminology, error handling. A model cannot make these consistent across sessions, because each session starts with no memory of the last.
- Add detail just before you build, not months ahead. Dictate it rather than typing it.
- If the first attempt misses, throw it away and run it again with a better description. Do not repair.
The rest of this article explains why.
Part 1. Why planning matters more when an AI writes the code
Rework is now more expensive than building
In conventional development, “we will build it now and fix it later” is a reasonable strategy. Fixing your own code usually costs about what writing it cost, and often less, because you understand it.
With a generative model that economy inverts. Reworking is systematically more expensive than the first attempt, for three mechanical reasons:
- You have to reconstruct an intention you never formed. The decision was made by the model, and nobody can explain it.
- The model does not remember why it did what it did. Each session starts from nothing.
- A change quietly breaks something you did not ask about, and without automated checks you will not notice.
Aim for the result you want on the first attempt. Every round of rework costs more than the time you would have spent stating the task properly.
If you track one number while you work, track this one: what proportion of your requests are accepted without rework? It predicts the cost of the whole exercise better than anything else.
The plan is not for you
You have a picture of the system in your head. The trouble is that nobody can hold everything relevant to a complex system in their head at once – that is a limit of attention, not of ability.
And until the picture is written down, part of it does not exist as far as the model is concerned. It receives what you said, not what you meant. What you did not write is exactly what comes back wrong.
The plan is not for you. The plan is for the thing that cannot read your mind.
The loop we are describing
The cycle is simple and repeats for every requirement:
Take the next requirement gather everything known about it hand it over as one complete package get the result.
We have automated this internally because we run it at volume. You do not need the automation. You need the same loop by hand, and you need each step to be possible – which is what the rest of this article is about.
Part 2. What counts as one requirement?
A customer requirement is an input to analysis, not a unit of work
“Reporting”. “Marketplace functionality”. “Workflow automation”. “Stripe integration”.
These are not tasks. They are raw input. Handed to a model in that form, they guarantee rework, because the model has to invent the boundaries, the data model and the scenarios on your behalf – and you will not notice until you see the result.
Before anything is handed over, work out what each requirement actually is:
- a user-facing capability – close to a workable unit already;
- an epic or whole domain – must be broken down further;
- a cross-cutting subsystem – built once and reused everywhere;
- an external integration – made visible as its own separate work;
- a complexity factor – affects other work without being work itself;
- an infrastructure requirement – not functional development at all;
- something already covered – do not build it twice.
Classification comes before estimation. It is the first job, not a formality.
The format: what someone can do, start to finish
A requirement needs a title that describes a complete function from beginning to end. We use a deliberately compact form:
| [User or role] can [perform an action] |
with an optional third part when the point of the action is not obvious:
| [User or role] can [perform an action] to [achieve an outcome] |
The conventional agile phrasing is more verbose than it needs to be. The logical structure is what matters.
This format is not a convention for its own sake. It works for a mechanical reason:
The grammar physically prevents you from describing a technical layer.
Try expressing “create the database table” as “[someone] can [do something]”. You cannot, because it is not something anyone can do – it is a step inside something else. The format rejects the wrong shape without anyone having to police it.
The role does not have to be a person. Plenty of real systems are mostly systems talking to other systems, and there is no need to force that into a human-shaped wrapper. System is as valid a role as User or Admin.
The test for whether something is a real requirement
The usual phrasing – “it must have independent business value” – is hard to apply. This is the test we actually use:
Would you notice it as a gap if it silently stopped happening?
System can synchronise supplier records to the CRM – you would notice. That is a requirement.
System can retry a failed API call with a backoff delay – you would not notice it on its own. That is a mechanism inside whatever requirement depends on the call succeeding.
Note that the test says nothing about screens, and nothing about whether a human is involved. The only question is whether this is a self-contained end-to-end outcome or a step inside someone else’s flow.
Cut vertically, not in layers
A requirement should be a complete capability – “Supplier can add a product” – including the database change, the logic, the validation, the API and the interface.
Do not cut the work by technical layer: “build the table”, “build the API”, “build the front end”. Those are stages inside one piece of work, not separate pieces.
The reason this matters for AI work specifically:
A vertical slice has its own acceptance criteria, so it can be checked on its own. A layer has none.
Hand a model “build the table” and you get something nobody can judge as right or wrong until the other two layers exist. By the time you find out, three pieces of work have been built on the mistake.
There is one important exception. For list-and-record screens, each operation is its own requirement: view and filter the list, add a record, edit a record, delete a record. Four requirements, not one. “Manage users” is almost always a poor requirement – it hides several independent pieces of work behind one verb.
How this differs from a traditional specification
The classic format is a list of “the system shall…” statements organised by system function. It is not worse, and in some contexts it is mandatory. But for our purposes it has a specific defect: a statement like “the system shall accept Visa cards” is neither independently buildable nor independently checkable. It has no boundaries – there is no way to say where the work starts and stops. It cannot be handed over as a unit.
There is a second problem. A list of requirements is very hard to read without designing a solution in your head as you go, which means your attention is spent on the first few items and everything after is read through a decision you have already made. A requirement written as a complete outcome does not do that, because it describes a finished result rather than a fragment of a mechanism.
What comes next
In the next parts of this series we will cover the remaining aspects of preparing a plan for AI-assisted development: how to keep each requirement small enough to be built in a single attempt, how to record requirements and define what “done” actually means, what has to be settled before a model writes any code, when and how to add detail, and what to do when the first attempt misses. Follow us to catch each part as it goes up.
Software Planet Group has been building complex SaaS platforms and web products under high uncertainty since 2015. If you are planning a product and want an independent view on how to structure the work – including whether it needs building at all – we are happy to talk..