DEV Community

Cover image for Spec-Driven Development: What Does a Spec Say? (Part 3 of 4)
Dirk Mattig
Dirk Mattig

Posted on AI-assisted

Spec-Driven Development: What Does a Spec Say? (Part 3 of 4)

In part 1, I distilled five key properties of a spec from the existing SDD definitions: it is written in natural language, it defines testable behavior (the "what", not the "how", not the "why"), it is executable by an AI coding agent, it prescribes rather than describes, and it is long-lived.

In part 2, I examined what a spec is made of: text, written primarily in nonfiction prose, and ideally in a spec language.

In this third part, the questions are what a spec actually says, how long it lives, why it drives, and what exactly is being developed.

Content

As mentioned above, the spec's key property regarding content is that it defines the "what", not the "how", not the "why".

So, what is the "what"? And what is it not? To clarify, let's look at the entire chain of artifacts and transitions between them.

  1. An initial intent triggers the creation of requirements (the "why" behind the spec) for a deliverable, including in particular business objectives, functional and quality requirements, and constraints (technological, organizational).
  2. The requirements inform the creation of the spec (the "what"), detailing the domain logic, the observable behavior, and the external interfaces of the entire deliverable. To be explicit (existing SDD definitions disagree on exactly this point), the spec defines a deliverable that meets the requirements, but the requirements are not the spec. The requirements are the reason the spec exists.
  3. The spec forms the basis for a design (the "how"), which is technical in nature and details how to realize the specified deliverable using the selected technologies.
  4. The spec, together with the design, is translated to source code.
  5. A binary is built from the source code (or whichever other runnable form the language calls for).
  6. The execution of the binary materializes the deliverable, making its specified observable behavior tangible.

The deliverable can be scoped as narrowly as needed, as long as it has external interfaces of its own through which its observable behavior can be validated against the spec. A feature usually does not qualify: it cuts across a deliverable rather than standing on its own.

While this adequately defines the content boundaries of a spec, it is still silent on which topics exactly a spec needs to cover in what ways within these boundaries. SDD definitions, in my experience, tend to remain vague on this point as well. They sometimes give short lists of topics usually covered by architecture specifications or software design documents, as can be seen from the quotes in part 1.

What is still missing, and what I personally would wish for, are standards for specs comparable to what architecture frameworks are today for software architecture descriptions.

Regardless of whether we will have something like this or not going forward, I suggest allowing for a "spec content type" or "spec style" within the definition of SDD, leading to various forms of SDD distinguished by their "spec style".

As long as it is kept strictly optional, it does not hurt to include this concept in the term definition. The requirement-level key words follow RFC 2119 and RFC 8174.

A spec MAY adhere to a specific "spec style". A "spec style" SHOULD in particular mandate the use of a specific spec language.

Lifecycle

As pointed out above, a spec is long-lived. More precisely:

A spec MUST exist continuously and prescribe its entire deliverable until that deliverable reaches its end of life.

Ideally, a spec predates the creation of its deliverable, but the definition has to allow for retroactively created specs (by reverse engineering an existing deliverable, for example).

This property is rarely spelled out, possibly because it is implicitly assumed to follow from the very nature of a spec. However, it has a far-reaching consequence for what falls under SDD. Any approach where the spec is either abandoned at some point or turned into documentation cannot be classified as SDD.

The same applies to specs that only describe a change to a deliverable, such as a new feature. Once the change is implemented, such a spec has served its purpose. Whether it is deleted or kept as a record, it no longer prescribes anything, and the deliverable as a whole is prescribed by nothing but the code. Describing a change separately is perfectly fine as a step in the workflow, as long as the change ends up in the one spec that prescribes the entire deliverable.

This is in no way, shape, or form a statement about the usefulness of such an approach, just about its classification in terms of SDD.

What is spec-driven?

Now that we have discussed the term spec in great detail, we are set to take a look at the next constituent of the term SDD.

In software development, -driven means that a specific artifact or concept controls and steers the rest of the work.

We already know this linguistic construct only too well from terms like test-driven development (TDD), behavior-driven development (BDD), or domain-driven design (DDD).

So the spec has to be in the driver's seat.

Once it exists, a spec MUST always be before the fact.

A spec change MUST cause a code change, not the other way around.

A spec MUST NOT be documentation, which is after the fact.

What is development?

Or, to be precise: development of what exactly?

The aforementioned linguistic construct of "-driven" suggests a conceptual closeness of spec-driven development to TDD and BDD, which are both software development methods.

But since specs are not written in a programming language and define the "what" and not the "how" (the realization using certain technologies), can SDD really be regarded as a software development method?

When taking a second look at the SDD definitions, it is striking that they switch between software and system, sometimes within the same source:

The existing definitions already hint at the fact that specs can exist on different levels of abstraction ranging from concrete software to the fully abstract notion of a system. By system, I mean the deliverable defined in terms of its behavior, independent of how it is realized.

This distinction is closely tied to "spec style", since different levels of abstraction require a spec to touch on different topics or on a particular topic in different ways. I am convinced that the abstraction level is the primary axis along which all "spec styles" can be positioned. I therefore suggest defining it as a degree of freedom within the definition of SDD, ranging from "software" (concrete) to "system" (abstract).

Allowing specs to reach all the way up to the system level characterizes SDD as a system development method for systems that are to be realized in software. Putting it this way might sound a bit peculiar at first, possibly even nitpicky. However, this phrasing highlights the fundamental mindset shift our profession is about to experience. We will all (have to) climb up the abstraction ladder, adopting a new playbook:

Think in systems, not software.

Own behavior, not programs.

Stop coding, start specifying.

In part 4, the final part, I will turn to the one aspect still missing, the actors, and put the definition back together.

Top comments (0)