RunMirror
← All posts
TAB Forward — Chapter 4
Jun 30, 2026·12 min read

The Founder, The Calibrator, and The Customer

Or — how AI generates code at infinite speed, and why that only matters if a human is in the loop with the instinct to push back.

TABForwardRunMirrorBuildInPublicAInativeDevelopmentFoundersJourney

← TAB Forward — Chapter 3: I Built an $80,000 Product This Weekend for $20


The frame

Chapter 3 named the three roles that scale in an AI-native world: Orchestrator, Builder, Calibrator — with AI as the substrate beneath them. That's the model for teams.

Today I want to write about what happens when a single person plays all three at once — and what they build in a day.

The three roles compress into one seat. But the posture between them shifts, minute to minute, depending on what the moment asks for:

  • The Founder decides what to build and why it matters.
  • The Builder ships it.
  • The Calibrator verifies what the AI produced and pushes back when the tidy explanation isn't the true one.
  • The Customer — my own product's customer, sometimes literally me — receives what got made.

The Founder points at the horizon. The Calibrator refuses to move until the ground under the last step is verified. The Builder moves. The Customer decides whether it was worth it.

When you're one person with AI at infinite speed of code generation, you're switching between these postures dozens of times a day. The people who ship well aren't the ones who move fastest. They're the ones who know which posture the moment requires.

Today was a live demonstration.


What got built today

I want to log what actually shipped, because "AI helps you build fast" is meaningless without specifics.

1. RunMirror's Strava API compliance work.

