A product specification template built on decisions, not prose

A spec is read to settle arguments, not admired. Its valuable sections are the open questions and the decisions with their reasons.

A product specification template is worth having only if it is read to settle arguments, which means its valuable sections are the open questions and the decisions with their reasons.

A product specification template built on decisions: the decision, the reason, what is still open.
A product specification template built on decisions: the decision, the reason, what is still open.

Most specs are written as descriptions and pulled out of a folder mid-meeting to answer "did we decide whether links expire", and the description does not say.

Structuring the spec around the arguments makes it shorter and more useful, and putting it at one address means the decision recorded on Tuesday is the one everyone reads on Thursday.

This guide covers the shape, why one address matters, what to leave out, and the four steps.

Most specs are written as descriptions and read as reference material for arguments. Structuring them around the arguments makes them shorter and more useful.

The product specification template that settles arguments

<h2 id="problem">What is broken</h2>
<h2 id="scope">In scope / out of scope</h2>
<h2 id="open">Open questions</h2>
<h2 id="decisions">Decisions</h2>
<h2 id="detail">Behaviour</h2>

Note the order. Open questions and decisions come before the detailed behaviour, because those are the sections people come back for.

What is broken

Two or three sentences, with a number if one exists. Not a paragraph of background.

<p>Sharing a page requires re-uploading the file after every edit.
   Support sees roughly a dozen "which version is current" tickets a week.</p>

In scope, out of scope

The out-of-scope list is the more valuable half, and the one usually missing. It is what prevents the feature growing by a third during implementation, and it is what you point at when somebody asks for the obvious extra thing.

<h3>Out of scope</h3>
<ul>
  <li>Per-page passwords — separate piece of work</li>
  <li>Link expiry — not asked for by any customer yet</li>
</ul>

"Not now, and here is why" beats silence, which reads as an oversight.

Open questions

<li id="q-expiry">
  <strong>Open:</strong> should an edited page keep its old versions accessible?
  Blocking the storage design. <strong>Needs:</strong> Mina, by 20 Sep.
</li>

What is undecided, what it blocks, who decides, by when. A spec with no open-questions section is either finished or lying, and it is usually lying.

Give each question an id, so it can be linked directly in a chat thread.

Decisions, with reasons

<li>
  <strong>Decided 12 Sep:</strong> the address does not change when a page is edited.
  <br><span class="why">Because the whole value is that a sent link stays correct.
  Cost: no way to invalidate a leaked link without deleting the page.</span>
</li>

The reason is the part that matters. Three months later somebody will propose changing this, and a one-line reason plus its acknowledged cost ends the conversation in thirty seconds rather than a meeting.

Recording the cost of a decision is what makes it credible. A decision presented as having no downside gets reopened.

Behaviour

The detail, last. States, edge cases, what happens when things fail. Written as a list rather than prose, because it is read by looking things up.

<table>
  <thead><tr><th scope="col">When</th><th scope="col">Behaviour</th></tr></thead>
  <tbody>
    <tr><td>The page is deleted</td><td>The link returns 404</td></tr>
    <tr><td>The reader is signed out</td><td>The page still opens</td></tr>
  </tbody>
</table>
A copy per person ✗ Each edit lives on one machine ✗ No way to merge the changes ✗ Nobody can say which is current ✗ The oldest copy keeps circulating One address ✓ Everyone opens the same page ✓ A correction is seen by all ✓ There is only one current version ✓ Forwarding shares the page, not a copy
A spec per reader, each frozen at the version they were sent, versus one page where the decision made on Tuesday is what everyone reads on Thursday.

Why one address matters here

A spec is amended constantly during implementation. Every amendment sent as a file creates a version, and the versions diverge from the code in different directions.

One address. Pulled out mid-meeting, it answers "did we decide" with the current answer.
One address. Pulled out mid-meeting, it answers "did we decide" with the current answer.

One address, amended in place, with the document's own history for "what did this say when we agreed it". Then a link in a ticket, a chat thread or a code comment stays correct — and a link to #q-expiry still lands on the right question a month later.

In NOS the spec is a document whose text is clickable text, so the person who notices a decision was recorded wrong corrects it. The engineer implementing it does not have to route a correction through whoever wrote the spec, which is where amendments otherwise stall.

Recording the reason

A decision without its reason gets re-argued the moment the people who made it are not in the room, because the new people cannot tell whether the constraint still holds.

Recording the reason next to the decision. Tuesday's decision is what everyone reads on Thursday.
Recording the reason next to the decision. Tuesday's decision is what everyone reads on Thursday.

"One link per page, because per-viewer links doubled support load in the prototype" can be revisited when support load stops mattering; "one link per page" cannot be revisited at all, only overturned. One sentence of reason per decision is the highest-value text in the document.

What to leave out

Implementation detail that belongs in the code. It will diverge and the code is authoritative.

Interface screenshots. They age faster than any text and cannot be corrected by a reader.

Anything written to sound thorough. A spec is read under time pressure by people looking for one answer. Length works against it.

Section value

Section Read after the first week Why
Open questions Constantly It is the live state of the work
Decisions with reasons Constantly It ends reopened arguments
Out of scope Often It is what you point at
Behaviour table When implementing Looked up, not read
What is broken Once Context, and then it is known
Background prose Never

The ordering of a spec should follow that column, which is why decisions and open questions come before the detailed behaviour rather than after it.

Where it connects

A spec records what was decided. The meeting notes record when, and the changelog records what shipped. Three documents, three addresses, each linkable from the others.

Keeping the spec at one address is what makes a link to a specific decision — #q-expiry — still land correctly a month later, which a file circulated by email cannot do.

Writing the spec as decisions: 4 steps

  1. Start with what is broken and the scope. One paragraph on the problem with a number in it, then in-scope and out-of-scope side by side.
  2. Keep open questions and decisions as the two live sections. Each question with an owner and a decide-by date; each decision with its date and its reason.
  3. Paste it into a NOS document and share one link. Share, then Share link, then Create link. Every meeting opens the same page; the spec in the deck and the spec in the thread are the same spec. Turning HTML into a link is this step.
  4. Move questions to decisions on the page as they close. Click, edit, add the reason. The spec is the record, and there is no v4 in anyone's inbox.

Questions people ask

What makes a spec useful?

A visible list of open questions, and a record of decisions with their reasons. The descriptive part is what people skim past.

Why record the reasons for decisions?

Because the same question is reopened three months later by someone who was not there. A one-line reason ends that conversation immediately.

One page or several?

One page per feature, with anchored sections so a specific decision can be linked directly in a discussion.

Should the spec be updated as things change?

Yes, in place, at one address. A spec whose latest version is in someone's attachments is not a spec.

Keep reading