New
Apps 606Makers 606This week 606
Promote your app−30%
Flywheel screenshot 1
1views in
the last 30 days

Flywheel

A factory for running coding agent workflows you own

Built with Claude Code

by suzworx · added Oct 29, 2026
no ratings0 comments
Open app Code

flywheel — own the factory

Own the factory. Rent the agents and the intelligence.

flywheel is a dark factory for AI coding work: a small Go CLI plus agent skills. The factory (work orders, gauges, the event log, its memory) is files you own; agents and models are rented from any vendor and swapped at will. Cheap disposable agents build, deterministic gauges re-measure every claim, and one frontier lead makes only the critical calls. It is for engineers who run coding agents in parallel and want every change measured, recorded and recoverable.

See it run: the live demo replays a real session and lets you drive the real factory view.

For agents: agents.html is one page with the roles, the loop as exact commands, the brief format and the rules; llms.txt indexes the docs.

Install

Download flywheel-<version>-<os>-<arch>.zip from the latest release (Windows binaries ship as flywheel-<version>-windows-amd64.exe.zip) plus checksums.txt, verify the SHA-256, and put the binary on PATH renamed to flywheel (the archive holds a single binary named after the release). Or install with Go (the module is github.com/suzworx/flywheel; the binary lands in $(go env GOPATH)/bin), or build from source:

go install github.com/suzworx/flywheel/cmd/flywheel@latest
# or
git clone https://github.com/suzworx/flywheel.git && cd flywheel
mkdir -p bin && go build -o bin/flywheel ./cmd/flywheel

flywheel upgrade --check tells you whether a newer release exists and flywheel upgrade installs it, checksum-verified. It refuses (exit 6) while a run's lease is live in --dir (default .), since swapping the binary can crash that run; wait for it (flywheel wait) or pass --force. Then install the skills into your agent, one per skill folder (Skills):

npx skills add suzworx/flywheel --skill flywheel
npx skills add suzworx/flywheel --skill flywheel-worker
# ... flywheel-planner, flywheel-foreman, flywheel-inspector, flywheel-reviewer,
#     flywheel-auditor, flywheel-steward, flywheel-operator

60-second tour

Offline, no API key: the sim adapter replays a recorded worker run instead of calling a model. In an empty git repository:

flywheel init
flywheel config set workers.default.adapter sim
flywheel config set workers.default.model .flywheel/sim.jsonl
cat > .flywheel/sim.jsonl <<'EOF'
{"type":"text","sessionID":"ses_demo","part":{"type":"text","text":"Wrote hello.txt. Gate passes."}}
{"type":"step_finish","sessionID":"ses_demo","part":{"type":"step_finish","reason":"stop","tokens":{"input":120,"output":40},"cost":0.001}}
EOF
cat > .flywheel/briefs/hello.txt <<'EOF'
owns: hello.txt (new)
needs: none
gate: grep -q "Hello from flywheel" hello.txt

# TASK: hello — write a greeting file

Write hello.txt containing the line "Hello from flywheel". At most one write per response.

## Checks

Report the commands you ran and their real exit status.
EOF
flywheel lint .flywheel/briefs/hello.txt          # 0 problems, 0 warnings
flywheel log --task hello --kind planned --brief .flywheel/briefs/hello.txt
flywheel run hello
hello r1 dispatched sim .flywheel/sim.jsonl
hello r1 finished rc=0 reason=stop model=.flywheel/sim.jsonl steps=1 tokens=160 cost=$0.0010
hello r1 finished without writing a file
hello r1 never ran gate(s) 1

The worker says the gate passes. The gauges measure instead of believing it:

$ flywheel validate hello                                  # exit 5
hello gate 1: failed (rc=2)
hello note: the worker never ran gate(s) 1 itself; its report's claims about them are unmeasured
hello owns: ok
hello validate: fail: gate 1 (rc=2)
$ flywheel inspect hello --verdict pass --session lead-1   # exit 6
flywheel inspect: T3: no passing supervisor validated reading for gate 1 on tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 after the latest finished event; run: flywheel validate hello
$ echo "Hello from flywheel" > hello.txt
$ flywheel validate hello                                  # exit 0
hello gate 1: pass (399ms)
hello owns: ok
hello validate: pass
$ flywheel inspect hello --verdict pass --session lead-1   # exit 0
hello inspected pass
$ flywheel factory --once
units (1)
  TASK               STAGE     ATT  SESSION      MODEL                    STEPS   AGE RUN
  hello              passed    r1                .flywheel/sim.jsonl         1    0s done

With a real worker (claude, codex, opencode or pi) the file is written by the agent; see the Quickstart for the full path to a landed unit.

Docs

