Course · Pi · Daily workflow
Assemble the harness
Every piece you’re about to see, you already built or sketched. This lesson doesn’t teach anything new - it’s the build log: the same directory you’d walk a new teammate through on their first day, with every file tagged back to the module that taught you to write it.
Here’s the claim, stated so you can check it yourself: of the 15 files below, most are finished and tested somewhere earlier in this course. A few are still just plans. Before you read past the tree, count them yourself - built (you wrote it, ran it, watched it work) versus design (the lesson sketched it and said, plainly, that it wasn’t done). Then read the walk below and see if your count matches.
stash/├─ .pi/│ ├─ APPEND_SYSTEM.md # stash's conventions, written once (module 3, built)│ ├─ settings.json # project config - routing, tool defaults (module 4, built)│ ├─ damage-control-rules.yaml # the DB/.env guardrail, in plain YAML (module 6, built)│ ├─ PLAN.md # the current unit of work (module 6, built)│ ├─ extensions/│ │ ├─ stash-tools.ts # /stash command + re-extract URL tool (module 5, built)│ │ ├─ damage-control.ts # blocks writes to stash.db and .env (module 6, built)│ │ ├─ tilldone.ts # blocks tool calls until one task is in-progress (module 6, design - not complete)│ │ ├─ plan-injector.ts # keeps PLAN.md in front of the model (module 6, built)│ │ └─ statusline.ts # live footer: model, context %, cost (module 6, built)│ ├─ prompts/│ │ └─ triage-fetch.md # the recurring triage pass, /triage-fetch (module 7, built)│ ├─ skills/│ │ └─ onboard-content-source/│ │ └─ SKILL.md # "wire up a new content source" procedure (module 7, built)│ ├─ themes/│ │ └─ stash-dark.json # the one purely cosmetic file in here (module 7, built)│ └─ agents/│ ├─ verifier.md # read-only child that checks the builder (module 8, built)│ ├─ reextract-chain.yaml # the batch re-extraction chain (module 8, design - Pi doesn't run this file on its own)│ └─ expertise/│ └─ extraction-lead.md # what the extraction lead learned (module 9, built)└─ (the actual stash codebase)Nothing in that tree is exotic. It’s markdown, YAML, and a handful of small TypeScript files, all readable in one sitting - which is itself the point Pi has been making since module 2: a harness you can read in one sitting is a harness you actually trust.
The rules and the routing - what the agent knows before it does anything
Section titled “The rules and the routing - what the agent knows before it does anything”APPEND_SYSTEM.md is the first thing loaded, and it’s where stash’s facts live once and stop needing repetition: the readability extractor’s known failure modes, the fetch worker’s rate-limit rules, how feed dates get normalized, which tags are reserved. Module 3 is where this file was born; here it’s just present, doing the same job it always did.
settings.json is where the routing from module 4 lives - cheap model for bulk re-extraction jobs, a stronger model for anything touching the search index or the fetch worker’s retry logic. If a local model is in the mix for throwaway grunt work, its practical context ceiling is a known, accepted limit here, not a surprise discovered mid-task.
The extensions - the features Pi didn’t ship, built on purpose
Section titled “The extensions - the features Pi didn’t ship, built on purpose”stash-tools.ts is the first extension you wrote - the /stash command and the re-extract tool, still the most-used thing in the directory because it turned a repeated chore into one keystroke. Built, and proven by use.
The other four all came out of module 6, and they don’t all land the same. damage-control.ts blocks a write or a destructive bash call against stash.db or .env; the module’s own Try It has you write it, then watch the hard-stop actually fire against a real rm -rf. Built and tested. plan-injector.ts keeps PLAN.md in front of the model on every turn - the lesson shows the whole file, no elisions, nothing left for later. Built. statusline.ts replaces the default footer with one that tracks a running tool tally recomputed fresh on every render - also shown whole, also built.
tilldone.ts is the one that isn’t. It’s meant to block every tool call except its own until exactly one task is in-progress, with state rebuilt from session history instead of a side file that could drift - but its own lesson says plainly: “the real implementation must define tasks and rebuild it from session history,” which the snippet shown never actually does. That’s not this lesson being sloppy. It’s an honest flag left in place on purpose, and it’s still sitting there unresolved.
The skill and the verify loop - the no-code layer and the check that doesn’t trust you
Section titled “The skill and the verify loop - the no-code layer and the check that doesn’t trust you”skills/onboard-content-source/SKILL.md is module 7’s packaged procedure for wiring up a new content source into stash - no code, just the steps, shared with anyone who installs it the same way you did. prompts/triage-fetch.md and themes/stash-dark.json are the same module’s smaller wins: a recurring triage pass you invoke as /triage-fetch instead of retyping, and the one file in this tree that exists purely because you have to look at the thing all day. All three built, all three exercised in their own lesson.
agents/verifier.md is module 8’s reviewer - a persona file, not an extension, because the only lever it gives you is the file. It’s built: a real system prompt that decomposes “done” into falsifiable claims and checks each one against the builder’s actual session log. agents/reextract-chain.yaml isn’t in the same state - its own lesson calls it “a design sketch for a driver you write; Pi does not load this file automatically.” It’s a real, useful sketch of a control-flow shape. It is not a file that runs.
The team - for when one context genuinely isn’t enough
Section titled “The team - for when one context genuinely isn’t enough”agents/expertise/extraction-lead.md is what’s left on disk from module 9’s migration team. The personas themselves are cheap - frontmatter and a paragraph, spun up only when a job is big enough that a single agent juggling everything would be the actual bottleneck. What’s worth keeping between runs is the expertise file: what the extraction lead worked out about which of stash’s saved sites break the new extractor, so the next lead doesn’t start from nothing. Built, and already earning its keep across more than one run.
What holds it together - and what doesn’t yet
Section titled “What holds it together - and what doesn’t yet”None of these pieces talk to each other through anything magic - a settings file, some markdown, and a handful of TypeScript files that hook into the same handful of lifecycle events. Reconcile the count now: 13 of the 15 files above are finished and tested. Two are not - tilldone.ts and reextract-chain.yaml, both flagged as incomplete in their own lessons, both still sitting exactly where you left them. If your count came out differently, go back and check which tag you missed; the tree above is now the answer key.
That’s assemble’s own cost, and it’s worth naming plainly: seeing all fifteen files in one tree feels like the harness is done. It isn’t. Two of them are still promises, and a promise doesn’t fail loudly - it just sits there until the day you need it and it isn’t there. Next: the maintenance that keeps the other thirteen from joining it.