A5.4.3 · dive 3/3
Acceptance gates
The Directive sets the agent in motion; the gate is where it stops. An Acceptance gate is the runnable check that closes a story — and the line between “the agent thinks it is done” and “the work is provably done.”
A gate is not the agent's self-report. It is a single command whose pass or fail is
unambiguous: a clean compile, a real render, a static grep, a self-heal. Every well-formed agent
story carries exactly one; a story with no gate can never close, because the agent has work to do but
no signal it is finished. Select each story on the right to read the runnable check that closes it,
drawn verbatim from the Portal's real f6.1.llms.md.
Each story's closing check · select a story
What a gate is
An agent story has two halves: a Directive (what the agent does) and an Acceptance gate (the check
that closes it). The previous dive paired them; this one isolates the gate. A gate is a single
runnable check whose pass or fail is unambiguous — a command the Operator (or a script) runs,
not a sentence the agent writes about its own work. “Done — it compiles” is a
self-report. GET /health returns 200 is a gate.
The distinction matters because an agent's report and the truth can diverge. A gate removes the gap: it makes “done” a closure over a check the human ran, not an opinion the agent stated. A story with no gate is a Directive with no closing condition — the agent has work to do, but nothing tells it, or the reviewer, when the work is finished.
A self-report
The agent states it is finished. The claim and the reality can diverge, and nothing the human can run resolves the difference.
A gate
A single runnable check whose result is unambiguous. The Operator runs it; the story closes on its pass, not on the agent's word.
The four gates
The Portal's web bootstrap, f6.1.llms.md, carries four agent stories, and
each one closes on a different kind of runnable check. F6.1-AS1 closes on a
boot — a clean compile, a running app, GET /health returning
200, and the tree booting store → engine → endpoint.
F6.1-AS2 closes on a real render — a known user renders their courses,
no enrollments renders an empty state, and the template references only assigns.
F6.1-AS3 closes on a static grep:
grep -rE "Portal\.Engine|Repo|GenServer\.call" apps/portal_web/lib/ must
return nothing — the boundary that keeps the web layer calling only the
facade, never the engine.
F6.1-AS4 closes on a self-heal and a fail-soft — killing the endpoint
restarts it and a later request succeeds, and an injected %Portal.Error{}
renders 422, never 500.
# f6.1.llms.md — the Acceptance gate of each agent story (verbatim checks) # F6.1-AS1 # boot mix compile clean; app boots; GET /health 200; tree order store → engine → endpoint F6.1-AS2 # render a known user renders their courses; no enrollments renders an empty state; template references only assigns F6.1-AS3 # grep grep -rE "Portal.Engine|Repo|GenServer.call" apps/portal_web/lib/ returns nothing F6.1-AS4 # heal killing the endpoint restarts it; an injected %Portal.Error{} renders 422, never 500
Four stories, four kinds of check, but one property in common: every gate is a command, and its result is yes or no. The hero figure above lets you read each gate against its story; the figure below shows what happens to a story that has no gate at all.
Each story closes on a runnable check, not a claim — a boot, a render, a grep, or a self-heal, each with an unambiguous result.
A story with no gate
All four of f6.1.llms.md's stories carry a gate, so the count of stories that
can never close is zero. Add a story with a Directive but no Acceptance gate and the picture changes:
the agent has work to do, but no check exists to close it. The story is incomplete by construction
— not because the work is hard, but because nothing defines when it is finished.
Toggle the figure between the four real stories and the same set with a gateless story added. The readout counts the stories that cannot close. A brief that ships a story without a gate ships work with no end — the agent runs, the reviewer waits, and “done” never becomes provable.
Stories that can never close · add a gateless story
A gate is the line between “the agent thinks it is done” and “the work is provably done” — a story without one can never cross it.
On the Portal
The two gates that carry the most weight in f6.1.llms.md are the ones that
protect the architecture, not the feature. F6.1-AS3 closes on the
master-invariant grep — no module under apps/portal_web/lib/ may name
Portal.Engine, Repo, or
GenServer.call — so the web layer is held to calling only the
Portal facade, never reaching past it.
F6.1-AS4 closes on the endpoint self-healing: kill
PortalWeb.Endpoint and the :one_for_one supervisor
restarts it, and an injected %Portal.Error{} renders
422, never a 500. Both gates are checks a human runs
and reads, not claims the agent makes.
The principle
The Acceptance gate is the runnable check that closes a story; a story with no gate is incomplete, because nothing defines when its work is done.
On the Portal
f6.1.llms.md closes F6.1-AS3 on
grep … apps/portal_web/lib/ being empty and
F6.1-AS4 on the endpoint self-healing under
:one_for_one with an injected %Portal.Error{}
rendering 422.
A gate is the line between “the agent thinks it is done” and “the work is provably done.”
Recap — the gate closes the story
An Acceptance gate is the single runnable check that closes an agent story: a boot, a render, a grep,
a self-heal — each a command whose pass or fail is unambiguous, run by the human, not reported
by the agent. Every story in f6.1.llms.md carries one; a story with no gate
can never close. That completes A5.4: a user story says what someone needs, and an agent story says
what the agent does (the Directive) and how the work proves itself done (the gate). The next module
assembles the four parts — references, requirements, topology, and stories — into the
single implementation prompt the agent runs.
Back to the hub: A5.4 · Agent stories — the Directive and the gate, the first two stories, and the gate that closes each one.
References
Primary sources on what makes a story closeable — a testable acceptance criterion rather than an open goal — and where the stories these gates close, and the boundary one of them guards, are defined in the courses.
Sources
- Cohn, M. — User Stories Applied — conditions of satisfaction: the explicit, testable check that tells a team a story is finished.
- Wake, B. — INVEST in Good Stories — the “Testable” property: a story you cannot write a check for is not yet a story.
- Hunt, A. & Thomas, D. — The Pragmatic Programmer — assertive programming and design by contract: state the condition that must hold, then check it.
Related in this course
- A5.4.1 · Directive and gate — the two halves a gate completes.
- A5.4.2 · The first two stories — the stories these gates close.
- A5.4 · Agent stories — the module hub.
- A5 · The agent brief — the chapter, whose fifth part assembles these stories into the implementation prompt.
- Companion · Phoenix lifecycle (F6.1) — the real chapter whose
f6.1.llms.mdcarriesF6.1-AS1…AS4.