EP 12

I Moved the Finish Line


August 2026·5 min read·#decision#scope#architecture

At the end of EP 10, I wrote this:

"STATE B — the moment Pepper writes its own code — is the real finish line for Phase 0."

I went back on that sentence.


Finishing the STATE A pipeline

Once triage splits into six branches, each branch needs a hand to catch it. Building those hands was the rest of STATE A.

store — write to the Vault. An extractor (Flash-Lite) pulls the structure out of "Save GOOGL at $245," and a vault-writer embeds it and inserts it.

lookup — real-time external info. weather (wttr.in), calendar, web.search (Serper), bundled into a tool registry.

task — register something for me to do.

So far, fine. The problem was what came next.

"Tell me the weather and the exchange rate" — two intents. To handle them in order, you need a planner: an orchestrator that builds a plan, executes it step by step, and passes each step's result to the next ($ref).

I defined the planner types, stubbed out createPlan / executePlan, wired up the multi-step branch. And into the actual execution path, I wrote this:

if (triageResult.intents.length > 1) {
  responseText = 'Handling multiple things at once is coming soon!'
}

A stub. "Coming soon."

The moment I left one multi-step case as a stub, a bigger question came with it.


How far away was STATE B, really?

STATE B is Pepper building a function it doesn't have. It generates code, validates it in an isolated environment, and registers it into the system automatically.

That "isolated environment" was the problem. Standing up a sandbox like E2B, running Pepper's generated code safely, retrying three times on failure, and — when that fails — auto-creating a GitHub issue for STATE C: building all of that is weeks of work.

And for those weeks, my family can't use Pepper at all.

That's when I understood exactly what the temptation is, for a non-developer. You want to build the coolest thing first. Pepper writing its own code is the most thrilling scene in this whole project. That's why I called it the finish line in EP 10.

But a product that never ships isn't a product.


So I moved the finish line

I wrote the decision into the documents — context.md and the roadmap.

STATE B/C move to Phase 2. Phase 0 is redefined as completing STATE A.

Phase 0's success condition changed. From "Pepper writes its own code" to "Pepper becomes an app my family opens every day."

It felt like a retreat. I sat with it for a few days. But once the decision was written down, it became strangely clear. The document system I built back in EP 02 did its job again — when my thinking wavers, the document holds firm. The next session's version of me, and Claude Code, both moved on top of this decision without drifting.

Self-evolution is still the North Star. I didn't cancel it; I reordered it. What my family needs right now isn't a Pepper that grows on its own — it's a Pepper that gives them a briefing this morning.


Leaving the planner as a stub was the same decision

"Coming soon" isn't a cop-out. It's the same philosophy as STATE C — say honestly that you can't do something, but let that be the input for the next iteration. Multi-step went into the backlog, and in its place stands an honest sentence.

One thing at a time. One file, one function, one step. This project's rule held here too. Moving the finish line was part of that rule.

Now it's time to actually build — not the brain, but the app my family holds in their hands.