Flywheel

Concept tour · from idea to merged

Exports fail when the API rate-limits us.

One raw sentence — the kind that arrives in a chat window on a Tuesday — followed through all seven steps of the flywheel, with the artifact each step leaves behind. The steps never change; that constancy is the lesson. Only the idea does.

the same journey, other ideas: onboarding emails arrive out of order · give the dashboard a dark theme

step 1 of 7 · dispatch

You say one sentence, anywhere dispatch listens.

No template, no form. Dispatch triages it: this is product work, it deserves an intent. It files the change and the first item — you are already done for now.

actor: dispatch · your cost: one sentence

the artifact it leaves
◎ tracker item
Exports fail when the API rate-limits us
milestone · intent/export-backoff type:question state:queued

step 2 of 7 · the intent expands

The intent expands: questions fan out.

An intent loop wakes and frames the work: what has to be true before anyone writes code? The open questions become items — the frontier of the change.

actor: intent loop · your cost: nothing yet

the artifact it leaves
▤ openspec/changes/export-backoff/
export-backoff/
├── intent.md        the sentence, framed
├── questions
│   ├── #312 retry, queue, or shed load?
│   └── #313 what does the API's Retry-After promise?
└── sessions/        empty — no one has worked it yet

step 3 of 7 · a session works the round

A design session works the questions.

In its own worktree it reads the export client, probes the API's actual rate-limit behaviour, and writes up the options with evidence — retry with backoff, a send queue, or load shedding.

actor: design session · your cost: nothing yet

the artifact it leaves
▤ sessions/2026-08-12-rate-limit-shape/
rate-limit-shape/
├── findings.md     API returns Retry-After on 429 — honoured? yes
├── options.md      backoff vs queue vs shed — costs of each
└── README.md       what this session did and why

step 4 of 7 · the plan

The round closes into one screen.

Everything the session settled — and everything it proposes next — lands as one plan: answers seeded, a decision drafted, a unit of construction proposed, sometimes the next round. Nothing on this screen exists on GitHub yet.

actor: the session, assembling · your cost: still nothing

the artifact it leaves
the plan · caps the round
what Retry-After promises — answered, with evidenceclosed
retry shape → backoff, capped — drafted as a recordclosed
unit · export-backoff · 3 changes · bolt-default→ construction
next round · harden the export testsexpands
Approveone word · nothing existed on GitHub before it

step 5 of 7 · your word

One word contracts the round — and can expand the next.

You correct what's wrong — a route, a type, an answer typed into a row — and approve once. The retry decision becomes a record in the change, the unit drops into construction — and the test-hardening round opens only because you said grow.

actor: you, on the rim · your cost: one word

what that word left behind
✎ decisions/retry-shape.md
# Decision — how exports survive rate limits

Retry with exponential backoff, capped at 5 tries.
Honour Retry-After when the API sends it.
A send queue is out: it hides latency instead of
surfacing it. Closed by the operator, 2026-08-12.
⚙ unit · export-backoff → construction, covered by this word ⊕ elaboration · harden the export tests — the next round, open

step 6 of 7 · build — the bolt runs

Past your approval, construction runs without you.

The bolt gives each approved change its own spec, an independent review, then a build agent in a nested worktree. The design book the decision landed in is the spec's source of truth — not a memory of a conversation.

actors: bolt loop + construction sessions · your cost: none

the artifact it leaves
± lib/export/client.ts
@@ send() — on 429 @@
- throw new ExportError(res.status);
+ const wait = retryAfter(res) ?? backoff(attempt); // decisions/retry-shape.md
+ if (attempt < 5) return this.retry(req, attempt + 1, wait);
+ throw new ExportError(res.status);

step 7 of 7 · merged

Evidence climbs back out.

Acceptance runs on the bolt branch, the final checks pass, the work lands on main — and the landing is reported back so the intent checks its task off. The journey leaves a spec trail the whole way down. And the round you opened with the same word is already turning — that is the flywheel in motion.

actor: bolt loop · your cost: none — you already spoke

the artifact it leaves
⇂ merged to main
9f21c04  feat(export): retry with capped backoff, honour Retry-After
☑ intent/export-backoff · handoff landed
☑ #312 retry, queue, or shed load? — closed: decided

Seven steps, one spec trail

Your cost, totalled: one sentence, a few minutes of annotation, one word. Everything else ran on its own ring — and every step handed the next one something written down. The rings turn at 1 : 2 : 6 : 24, and every turn leaves spec behind.

back to the walk ↩ · same journey, other ideas: onboarding email order → · dashboard dark theme →