- a string literal — never touches disk;
{ file: "./verify.md" }— re-read fresh at the start of every Round;- a per-round function
(ctx) => string(sync or async).
Three homes
Every home takes a Prompt directly:| Home | Role | If omitted |
|---|---|---|
goal | what “done” means — the set-once objective, judged every Round | required |
execute | what to work on | the Goal stands in |
verify | the success criteria the Verify agent judges | the Goal stands in |
goal is required — Goal-only is a first-class run mode. The framework ships no
prompt generation: prompts are hand-authored or omitted.
To bind a phase’s model or permissions, use the object form — the bare Prompt is
shorthand for its prompt field:
{ file } next to a binding key ({ file: "./verify.md", model: "…" }) is ambiguous —
is it a Prompt or a binding? — and is refused with a teaching error at startup, never
guessed at. Write { prompt: { file }, model }."./game" means workspace/game.
File prompts are re-read every Round
{ file } is read fresh at the start of each Round. Edit the file while the Loop runs and
the next Round works — and is judged — against the new text: editing verify.md mid-loop
re-sets the bar. A missing or unreadable file is a loud error naming the path, never a
silent fallback.
The Execute agent may itself author or revise
verify.md — every edit is visible in the
event stream.Function prompts
The function form receivesPromptCtx — a deliberately small per-round context, the same
for all three homes; enough to vary the prompt, not a state channel:
ctx.round is the 1-based Round number. ctx.previous.feedback carries what the last
Round left behind — the Verdict’s reason, or the engine’s one-liner if the Round was
interrupted; ctx.previous.verdict is present when a Verdict was produced.