jonnifyagile agents
jonnify / Agile Agent Workflow / A4 · The spec layer / A4.7 / A4.7.1 · The engine deliverables

A4.7 · Workshop · dive 1

The engine deliverables

Before a spec is written, its inventory is fixed: the deliverables — the concrete artifacts a rung ships. F5.1 carries seven, D1 through D7.

Each deliverable is one artifact, and each constrains the build by naming what exists without dictating how it is coded. They are read from F5.1 — Portal's engine-facade rung, the first rung of the engine chapter (taught in the companion Elixir course) and the seed of the F6 master invariant. Then see the line F5.1-INV1 draws — the replaceable web seam that becomes that invariant. Pick a deliverable on the right to read what it constrains.

F5.1's seven deliverables · pick one

D1 · a supervised Mix project D2 · Portal.ID, branded Snowflake ids D3 · the stubbed engine boundary D4 · the thin router D5 · the supervised application D6 · the replaceable web seam + roadmap D7 · verification
D1 · a supervised Mix project portal with bandit, plug, jason — no Phoenix, no Ecto. Constrains: what exists (a supervised app that compiles clean), never how it is coded.

Seven artifacts, named not coded

A spec's Deliverables section is its inventory: the concrete artifacts the rung ships. F5.1 — Portal's engine-facade rung carries seven, each a single artifact and each constraining the build by naming what must exist — while leaving the implementation to the Author. That is the line A4.3 drew between constraining and over-specifying, here on a real rung.

F5.1-D1
A supervised Mix project portal with bandit, plug, jason; no Phoenix, no Ecto; a clean compile.
F5.1-D2
Portal.ID — branded Snowflake ids: a 3-letter namespace plus the width-11 Base62 of a snowflake (14 chars). The id contract the whole system identifies on.
F5.1-D3
The stubbed engine boundary — dispatch/1 and query/2, each returning an ok-or-error result, both stubbed for now.
F5.1-D4
The thin router — parse a request, call the engine boundary, format a response: one read route, one write route, a 404 fallback. No domain logic.
F5.1-D5
The supervised application — the engine and the web server supervised :one_for_one, so a crashed child restarts on its own.
F5.1-D6
The replaceable web seam — the web layer is a thin adapter only, plus a roadmap of what stays (the domain, the ids, the engine boundary) and what F6 replaces (the web layer).
F5.1-D7
Verification — the app boots, POST /enroll returns 422, an unknown path returns 404, and a killed engine restarts.

A deliverable names the artifact and what it must do, not the code that does it. “A thin router that parses, calls the boundary, and formats a response” constrains the build; “use a case not a cond” would over-specify it.

The replaceable seam — F5.1-INV1

One deliverable carries more weight than the rest. F5.1-D6 makes the web layer a thin, replaceable adapter, and the invariant that names it — F5.1-INV1, “the replaceable seam, the seed of the master invariant” — states the rule verbatim: “the web layer holds no domain logic … so F6 can replace Bandit with Phoenix untouched.” The web seam is the part the next chapter swaps; keeping it thin now is what makes that swap cheap later.

Switch the view to put domain logic on either side of the seam. With the web layer thin — the F5.1-INV1 position — the engine boundary and the domain are untouched when the web layer is replaced. Push domain logic up into the web layer and the seam breaks: the F6 swap would now disturb the domain. The two figures teach different moves — the hero reads the inventory, this one holds an invariant and tests its consequence.

Where the domain logic sits · switch the view

WEB LAYER · Bandit + Plug router parses HTTP · calls the engine boundary · formats a response — no domain logic the replaceable seam ENGINE BOUNDARY · the domain dispatch/1 · query/2 — depends on nothing in the web layer F5.1-INV1 · web layer holds no domain logic · F6 replaces Bandit untouched
Web layer thin — the seam holds. The router only translates HTTP to the engine boundary; the domain depends on nothing above it. F6 can replace Bandit with Phoenix untouched. F5.1-INV1 holds for every request.

D6 ships the seam, F5.1-INV1 names it — and keeping the web layer thin now is what lets the next chapter swap it for Phoenix without touching the domain.

The deliverables on the Portal

On the Portal — the learning platform this course builds — the real artifact is the spec for F5.1 — Portal's engine-facade rung, the engine chapter's first rung. Its Deliverables section lists the seven above, and its Invariants section opens with F5.1-INV1, the replaceable seam. Read together, they fix what the rung ships and the one rule it must never break — the workshop's starting material, which A4.7.2 runs the six moves over.

The one Portal API the course names freely is the id contract, Portal.ID.generate/1 and Portal.ID.decode/1 — a typed branded id minted and decoded. Everything else in the list stays at the spec level: a deliverable is a named artifact, not the source that realizes it.

# f5.1.md — Deliverables (verbatim glosses; a deliverable names an artifact).
#   F5.1-D3 — the stubbed engine boundary: dispatch/1, query/2 — ok-or-error.
#   F5.1-D6 — the web layer is a thin, replaceable adapter, plus a roadmap of
#            what stays (domain, ids, engine boundary) and what F6 replaces.

# f5.1.md — Invariants — the master-invariant seed, verbatim:
#   F5.1-INV1 (replaceable seam · seed of the master invariant) — the web layer
#   holds no domain logic … so F6 can replace Bandit with Phoenix untouched.

# The one named id contract, at the spec level — what exists, not how it is built:
id      = "the id contract"   # Portal.ID.generate/1 mints a typed branded id
decoded = "decode(id).type"   # Portal.ID.decode/1 reads its type and timestamp
the principle

Deliverables fix the inventory of a rung: each names one artifact and constrains what exists, leaving how to the build — and an invariant names a rule the build must never break.

on the Portal

F5.1 ships D1–D7 — the supervised app, Portal.ID, the engine boundary, the thin router, supervision, the replaceable-seam discipline, and verification — with F5.1-INV1 holding the web seam thin.

Name the deliverables and the invariant they hold, and the build has a precise target without a dictated solution.

Recap — the workshop's starting material

F5.1's seven deliverables are the engine rung's inventory: each names an artifact — the supervised app, the id generator, the stubbed engine boundary, the thin router, supervision, the replaceable seam, and verification — and constrains what must exist, never how it is coded. Over them sits F5.1-INV1, the seed of the F6 master invariant: the web layer holds no domain logic, so the next chapter can swap it for Phoenix untouched. With the deliverables and the invariant in hand, the next dive runs the six A4 moves over them.

Next in A4.7: A4.7.2 · Run the sequence — step the six moves (by-example, triad, anatomy, stories, invariants, traceability) over the F5.1 triad and watch the spec fill, part by part.

References

Primary sources for deliverables as a constrained inventory and the thin first slice, and where this dive connects in the course.

Sources

Related in this course