On this page

Flywheel

stado flywheel turn spends what would otherwise go unused: the usage your subscription plans have left before their windows reset, and the cores and memory the fleet's hosts have free. One turn reads both and starts one improvement session for each plan with usage to spare, on a host with room for it. Each session runs rounds of jeden hillclimb in that host's checkout of a repository you named. A turn that finds nothing spare starts nothing.

Stado decides where a session runs. Brama still chooses which member of a provider's pool serves each call of a session, and Jeden chooses what to improve.

Invocation

stado flywheel turn \
  --workspace <NAME> [--workspace <NAME> ...] \
  --route <PROVIDER=MODEL> [--route <PROVIDER=MODEL> ...] \
  --keep <SHARE> --sessions <N> --rounds <N> --max-steps <N> \
  [--pool <FILE>] [--focus <TEXT>] \
  [--apply --allow-write --allow-command] [--json]
  • --workspace names a repository to improve, by the name of this machine's checkout of it. Repeat it for several; sessions are dealt to them in the order given. A host's checkout is cloned from the origin this machine's checkout fetches from, so a turn runs on a machine that holds the checkouts.
  • --route names the model route sessions take to spend one provider's plans: the provider as the pool names it, and a model Brama lists. A plan whose provider has no route is not spent.
  • --keep is the share of every plan's tightest usage window kept for your own work, from 0 up to but not 1. Only what is unused beyond it is spent.
  • --sessions is the most sessions one turn starts.
  • --rounds is how many hill-climb rounds each session runs, and --max-steps is Jeden's upper bound on each session's steps. Nobody watches a session a turn starts, so both are yours to state.
  • --focus is what the hill-climbs favour when they choose an improvement; nothing in particular without it.
  • --apply starts the sessions. Without it the turn only says what it would start. A hill-climb changes the code it improves and runs its checks, so --apply takes --allow-write and --allow-command with it.

The pool

Without --pool, the turn asks the host the service directory says Brama is active on, through the approved read stado host exec runs there: start-with-skarbiec subscription list --json --refresh-usage. That read asks each provider for its current usage report first, starts no sign-in and no model request, and answers while the gateway itself is not serving.

--pool <FILE> hands the same document in from a file, and --pool - from standard input:

brama subscription list --json --refresh-usage | stado flywheel turn --pool - ...

Which plans are spare

Every plan of the pool is listed with one standing:

Standing Meaning
spare It serves, runs no session, has a route, and more than --keep of its tightest running window is unused.
kept What is unused is within the share you keep.
in use Sessions run on it, so what it has left is theirs.
not serving Its gateway does not serve from it.
no route No --route names its provider.
unmeasured No window it reported is still running, so nobody knows what it has left.

A window that has reset since it was read says nothing about the one running now and is not counted. A plan whose every window has reset is unmeasured and is not spent; the gateway's own read (no --pool) or --refresh-usage gives it a current reading. What a plan has spare is one minus the largest used share among its running windows: the tightest window bounds what a session can use of every other.

Which hosts have room

A host has room when its own agent admits work in a capacity publication still within the promise the agent made, states its free cores and memory, and the registry declares a work root for it. Its room is how many jeden-session reservations what it has free holds. stado capacity list shows the same publications.

A session's checkout and ledger live below the host's work root, so a host that declares none is listed with work_root false and room 0, as a session start would refuse it. stado space root <HOST> --path <PATH> declares one.

Where the sessions go

Spare that resets soonest is lost soonest, so it is spent first; of two that reset together, the larger. Sessions are dealt to the workspaces in their order, round and round, each on the host with the most cores still free. A host carries at most one session of a workspace in a turn: it keeps one checkout of each repository, and one hill-climb owns that checkout's ledger at a time. A second hill-climb started in a checkout an earlier turn's session still climbs ends at once, before any model call, naming the ledger's holder.

What a session does

Each session is a detached jeden-session pinned to its host, started as stado workload start starts one (see Sessions), and runs jeden hillclimb --rounds <N> in the host's checkout. Each round chooses the repository's next improvement, has it carried out and independently accepted or rejected, and writes how it ended to the checkout's ledger. The next round, of this session or of a later turn's on that host, chooses from that ledger, so what one turn spent is what the next builds on.

Nobody waits on a session the flywheel starts, so it queues at priority 0, with routine batch work and never ahead of a session a person started (priority). A plan a flywheel session runs on is in use to the next turn, which does not stack another on it.

The turn document

--json prints one document:

{
  "schema_version": 1,
  "generated_at": "2026-11-13T17:08:10+00:00",
  "applied": false,
  "keep": 0.2,
  "plans": [
    {"subscription": "plan-a", "provider": "claude-code", "standing": "spare", "spare": 0.5, "resets_at_ms": null}
  ],
  "hosts": [
    {"target": "alpha", "admitting": true, "work_root": true, "free_cores": 4, "free_ram_gb": 8.0, "room": 2}
  ],
  "spins": [
    {"target": "alpha", "workspace": "example-workspace", "model": "claude", "provider": "claude-code", "subscription": "plan-a"}
  ]
}

spare and resets_at_ms are null where the standing measured none, and free_cores and free_ram_gb where the host's publication does not state them. subscription in a spin is the plan whose spare the session was counted against. With --apply --json the document is followed by the placement record of each session started, as stado workload start --json prints it.

Turning on a schedule

A turn is one shot. A schedule in this host's own store turns the flywheel from the machine that holds the checkouts:

stado schedule create --host-store --cron "*/30 * * * *" \
  "stado flywheel turn --workspace example-workspace --route claude-code=<MODEL> --keep 0.2 --sessions 2 --rounds 1 --max-steps 200 --apply --allow-write --allow-command"

Reading what it did

The sessions a turn starts are ordinary sessions: stado workload sessions lists them, stado workload logs <JOB> reads one's transcript, and stado cancel <JOB> --reason <TEXT> stops one. A session's final answer is the hill-climb's own report: its rounds, how each ended, and how many were accepted. On the host, jeden hillclimb --status in the checkout reads the whole ledger.

Refusals

Each is refused before any session is started.

  • A --route that is not PROVIDER=MODEL (stado.flywheel.route-malformed, exit 2).
  • A --keep outside 0 up to 1 (stado.flywheel.keep-not-a-share, exit 2).
  • No --pool and a service directory that declares no Brama (stado.flywheel.gateway-undeclared, exit 1).
  • A --pool that cannot be read, or standard input that is a terminal (stado.flywheel.pool-unread, exit 2).
  • A document that is not the pool, or a member it does not state in full (stado.flywheel.pool-malformed, exit 2).

A read of the gateway's host that fails and prints no pool is that host's report that did not end as asked (stado.host.report.report-not-ok), which a later turn may find answered. Reading capacity and starting a session fail as workloads do.

Source: this website