Intent Formulation
Overview
Section titled “Overview”Section 1 gave you machinery that assumes one thing: that the behaviour can be listed. Functions are enumerable, scenarios are finite, and a tester can walk the list.
An open-ended natural-language interface breaks that assumption on day one. This topic is about what replaces the list.
The enumeration problem
Section titled “The enumeration problem”A conventional functional requirement is a finite statement. Given this input, in this state, produce this output. You can count the branches, and a reviewer can tell when one is missing.
Now specify a system that answers any question a customer might type about a product with hundreds of features, in several languages, with typos, mid-conversation, sometimes about something it should refuse. The input space is unbounded, and the correct output for most inputs is a judgement rather than a value.
Writing more requirements does not fix this. It produces a document that is simultaneously enormous and incomplete.
Deterministic specification — finite branches, and you assert the result:
graph LR I["Enumerated<br/>inputs"] --> B["Branches you<br/>listed"] --> O["Expected<br/>output"] --> T["Assert:<br/>equal?"] classDef det fill:#7D9A4E,stroke:#5F7A38,stroke-width:2px,color:#ffffff class I,B,O,T det
Intent specification — unbounded inputs, and three things stand in for the list:
graph LR U["Unbounded<br/>inputs"] --> P["<b>Intent</b><br/>what good<br/>looks like"] U --> BD["<b>Boundaries</b><br/>refuse, escalate,<br/>out of scope"] U --> EX["<b>Examples</b><br/>a labelled set that<br/>stands in for the rule"] P --> EV["Measure:<br/>does it hold<br/>often enough?"] BD --> EV EX --> EV classDef spec fill:#E8A33D,stroke:#C4832A,stroke-width:2px,color:#ffffff classDef edge fill:#D9695B,stroke:#B4483A,stroke-width:2px,color:#ffffff class P,BD,EX spec class U,EV edge
Two ways to say what a system must do. The amber boxes are the whole specification — there is no enumerated list underneath them, and pretending otherwise is the failure mode.
The three parts of an intent specification
Section titled “The three parts of an intent specification”Intent. One paragraph: what the system is for, who it serves, and what a good outcome looks like from the user’s side. Not mechanism. The test is whether someone could use it to settle an argument about a borderline case.
Boundaries. What the system must refuse, what it must escalate, and what is simply out of scope. This is the part that does structural work, because a refusal is a code path and an escalation is an integration. Boundaries are also where guardrails get their requirements: a guardrail with no stated boundary is a filter somebody tuned by feel.
Examples. A labelled set of inputs and acceptable outputs, including hard cases, ambiguous cases and cases that must be refused. For an unbounded input space, a curated set of examples is the specification — it carries the meaning that prose cannot pin down.
That third part is the uncomfortable one, because it means the specification has a maintenance cost that never ends. Treat the example set as an asset, name an owner for it, and expect to keep adding to it every time a real interaction surprises you.
Where the spec ends and the eval begins
Section titled “Where the spec ends and the eval begins”A clean line, and worth holding:
The specification says what good means. The evaluation measures whether it holds.
The spec is prose plus examples, owned by whoever owns the product outcome. The eval is executable, run on every change, and owned by engineering. Module 6 builds evaluation properly; what matters here is a design rule that falls out of the split:
Every intent statement must name the observable that would show it is being met. If you cannot say what you would look at, you have written an aspiration. “Answers should be helpful” names nothing. “Answers should resolve the question without a follow-up, measured as the share of conversations with no second question on the same topic” names something, and the number can be argued about.
Writing intent that a team and an agent can both act on
Section titled “Writing intent that a team and an agent can both act on”The same document now has two audiences. Engineers read it to build; the system itself reads some version of it as instructions.
That sounds like a reason to write two documents. It is a reason to write one, carefully. The qualities that make intent usable by a model — explicit scope, explicit refusals, concrete examples, no contradictions — are exactly the qualities that make it usable by a new engineer. This is the same argument as Documentation as Code, applied earlier in the lifecycle.
One genuine trap: over-specification makes probabilistic systems worse. A prose rulebook with forty constraints, several in mild conflict, produces output that satisfies none of them reliably. Fewer, clearer boundaries plus more examples beats an exhaustive rulebook — which is the opposite of the instinct Section 1 trains.
Feeds the workbook
Section titled “Feeds the workbook”Your requirements catalog needs an intent statement for the assistant, with boundaries written as explicitly as the functions. The escalation and refusal boundaries should reappear as scenarios on your Utility Tree.
→ Intent says what good means. Now someone has to decide how often “good” is good enough, and what the other times cost. — Specifying probabilistic outcomes