Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

16KB

Spec Driven Development — Chapter-05: 2 - Anatomy of a specification

  • Source: /library/Spec Driven Development/source-file.pdf
  • PDF pages: 33–42
  • Pages without text: none

2 - Anatomy of a specification From vague intent to a blueprint At the end of the previous chapter a promise was left: to open the blueprint and examine the parts of a good specification, from intent to the document that guides what will be built. Time to keep it. Start at the start of almost every project, a loose sentence. “I want a to-do list app to organize what I have to do.” You have probably said something like it about an idea of your own. It is an honest starting point, but that is all it is, a starting point. Notice how much it leaves open. Whose tasks? One person or a team? What does “organize” mean? What does the app do when you finish a task, when the list is empty, when you type only spaces? The intent exists, but the blueprint doesn't yet. Hand that sentence to a bricklayer, human or AI, and they will fill the gaps on their own, guessing. Some guesses will please you; others will cost you rework. This chapter is about what turns that loose sentence into a blueprint that truly guides. The question driving everything from here on is simple: what needs to be in a specification for it to work? We will answer part by part, using that same to-do list as an example that grows with each section, until the raw intent becomes a document anyone, person or machine, can follow without guessing.

What a spec is (and what it isn't) Before listing the parts, we have to fix what a specification is, because most mistakes start here. I will use the short name that already appeared in the previous chapter: spec, the specification of what you want. The first rule fits in a few words: a spec describes the what and the why, not the how. What the system does and why it matters go in the spec. How it does it, which language, which database, which architecture, that is another step, plan, the stage of the specify → plan → tasks → implement cycle where the technical approach is decided. When you write “a completed task leaves the pending list,” you are describing behavior, and that is spec. When you write “store the tasks in a PostgreSQL database,” you are deciding implementation, and that is plan. That is the boundary, and it is worth repeating because it is easy to cross without noticing: implementation decisions do not belong in the spec. Once it is ready, somebody still has to decide which file each rule will live in, and that belongs to FOCUS Architecture (2026, https://books.kodel.com.br/en/books/focus/), the second volume in this trilogy, which answers where each rule lives and why dependencies point inward. You do not need it here: it is enough to know that the decision exists, that it comes later, and that pulling it forward is exactly the mistake this chapter wants to spare you. This holds even for the choice of technology, and the point is important. The technology is your choice, declared in the plan, not in the spec. If at some point I say the to-do list is a web app built in React with TypeScript, treat that as an example, not a requirement. Swap in any other stack and nothing the spec describes changes, because the spec talks about the problem, not the tool that solves it.

The second rule answers a common fear. Anyone who associates “specifying” with the weight of waterfall fears they are signing a contract carved in stone. A spec is a living artifact: a document made to be revised and run again cheaply, nothing frozen about it. It is the previous chapter's thesis made flesh: because AI knocked down the cost of rewriting, changing the blueprint stopped being expensive, and the spec can change as many times as reality demands. The third rule aims at the right target: the spec seeks testable clarity before volume. The best spec is rarely the longest; it is the one that reduces ambiguity, that is, reduces the passages that allow more than one reasonable reading. It says enough to guide and to stop guessing, without becoming paperwork nobody reads. One phrase that will come back still needs explaining: the spec has to be machine-readable. There is nothing esoteric about it. The AI reads your spec as context, the text it receives in order to act, and it acts from what is written there. Where the text is clear, it executes; where it is ambiguous, it guesses. And guessing costs: it creates rework when the guess misses and burns tokens rereading and redoing. A machine-readable spec is just a spec with no holes for the guess to slip through. The same text that removes a person's doubt removes the AI's doubt. One clarification is worth making, because it undoes a common misunderstanding: ambiguity does not force the AI to guess in silence. In SDD, a well-guided AI does what any serious professional would do, it asks. Faced with a passage that allows two readings, it can stop and hand the doubt back to you (“does the completed task disappear from the list or just change color?") before writing a single line. Think about how this would happen with people. If the AI were a human developer running a project in waterfall or in Scrum, they would not make up what you

meant; they would raise their hand in the meeting, send the message, close the gap by talking, because they know that building on a wrong assumption is expensive. The AI is capable of the same gesture, and the spec is where those answers get recorded instead of getting lost in the chat. So treat every question it asks as a gift: it is an ambiguity showing up early, while fixing it is still cheap, and not late, after it has become wrong code. The why part: problem and intent Now the parts, one by one. The first is the why part: the problem and the intent. What problem this solution solves, for whom, and why it matters. It seems obvious to the point of skipping, and it is exactly what gets skipped most. Without the why, everything else loses direction: you have no way to decide what goes in and what stays out, nor how to judge whether a choice is good, because you don't know what you are choosing in favor of. Filling it in with the to-do list: the problem is that a person forgets tasks scattered across notes and in their head, and wants a single place to record what they need to do, see what is left, and check off what they finished. For whom: a person organizing their own tasks, alone, in what we will call single-user use. Why it matters: to reduce forgetting and the sense of overload. Three lines, and the loose intent from the start already has a north. Every decision from here on will measure itself against this why: does it serve one person organizing their own tasks? Then it makes sense. Doesn't serve it? Then it is probably scope too much. This is the moment to name a word that will show up constantly: requirement. A requirement is a testable statement of what the solution needs to do or respect. The why itself is not a

requirement; it is the ground the requirements rest on. The scope part: in, out, and non-goals With the why fixed, the second part draws the boundary: the scope. Scope is the boundary of what goes in and what stays out of a solution. It has three compartments, and the third is the one most people forget. In: what the solution does in this version. In the to-do list, that is creating a task, marking it done, editing the text, deleting, filtering by status (all, to do, done), and setting an optional due date. Out: what is left for later. Here, accounts and login, sharing between people, notification reminders, attachments, and subtasks. None of it is forbidden forever; it just isn't in this version. That “this version” has a name, and it is one of the most useful concepts in all of software building: the MVP (minimum viable product). The MVP is the smallest version of the solution that already solves the core problem end to end and can go into someone's hands. Notice the word carrying the weight: viable. The lean version truly works for the why you fixed, without what isn't essential yet; crippled is something else. That is why “Out” is a strategic decision, with no taste of defeat: you push to later everything that isn't needed for the first version to be worth it, precisely so you can ship, see it working, and learn from real use before investing in the rest. In the to-do list, the MVP is recording, seeing what is left, and completing tasks; login, attachments, and sharing stay out not because they are bad, but because the first version already delivers value without them.

Cutting scope early is what makes software come into existence; wanting everything in the first version is like waterfall's old trap, the giant bet that takes forever to prove whether it is any good. And the third compartment, the decisive one: the non-goals. A non-goal is something you declare explicitly outside the target, on purpose. It differs from “out for now”: it means “this is not what we are building.” In the to-do list: it is not a project manager, it has no collaboration between multiple users, and it does not promise to sync across devices. Why name what you are not going to do? Because that is how you contain the AI. Remember that it fills silence with guessing. If the spec doesn't say that multi-user collaboration is out, a well- meaning assistant might decide that “to-do list” calls for sharing and hand you accounts, permissions, and invitations you never asked for. The non-goal closes that door before it opens. Declaring what stays out is worth as much as declaring what stays in. The behavior part: scenarios, rules, and acceptance criteria The third part is the behavior: what the system does, described in two ways that complete each other, scenarios and rules. A scenario, also called a user story, is a short description of a use situation, from the point of view of whoever uses it: what the person does and what happens in response. In the to-do list: “when creating a task with filled-in text, it appears at the top of the to-do list”; “when completing a task, it leaves the to-do view and starts counting as done.” They are stories of what happens, in the language of whoever uses it, without a word about how it is built inside.

The rules are the constraints that always hold, underneath the scenarios: “the task text can't be empty or only spaces”; “the due date, when given, can't be in the past at the moment of creation.” Scenarios tell what happens on the happy path; rules say what always holds, including when someone tries to step out of line. But scenario and rule still leave a gap, and this is where the most important piece of this part comes in: the acceptance criterion. The acceptance criterion is what counts as done and correct, the verifiable condition that decides whether a requirement was met. It is the testable heart of the spec. Notice the difference: the scenario is the story (what happens); the acceptance criterion is how you know, beyond argument, that the story happened correctly. An example makes the distinction concrete. Imagine the rule “the app must be fast.” It sounds good and is useless, because nobody can say objectively whether it was met. Fast how much? Measured how? Turn it into an acceptance criterion and it becomes verifiable: “opening the list with a hundred tasks shows the first screen in under a second.” Now it can be tested, and the answer is yes or no, with no opinion in the middle. The to-do list's acceptance criteria follow the same pattern: “creating an empty task is refused, with a clear message”; “completing a task removes it from the pending count”; “the done filter shows only completed tasks.” Each can be checked by anyone, without ambiguity, and it is exactly that quality, being measurable, that lives inside the acceptance criterion: an attribute of a well-written criterion, not a separate section of the spec. The edges: exceptions, assumptions, and dependencies

What is left is the part that separates a naive spec from a robust one: the edges. They are three things the happy path tends to ignore: edge cases, assumptions, and dependencies. An edge case is a rare or extreme situation, of emptiness, limit, or error, that the solution still has to handle well. In the to-do list, it is the empty list on first use (what does the screen show when there is nothing?), text with only spaces, a due date typed in the past, the attempt to delete a task that was already deleted, the list that grew long enough to become too long. None of these is the common use. That is why they are forgotten, and it is when they happen that they break everything. A spec that names its edges is a spec that decided, ahead of time, what to do when life goes off script. An assumption is something you take as true without guaranteeing it, and which, if it changes, changes the solution. In the to-do list, the assumptions are concrete: a single user, on the same device; no need for an account in this version; the data is stored locally on the device. Writing this down keeps someone from later building on an assumption nobody agreed to. The dependencies are the third item: what the solution depends on externally and does not control. It is worth naming the category even when it is empty, and that is the case here: in this version, the to-do list has no external dependency, and recording that is already useful information. In a future version, with the data stored on a server, dependencies would appear, and they would go here. Don't force a dependency just to fill the section; record the truth, including when the truth is “none.” The whole blueprint and what makes a spec good

Now you can see the whole blueprint at once. Gather the parts in the order they usually appear in a specification document:

  1. Problem and intent (the why)
  2. Scope: in, out, and non-goals
  3. Behavior: scenarios and rules
  4. Acceptance criteria (what counts as done and correct)
  5. Edges: exception cases, assumptions, and dependencies This is the skeleton of a spec: a document structure you can write in an ordinary text editor, with no code or tool. The names may vary from one place to another, but the anatomy is this, and it is what you will recognize later, when the material reaches the tools that give shape to this document. With the blueprint in view, the attributes of a good spec boil down to one line: clear (each passage allows a single reading), testable and measurable (the acceptance criterion decides with a yes or a no), and readable by human and by machine. Each attribute came from a part you just saw; none of them depends on size. Repeat it like a motto: the spec's job is to reduce ambiguity, and no amount of volume replaces that. And it is with these attributes that you gain what the chapter promised, the ability to look at a loose intent and say what is missing. Go back to the opening sentence, “I want a to-do list app.” Now you don't just see an idea; you see the holes. The why is missing (solve what, for whom?), the scope is missing (what stays out?), the non-goals are missing, the acceptance criteria that would let you test are missing. You don't need the finished document to diagnose; you just pass the intent through the anatomy and mark what is blank.

For those already working with software: you must have noticed that performance, accessibility, and security barely showed up here. They exist and have a name, the non- functional requirements, and they describe not what the system does but how well it does it (fast, accessible, secure). In a spec they usually live alongside the rules and the acceptance criteria (“the first screen loads in under a second” is one of them); for this chapter's anatomy, it is enough to know they exist and where they fit, and treating them in depth is left for another time. The next step The blueprint is drawn, from the loose intent at the start to the document with why, scope, behavior, criteria, and edges. One thing is missing, and it doesn't fit on the blueprint. Knowing what to build is not the same as knowing how to get it off the paper. The spec describes the destination carefully; the next step of the cycle is exactly leaving the blueprint for the build, deciding the how and getting your hands dirty. That is where we go next, putting our hands on the first tool in practice, now that the blueprint is ready to guide the way.

Powered by TurnKey Linux.