A3.3 · Anatomy of a roadmap.md · dive 2
The iteration table
The per-iteration table is the operational heart of a roadmap. Each row is one rung — what it ships, the demo, the harness, and the feedback asked.
Verbatim from phoenix.roadmap.md: each rung is “a PR-sized
increment — a spec triad, the slice, a green harness, a demo, a feedback note”. Pick a rung on the
right to read its row from the real file.
Read one row of the table · pick a rung
Five columns, one rung per row
The per-iteration table is where a roadmap turns operational. Its header row, verbatim from
phoenix.roadmap.md, is
| Rung | Ships (the slice) | Demo | Harness | Feedback asked |. Each row is one rung,
and each cell answers a concrete question.
- Rung
- The increment's id, e.g.
F6.1— the line that points at its spec. - Ships
- The slice it delivers, verbatim for F6.1: “the engine served as a web app (endpoint, request → facade → render)”.
- Demo
- What you can show at the end, verbatim for F6.1: “hit the root, see a page”.
- Harness
- How it is verified, verbatim for F6.1: “ConnTest GET smoke”.
- Feedback asked
- The question the demo answers, verbatim for F6.1: “shell and layout right?”.
In the file's words, each row is “a PR-sized increment — a spec triad, the slice, a green harness, a demo, a feedback note”. The loop per rung is “sharpen → build → ship → demo → review → feedback → adapt”.
Re-order the rungs, edit no spec
The table holds order, not behaviour. Re-ordering the rungs re-plans delivery — it changes
which slice ships first — and edits no spec, because the behaviour lives in the
f6.N.md the row points at, never in the row. The control below re-orders a real
slice of the F6 table; the spec-edits counter is wired to the order and stays at 0 no matter
how the rungs are shuffled.
This is the move the hero figure could not show: the hero read a fixed row; this proves a consequence — that order is decoupled from definition. Re-plan freely above the facade; the specs below it do not move.
Re-order the rungs · the spec-edits counter stays at zero
- 1.f6.11 · Ship the catalog
- 2.f6.31 · Ship the catalog
- 3.f6.51 · Ship the catalog
- 4.f6.62 · Make it live
- 5.f6.72 · Make it live
spec edits: 0 · re-orders: 0
The per-iteration table holds order; the specs hold behaviour — so a re-order re-plans delivery and edits no spec.
The table, on the Portal
On the Portal, the real per-rung table in phoenix.roadmap.md lists nine rows,
F6.1 through F6.9. F6.5 ships “the rendered catalog
(index, course_card, form, inline errors)”, demos “browse the catalog;
create with inline errors”, is harnessed by “HTML render tests; valid/invalid create”, and
asks “layout, UX, error wording?”. F6.6 ships “interactivity (live search, live create,
streams)” and asks “does the interaction feel right?”.
Each row is a vertical slice built to production quality, harnessed with
ConnTest or LiveViewTest, and demoed for feedback. The
order of the rows is the delivery plan; it re-plans without touching the specs, because every row points at a
spec and defines no behaviour of its own.
# phoenix.roadmap.md — the per-rung table (verbatim cells). | Rung | Ships (the slice) | Demo | Harness | | f6.1 | the engine served as a web app | hit the root, see a page | ConnTest GET smoke | | f6.5 | the rendered catalog (index, course_card, …) | browse the catalog; create | HTML render tests | | f6.6 | interactivity (live search, live create) | search as you type; no reload | LiveViewTest | # Re-ordering the rows re-plans delivery; the f6.N.md specs they point at do not change. order = ["f6.5", "f6.1", "f6.6"] # a re-planned sequence spec_edits = 0 # order is decoupled from definition
The per-iteration table makes each rung a PR-sized increment with a demo and a harness; re-ordering the table re-plans delivery and edits no spec.
phoenix.roadmap.md's per-rung table lists
f6.1…f6.9; the loop is “sharpen → build → ship → demo
→ review → feedback → adapt”, and feedback edits the spec, not the order.
Each row a rung, four cells of slice, demo, harness, and feedback — and the order re-plans delivery while the specs hold still.
Recap — the operational heart
The per-iteration table is where a roadmap turns operational: one rung per row, five columns — rung, ships, demo, harness, feedback asked — each row a PR-sized increment. The order is the delivery plan, and re-ordering the rungs edits no spec, because each row points at a spec and defines no behaviour. With the table read, the closing dive turns to what the roadmap names but does not resolve: the open decisions.
Next in A3.3: A3.3.3 · The open decisions — what a roadmap names but defers, and the invariant that bounds every resolution.
References
The small-batch delivery tradition the per-iteration table draws on, and where it connects in the course.
Sources
- Humble & Farley — Continuous Delivery — each rung a small, demoable release down a pipeline; the deployment harness.
- Beck, K. — Extreme Programming Explained — small releases, continuous feedback, and the planning game's re-orderable stories.
- Hunt & Thomas — The Pragmatic Programmer — orthogonality: re-plan delivery without disturbing the specs below.
Related in this course
- A3.3 · Anatomy of a roadmap.md — the module hub.
- A3.3.1 · What it carries — the previous dive.
- A3.3.3 · The open decisions — the next dive.
- A1.04 · Two layers — the roadmap over the spec.
- A0.2.2 · The four artifacts — the spec a row points at.
- F6 · The Portal on the web (Phoenix) — the real chapter and its per-rung table.