Course · Pi · Getting started
Understand one turn of the Pi loop
You’re authenticated, sitting at a live prompt inside stash, the course’s running example, a small FastAPI feed reader (install and bring your own key get you here if you’re starting fresh), and the date bug behind your mis-sorted reading queue is right there. Hold off for two minutes anyway. If you’ve spent any time with Claude Code or Codex, you already have a mental model of “the agent loop” - read, propose a plan, wait for you to say yes, then apply. Four beats. Watch this lesson for the pause between “propose” and “apply”; it never comes. Pi’s loop has three beats, and the one it drops is the one you’re used to trusting.
Make your first turn a question
Section titled “Make your first turn a question”stash is new to Pi too - it knows nothing about the codebase it hasn’t read yet. A read-only question costs you nothing and shows you exactly how the loop behaves before you ever ask it to change something:
> what does this service do, and where do saved articles get their dates from?
bash: rg -l "date" stash/ → stash/extract.py stash/feeds.py stash/models.py
read: stash/extract.py read: stash/feeds.py
stash is a small FastAPI feed reader - you sync a feed, it fetches the XML, pulls out each entry's title, link, summary, and updated date, and stores the rows in SQLite. Dates flow through feeds.py into parse_date() in extract.py, which tries two strptime formats and returns None if neither matches - so a date carrying a timezone offset never parses at all. That's almost certainly where your queue-sorting bug lives.Watch what one turn actually bought you. Pi didn’t guess from the prompt - it ran a real shell command to find files that mention dates, read the ones that looked most relevant, and came back with an answer and a lead on your bug. Gather context, then answer: that’s the loop, once, with nothing written and nothing run that could touch your data. It used the same tools it will use for the real fix.
The loop, stripped to its mechanism
Section titled “The loop, stripped to its mechanism”Stated as plainly as it can be: the model responds, any tool calls it made get executed, the results go back into the conversation, and the model responds again. It repeats for as long as it keeps calling tools, and it stops the moment a response comes back with none. There’s no step counter and no built-in ceiling on repeats. A five-line fix might close in one round trip; a gnarlier bug might take a dozen tool calls before the model has enough to work with.
Compare that to the four-beat shape you may already know - read, propose, approve, apply. Pi’s loop has three of those beats, not four:
- Gather - the model calls a tool (
bash,read) to see what it needs to see. - Act - it calls a tool that changes something (
write,edit, or abashcommand that mutates state). - Verify - often another tool call, checking the result of the last act - and if verification fails, straight back to gather, not a dead end.
The missing beat is approve. Nothing in that list stops and waits for your yes. By default, Pi has no permission gate at all - every tool call it decides to make, including ones that write files or run arbitrary shell commands, executes immediately, without asking. Read, propose, approve, apply collapses into gather, act, verify, and the step you’re used to trusting before anything happens on disk simply isn’t there.
Predict the next demo before you run it: a small fix, traced one step at a time, should show exactly gather → act → verify → done, with no fifth step anywhere that waits on you. Here’s that same shape on a fix that has nothing to do with stash yet, so you can check the prediction cleanly before spending it on the real bug. (The stepper’s tool labels are generic - run:, read:, edit:, reply: - standing in for Pi’s bash, read, edit, and a plain response; the shape is the point, not the labels.)
The stepper’s last note - every tool result staying in the window - is a real cost, and this lesson deliberately stops at naming it. What the accumulating window actually holds, and how to read it live down to the byte, is the observability lesson’s job, one chapter ahead. For now carry only the loop’s shape.
You’ve now watched the loop close once, cleanly, with nothing at stake, and you know its shape: gather, act, verify, repeat until it’s done. You also know the one beat it doesn’t have. Those are the two things to carry into the real fix - what it does when nobody stops it, and what it never does on its own, which is ask. Next: ship your first fix.