The feature ships on the agreed date. In the demo, the product manager looks at the screen, clicks twice and says, "That's not what I asked for." The developer pulls out the spec and shows that everything written there was built. Both are right, and the document is the problem.
A spec usually fails because the detail went to the wrong place: a lot about how the screen looks, almost nothing about what should happen when something goes wrong. Here is how to write a document a developer can build from without guessing.
Start with the problem, not the solution
The first paragraph of a spec should answer one question: who is the user, what are they trying to do today, and where does it get stuck. Instead of "an order management system," write "a sales rep types in an order by phone during a customer visit, and without reception loses what they typed."
A paragraph like that gives the developer something no requirements list can: context. When they hit a decision the spec doesn't cover, they can decide based on the goal instead of asking or guessing. A truly senior developer makes use of this and sometimes proposes a simpler solution than the one you planned.
Describe behavior, not screens
A mockup answers "what does it look like." It says nothing about what happens when a field is empty, when the user double-clicks, when the server doesn't respond, or when permissions change mid-action. Those are exactly the places where bugs and disputes are born.
For every key action, write four lines:
- What the user does and what they see in response.
- What the system stores, where and when.
- What happens when the action fails, and what the user sees.
- Who is allowed to perform it and who is not.
The third line is the one most specs skip. A project that starts without defining failure states almost always discovers them in testing or from users, when fixing them costs the most.
Acceptance criteria you can test
A sentence like "search should be fast" can't be tested, so nobody can agree it's done. Phrase each requirement so that someone who didn't write it can say "pass" or "fail":
- "Searching by order number shows the matching order. If there is no match, a message appears, not an empty screen."
- "A user with view-only permission sees the button disabled, not hidden."
- "The export includes all rows shown under the current filter, not the entire table."
If you have a measurable figure, such as a maximum response time or a file size, write it down explicitly. If you don't, it's better to admit the figure isn't known yet and mark it as an open question.
Requirements like "export to Excel" or "permission management" sound clear, but questions almost always hide inside them: which columns, in what order, who can see what, and who can change it. When those questions aren't asked during the spec stage, they surface during testing, and then every answer costs more.
State explicitly what is out of scope
An "out of scope" section is one of the most effective parts of a spec. It is short, and it prevents the "I thought that was included" conversation. List everything that came up in discussions and was pushed to the next version: additional languages, a mobile app, an integration with another system, advanced reports.
This section also supports the broader decision about how big the first version should be. If you're building a new product, read how small an MVP should be as well, because cutting well starts before you write the document.
A small example: the same requirement, before and after
This example is for illustration only. Say the requirement is: "The user can export a report." The developer will build a button that downloads a CSV of the table, and next week it turns out you wanted a formatted Excel file, only for the filtered data, and only managers were supposed to be able to download it.
The precise version looks like this: "A manager sees an 'Export' button on the orders page. Clicking it downloads an xlsx file with the displayed columns and the rows that passed the filter. A regular user does not see the button. If there are more than ten thousand rows, a message appears suggesting a narrower filter." Four lines instead of one, and fewer rounds of fixes.
Mistakes that keep recurring in specs
- Words like "etc.," "easily," "user-friendly." Each one hides a decision nobody made.
- Several versions of the document in different places. A developer will build from the version that reached them, not the current one.
- A spec written alone. A document the product manager wrote without sitting down with a developer or talking to a user contains assumptions nobody has checked.
- Everything at the same level of detail. The simple parts don't need a page. The parts involving money, permissions and integrations need far more.
What to put in a spec and what to leave out
A working spec is as short as possible and as complete as necessary. A structure that fits most projects:
- Background and goal: one paragraph, including how we'll know we succeeded.
- Users and permissions: who logs into the system and what they are allowed to do.
- Key processes: for each one, the four lines above.
- Data: which entities exist, which fields are required, what is unique, what is deleted and what is kept for history.
- Integrations: who the system talks to, in which direction, and what happens when the other side is unavailable.
- Out of scope and open questions.
What to leave out: technology decisions the developers can make better, and descriptions you copied from another project. If the technology has a real constraint, for example the system must run on a specific cloud or an internal server, write it down as a constraint along with the reason.
The check before you hand it over
Before the spec goes to development, ask a developer who wasn't part of the discussions to read it and tell you in their own words what they are about to build. Don't correct them while they talk. Just note where they diverged.
Every point where their story differs from what you meant is a hole in the spec, and this is the cheapest time to find it. Also count how many questions they asked. Zero questions on a ten-page document is a bad sign. It usually means the developer didn't read to the end or prefers to assume.
A good question from a developer at the spec stage is worth a lot. Sometimes it exposes a case nobody thought about. Sometimes it shows you can reach the same result a simpler way, with fewer screens or fewer integrations. In both cases, fixing the document costs very little compared to fixing code.
A spec is a living document
After development starts, the spec keeps changing, and that's normal. The rule is that a change goes into the document before it goes into the code, with a date and the name of whoever approved it. Otherwise, within a month there are two versions of the truth, one in the document and one in everyone's head.
At our company the spec is the first stage of every project, and the work plan with its timelines is built on top of it. If the spec is loose, the plan will be too, so we prefer to invest more time in it at the start.
The bottom line
A good spec starts with the problem, describes behavior including failures, is phrased so it can be tested, and says explicitly what stays out. A read-back by an outside developer exposes the holes before they turn into code.
If you have an idea and no spec yet, this is how our Software House track works. If you have a defined product and need someone to manage development against deadlines, that's our Outsourcing track.





