Converting a chapter to the node format
For anybody holding a spec written before the node format, wondering what it costs to move.
It costs one chapter at a time, and nothing until you start. node_format is off by default, so a corpus in the older shape keeps gating exactly as it did — every chapter is read the old way, counted, and never failed. Turn the flag on per project when your chapters are converted, not before.
This method's own corpus and Plumb's have both been through it. All four chapters of goldspec/spec/ and all twelve of plumb/spec/ were converted with this page, one at a time, and node_format = true is set in both. That is worth saying because the alternative — publishing a conversion guide for a corpus that had not been converted — is the failure the method is about.
What it cost, honestly. The reordering is mechanical and fast. Step 5 below is where the hours go and where everything is found, and on sixteen chapters it found: five pieces of information a step holds and never leaves, which the older shape had no column for and which were therefore either absent or faked as inputs; two parameters and two NFRs written as sentences inside a claim; four elements a story requires and no table defined; four subjects drawn in no diagram, because the older shape checks placement against a prose section rather than against the picture; and one step the whole of a chapter is about that no subject in it claims.
Two complete versions of the same chapter ship beside this page:
example/before/ |
the older shape — one ## Input → process → output and one ## Data definitions for the whole chapter. No goldspec.toml at all, because it needs none |
example/ |
the same chapter converted |
Both gate clean. Read them side by side; this page is the map between them.
What moves where
| Old | New |
|---|---|
## Story → test trace, one row per subject |
## Nodes, one ### block per subject |
| the claim in that row | the node's story — as a <role> I want … so that … |
| the reasoning crammed in after the claim | the node's closing paragraph — and see below, this is where the work is |
## Input → process → output, [P*] steps |
each node's In / Held / Out |
### What each step takes and leaves |
gone; it was per-node IPO with the middle missing |
## Data definitions |
## Elements, under **Defined here.** |
| elements another chapter owns | ## Elements, under **Imported.** |
## Open unknowns |
unchanged |
## Glossary |
unchanged |
The section order changes with them: ## Elements, ## Nodes, ## Open unknowns, ## Glossary.
Nothing about the diagram changes, except that you will probably want to draw the parameters you are about to discover.
The step that is the whole point
Read each trace row and ask what kinds of thing are in it. A row in the old format is the only place a chapter had to put anything, so rows accumulate. In a real conversion one row reached 486 words against a chapter average of 161, and reading it apart found twelve separate things wearing one id: a claim, a decision, three pieces of history, a measurement, a cross-reference, two constraints, and two steps that had never been drawn because there was no flow for them to be steps in.
Sort what you find:
| What it is | Where it goes now |
|---|---|
| what somebody wants, and why | the node's story |
| why the step is built this way | the node's closing paragraph |
| a value nobody has measured, that you could write a model for | a parameter, chN-P<n> |
| an external restriction the flow must survive | an NFR, chN-N<n> |
| a question with no answer yet | an open unknown, chN-U<n> — it probably already is one |
| what went wrong on a particular day | the commit message. It is history and it stops being true |
| a fact about a piece of information | the element's Domain, in ## Elements |
| steps, described because they could not be drawn | new nodes, or a sub-flow |
In the shipped pair, two of those are real and you can see both. The old ch1-2 row ends with:
A reservation is held between the check and the charge, and how long it is held is a real question nobody here has measured: too short and a slow card releases stock somebody has already been promised; too long and a browsing customer holds stock nobody can sell.
That is a parameter with its model already written, buried in a sentence. Converted, it is ch1-P1, it is drawn on the flow, and it is a thing somebody can go and measure.
The old ch1-3 row ends with:
Note also that the processor's reconciliation window closes at 02:00, which is not ours to negotiate…
That is an NFR — external, known, restricting. Converted, it is ch1-N1, and it has an id a room full of people can point at.
Neither was invented in the conversion. Both were already written down, in the one place the old format had for them, where nothing could cite them and nothing could tell them apart from the claim.
The order to do it in
- Split the trace rows into
###blocks. One per subject, id first, the claim becoming a story in role/want/goal shape. Do not rewrite the reasoning yet — move it below the table as the closing paragraph and leave it. - Give each node its In / Held / Out.
### What each step takes and leavesalready has In and Out per step; copy them across. Held is the new part — information that exists only inside the step. It is usually already in your element table with nothing consuming it, which is the clue. - Rename
## Data definitionsto## Elementsand add the**Defined here.**run-in. Move any element another chapter owns into an**Imported.**table and delete its columns — an import names the corpus and stops. - Reorder the sections and delete
## Input → process → output. - Now go back to the closing paragraphs and pull out the parameters, the NFRs and anything that is history. This is the step that finds things, and it is deliberately last: you can only see what a paragraph is really made of once it sits under one node instead of doing duty for a chapter.
- Run the gate with
node_format = truefor that project. Expect it to name a few things — a node drawn and not expanded, an element nothing moves, an import carrying a note.
A node whose closing paragraph is still too long after step 5 is a node hiding a flow. Give it a drill-down file rather than editing it down.
What you can leave alone
- Chapters you have not converted. They gate as they always did, and a corpus can be half converted for as long as it likes. Turn
node_formaton only when the last one is done. - Ids. Nothing renumbers. A subject keeps its id, so every citation to it keeps resolving — which is the property that makes this safe to do gradually.
- The diagram. Add flag nodes for the parameters you find; otherwise it stands.
data_definitions. It governs the six-column table wherever that table lives, and applies under both shapes.
Where to go next
- Getting started — the node format explained part by part.
- From decision records to user stories — the larger conversion, from documents to a spec at all.