The site renders all of these: suzworx.github.io/flywheel.

  • Quickstart — from a binary to one landed unit through the loop.
  • Concepts — work orders, owns:, gates, the event log, the poka-yoke rules.
  • Protocol — the normative contract: every event kind, rule and exit code.
  • Features — the long walkthrough: adapters, routing, limits, recover, worktrees, the review agent and panel, freeze and resume, the wake schedule, ship.
  • Factory screens (docs/screens.html) — the approved k9s-style design for flywheel factory, each screen marked shipped, building or planned.
  • HUMAN.md — leading the agents yourself from the terminal.
  • Design docs:
  • Review calibration — the review agent measured against past PRs.
  • Skills — one skill folder per factory role; AGENTS.md holds the house rules.

Built by flywheel

Flywheel is built by flywheel. Sujeet (@suzworx) runs its development as a dark factory.

  • From v0.3.0 on, flywheel's own features (flywheel run, the gauges validate, inspect and verify, the flywheel factory view), the CLI help and flag fixes, and the factory design docs were built as work orders by disposable OpenCode workers on DeepSeek v4 flash (variant max).
  • Since September 2026 the workers are claude-haiku-4-5 agents dispatched through the claude adapter, and the lead is Claude. Across 30 units (33 attempts) a unit cost a median $0.55 (range $0.27-1.63) and took a median 14 minutes; every attempt finished cleanly, yet the lead's review and an independent PR reviewer still caught defects in most units, which is why every claim is re-measured rather than trusted.
  • Each work order is a brief with owns:, needs: and gate: lines. flywheel's own gauges re-run the gates on the exact tree hash and check owns:; inspection and flywheel verify (rules T1, T3, T4, T5 and T8) gate every commit. Workers never commit.
  • One frontier lead seat outlines work orders, reviews diffs, runs checks against the built binary and signs off. The lead seat changed hands between vendors mid-project and the work continued from the files.
  • Measured worker cost: the CLI help and flag work took 7 units, 1.7M tokens and $0.33; a design doc was drafted, corrected and extended by 5 units for about $0.03; a code unit costs $0.03-0.08 and takes 15-29 minutes.

The house rules the workers follow are in AGENTS.md.

The factory

Flywheel is a factory for AI coding work: a small Go CLI plus agent skills that run a durable orchestrator-to-worker loop. A frontier lead agent plans, briefs and judges; cheap disposable worker agents (Claude Code, Codex or OpenCode) do the reading, writing and testing. The control plane dispatches work and enforces policy; the data plane keeps traceability, telemetry and accountability for every session.

Roles

Factory role Persona Does Never
Plant manager lead sets goals and policy, handles escalations, signs off implements
Production planner planner turns a spec into work orders (owns:/needs:/gates) dispatches or inspects
Line supervisor foreman runs a line of workers, retries by policy, pulls the cord plans or implements
Line worker worker (any agent CLI) builds one work order at its own station plans, inspects, commits
Machine gauges supervisor (CLI, no model) measures every unit: runs gates, checks owns: judges intent
QC inspector inspector inspects a unit against its work order runs gauges or fixes units
External auditor auditor audits first articles and samples, files nonconformances works the line
Continuous improvement steward turns signals and nonconformances into learnings changes units
Owner operator installs, assigns roles, sets merge and publish policy —

A unit's path

flowchart LR
    WO["Work order"] --> W["Worker (agent CLI)"]
    W --> G["Machine gauges"]
    G --> I["QC inspector"]
    I --> A["Auditor (first articles, samples)"]
    A --> L["Landing"]
    I -. "rework" .-> W

Set up, run, watch

  • Set up — flywheel init scaffolds flywheel.md plus the .flywheel/ state files and ends with a factory summary: worker lines, limits, audit policy and the enforcement layers installed (with the command for each missing one). The default worker uses the first agent CLI it finds on PATH (claude, opencode, codex, then pi: npm install -g @earendil-works/pi-coding-agent, models provider/id), or the one --adapter NAME chooses. The full factory is epic #69.
  • Run — the lead records each work order with flywheel log --kind planned; flywheel run dispatches it through the claude, codex, opencode, pi or sim adapter and records the run; --worktree builds each unit in its own .flywheel/worktrees/<task> on branch fw/<task>.
  • Watch — flywheel state derives the floor from the log, flywheel factory opens an interactive k9s-style view of it, flywheel watch streams every event as one line, and flywheel wait <task>... blocks until the named units finish. In the view, :pulse and :metrics chart the metrics and drill to the units behind each number (factory view); flywheel fleet status merges every factory on the machine into one table (fleet).