Full audit of every Strava API call site in the codebase. Found and fixed two policy-visible issues before Strava reviewers would ever see them: an over-scoped OAuth request (profile:read_all we didn't actually use) and dead code referencing endpoints Strava is deprecating in September 2026. Deployed to production. Now our OAuth request is minimum necessary, and the dead code that would signal "planning to use deprecated APIs" to a reviewer is gone. Small, visible, meaningful.

2. A silent pipeline gap fixed system-wide.

The Race Wall feature (below) surfaced a bug that had been silently dropping GPS coordinates for enriched activities. Not for me — for everyone. Once diagnosed, we backfilled 7,528 activities across 10 athletes with coordinate data that had been present in the raw stream tables the whole time but never landed in the field the geocoder reads. The root cause fix went in too, so the leak is permanently closed for every activity going forward.

3. The Race Wall — RunMirror's newest feature.

A comparison view for the last four marathons a runner has completed. Mile-by-mile pace overlay. Mile-by-mile heart rate overlay. Synchronized cursors between the two charts so hovering mile 15 on pace lights up mile 15 on HR. Custom title strips showing race city, date, total time, and average pace or HR per race. Race Shelf UI to pick which races to compare (2 to 4). Six database changes, four new components, three new API endpoints. Live in production tonight.

4. An email to Strava.

A carefully written note to developers@strava.com — after our first reapplication was rejected — laying out three things: what our steady-state API usage actually looks like on their dashboard (averaging in the teens against a 4,000/day allowance), the two specific policy-visible tightenings from the audit, and one specific product question about athlete-purchased physical prints of the athlete's own data. Also asking to raise our athlete cap from 10 to 100 — a defensible step, not a leap.

Four things. In a day. Which brings me to the interesting part.


The Founder — deciding what mattered

Today started with the Strava rejection sitting on my desk from a while back. I'd stepped away from it for personal reasons and hadn't come back with energy. When I sat down again, the honest question was: what's the actual next move?

The tempting answer was "reapply louder." Longer email, more explanations, ask for more athletes.

The Founder posture said: no, that's motion without progress. The rejection wasn't personal, it was a form letter — a template Strava sends to a queue that's grown 448% year-over-year. Another louder email lands in the same queue. What separates a reapplication from the pile is evidence of change, not volume of argument.

So the Founder made a decision: before we resubmit, we audit ourselves against every one of Strava's four common rejection reasons, fix what we find, and only then ask again — with proof.

That reordered everything. Audit first, email second, feature work third. Every hour spent on a new feature before the audit was an hour spent on something whose foundation we hadn't yet verified.

That decision took thirty seconds to make and shaped the entire rest of the day.


The Builder — moving at the speed of the substrate

Then Claude Code took over.

I handed Sonnet a scoped audit prompt: grep every Strava API call site, check incremental sync, streams caching, rate-limit handling, deauthorization, token refresh, response-error handling, over-scoped credentials, deprecated endpoints. Twelve minutes later I had a full markdown report with a call-site inventory, findings organized by priority, and specific line-number references.

I read it, picked the two P0 fixes (scope minimization and dead-code removal), and handed Sonnet a tight surgical prompt: three files, one commit, no scope creep. Ten minutes later it was committed, deployed, and live. Then the audit-informed email to Strava — one draft, minor revisions, sent.

Then we started The Race Wall.

Eleven tickets. Marathon detection, splits extraction, race shelf UI, comparison charts, pattern engine, strategy bullets, launch verification. Each ticket got its own Claude Code session. Each session ended with a verification step. Between each, I reviewed the output, spot-checked the data, approved or corrected, then handed the next ticket.

The speed felt inhuman. Data model, API endpoint, chart component, pattern engine — each an hour or two of previous life, each a session or two today. Sonnet wrote the actual code and tested it against real data; I checked its math on Cincinnati mile 7's elevation gain myself, walking through 23 GPS points by hand and confirming it was physically consistent.

That is what infinite speed of code generation looks like. It's real. It's here.

And it's exactly why the third role matters more than the first two.


The Calibrator — the sub-move nobody talks about

Everyone says "verify AI output against the data." That's Chapter 3 material now. Table stakes.

Today I learned a sharper version. Two of them, actually.

Calibrator sub-move #1 — verify the explanation, not just the output

The Race Wall's race cards were rendering "MARATHON" for every race instead of the city names. I asked Sonnet what was going on.

Sonnet ran a diagnostic and came back with a tidy story: Strava's map privacy setting strips coordinates from the API response even under our scope. The activities have their maps set to private, so Strava is withholding the location data. Two paths forward — change the Strava privacy setting, or manually patch the DB.

The explanation was confident. It was consistent with the data Sonnet had queried. It came with two supporting facts (visibility inference plus proportion counts across the athlete's other activities). And it offered clean options.

It was also wrong. And there was no way to tell it was wrong from inside the explanation itself.

The Calibrator sub-move was not "reject Sonnet's diagnosis." It was: "Sonnet has made a specific empirical claim about how a third-party system behaves. Have we verified that claim, or inferred it? Let's verify."

I wrote a diagnostic prompt asking Sonnet to hit three different Strava endpoints and empirically test the claim.

Sonnet came back a few minutes later with the empirical results:

  • The activity detail endpoint did return coordinates.
  • The streams endpoint did return coordinates.
  • The "map-private" marathon turned out to have visibility: 'everyone'. Not private at all.
  • location_city was null on public activities too.

The actual bug wasn't Strava's privacy behavior at all. It was our own enrichment pipeline silently dropping coordinates that Strava had freely given us. We were losing data we already had.

The tidy explanation had been the opposite of the truth.

The rule I'm walking away with: any time the AI offers a root cause that hinges on how an external system behaves, ask for the empirical test before you accept the causal chain. Don't settle for the tidy story.

Calibrator sub-move #2 — the fix is often bigger than the presenting symptom

The bug affected 4 race cards on The Race Wall. Sonnet's first proposed fix was a 4-row SQL patch — populate start_lat and start_lng for those 4 specific activities, ship The Race Wall today.

The Calibrator asked one more question: what about all athletes? What's the actual scale of this?

The answer: 7,528 activities across 10 athletes. Silent data loss on the same pipeline path for everyone who had ever used RunMirror. One athlete had 87% of their activities affected — their persona engine had been running on partial data since they signed up.

If I'd accepted the 4-row patch, The Race Wall would have shipped correctly tonight. And seven thousand five hundred and twenty-four other activities would still be silently broken tomorrow.

When you find a bug caused by a systemic gap, fix the systemic gap, not just the presenting instance.

That's what shipped. The pipeline is repaired. The 7,528-activity backfill is complete. Every athlete's data is now more accurate than it was this morning.


The Customer — receiving your own work

RunMirror's first customer is me. I built it because I wanted a mirror for my own thirteen thousand miles of running. Ten other athletes have connected since. That's the entire customer base as of today.

When The Race Wall shipped tonight, I clicked into it as a runner, not as a founder.

The page rendered. My four marathons — Cincinnati (Flying Pig, May 2026), New York City (Nov 2025), Milwaukee (Oct 2025), and a Snoqualmie Valley race (Jun 2026) — laid out mile by mile. Pace lines overlaid. Heart rate lines overlaid. City names, race times, average pace or HR, colored coded so you can hold three data streams in your head at once.

And there was Cincinnati — my most disciplined race, 4:14:20, average HR 159. And there was Snoqualmie next to it, 4:35:31, average HR 158. Twenty-one minutes slower on essentially the same heart rate. Same effort, one race twenty-one minutes faster than the other.

That's the moment where the founder disappears and the customer receives the work. I already knew Cincinnati was my best marathon. I did not have a way to see — in one glance, on one page — that the difference between my best and worst marathon wasn't fitness. It was pacing decisions. Twenty-one minutes of decisions.

That's the reason to build any of this.


What this session cost, honestly

Straight from Claude Code's own usage log:

  • Wall time: 5 hours 46 minutes.
  • Actual model compute time: 1 hour 46 minutes. The difference — four hours — is me reading, verifying, deciding, pushing back.
  • API cost: $21.15. Almost entirely Claude Sonnet 4.6 in Claude Code. (Strategy and drafting in claude.ai runs on my Claude Max subscription, so no additional marginal cost there.)
  • Code changes: 2,228 lines added, 223 lines removed. Net +2,005 lines of production code.

For a shape-check: the same session, done by one engineer without AI, would have been a solid week and a half. Sonnet alone couldn't have done it either — it needed the Founder to point, the Calibrator to push back, the Customer at the end to receive it.

Twenty-one dollars. Four features. One systemic bug quietly repaired for every athlete on the platform. A new feature shipped end to end. An email to a partner ecosystem written with real evidence behind it.

That's not a ratio I can imagine from any prior era of software.


What I'm walking away with

The framework I wrote about in Chapter 3 — Orchestrator, Builder, Calibrator — held up under a full day of real work. But I learned something I hadn't articulated yet:

The Calibrator has sub-moves, and they matter more than the surface-level idea of "verify AI output."

  1. Verify the explanation, not just the output.
  2. Watch for tidy stories that hinge on unverified empirical claims about external systems.
  3. When you find a systemic gap, fix it globally, not just where it presented.
  4. Trust the substrate. Distrust the story you're being told about the substrate.

None of these are hard to say. All of them are easy to skip when you're moving fast and the AI's answers sound right.

Today I almost changed my Strava privacy setting to fix a bug in my own code. That would have taken me down a road with no return. What saved it wasn't intelligence — it was a posture instinct. Sonnet's explanation was too tidy for the mess I know software actually is. The Calibrator noticed the mismatch and asked one more question.

That instinct is what human founders bring that infinite-speed code generation doesn't. Not smarter reasoning, not better memory, not faster typing. Instinct about when something is too clean to be true.

The AI generates code at inhuman speed. The human's job is to know which posture the moment requires, and to hold the line when the tidy story would have carried the day.

Founder → Calibrator → Builder → Customer. In and out, minute by minute, until the work is real.

That's what today looked like.


RunMirror is live at runmirror.app. The Race Wall shipped tonight. If you're a long-tenured runner and you want to see who your running has made you, connect your Strava and take a look. And if you're building anything alone with AI as your substrate — write down your Calibrator sub-moves as you find them. They're the actual craft.

#TABForward #RunMirror #BuildInPublic #AInativeDevelopment #FoundersJourney


→ Next chapter coming soon

Try RunMirror

See what your running data says about you.

Connect Strava. Get the 60-second story of who you really are as a runner.

Open RunMirror →