ESCAPE VELOCITY · SESSION 2 HANDS-ON WORKSHOP · SUMMER 2026

Building
agentic
harnesses

Two flights in one afternoon: first the harness that makes an agent worth trusting — then what happens when that harness starts maintaining itself.

RISHI DEAN · github.com/rishidean/pedal
THE AGENDATWO PARTS · ONE ARC

Two flights, one afternoon.

Part one is the harness you can run tomorrow. Part two is where it goes.

Part one · Getting airborne
The harness
Build a loop you can leave running unattended.
01
Where we left off — a 60-second recap of the keynote.
02
The double loop — the system, taken apart piece by piece.
03
Your turn — clone it and run the loop yourself.
04
Looking ahead — what airborne means — and the one ask.
Break
Part two · Breaking atmosphere
Adaptive software
What the harness becomes when it writes itself.
01
Where we left off — the harness, in one breath.
02
Jet fuel is expensive — Dhaka 2019, and the three cracks.
03
The three inventions — layered context, pipeline, determinism.
04
One loop — the flywheel, and why it compounds.
05
Watch the code get written — the live demo.
06
The frontier — what's flown, and what hasn't — yet.
07
What the rocket was built for — compiling the company, plus the ask.

Part one builds the harness — part two is what happens when the harness starts writing itself.

github.com/rishidean/pedal  ·  Self-paced2
DEVELOPING WITH AGENTIC WORKFLOWS HANDS-ON WORKSHOP · JUNE 2026

Getting
airborne

Demystifying agentic engineering, so we can leave the "ground" and "take flight" on the AI Adoption Continuum

RISHI DEAN · github.com/rishidean/pedal
HOW TO READ THISSELF-PACED

Mapping the flow.

Read straight through, or jump to the part you need.

Part 1
Where we left off
A 60-second recap of the keynote.
Part 2
The double loop
The system, taken apart piece by piece.
Part 3
Your turn
Clone it and run the loop yourself.
Part 4
Looking ahead
What airborne means — and the one ask.
Appendix · jump ahead
Why it works
The theory under the loop — five ideas.
Extending this model
From solo to org — the four moves.
Making it run
The actual files, and how to run it.

Every claim here is runnable — the repo builds a real app, unattended.

github.com/rishidean/pedal  ·  Self-paced4
A quick caveat

This is one way.
Not the way.

There are many ways to build agentic loops. This is a simplified version of what I do.  The tools are moving fast, and some of this may even be outdated by the time you finish reading this deck!

Take the principles, not the syntax. The shape of the loop matters more than which file does what.

github.com/rishidean/pedal  ·  Self-paced5
HOW TO READ THE DEMOMINIMAL REPRODUCIBLE CASE

The demo is a repro, not a product.

The app is deliberately trivial, so that the loop is the only variable.

What’s under test
The loop — spec, build, verify, document, state in files. Not the app it happens to produce.
Why it’s small
You strip a system to the smallest thing that still shows the behaviour. Standard practice. Nobody answers a repro with “too small, so the bug isn’t real.”
What scale adds
More context to route, more invariants to protect, more ways to be wrong. That changes the anchors (the deterministic checks; Part 2 names them) — not the shape of the loop.
What it can’t prove
That your worst-case bug is as cheap as mine. That one is real. It gets its own slide in Part 4.

Judge the mechanism first. Then argue about blast radius — I’ll make that argument for you.

github.com/rishidean/pedal  ·  Self-paced6
Part one

Where we left off

A sixty-second recap of the keynote — the continuum, ground vs. air, and how you operate. Then we fly.

What this answers: what the keynote established, and where today picks up.
github.com/rishidean/pedal  ·  Self-paced7
THE AI ADOPTION CONTINUUMRECAP · FROM THE KEYNOTE

Think of AI adoption as modes of transport.

{{ s.markerText }}
{{ s.icon }}
{{ s.num }}
{{ s.name }}
{{ s.desc }}
github.com/rishidean/pedal  ·  Self-paced8
THE AI ADOPTION CONTINUUMRECAP · FROM THE KEYNOTE

Six ways to move. Only some leave the ground.

95% of teams live here
THE 10X LIVE HERE
GROUND        AIR
{{ s.markerText }}
{{ s.icon }}
{{ s.num }}
{{ s.name }}
{{ s.desc }}
Ground — same work, faster Airborne — a different process
github.com/rishidean/pedal  ·  Self-paced9
How you operateRECAP · FROM THE KEYNOTE

The shift from player, to coach, to conductor.

Autocomplete
Player
You AI AI You
Linear. You in every step.
Agentic
Coach
You set goal Agent loops Plan Act Verify You review
Cyclical. You manage the loop.
Orchestration
Conductor
You set strategy Agent A Agent B Agent C Agent D You verify outcome
Systemic. You conduct the fleet.
github.com/rishidean/pedal  ·  Self-paced10
The jump we make today

From using agents to code, to building agents that code.

That's the ground-to-air jump — a different process, not a faster tool. The keynote drew the map. Today we fly the first leg.

github.com/rishidean/pedal  ·  Self-paced11
What you'll walk away with

Get
airborne.

By the end of this deck you'll understand a multi-sprint, self-verifying, autonomous development loop...and the means to run it yourself.

That system is the harness in the session title: the structure around the model that turns “an AI that can code” into a system that builds software.

github.com/rishidean/pedal  ·  Self-paced12
Part two

The double loop

Some files and a bash script. We'll take it apart piece by piece, and then watch it build an app, unattended.

What this answers: what the system is, and how it runs unattended.
github.com/rishidean/pedal  ·  Self-paced13
THE OPEN SECRET

Agentic Orchestration is a fancy term,        for some files +  a loop.

github.com/rishidean/pedal  ·  Self-paced14
WHERE THE INTELLIGENCE LIVES

We're shifting the burden from the model to specification & scaffolding.

Model
The engine
Raw capability. Necessary, but the part everyone talks about.
+
Files
The judgment
Standards, specs, and memory. Where your engineering lives.
+
Loop
The discipline
Build, verify, document (repeat until done).