The details (bases, --notify, the TREE column, withdrawing a plan) are in docs/features.md. The planned screens of the factory view, each marked with what exists today, are on the screens page.

  • Set up — flywheel init scaffolds flywheel.md plus the .flywheel/ state files (available in v0.2.0). It ends with a factory summary — the worker lines, limits, audit policy, which enforcement layers are installed (and the command for each missing one) and how to view the floor. Building the full factory — lines, staffing, and the policy that keeps it safe — is epic #69.
  • Run — the lead records each work order as an event with flywheel log --kind planned; flywheel run dispatches it to a worker through the claude, codex, opencode or pi adapter and records the run automatically. For parallel units flywheel run --worktree is the default: each unit builds in its own .flywheel/worktrees/<task> on branch fw/<task>, against the main ledger. Each tree's worker, setup and gates get FLYWHEEL_SLOT, a per-tree number for ports and databases, so parallel units never share them (#697). A resource they must share (one local database, a fixed port) goes on a brief's resources: e2e, dev-db line: flywheel validate then holds an exclusive lock per resource, per repository (all its worktrees on this host), while a gate that uses it runs (gate[resources]:, or every gate when none is marked), so two units never run those gates at once; it serialises validate's gates, not the worker's own runs (#697). A gate waiting for another unit's lock records a resource_wait event as the wait starts, and flywheel factory shows it live in the unit's RUN cell (waiting for resource e2e (<holder>) 2m) until the gate's reading ends it (#697). A gate whose suite already fails on the unit's base is written gate[vs-base]: with a fail-match: <regexp> line naming the failing-test lines: validate reruns it at the base (cached) and passes it only when the unit adds no failing line the base lacks, printing the debt (passed vs base <sha>: 24 failing on base too) (#788). The debt stays visible as N failing on base too: the floor shows vs-base <n> on the unit's row, inspect --verdict pass prints each such gate, and flywheel verify checks every vs-base pass (rule V1). --worktree --base REF branches a new fw/<task> from REF, without checking REF out. Without --base a new fw/<task> starts from origin/<integration.branch> (else the local branch) when integration.branch is set, and is refused when neither resolves; otherwise from the main checkout's HEAD, with a warning when HEAD carries commits origin/main lacks (#550). The dispatched event's base records the commit the unit branched from. flywheel run --workdir PATH runs the worker in an existing tree the lead prepared (a merge in progress, say) while events still go to --dir's ledger; it is refused (exit 6) with --worktree or --base, or when PATH is not a git working tree of the same repository. flywheel run --session ID (default $FLYWHEEL_SESSION) records the dispatching lead session as the dispatched event's lead, so leads sharing one ledger can tell their units apart.
  • Watch — flywheel state derives the floor from the event log; flywheel factory opens an interactive, k9s-style view of the floor (:units :workers :andon :events :lines to switch, / to filter, enter to explain a unit, l for its log, ? for help, q to quit; --plain keeps the plain redraw), and flywheel watch streams every event as one readable line. When any unit runs in a worktree, the plain floor's (flywheel factory --plain) units table adds a TREE column with that worktree and its base commit (CP-A@abcdef1), and the --json view carries workdir and base.
  • Know when a unit finishes — never background a dispatch with a bare & and hope to notice: flywheel wait <task>... [--timeout D] [--notify CMD] blocks until each named task finishes its current (or first) attempt, printing <task> <attempt> finished reason=<r> as each lands (exit 0 all clean, 4 any unclean, 8 timeout), and flywheel run <task> --notify CMD runs CMD through the shell when the run returns on any path, with FLYWHEEL_FINISHED="<task> <attempt> reason=<r> exit=<code>" in its environment; a failing notify only warns. flywheel wait --notify CMD runs CMD the same way once per task whose finish is not a clean stop (a rate-limited or error unit), and a provider-error finish is retried once in process after 2 minutes (limits.provider_error_retries, default 1) (#830).

Design priorities, in order: efficiency and consistency, then speed, reliability and recoverability — the lead spends tokens only where judgment is needed, gauges and telemetry cost no tokens, and everything replays from the log after any crash.

Why flywheel

Frontier-quality results at a fraction of frontier cost — measured, not promised: the field run behind the skills used 99 worker runs across 44 tasks, up to 7 workers in parallel, and about 90 % of all worker input across the field run served from the model cache. max_parallel caps concurrent workers, not concurrent gates: units whose gate: lines name the same expensive command serialise on it, and the contention manufactures false findings (phantom timeouts) that read as code defects — flywheel run prints a shared-gate warning at dispatch whenever an in-flight unit declares the same gate line.

The goal is to ship with no human in the loop. That is only safe if every step is recorded (an append-only event log), measured by the machine (gauges run by the CLI, never self-reported by an agent), and audited by independent checkers. Today all three are in place: the append-only event log is hash-chained, so an edited record, or one removed from the middle, is detected (flywheel verify --log; cutting records off the end needs an outside anchor such as a pushed commit); the gauges validate, inspect and verify measure every unit, with flywheel supervise measuring each finished unit nobody has measured yet; and flywheel audit re-measures a unit in a clean copy from a session that neither built nor inspected it, selecting first articles and seeded samples (#61). Enforcement sits in more than one layer: the CLI refuses illegal transitions (exit 6), an agent Stop hook runs flywheel gate, and git hooks check every commit and push (flywheel init --git-hooks; the pre-push hook runs flywheel verify --shipped, so a unit that was only planned, never built and judged in flywheel, cannot be pushed); whatever the worker's adapter, flywheel run flags an attempt that moved HEAD, switched branch or stashed with a git-write signal, which blocks landing until the lead triages it (it compares the attempt's end points, so a push or a write undone before exit needs the command-level guard, #319). That guard is in place: flywheel run puts a git shim first on the worker

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#automation · #agents