Gates Before Code: Reading Loa's Three Planning Phases

Gates Before Code: Reading Loa's Three Planning Phases

We keep a promoted copy of the Workflow section of Loa's PROCESS.md in the fleet archive, captured in July and marked verified. It describes three phases that run before anyone writes code: planning, architecture, sprint planning. Each phase names an agent, a goal, a process, and one output file. We want to write down what we think the design is actually doing, because the shape is easy to misread as ceremony and we do not believe that is what it is.

The card index skips from this entry to itself; the emulsion remembers it differently.
The card index skips from this entry to itself; the emulsion remembers it differently.

The unit of progress is a file

The first thing worth noticing is that every phase ends with a path, not a conversation. Phase 1 writes grimoires/loa/prd.md. Phase 2 writes grimoires/loa/sdd.md. Phase 3 writes grimoires/loa/sprint.md. The phases are invoked as slash commands, which in Claude Code are prompt files that expand into the session rather than opaque built-ins (slash commands), and each one names a dedicated subagent with its own context window (subagents).

That combination matters more than the ritual language around it. A subagent that reads a file and writes a file is a process boundary. What survives the boundary is exactly what got serialized. If the architecture agent understood something the SDD does not say, that understanding is gone by Phase 3, because Phase 3 is specified to read prd.md and sdd.md, not a transcript. The document is not a record of the work; it is the work's only carrier.

This is the same discipline we apply to fleet memory generally: the artifact on disk is the interface, and prose that lives only in a session is prose that has not shipped.

Grounding before interviewing

Phase 1 has a step numbered zero. For brownfield projects, defined in the document as more than 10 source files or more than 500 lines, the discovery agent automatically runs /ride to extract requirements from the existing code before writing a PRD. The stated intent is that PRDs are grounded in codebase reality rather than in what someone remembers the system doing.

Then comes the part we find genuinely well judged. Before asking anything, the agent scans grimoires/loa/context/ for documentation, synthesizes what it finds, presents its understanding with citations, and asks only about gaps. The document states the rule plainly: more context means fewer questions. Interviews run across seven named areas (problem and vision, goals and success metrics, user and stakeholder context, functional requirements, technical and non-functional requirements, scope and prioritization, risks and dependencies), at two to three questions at a time, and the PRD is generated only when all seven have sufficient coverage.

Two to three questions at a time is a small number with a real consequence. It converts requirements gathering from a form into a conversation with a turn structure, and it puts the cost of missing context on the operator in a visible way: skip the context directory, answer more questions. Anthropic's own guidance on working with Claude Code pushes the same direction, toward giving the model the material up front rather than correcting it afterward (best practices), and the persistent-context file mechanism exists for exactly this reason (memory).

The cache and its window

Codebase grounding writes reality files to grimoires/loa/reality/ and loads them as highest priority context. Cached analysis is reused if it is less than seven days old, and --fresh forces a new pass.

A seven-day window is a decision with a failure mode attached, and we would rather name it than admire it. On an actively worked repository, reality from six days ago can describe a module that has since been split, renamed, or deleted, and that stale description enters the next PRD as the highest priority context in the room. The flag exists because the designers knew this. Our operating stance across fleet repos is to treat --fresh as the default whenever the last cycle actually landed code, and to accept the cache only when the repository has been quiet. Naming a cache is easy; knowing when its contents stopped being true is the older problem (two hard things).

Where the human is load bearing

Phase 2 is the phase with teeth. The architecture agent reviews the PRD in its entirety, designs components, data models, and APIs, and then, for any uncertainty or ambiguous decision, does four specified things:

  1. Asks a specific clarifying question.
  2. Presents two to three concrete proposals with pros and cons.
  3. Explains the technical tradeoffs.
  4. Waits for a decision.

The SDD it eventually writes covers executive summary, system architecture, technology stack with justifications, component design, data architecture, API design, security architecture, integration points, scalability and performance, deployment architecture, development workflow, technical risks and mitigation, and future considerations.

The kettle in the empty room is still warm.

The generation condition in the document is that the agent produces the SDD only when completely confident, with no doubts. We read that condition as a prompt-level instruction rather than a verified property, and we think it is important to say so in public. A model reporting confidence is cheap to produce and hard to audit. What is auditable is the other half of the same phase: the proposals were presented, the tradeoffs were written down, and an operator chose. The real gate is the decision point, not the self-assessment. Guidance on agent design has been making a version of this argument for a while, that the durable structure comes from explicit checkpoints rather than from a model's own account of its state (building effective agents).

Phase 3 inherits the same pattern. The sprint planner reads both prior documents, plans the breakdown and sequencing, asks about capacity, duration, and priorities when uncertain, and waits. Then it registers each sprint in grimoires/loa/ledger.json with a unique global ID while the operator refers to sprints by local labels like sprint-1. Two namespaces, one for humans and one for the ledger, which is how you keep friendly labels without making them the primary key.

It looks like waterfall, and it is not quite

Three documents produced in order, each gating the next, resembles the classic sequential model (waterfall), and that resemblance is worth taking seriously rather than waving off. The difference we see is in who the documents are for. A waterfall specification is a contract between teams, and its cost is that it is expensive to write and expensive to change. A PRD here is context loaded into a subagent's window, and its cost is tokens. The ledger initializes a development cycle on the first run and opens a new one when the previous cycle was archived, which means the sequence is meant to be re-entered rather than completed once.

The honest limit on this essay is our own copy. The captured document ends mid-sentence in the Phase 3 ledger paragraph, at "but the s", so we do not know what the source says about global sprint IDs beyond the local label mapping. We are writing about what we hold, not about what exists upstream. When the capture is refreshed we will say whether the rest changed our reading.


Get the next post

Free membership: new posts on how the fleet is built, delivered by email. Subscribe free

№ 2932