AI fill
Why fill is a declarative decision the platform executes rather than a callback in your code, and what a closed set of decision kinds buys the platform in exchange.
What it is
Section titled “What it is”Fill is the pipeline stage that turns a section’s declarations into slot values for one deliverable, before anyone opens the draft. Its first pass runs between intake and edit, and it is the stage that actually resolves the sources facts and provenance describes — reading what a slot is bound to and producing the value that lands on it.
Why it works this way
Section titled “Why it works this way”Fill is declarative because it runs on the platform, not in your code. You do not write a function that fetches a property’s content and decides what to do with it; you write a description of a decision, and the platform is the thing that carries the decision out. That is a stricter contract than “generate something here” — it is a closed vocabulary of decision kinds, each with a fixed shape, and every decision a section declares has to be one of them.
That closure is not an aesthetic preference; it is what makes the rest of the platform possible, and it is worth separating into what it actually buys, because each of these fails on its own:
- Plan. Because every decision’s shape is known ahead of time, the platform can look at a whole deliverable’s declarations before running any of them and work out what needs to happen, and in what order.
- Cache. A decision the platform recognizes is one it can compare against the last run — same source, same instruction, same shape — and skip re-running when nothing has changed.
- Cost. A closed set of decision kinds is a set the platform can meter: it knows in advance roughly what each kind costs to run, and can budget or bill a fill pass before starting it.
- Re-run one slot. Because a decision is scoped to the slot or slots it produces, the platform can re-run exactly the ones a late-arriving fact or a newly added section actually touches, leaving everything else — including a user’s own edits — untouched.
An arbitrary callback would cost the platform all four at once: it cannot plan around code it has not run, cannot know whether that code behaves the same way twice, cannot price code it cannot inspect, and cannot scope that code’s effects to one slot. This is also, plainly, why you cannot call a model yourself from inside a template — not because the platform forbids the network call, but because a call your own code makes is exactly the arbitrary callback the whole design routes around. If you have used other AI tooling, this is probably not what you expect: most of it hands you the model and lets your code decide what to do with the response. Here the decision is the artifact you author, and the platform is what runs it.
How it works
Section titled “How it works”In prose, not code: a decision names the slot or slots it produces, and the kind of decision it is. The kind picks how the value gets made — the fill decisions is the closed set, with what each one produces and when to reach for it. The declaration itself lives in the fill spec, naming the same fact and slot vocabularies facts and provenance and slots already introduced.
One property of a generated-text decision is worth calling out here, because it is easy to assume the platform enforces it and it does not: a length cap is a target the generator is asked to write to, not a limit the platform checks afterwards. Nothing rejects a slot value for coming back long, and nothing re-measures a stored value later — the cap shapes what gets asked for, not what a slot is allowed to hold. That cap is the slot’s own, declared once in the schema and inherited by the decision that fills it. What actually happens to an over-cap value is covered in the fill spec; the point to take from it here is that you are aiming the generator, not fencing the result.
What it is not
Section titled “What it is not”Not a prompt playground. You are not iterating against a live model response — you are writing a declaration the platform interprets the same way on every property, and the closed set of decision kinds is what keeps that interpretation predictable rather than a matter of how one particular prompt happened to land.
Not run at render time. Fill has already finished by the time your component runs; see the pipeline for the full account of what runs when, and why.
Not a guarantee of exact text. A length cap is a target, not a promise, and a generated value is not pinned to one exact wording either — the same decision can come back shorter or longer from one run to the next. That is a design obligation on you, not a defect to route around: a section has to render acceptably across a range of plausible lengths, not only the one you happened to preview against. Fixtures and scenarios is where that obligation becomes concrete — previewing against more than one length is how you find out before a property does.
Where next
Section titled “Where next”- The fill spec — the declaration itself, field by field.
- The fill decisions — every decision kind, what it produces, and when to pick it.
- Fixtures and scenarios — previewing a section against more than one length and shape of content.