A3.8 · Workshop: roadmapping Portal · dive 2
Choose the tracer
A roadmap with milestones still has to start somewhere. Start with one honest thread through every layer — and name the breadth you are leaving for later.
Apply tracers (A3.7) and thin-but-robust (A3.4): the first rung is the tracer bullet — F6.1, request to facade to render — shipped before persistence or the rendered catalog, kept and grown, not a prototype. Pick a candidate first rung on the right; only F6.1 threads every layer.
Pick the tracer from the ladder · which rung threads every layer
The first thread, end to end
A roadmap grouped into milestones still has to start somewhere, and the choice matters most when integration is the risk. The answer is a tracer bullet: a thin slice that runs the whole path end to end, from the first request to the rendered response, before any one layer is built out. It de-risks integration early, because the layers are proven to connect on day one.
On the F6 ladder the tracer is F6.1, verbatim: “the engine served as a web app
(endpoint, request → facade → render)”. It ships before persistence (F6.3) and the
rendered catalog (F6.5). Its demo is “hit the root, see a page”; its harness is a
ConnTest GET smoke. It is a real thin feature — kept and grown into the live
platform — not a prototype built to learn and then discarded.
A tracer differs from a walking skeleton (end-to-end structure with no feature yet) and from a prototype (built to learn, then thrown away). F6.1 is the tracer: a real capability that stays in the codebase and grows, rung by rung, into the deployed product.
Defer the breadth, and name it
Choosing the tracer is also choosing what not to build yet. The honest roadmap names the breadth it defers rather than pretending the first rung is complete. The board below places each seam: rendering ships in the tracer; persistence, interactivity, authentication, deployment, and the dashboard are deferred — each to a named rung. The two figures teach different moves — the hero proves F6.1 threads every layer, this one shows the breadth held back behind it.
The deferred-seams board · in the tracer, or deferred to a rung
The tracer ships one honest thread; the breadth behind it is deferred to named rungs, not forgotten.
The tracer, on the Portal
On the Portal — the learning platform this course builds — the tracer for the web surface is
f6.1, the engine served as a web app: request → facade → render. It is the
first thread through every layer, shipped before the durable catalog (f6.3) or the
rendered catalog (f6.5). The roadmap's Seams & open decisions section
names the breadth it defers — authentication and deployment at f6.8, the
dashboard at f6.9 — as decided then, not now.
The fragment below is the tracer row and the deferred decisions as the roadmap names them — markdown, not Elixir source. Choosing the tracer and deferring breadth are roadmap moves; no spec is edited.
# phoenix.roadmap.md — the tracer row + the deferred seams (markdown; verbatim). | Rung | Ships (the slice) | Demo | Harness | | f6.1 | the engine served as a web app | hit the root, see a page | ConnTest GET smoke | # Seams & open decisions — named, not resolved: # - Authentication (f6.8) — the choice of session model "is decided then". # - Deployment & clustering (f6.8) — the deploy target "is decided then". # - Dashboard data (f6.9) — which metrics it shows "is decided then". # f6.1 is kept and grown — not a prototype. All of it under the master invariant: # the web layer calls only the Portal facade.
The tracer is a real thin feature, kept and grown — distinct from a prototype built to learn and then discarded. Ship one thread end to end first; defer the breadth, and name it.
On the Portal f6.1 is the tracer (request → facade → render, kept and
grown into the live platform); auth, deploy, and the dashboard are named seams deferred to later rungs, all
under the master invariant.
Start with one honest thread through every layer; defer the breadth, name it, and keep the thread.
Recap — one thread now, the breadth named for later
The tracer is the first end-to-end thread — F6.1 on the Portal, request to facade to render — shipped before depth, kept and grown rather than discarded like a prototype. Around it the roadmap names the breadth it defers: persistence, interactivity, auth, deployment, the dashboard, each to a rung. Choosing the tracer and deferring breadth are roadmap moves; no spec is touched. With the tracer chosen, the last dive places this chapter beside the bot in the program view.
Next in A3.8: A3.8.3 · The program view — web (F6) and bot (F10) as parallel surfaces over one facade.
References
The sources behind tracer bullets and shipping a thin thread first, and where it connects in the course.
Sources
- Hunt & Thomas — The Pragmatic Programmer — tracer bullets: a thin thread through every layer, kept and grown.
- Humble & Farley — Continuous Delivery — a thin end-to-end slice that keeps the system releasable from the first rung.
- Beck, K. — Extreme Programming Explained — do the simplest thing first and defer the rest, deliberately.
Related in this course
- A3.8 · Workshop: roadmapping Portal — the module hub.
- A3.8.1 · Ladder to roadmap — the previous dive.
- A3.3 · Anatomy of a roadmap.md — where the tracer row and the deferred seams live.
- A3 · The road ahead — where the spec layer takes each rung next.
- A3 · The roadmap layer — the chapter.
- F6 · The Portal on the web (Phoenix) — the real chapter, where F6.1 is the tracer.