Take any one away and it stops working. And most of what makes it good isn't the model. It's the files (and what we'll cover in the rest of this deck.)

github.com/rishidean/pedal  ·  Self-paced15
WHAT WE MEAN BY AGENTIC

We're going to orchestrate the model to run in a loop.

Many are still thinking about "autocomplete", but they're very different.

It is — a loop
Sets its own intermediate steps
Calls tools to act, not just answer
Checks its own work
Loops until the goal is met
It isn't — a turn
Autocomplete on steroids
A chatbot you babysit turn by turn
“AI that writes code for you,” one prompt at a time
github.com/rishidean/pedal  ·  Self-paced16
TWO THINGS MODELS DO

It can generate, or it can call.

Only one of these can hallucinate. Knowing which is what makes the loop trustworthy.

Generate can hallucinate
Text from weights
The model writes the most plausible next tokens from what it learned. Brilliant for synthesis and code — and the only place a guess can sneak in.
promptmodelplausible text
Call returns a fact
A tool runs, for real
The model emits a structured request; a deterministic system runs it — code, a search, a test — and hands back ground truth the model then reads.
requesttool runsfactmodel reads

In a loop, most of the work is tool calls returning ground truth not the model free-associating. run-qa’s Playwright test actually ran; the model didn’t decide it passed. A call is an anchora result that can’t be argued with.

github.com/rishidean/pedal  ·  Self-paced17
THE PRIMITIVES

A few words to help speak the language.

New to Claude Code? Everything that follows is just some form of these terms.

Session
One run of Claude Code. Fresh memory every time. Nothing carries over.
Context window
The working memory a session holds at once. Finite. Fill it and quality drops.
CLAUDE.md
A context file Claude reads automatically at the start of every session.
Task tool
How a session hands a job to a subagent — and gets the result back. It's how run-qa calls its three agents.
Skill
A reusable procedure Claude can invoke by name — like run-qa.
Command
A saved prompt you trigger with a slash — like /review.
Subagent
A scoped helper for one narrow job. Often a cheaper, faster model.
github.com/rishidean/pedal  ·  Self-paced18
THE SYSTEM

Three parts that mirror what we do IRL.

Overview · the three stages
This map recurs — the next three slides zoom into one stage each.
{{ c.tag }}
{{ c.title }}
{{ it }}
github.com/rishidean/pedal  ·  Self-paced19
THE TOPOLOGY

One loop inside another.

The outer loop marches through sprints with a fresh brain each time. The inner loop is one session: build → verify → document.

GREEN = passed, ship it · RED = failed, fix & re-run (max 3)
Outer loop · run.sh — marches through sprints, fresh brain each turn
Sprint 1
Sprint 2
Sprint 3
…until done
Inner loop · one session
Build
the feature
Verify
QA crew → GREEN / RED
Document
tick manifest, handoff
↺  RED → fix → re-verify  (max 3 attempts, then stop)
github.com/rishidean/pedal  ·  Self-paced20
THE TOPOLOGY · BY FILE

How the loop is built in practice.

Same loop as the previous slide — now wired to the real filenames.

Outer loop · marches through sprints, fresh brain each turn
[script] run.sh docs/Roadmap.md → the manifest prompt.md → read each turn
Sprint 1
Sprint 2
Sprint 3
…until done
Inner loop · one session
the Builder → a fresh Claude Code session
Build
the feature
CLAUDE.md specs/booking/S*.md
Verify
QA crew → GREEN / RED
[skill] run-qa
[agent] linter [agent] code-reviewer [agent] playwright-tester
Document
tick manifest, handoff
docs/Roadmap.md → ✅ PROGRESS.md → handoff
↺  RED → fix → re-run [skill] run-qa  (max 3 attempts, then stop)
github.com/rishidean/pedal  ·  Self-paced21
THE LOOP OBJECTION WHERE THE LOOP LIVES

“I’m skeptical of loops.” You’re already running one.

There are only three places a loop can live. Declining to build one doesn’t delete it — it leaves it in the most expensive place.

03 · Driving · most teams
In your head
04 · Helicopter · you are here
In files
06 · Spaceship · the sequel
In the system
Who runs it
You, in real time
run.sh, from files
The system, from compiled rules
When you stop
It stops
It keeps going
It never needed you
Scales with
Your attention
Your specs
Your corrections
Where the gate goes
Nowhere — you are the gate
On the diff, every sprint
On the equivalence check

“Offloading a full task to an agent” is a loop too — someone else’s, with the control surface hidden. The one you can see is the one you can put a gate in.

github.com/rishidean/pedal  ·  Self-paced22
THE SYSTEM

The setup stage is for our specifications and agreements

Stage 1 / 3 · Setup
Why first: the system can't act until it knows the rules.
Setup
What it knows
Tech Lead
PM
Design
QA Lead
Actors
Who does the work
The Builder
QA Team (x3)
QA Manager
Orchestrator
What keeps it moving
Eng Manager
PM
github.com/rishidean/pedal  ·  Self-paced23
BROAD CONTEXT (CLAUDE.MD · PROMPT.MD)

How we work.

Everything true for every sprint: architecture, conventions, and the definition of done. One constraint forces quality —

"Not done until run-qa returns GREEN."
This is the scaffolding that earns the trust.
CLAUDE.md
# Project architecture & conventions
# Marching orders, every session
## Definition of done
Not done until run-qa is GREEN.
prompt.md
Read the manifest. Pick the next sprint.
Build it. Run QA. Update state.
# same instructions, every time
github.com/rishidean/pedal  ·  Self-paced24
THE MANIFEST (DOCS/ROADMAP.MD)

What needs to get done, where we're at.

One glyph per sprint — that's your state machine. The glyph flips after each sprint. Stuck work marks and stops.

This file is your project status.
🔲  not started   done   blocked — stops for a human
docs/Roadmap.md
## Sprints — Booking
S1 — App Setup and Shell
🔲 S2 — Ride Request
🔲 S3 — Ride Lifecycle
S2 starts only after S1 passes.
github.com/rishidean/pedal  ·  Self-paced25
How to decompose · docs/Roadmap.md

Slice it vertically, not horizontally.

Weak · horizontal layers
# Roadmap
- [ ] Build all data models
- [ ] Build all API endpoints
- [ ] Build all UI screens
- [ ] Wire it together
- [ ] Test everything
Nothing runs until the very end. No verifiable step — nothing for QA to gate.
Good · vertical slices
# Booking · vertical slices
S1 The shell runs a real app boots
🔲 S2 A rider gets matched on top of S1
🔲 S3 A full ride completes needs S2
Each slice ships a working app, ordered by dependency. 🔲 ✅ ⛔ legible at a glance.
github.com/rishidean/pedal  ·  Self-paced26
SPECIFIC CONTEXT (SPECS/BOOKING/S*.MD)

What to build this turn.

One spec per sprint: acceptance criteria, technical approach, edge cases. This is where your engineering judgment lives.

At Driving you write code. At Helicopter you write specs.
specs/booking/S1-App-Setup-and-Shell.md
# Booking S1 — App Setup and Shell
## Acceptance criteria
· App boots to destination entry
· State survives refresh (pedal.ride.v1)
## Approach
· Vite + React + TS strict · typed reducer · fixtures
## Edge cases
· Invalid stored state clears — never crashes
github.com/rishidean/pedal  ·  Self-paced27
Where judgment lives · S2-Ride-Request.md

A good spec makes the build trivial.

Thin · vague
# S2: Ride Request

Let riders request a pedicab
and get matched to a driver.
No criteria. No edge cases. The build is a guess; QA has nothing to assert.
Fat · explicit
# Booking S2: Ride Request
## Acceptance Criteria
- estimate (4 min · $18) shows before request
- matching is its own visible state
- assignment: Maya Chen · PEDAL 14 · ETA 3 min
- state survives refresh (pedal.ride.v1)
 
## Watch out for
- exactly ONE matching timer may assign (BR-007)
- a storage failure must fail closed (BR-016)
Explicit criteria + the trap to avoid. The build is trivial; QA is decisive.
github.com/rishidean/pedal  ·  Self-paced28
THE SYSTEM

Now, it's time to build.

Stage 2 / 3 · Actors
Why next: someone has to do the work — and check it.
Setup
What it knows
Tech Lead
PM
Design
QA Lead
Actors
Who does the work
The Builder
QA Team (x3)
QA Manager
Orchestrator
What keeps it moving
Eng Manager
PM
github.com/rishidean/pedal  ·  Self-paced29
THE BUILDER
builder · sprint session
$ claude -p "$(cat prompt.md)"
reading context…
building feature…
writing index.html

Executes the spec for a single  feature / sprint. Then done.

The Builder is just a Claude Code session — no special framework, no persistent agent. Spun up fresh for one sprint, then thrown away. Its power is that nothing carries over.

Stateless
Clean brain every turn — no context rot from the last sprint.
Self-checking
It calls run-qa on its own work before it ever declares done.
Hands off
Writes its memory to PROGRESS.md so the next session can pick up.
github.com/rishidean/pedal  ·  Self-paced30
THE QA MANAGER

When code is complete, the 
manager delegates the QA tasks

One call — run-qa — runs all three QA agents and returns a single verdict: GREEN or RED. RED three times and it stops for a human.

run-qa
Lint
Review
Test
GREEN
↺  RED → read failures → fix → re-run
max 3 attempts, then mark blocked & stop
.claude/skills/run-qa/SKILL.md
---
name: run-qa
description: Full QA pass — lint, review,
  e2e. Returns one GREEN/RED verdict.
---

# run-qa
Run these in order, each as a subagent:
1. Delegate to linter.
2. Delegate to code-reviewer.
3. Delegate to playwright-tester.

Verdict: any lint error, CRITICAL
finding, or failed spec → RED.
Otherwise → GREEN.

If RED: fix, re-run from step 1.
Stop after 3 attempts; report to human.
github.com/rishidean/pedal  ·  Self-paced31
THE QUALITY TEAM

Each team member has a very specific job.

.claude/agents/They check, they don't build — cheaper, faster models.
This is the scaffolding that earns the trust — the answer to the doubt loop from Part 1.
Every verdict is a contract — GREEN / RED · CRITICAL / WARN / NIT — a shape the next step consumes, never prose.
Judgment · latent vs Verification · anchored Two anchors and one opinion — lint and tests are deterministic; the reviewer is a fresh-context judgment, and the anchors outrank it.
{{ q.mark }}
{{ q.name }}
{{ q.model }}
{{ q.job }}
{{ q.snippet }}
{{ q.file }}
github.com/rishidean/pedal  ·  Self-paced32
THE INNER LOOP

RED doesn't stop the loop — it routes back to the Builder.

On RED, the verdict carries the actual failures — the Builder reads them, patches, and re-runs. Three attempts, then it stops. RED isn't an opinion — it's a failed assertion; the fix targets a fact, not a feeling.

RED → read failures · fix · re-run
The Builder
Write & fix
Builds the feature. On a RED return, reads the failures and patches the code.
run-qa
Verify
Lint · review · test. Returns one verdict — and the failures with it.
RED loops back ↑
GREEN exits → Document
Three attempts, then it stops. Still RED after the third try → mark the sprint [!] blocked and hand back to a human. Autonomous, never infinite.
github.com/rishidean/pedal  ·  Self-paced33
THE SYSTEM

Close the sprint, and move to the next.

Stage 3 / 3 · Orchestrator
Why last: something has to keep the sprints moving, hands-free.
Setup
What it knows
Tech Lead
PM
Design
QA Lead
Actors
Who does the work
The Builder
QA Team (x3)
QA Manager
Orchestrator
What keeps it moving
Eng Manager
PM
github.com/rishidean/pedal  ·  Self-paced34
KNOWLEDGE HANDOFF

On GREEN, the session writes itself down.

QA GREEN three writes — roadmap = state · PROGRESS = memory · CLAUDE = learning
01 docs/Roadmap.md
Tick the box. The state machine advances.
State
- [ ] Sprint 3: scaling cost
- [x] Sprint 3: scaling cost
02 PROGRESS.md
Append a handoff for the next session.
Memory
## Sprint 3
scaled hire cost.
spend bug → fixed
(guard the spend)
03 CLAUDE.md
Promote durable learnings to permanent context.
Learning
## Gotchas
+ score must never go
+ negative — guard spend

A deliberate simplification. In production this handoff is a context-management system writing to several stores — here it’s one file per job, so you can read the whole mechanism in one sitting.

github.com/rishidean/pedal  ·  Self-paced35
THE ORCHESTRATORrun.sh

Ten lines. Dead simple by design.

#!/usr/bin/env bash
set -euo pipefail
MAX=4; n=0
while grep -q '🔲' docs/Roadmap.md && (( n < MAX )); do
n=$((n+1)); echo "=== turn $n ==="
claude -p "$(cat prompt.md)" || { echo "session error"; break; }
# permissions live in .claude/settings.json — no flags needed
grep -q '⛔' docs/Roadmap.md && { echo "blocked"; break; }
done
echo "done — $n turn(s)"
The distilled core. The real run.sh adds logging and scopes the count to the Sprints section.
github.com/rishidean/pedal  ·  Self-paced36
Part three

Your turn

Enough theory. A handful of files, one command, three sprints — run it yourself, now or later.

What this answers — how to run the loop on your own machine.
github.com/rishidean/pedal  ·  Self-paced37
STEP 1 · SET UPSTEP 1 / 4

Clone it. Set up. Three minutes.

git clone https://github.com/rishidean/pedal
cd pedal
./setup.sh # Playwright + Chromium, prereq checks
# auth: run `claude` once, or export ANTHROPIC_API_KEY
# prereqs, auth, and the contract live in README.md
The repo, top to bottom
pedal/
├── CLAUDE.md          # boundaries + "done = run-qa GREEN"
├── prompt.md          # marching orders, every session
├── PROGRESS.md        # handoff memory (starts empty)
├── run.sh             # the orchestrator (~20 lines)
├── docs/
│   ├── Roadmap.md     # the manifest / state machine
│   ├── Vision · Flows · BusinessRules
│   └── specs/booking/ # S1 · S2 · S3 — one spec per sprint
└── .claude/
    ├── settings.json  # permissions for unattended runs
    ├── skills/run-qa/SKILL.md  # the run-qa gate
    └── agents/           # linter · reviewer · tester
Three steps to your first run
1
Drop a CLAUDE.md into one service — your stack, your conventions, and the one line: done = run-qa GREEN.
2
Write a single spec for that mind-numbing weekly task.
3
./run.sh — and watch it go.
Before you run
Three real sprints — minutes each, not seconds
Real Claude Code sessions + subagents
Workshop → DEMO_MODE=planted ./run.sh
Clone the template
github.com/rishidean/pedal
github.com/rishidean/pedal  ·  Self-paced38
STEP 2 · RUNSTEP 2 / 4

One command. The loop writes the code.

$ ./run.sh # emergent run
$ DEMO_MODE=planted ./run.sh # guaranteed S2 RED → GREEN (planted matching bug)

A fresh session spins up for each sprint — it builds the feature, runs the QA gate, ticks the roadmap, and hands off. Then the next sprint starts with a clean brain. You write specs; the loop writes code.

Stuck or dirty repo?
$ git reset --hard harness # start over from the harness tag
README.md # prereqs, auth, the contract
github.com/rishidean/pedal  ·  Self-paced39
WHILE IT RUNS  ·  THREE SPRINTS

Now go hydrate.

A full run builds three real sprints — installs, tests, a real browser. Watch the console scroll by if you like, or step away, stretch, refill your water, and let the loop cook. It doesn't need you for this part.

// back in a few
github.com/rishidean/pedal  ·  Self-paced40
STEP 3 · WATCHSTEP 3 / 4

What one full run produces — no human at the keyboard.

$ DEMO_MODE=planted ./run.sh
 
  S1 App Setup and Shell: build -> run-qa ...
  S1: GREEN — shell boots, state survives refresh
 
  S2 Ride Request: build -> run-qa ...
  S2: RED — duplicate matching timer assigns twice (BR-007)
  S2: Builder reads the failure -> fix -> run-qa ...
  S2: GREEN — matching resolves once, driver card correct
 
  S3 Ride Lifecycle: build -> run-qa ...
  S3: GREEN — full ride, refresh-proof, resets clean
 
  ALL SPRINTS COMPLETE - 3 / 3 GREEN
The run, recorded · Booking S2 RED → GREEN

PLACEHOLDER — record the PEDAL proving run (GIF / MP4 frame): Booking S2 planted bug, RED → GREEN

github.com/rishidean/pedal  ·  Self-paced41
STEP 4 · PLAYSTEP 4 / 4

You didn't write a line of it.

$ npm run dev # then open localhost:5173 — add ?demo=1 for the ride controls

PLACEHOLDER — PEDAL screenshot from the proving run: driver card (Maya Chen · PEDAL 14) on the static city map

Pick the Ferry Building. Request. Watch matching resolve to a driver. Ride, then pay the driver directly. Three sprints, zero keystrokes from you.

github.com/rishidean/pedal  ·  Self-paced42
DEBRIEF

What just happened.

01
Stateless sessions, real progress. Continuity came from the files, not memory.
02
The gate caught a real bug. S2's matching timer assigned twice; the tester caught it, the Builder fixed it. The loop found it - not a model, nor a human.
03
Three sprints, zero keystrokes. You wrote specs; it wrote, tested, fixed, and documented.

The keynote’s thesis, running: specs made intent executable; the gate kept execution governed.

github.com/rishidean/pedal  ·  Self-paced43
LOW FLOOR  ·  HIGH CEILING EXTENDING THE LOOP

This is the seed. Extend it forever.

Every extension is the same shape — one small file in .claude/. Four moves take you from solo to enterprise; the depth is in the appendix.

Encode judgment
the loop writes its own inputs
Add a gate
raise the bar on GREEN
Add structure
scale breadth
Close the loop
durable & auditable
The loop
the seed
{{ iconHeli }} Helicopter (this repo) {{ iconJet }} Jet (a team) {{ iconSpaceship }} Spaceship (an org)
the four moves in full “Extending this model” (appendix)
github.com/rishidean/pedal  ·  Self-paced44
Part four

Looking ahead

What being airborne means for you, the team, and the org — and the single ask that starts it.

What this answers — what airborne means next, and the one ask.
github.com/rishidean/pedal  ·  Self-paced45
WHAT'S NEXT

How it spreads from here.

{{ p.who }}
{{ p.stage }}
{{ p.text }}
github.com/rishidean/pedal  ·  Self-paced46
THE CAPABILITY LADDER HELICOPTER → JET → SPACESHIP

Same craft. Three altitudes.

04 · This repo · You are here
Helicopter
05 · A team
Jet
06 · An org · The sequel
Spaceship
Context
One CLAUDE.md + one PROGRESS.md
Layered & indexed, shared by the fleet
Compiles and maintains itself
Execution
Sequential — one sprint at a time
Parallel — fan out, reduce, verify, synthesize
Self-routing — rule, nudge, or cold model
Verification
One QA gate per sprint
A fresh-context verifier on every edge
Equivalence checks graduate rules
Memory
State lives in files, per repo
Shared state + indexes across builders
Stable patterns compile out as rules
Cost
Full price, every run
Tiered — cheap nodes, strong judgment
Compiled paths run free
Control flow
You write the loop
You + the model draw the graph
The system draws its own
Sequential is a choice, not a ceiling. Everything in this talk is column one — learn the loop before you fleet it. Column three is the next talk.
github.com/rishidean/pedal  ·  Self-paced47
WHERE THIS FLIESKNOW YOUR BLAST RADIUS

Autonomy is priced by what a missed mistake costs.

Not by your seniority, and not by how complex the system is. By what happens when the loop is wrong and nobody notices.

Cheap to miss run unattended
Something below you holds the line
Types, the framework, the database, the platform enforce your invariants for you. The worst realistic bug is transient — restart, resync, gone.
mistakecaught by the floorrestart
Expensive to miss gate the diff
You are the invariant
Schema migrations, money movement, concurrency — anything that writes durable state. A missed mistake is silent and permanent, and no restart repairs it.
mistakedurableno undo

I work high in the stack, where the floor catches me — that is the fair version of the “toy” critique, and it was never that the example was small. The loop still runs down there. The gate just moves: a human on the diff, not on the keystrokes.

github.com/rishidean/pedal  ·  Self-paced48
WHAT AIRBORNE LOOKS LIKE

The secret is that there is no secret. It's just putting in the work. 

{{ s.markerText }}
{{ s.icon }}
{{ s.num }}
{{ s.name }}
{{ s.desc }}
Driving — the old way
{{ row }}
Helicopter — what the loop does
{{ row }}
github.com/rishidean/pedal  ·  Self-paced49
THE ACCELERATION

Each shift arrives faster than the last.

Walking
~ years
Biking
~ a year
Driving
months
Helicopter
now
Jet
The advantage compounds. The gap between Driving and Helicopter isn't closing — it's widening. In public: the Bun runtime port — ≈535K lines of Zig → 1M+ lines of Rust in 11 days, ≈$165K of usage against roughly a year of engineering. (The review-burden critique is real — and earned.)
github.com/rishidean/pedal  ·  Self-paced50
THE COST OBJECTIONTOKENS VS HEADCOUNT

You’re not buying tokens. You’re buying the headcount you didn’t add.

“An expensive way to spend tokens” prices the loop against zero. Nothing is priced against zero — price it against the person you’d have to hire.

The real baseline loaded cost
A day of senior attention: $1,500–2,500
Salary, benefits, overhead — before a single meeting eats it. The QA pass and the PM writing the ticket are the same currency.
taskheadcount$$$$
My actual bill measured, not modelled
A month of heavy use: $500–1,000
Hundreds of hours in Claude Code across a month of real work. Less than one engineer-day — at every corner of both ranges.
specloopverified sprint$
Cap first: one repo, twenty items  →  read the usage report  →  earn the scale, then double.

The honest limit: cost rides usage — at this altitude you pay full price on every run. That isn’t a rebuttal, it’s why Part 2 exists: compiling the stable paths until they run free.

github.com/rishidean/pedal  ·  Self-paced51
THE BUDGET OBJECTIONSEAT VS CAPACITY

$2.5M is only shocking if you booked it as software.

A thousand engineers at $2,500 a month is a real number. The question was never whether it’s big — it’s which line it belongs on.

Booked as a seat indefensible
$2,500 per user, per month
No tool is worth that, and it shouldn’t be. Sat next to Jira and a laptop it loses every time — and that is the comparison being made.
spendsoftware linerejected
Booked as capacity the right line
5–8% on top of a loaded engineer
Against $31K–52K a month of loaded cost, the bar is arithmetic: does it return more than 8%? And $2,500 is already 2.5× my actual spend.
spendcapacity line8% to clear

And the honest half: if the hours aren’t producing gains, it really is waste. Which is an argument for measuring it — not for skipping it.

github.com/rishidean/pedal  ·  Self-paced52
MY REQUEST OF YOU
90
days.

Every service gets a CLAUDE.md and a run-qa skill.

Pick the most mundane, repetitive task you do every week. That's your first candidate to automate. 

Where to start github.com/rishidean/pedal · scaffold the pattern into your own repo → ./scaffold-loop.sh
github.com/rishidean/pedal  ·  Self-paced53
TECH REFERENCES

Appendices

Optional reference, for those implementing. 

github.com/rishidean/pedal  ·  Self-paced54
APPENDIX A · THE THEORY

Why it works

Five ideas under the loop — optional reading. Every one resolves to a file you already ran.

github.com/rishidean/pedal  ·  Self-paced55
Why it works01 / 05

A skill stores a process, not content.

A skill file holds a procedure, not facts — how to do a recurring job: run the three checks, return one verdict. The method becomes reusable and versioned, kept separate from any single task it runs on.

that’s the skill SKILL.md / run-qa
github.com/rishidean/pedal  ·  Self-paced56
Why it works02 / 05

Subagents keep context clean.

Each subagent gets its own context window and exactly one narrow job. The reviewer never sees the builder’s scratch work; the tester starts fresh. Narrow scope means a cheaper model and no cross-contamination.

that’s the QA crew linter · reviewer · tester
github.com/rishidean/pedal  ·  Self-paced57
Why it works03 / 05

Fresh sessions beat a full context.

A model’s context is finite and degrades as it fills. So every sprint launches a new session with an empty window — the roadmap and PROGRESS files carry state forward, not the model’s fading memory.

that’s the clean brain per sprint docs/Roadmap.md + PROGRESS.md
github.com/rishidean/pedal  ·  Self-paced58
Why it works04 / 05

The loop improves itself.

When a session learns something durable — a gotcha, a convention — it writes it back into the broad context. The next session starts smarter. The system quietly edits its own instructions.

that’s the Document step promotes → CLAUDE.md
github.com/rishidean/pedal  ·  Self-paced59
Why it works05 / 05

Generate is latent. Verify is deterministic.

Generation is fuzzy by nature — synthesis, design, judgment. Verification isn’t: the assertion passes or it doesn’t. You never trust the model’s opinion of its own work; you run a tool that returns a fact. The gate is anchored: lint and tests are deterministic; the reviewer adds a fresh-context opinion — and anchors outrank opinions.

that’s why QA is a test a test, not a vibe check
github.com/rishidean/pedal  ·  Self-paced60
APPENDIX B · GOING FURTHER

Extending this model

The four moves in full — same shape every time, one small file in .claude/.

github.com/rishidean/pedal  ·  Self-paced61
Appendix · Going furtherThe four moves

Same shape, four directions.

Encode judgment
the loop writes its own inputs
·generate-roadmap
·spec-sprint
·plan-sprint  plan before build
Add a gate
raise the bar on GREEN
·security / a11y / perf
·planning approval
·PR-per-sprint + CI
Add structure
scale breadth
·epics → sprints → features
·the diamond: fan-out → verify → merge
·multi-repo
Close the loop
durable & auditable
·session-start / wrapup
·structured logs + cost
·knowledge base
Helicopter (this repo) Jet (a team) Spaceship (an org) full catalog EXTENDING.md
github.com/rishidean/pedal  ·  Self-paced62
Appendix · Going furtherEncode judgment · in depth

Add a PLAN phase.

Plan before you build — and, going further, before you spec.

pre-spec
runs once
intent
PLANauthor
docs/Roadmap.md + specs/booking/
approve
post-spec
per sprint
spec
PLANbuild
plan.md
approve
build
QA
document
The artifact · concrete
# specs/booking/S2.plan.md
 
files to touch — RideRequest.tsx, matching timer
order — request state → matching → assignment
approach — one scheduled assignment, cleared on fire
risksduplicate timer assigning twice (BR-007)
Four files, four jobs
roadmap = state
plan = intent
PROGRESS = memory
CLAUDE = learning
A plan is intent — its own slot, not jammed into memory.

Judgment moves up a rung — you approve plans instead of writing specs. That's the Jet step.

github.com/rishidean/pedal  ·  Self-paced63
Appendix · The principles

The principles, not the syntax.

Commands and flags change. What makes the output good doesn’t.

01
Plan before build. Decide the slice and the spec before a line of code.
02
Verify before done. “Done” means the gate is GREEN — never a feeling.
03
One job per subagent. Narrow scope, cheap model, clean context.
04
Fix, don’t ask. On RED, read the failure and patch — stop only when truly stuck.
05
Promote learnings. Write durable lessons back into the files so the next run is smarter.
This is my way — the syntax will change, but these don’t.
github.com/rishidean/pedal  ·  Self-paced64
APPENDIX C · THE FILES

Making it run

The key file types for this model, and to run the exercises

github.com/rishidean/pedal  ·  Self-paced65
APPENDIX · THE FILESFile 01 / 13

run.sh

The orchestrator — the outer loop (core trimmed for the slide; real file adds logging)
#!/usr/bin/env bash
# PEDAL outer loop. Dumb on purpose: all the
# intelligence is in the files it reads.
set -euo pipefail
MAX_TURNS="${MAX_TURNS:-4}"
# DEMO_MODE=planted swaps the S2 matching fixture first

for turn in $(seq 1 "$MAX_TURNS"); do
  if grep -q '⛔' docs/Roadmap.md; then
    echo "blocked (⛔). A human steps in. See PROGRESS.md."
    exit 1
  fi
  remaining=$(sed -n '/## Sprints/,/## Current Status/p' \
    docs/Roadmap.md | grep -c '🔲' || true)
  if [ "$remaining" -eq 0 ]; then
    echo "every sprint is done. Take the ride."; exit 0
  fi
  echo "── Turn $turn: $remaining sprint(s) left. Fresh session."
  claude -p "$(cat prompt.md)"
done
github.com/rishidean/pedal  ·  Self-paced66
Appendix · The FILESFile 02 / 13

CLAUDE.md

Broad context — true for every sprint
# PEDAL — Broad Context

## Product
Rider-only pedicab hailing app. Destination → estimate
(4 min · $18) → request → matching → driver assigned →
ride → pay the driver directly. Local, deterministic.

## Read order
README → Vision → FunctionalBrief → Flows →
BusinessRules → Roadmap → the active sprint spec.
BusinessRules governs behavior; Flows governs sequence.

## Technical boundary
Vite + React + TypeScript strict. Tailwind. Typed
reducer. localStorage pedal.ride.v1. Demo controls
only under ?demo=1. No backend, auth, APIs, payment.

## Operating rules
Implement only the states the artifacts define. Never
widen scope. Deterministic fixtures — never random.

## Definition of Done
Not done until run-qa returns GREEN.
Then: results record, roadmap glyph, PROGRESS handoff,
recovery commit with the spec's exact message.
github.com/rishidean/pedal  ·  Self-paced67
Appendix · The FILESFile 03 / 13

prompt.md

Marching orders — read at every session start
# Sprint Session — Marching Orders
You are the Builder for exactly one sprint. Fresh
session, no memory; everything you need is on disk.

1. Orient — CLAUDE.md, PROGRESS.md, docs/Roadmap.md.
   Find the first 🔲 sprint. Any ⛔ → stop.
2. Read the contract — the spec, plus Flows.md and
   BusinessRules.md for anything it references.
3. Build — only what the spec defines. A missing
   product decision? Mark ⛔, name it, stop.
4. Verify — run-qa until GREEN (max 3 attempts).
   Still RED → mark ⛔ with the failing check, stop.
5. Document — Test Results Log, docs/results/,
   roadmap glyph, PROGRESS handoff, promote learnings.
6. Commit — the spec's exact message.

One sprint per session. The loop handles the next.
github.com/rishidean/pedal  ·  Self-paced68
Appendix · The FILESFile 04 / 13

docs/Roadmap.md

The manifest — one glyph per sprint
# PEDAL Roadmap · ## Sprints — Booking

🔲 S1 — App Setup and Shell   — specs/booking/S1-App-Setup-and-Shell.md
🔲 S2 — Ride Request          — specs/booking/S2-Ride-Request.md
🔲 S3 — Ride Lifecycle        — specs/booking/S3-Ride-Lifecycle.md

S2 starts only after S1 passes. A failed sprint stays
active; the harness may not skip ahead.
github.com/rishidean/pedal  ·  Self-paced69
Appendix · THE FILESFile 04 / 13 · at scale

docs/Roadmap.md

One file, nested — named epics, ordinal sprints
# PEDAL Roadmap

## Catalog  «1»
✅ Groundwork   artifacts complete, tagged defined
🔲 Booking      one full rider journey · active
—  Realism      DIRECTIONAL — needs Discovery

## Sprints — Booking  «2»
✅ S1  App Setup and Shell   specs/booking/S1-…
🔲 S2  Ride Request          specs/booking/S2-…
🔲 S3  Ride Lifecycle        specs/booking/S3-…
  gate: S2 starts only after S1 passes   «3»

## Current Status  «4»
Active   Booking S2 — Ride Request
Shipped  Booking S1 — shell up, checks green
Next     S3 Ride Lifecycle → Realism Sprint 0
1
Named epics. Booking, Realism — real words, never numbers. Session 1's convention, running.
2
Same glyphs, nested. Epics → sprints, ordinals only inside the epic. Each sprint points at one spec.
3
A gate can be human. Not just code — the loop stops and waits for a checkpoint.
4
The living handoff. Current Status is rewritten at the end of every session.
github.com/rishidean/pedal  ·  Self-paced70
Appendix · The FILESFile 05 / 13

PROGRESS.md

The memory — the Builder writes it, sprint by sprint
# Progress Log
// starts empty — one handoff entry appended per sprint: // what was built · key decisions · gotchas · next-up
github.com/rishidean/pedal  ·  Self-paced71
APPENDIX · THE FILESFile 06 / 13

specs/booking/S1-App-Setup-and-Shell.md

App Setup and Shell
# Booking S1: App Setup and Shell

## What to build
The PEDAL foundation: Vite + React + TS strict,
Tailwind visual system, mobile rider frame, static
city map, typed reducer, deterministic fixtures.

## Acceptance Criteria
- App boots to destination entry — nothing more
- State survives refresh via pedal.ride.v1
- Invalid stored state clears; never crashes
- typecheck · test:run · build · test:e2e all pass

## Technical Notes
- Demo Controls foundation behind ?demo=1
- No ride-request behavior beyond the shell contract
github.com/rishidean/pedal  ·  Self-paced72
APPENDIX · THE FILESFile 07 / 13

specs/booking/S2-Ride-Request.md

Ride Request — the planted bug lives here
# Booking S2: Ride Request

## What to build
Destination → review → request → matching →
driver assigned. Landmark selection; canonical
estimate; deterministic 1,200 ms assignment.

## Acceptance Criteria
- Estimate shows 4 min · $18 before request
- Matching is its own visible state
- Assignment: Maya Chen · PEDAL 14 · ETA 3 min
- Every state survives refresh

## Technical Notes
- Playwright evidence through driver_assigned
- Exactly ONE matching timer may assign (BR-007) —
  the planted demo bug violates exactly this
github.com/rishidean/pedal  ·  Self-paced73
APPENDIX · THE FILESFile 08 / 13

specs/booking/S3-Ride-Lifecycle.md

Ride Lifecycle — the epic completes
# Booking S3: Ride Lifecycle

## What to build
Driver arrived → ride in progress → ride complete →
"Pay the driver directly" → reset to a fresh ride.

## Acceptance Criteria
- Demo-mode transitions drive each lifecycle state
- $18 fare + the payment instruction at complete
- Every state restores after refresh; reset is clean
- Full end-to-end verification path passes

## Technical Notes
- Demo controls only under ?demo=1 — honest mocks
- Lifecycle transitions valid only in order (BR-008)
github.com/rishidean/pedal  ·  Self-paced74
APPENDIX · THE FILESFile 09 / 13

docs/results/booking-s1.md

The result record — shape fixed by the spec; the run fills it in
# Booking S1 — Result Record

Outcome       Shell boots to destination entry;
              state survives refresh
Files         created + modified paths, listed
Verification  typecheck   test:run   build   e2e 
              network boundary: local-origin only 
Deviations    any spec departure, and why it
              preserves the contract
Unresolved    None — or a named blocker, never
              a hidden TODO
Recovery      feat(booking-s1): app setup and shell
              the commit to return to
github.com/rishidean/pedal  ·  Self-paced75
APPENDIX · THE FILESFile 10 / 13

.claude/skills/run-qa/SKILL.md

run-qa — the quality gate
---
name: run-qa
description: The PEDAL quality gate. Anchors first,
  opinion second. One GREEN/RED verdict.
---

# run-qa — the gate
1. Anchors (deterministic):
   npm run typecheck · test:run · build · test:e2e
2. The crew (subagents):
   lintercode-reviewerplaywright-tester

Verdict:
- Any anchor FAIL or any CRITICAL finding → RED,
  every failure listed so the Builder can fix blind.
- WARN and NIT never block. Anchors outrank opinions.

Never weaken a check to reach GREEN. A test that
cannot run is a FAIL, not an N/A.
Three attempts, then ⛔ — a human steps in.
github.com/rishidean/pedal  ·  Self-paced76
APPENDIX · THE FILESFile 11 / 13

.claude/agents/linter.md

Subagent 1 — structure & syntax
---
name: linter
description: Deterministic well-formedness anchor.
tools: Bash, Read, Edit, Glob, Grep    model: haiku
---

You check; you do not build.
1. npm run typecheck — record pass/fail with the
   first errors verbatim
2. npm run lint, if the script exists
3. Auto-fix only trivial formatting; anything
   needing judgment gets reported, never fixed

Report format, nothing else:
LINTER: GREEN | RED
FIXED: <files auto-fixed, or none>
ISSUES: <file:line — verbatim compiler output>

RED only for real failures: type errors, parse
errors, lint errors at error severity.
github.com/rishidean/pedal  ·  Self-paced77
APPENDIX · THE FILESFile 12 / 13

.claude/agents/code-reviewer.md

Subagent 2 — bugs & logic
---
name: code-reviewer
description: Read-only review against the invariants.
tools: Read, Glob, Grep    model: sonnet
---

Review the sprint's diff against BusinessRules.md,
Flows.md, and the spec. Never modify files.

Hunt in priority order:
- Boundary violations — network, auth, payment,
  random values. Always CRITICAL (BR-013/014).
- Invariant violations — one matching timer (BR-007),
  lifecycle order (BR-008), fail-closed storage (BR-016)
- Persistence contract — pedal.ride.v1
- Logic bugs & unmet acceptance criteria

Return findings as CRITICAL / WARN / NIT, file:line
each. RED only when a CRITICAL exists. If the diff
is clean: GREEN, zero findings, stop.
github.com/rishidean/pedal  ·  Self-paced78
APPENDIX · THE FILESFile 13 / 13

.claude/agents/playwright-tester.md

Subagent 3 — behavior & acceptance
---
name: playwright-tester
description: Behavioral anchor — acceptance criteria
  in a real browser.
tools: Bash, Read, Write, Edit, Glob, Grep   model: sonnet
---

Author tests for any acceptance criterion not yet
covered, then run npm run test:e2e. Deterministic
fixtures, deterministic tests — no arbitrary sleeps.

Key scenarios for Booking S2:
- Estimate (4 min · $18) shows before request
- Matching state observed BEFORE assignment
- Exactly one assignment fires (BR-007)
- Driver card: Maya Chen · PEDAL 14 · ETA 3 min
- Every state persists across refresh
- Network boundary: local-origin requests only

Return "GREEN" if all pass, else "RED" plus, per
failure: test name, failed assertion, actual result.
github.com/rishidean/pedal  ·  Self-paced79
APPENDIX D · OBJECTIONS

Fair questions

The pushback this deck hears most — with straight answers. Take them into your own Q&A.

github.com/rishidean/pedal  ·  Self-paced80
Appendix · ObjectionsFair questions · 1 of 2

The gate answers most of them.

“It’ll game its own metric”
The gate is an anchor, not the loop’s metric
·tests ran — or they didn’t
·specs set the bar, not the model
·[!] escalates to a human
“Models can’t grade their own work”
Correct — so they never do
·worker & verifier never share context
·lint + tests anchor the verdict
·the harness is built from distrust
“What if a step fails silently?”
A 3-character state machine can’t
·[ ] → [x] → [!] — nothing else
·max 3 attempts, then stop
·[!] blocked → a human steps in
“Isn’t context the hard part?”
Yes — deliberately out of scope
·this talk assumes context exists
·layered context → the sequel
·one boundary, drawn on purpose
If you don’t trust the model — good. Neither does the harness. Your distrust is the architecture: it’s called the QA gate.
github.com/rishidean/pedal  ·  Self-paced81
YOU MAY HAVE HEARDLOOPS VS GRAPHS

“Loops are dead. Graphs won.” — look again.

The loop you just met, relabeled in graph vocabulary. It was a graph the whole time.

Nodes
Build · Verify · Document — one bounded job each.
Conditional edges
The GREEN / RED verdict routes the flow. RED cycles back — bounded at 3.
Checkpointed state
docs/Roadmap.md · PROGRESS.md · CLAUDE.md — the run survives any session.
Traversal engine
run.shevery graph framework runs a loop underneath.

An edge is real only if data moves across it — and every arrow here carries data. By the graph crowd’s own rule, “a loop is fine.” Loops buy depth; graphs buy breadth — Jet is this, fanned wide.

github.com/rishidean/pedal  ·  Self-paced82
APPENDIX · OBJECTIONSFAIR QUESTIONS · 2 OF 2

“Fine for toys — our system is much more complicated.”

PEDAL is a pendulum, not a bridge. Nobody says gravity only applies to pendulums.

What scales unchanged
The invariants
Thick specs make building trivial. Anchored gates catch what generation hallucinates. State survives in files. None of this cares how big your system is.
What your complexity becomes
The specs and the gates
Edge cases, tribal scar tissue, the rules an optimizer would bend — that content comes from senior engineers and nowhere else. The complexity objection is the job description.

Receipts, if pressed: the Bun port — a year of work in eleven days, in public · the fan-out-and-verify diamond running in production inside Claude’s research feature · three communities converging on file-based state and deterministic gates without ever meeting.

github.com/rishidean/pedal  ·  Self-paced83