Flywheel

Overview

The operator's reference. It assumes you have the plugin installed and want to know what is running: the fleet and what each actor is allowed to write, the plan surface every approval arrives on, the five bolt types and what each one buys, the states a work item moves through, and how to work on the flywheel itself. The home page teaches the shape of the thing; this page is the map you keep open beside it.

The fleet

Two loop programs, six agent profiles, three persona lenses. Each actor owns a write scope, and the scopes do not overlap.

The loops are programs, not agents: flywheel server is a daemon you start on any host, and every 60 seconds it starts one stateless loop process per milestone the tracker gives a job to, and stops those without. Dispatch — the one standing agent — is started by flywheel dispatch. A profile exists where a mind is needed and nowhere else.

flowchart TD
  op(["you"])

  srv["flywheel server
one per host · every 60s"] disp["flywheel-dispatch
always · one per fleet"] ic["flywheel-intent-loop
one process, while its intent has a job"] bc["flywheel-bolt-loop
one process, while its bolt has a job"] bp["flywheel-bolt-planner
one planning run"] ds["flywheel-design-session
one task batch"] is["flywheel-interactive-session
one task batch · builds a page you work"] cs["flywheel-construction-session
one work-item batch"] fr["flywheel-findings-routing-session
one queued set"] tracker["the tracker
the only bus"] wIntake["new intent changes,
at the moment of triage
· inbox files"] wIntent["that intent's records,
on main"] wBolt["the bolt change's record
and every merge, on the bolt branch"] wPlan["bolt milestones and
plan cards, at board Backlog"] wSession["its session directory, its own task
lines, its charged closures
— in its worktree"] wRoute["its routing plan, under
the bolt's change"] wBooks["the design books
and the context map"] wCode["the built repositories, and its own
task lines — in its worktree"] op -- "your approval" --> tracker op -- "a raw idea, or an answer" --> disp disp -- "the answer, as an item comment" --> tracker tracker --> srv srv -- "a job" --> ic srv -- "a job" --> bc srv -- "a planning run" --> bp ic --> ds ic --> is bc --> cs bc -- "a non-empty findings queue" --> fr disp --> wIntake ic --> wIntent ic --> wBooks bc --> wBolt bp --> wPlan ds --> wSession is --> wSession ds --> wBooks is --> wBooks cs --> wCode fr --> wRoute classDef hu stroke-width:2px classDef d stroke-width:1.5px classDef b stroke-width:1.5px classDef w stroke-width:1.5px,stroke-dasharray:4 3 class op hu class disp,ds,is,cs,bp,fr d class srv,ic,bc b class tracker,wIntake,wIntent,wSession,wBooks,wBolt,wPlan,wRoute,wCode w

Grey boxes are write scopes. Every session directory is its own, so the books and the context map are the one scope more than one actor writes the same copy of — and that is deliberate: they are the destination, and every loop reads them. Nothing here messages anything else — every arrow into a loop is a tracker query, and every arrow out of a session is a commit, an item comment, or a label.

ActorLives as long asWrites
flywheel serveralways — one per host in the fleetnothing; it starts and stops loop processes
flywheel-dispatchalways — one per fleetnew intent changes, at the moment of triage; inbox files; nothing else
flywheel-intent-loopone process, while its intent has a jobthat intent's records on main; the books; the context map
flywheel-bolt-loopone process, while its bolt has a jobthe bolt change's record and every merge, on the bolt branch
flywheel-bolt-plannerone planning runbolt milestones and plan cards, delivered at board Backlog
flywheel-design-sessionone task batchits session directory, its own task lines, its charged closures, the books and map — in its worktree
flywheel-interactive-sessionone task batchthe same, and it builds a page you work
flywheel-construction-sessionone work-item batchthe built repo and its own task lines — in its worktree
flywheel-findings-routing-sessionone queued setits routing plan, under the bolt's change

The user-* profiles — data scientist, DevOps engineer, app developer — are personas: lenses a review session reads built work through, never actors, never owners.

Three consequences worth stating outright

  • A session closes what it was charged with; the loop opens what it discovered. In its own worktree a session checks off exactly its assigned task lines and writes the decision records for questions it closed firsthand; the loop is sole writer on its branch, and its merge is what admits a session's work. A loop, symmetrically, never edits inside a session's directory.
  • Dispatch is the only actor bridged to a human. A question a construction session cannot answer travels out through dispatch — resolved change → owner → DM — and the answer comes back as a comment on the item that raised it, never to a different actor, and never as an edit to that bolt's change.
  • Nothing messages anything else. The tracker is the only bus: a discovery is an issue, an escalation is a label, a completion is item state, and each consumer — server, bolt loop, intent loop, dispatch — reads one exact filter over it.

Read this in full in the README

The plan surface

Every approval arrives the same way: a batch of routed outcomes, facing you as one page.

Three origins build a plan — a design session closing its round, dispatch triaging accumulated raw ideas, and a findings-routing session the bolt loop charges over its queued findings. Whatever built it, the shape is one: containers for each intent and bolt it proposes, one row per outcome placed under exactly one of them, and every choice already made — the round corrects choices rather than supplies them. The home page's fourth section shows the screen itself.

Nothing the plan proposes reaches GitHub before your approval. A plan is previewed, corrected, or abandoned without leaving a stranded object on the board. Per row, one route:

RouteWhat it does
approvefiles the row under its container — an item in an intent's elaboration, or a unit card on a bolt. A unit's type rides the card and is yours to override.
backlogfiles it state:queued on the container's milestone, out of this round — the board's word for parked work.
dropnot filed at all.
answeredquestions only — type the answer into the row and it closes now, no session charged.

The same plan reaches you on whichever channel you are on: the page in a browser, or a numbered digest over chat where corrections go by number and yes to all is the whole approval. An omitted correction means as-proposed — which is what makes one word enough.

The protocol, in full

The five bolt types

The type is the whole choice: a named loop configuration, nothing beside it.

A bolt binds one type at creation, and a unit may name its own on its card's Type: line — the control you see seeded on every plan. The type sets the stages that run, how the spec is written, and whether a spec is written at all. There is no other axis: no mode, no per-bolt declaration, nothing read from a milestone.

TypeSpecVerifyPick it for
bolt-defaultproposal first, then the artifactsrunsthe ordinary case — work that deserves a spec trail and an acceptance pass
bolt-quickgenerated in one commandrunsthe same scrutiny with a cheaper spec — small, well-understood work
bolt-adversarialstepped artifact by artifactrunswork worth slowing down for: the most boundaries exposed for review to attach to
bolt-directgenerated in one commandskippedwork whose correctness the spec and the repo's merge gate already settle between them
bolt-plannone — the approved plan stands as the specskippedpages and prose, never machinery: work that leaves no implemented specs behind

What never varies by type: the merge gate. wt merge runs the repository's own checks at every merge-back and again at the landing, on bolt-plan exactly as on bolt-default, and no type weakens it.

The schemas, one directory per type

An item's life

One stage: label names its leading edge; the label's absence is the honest record of a stage that did not run.

A work item is born on the bolt's milestone when you approve its unit. From there its history is its comment thread plus one stage label at a time, and it closes twice: closed:merged when its work reaches the bolt branch — which is what advances the unit's progress bar — and the landing upgrades that to closed:done with the landing commit in the closing comment.

flowchart LR
  born["born on the milestone
your approval of the unit"] planned["stage:planned
its spec validates — or, on bolt-plan,
the plan is approved in the pane
"] built["stage:built
build session, nested worktree"] verified["stage:verified
acceptance on the bolt branch —
only on types that run verify
"] merged["closed:merged
merge-back through the repo's gate"] done["closed:done
the landing on main"] born --> planned --> built --> verified --> merged --> done built -- "bolt-direct · bolt-plan" --> merged classDef d stroke-width:1.5px classDef g stroke-width:2px class born,planned,built,verified d class merged,done g

A verify with findings charges a review session to rule on them before the merge-back — by evidence, not by type. Discoveries never widen an item: a finding becomes a new queued item on the bolt, and the findings-routing round proposes where each one goes.

The label grammar, in full

Working on the flywheel itself

The install commands are bypassed while you are editing the plugin.

Point Claude Code at a checkout and reload in place — no publish, no reinstall, no version bump between an edit and trying it.

claude --plugin-dir /path/to/flywheel/main
/reload-plugins

The first command starts the session against your working tree; the second, run inside that session, picks up an edit you have just made.

Read this in full in the README

Where the rest of it is written down

Four places, and the first of them is the reference of record.

  • The README — the whole machinery in prose, and the source of every claim on this page.
  • skills/ — the loop skills and the session-type skills.
  • agents/ — the agent profiles, one file each.
  • schemas/ — the OpenSpec workflow schemas, one per bolt type, published for consuming repositories to bind to.

Source on GitHub · MIT licensed · back to the home page