jonnifyagile agents
jonnify / Agile Agent Workflow / A3 · The roadmap layer / A3.3 / A3.3.2 · The iteration table

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

| Rung | Ships | Demo | Harness | Feedback asked | rung f6.1 ships (the slice) the engine served as a web app demo hit the root, see a page harness ConnTest GET smoke feedback asked shell and layout right?
f6.1 ships: the engine served as a web app (endpoint, request → facade → render) · demo: hit the root, see a page · harness: ConnTest GET smoke · feedback asked: shell and layout right?

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. 1.f6.11 · Ship the catalog
  2. 2.f6.31 · Ship the catalog
  3. 3.f6.51 · Ship the catalog
  4. 4.f6.62 · Make it live
  5. 5.f6.72 · Make it live

spec edits: 0 · re-orders: 0

order: f6.1 · f6.3 · f6.5 · f6.6 · f6.7 — spec edits: 0. Re-ordering changes delivery, never definition.

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 principle

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.

on the Portal

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

Related in this course