jonnifyagile agents
jonnify / Agile Agent Workflow / A5 · The agent brief / Numbered requirements

A5.2.2 · dive 2/3

Numbered requirements

References tell the agent what to read. The second part of the brief tells it what to build — as numbered, testable lines, each a single statement with a single check.

The Portal's web bootstrap brief, f6.1.llms.md, carries eight of them: F6.1-R1 through F6.1-R8. Each names exactly one thing the agent builds and exactly one check that closes it — a boot, a render, a static grep, a restart. Toggle the figure on the right to read each requirement as one numbered line and the kind of check that proves it.

One numbered statement, one check · pick a requirement

f6.1.llms.md · Requirements — one numbered line, one check each R1 — the Endpoint plug stack + LiveView socket boot R2 — two :one_for_one supervisors boot R3 — :browser pipeline + the courses route render R4 — controller calls only Portal.courses_of/1 render R5 — CourseHTML renders from assigns only render R6 — GET /health returns 200 “ok” render R7 — no Engine/Repo/GenServer.call in portal_web grep R8 — failure → 422; killed endpoint restarts restart check kind selected: 4 render · 2 boot · 1 grep · 1 restart
F6.1-R1…R8 — eight numbered requirements, each a single checkable line: 4 render checks, 2 boot checks, 1 static grep, 1 restart. Every line names what to build and the check that closes it.

One statement, one check

A numbered requirement is one checkable statement, given an id, that names exactly one thing the agent must build and exactly one check that closes it. It is the unit the brief decomposes the work into. If you cannot say what check closes a line — a boot, a render, a grep, a restart — the line is a wish, not a requirement.

Read F6.1-R7 as the cleanest case: no module under apps/portal_web/lib/ contains the strings Portal.Engine, Repo, or GenServer.call. That is the master invariant, and its check is a single static grep that either returns nothing or names the offending file. There is no room to interpret it. F6.1-R6 is the same shape on a runtime check: GET /health returns 200 with body ok and performs no domain call — one request, one observable answer.

The principle

A requirement is one observable fact and the kind of check that proves it. Name the check — boot, render, grep, restart — or the line is intent the agent must interpret.

On the Portal

f6.1.llms.md writes each of R1–R8 as a single line with a single check: R7 is a grep, R6 a request, R8 a 422-not-500 observation plus an endpoint restart.

A requirement the agent can run a check against is buildable; one it can only interpret is not.

Numbering keeps them separable

Numbering is not a tidy habit. R1, R4, R7 are addresses: the build cites them, the task DAG cites them (T5 … [R4, R8]), the agent stories cite them, and the review walks them. Eight numbered lines are eight separately-checkable units. Fold two of them into one paragraph and the checkable count falls — one paragraph is one ambiguous unit, however many checks it once held.

Toggle the figure below between the eight numbered requirements and a version that merges R7 and R8 into a single paragraph. The static grep and the 422-and-self-heal check are distinct obligations; merged, they read as one line of intent, and the separately-checkable count drops from eight to seven.

Separately-checkable requirements · toggle how they are written

each cell = one separately-checkable requirement R1 R2 R3 R4 R5 R6 R7 R8 numbered — every requirement is one addressable, checkable line separately-checkable requirements: 8 of 8 a paragraph that folds two checks together is one ambiguous unit, not two
Numbered: 8 separately-checkable requirements. Each line — R1 boot, R4 render, R7 grep, R8 restart — is one statement the build satisfies and the review checks.

Numbering turns a paragraph of intent into a checklist the build and the review share.

On the Portal

The Portal's web bootstrap ships from f6.1.llms.md, and its ## Requirements section is eight numbered lines — F6.1-R1 through F6.1-R8. The first pins the PortalWeb.Endpoint plug stack and the LiveView socket; the seventh is the master invariant a single grep proves; the eighth is two observations — an expected failure renders 422, never 500, and a killed endpoint restarts under its supervisor. The controller that satisfies R4 lives in the companion course at the controllers lesson, where index/2 calls Portal.courses_of/1 and renders the 422 path on a %Portal.Error{}.

# f6.1.llms.md — ## Requirements (numbered, testable; verbatim)
#
  F6.1-R1  PortalWeb.Endpoint is the outermost plug — Plug.Static, RequestId,
           Telemetry, Parsers, Session, then plug PortalWeb.Router last;
           it declares socket "/live", Phoenix.LiveView.Socket.   [US: F6.1-US1]
  F6.1-R6  GET /health returns 200 with body "ok" and performs no domain call.   [US: F6.1-US1]
  F6.1-R7  no module under apps/portal_web/lib/ contains Portal.Engine, Repo,
           or GenServer.call — the master invariant, statically checkable.   [US: F6.1-US3]
  F6.1-R8  an expected domain failure yields a 422, never a 500;
           killing the endpoint restarts it under the supervisor.   [US: F6.1-US4, F6.1-US5]
#
# R7 closes on a literal grep over code:
  grep -rE "Portal\.Engine|Repo|GenServer\.call" apps/portal_web/lib/   # returns nothing

The principle

Number the requirements so each is a single statement the agent can satisfy and the reviewer can check — and so every other artifact can cite the exact line.

On the Portal

f6.1.llms.md numbers R1–R8; R7 is a literal grep (grep -rE "Portal.Engine|Repo|GenServer.call" apps/portal_web/lib/ is empty), and the task DAG cites each requirement the steps satisfy.

Numbering makes a requirement addressable — cited by the build, the task DAG, and the review, never restated and never lost.

Recap — eight lines, eight checks

The brief's second part is a list of numbered, testable requirements: each one a single statement that names what the agent builds and the check that closes it. On the Portal that list is F6.1-R1 through F6.1-R8 — a boot, a render, a static grep, a restart, each addressable and each separately checkable. Fold two into a paragraph and the count falls; keep them numbered and the build and the review share one checklist. The next dive carries the line further: each requirement also names the story it serves, so the list is not only checkable but accountable.

Next in A5.2: Traceability — each requirement names the user story it serves and the check it satisfies, and an untraced requirement is flagged.

References

Primary sources for writing testable, numbered requirements an agent can satisfy and a reviewer can check, and where the requirement this dive grounds on is built in the companion course.

Sources

Related in this course