Migrating to v0.50.4

Two breaking changes. The first prices every metered runner second by the node's cpu class and changes a cloud bill; the second affects a machine whose agent.yaml still carries name or coordinators and anyone running sparkwing fleet agents enroll. One schema migration also takes longer than the others on a large database; it needs no action.

Enrolled agent configuration is removedSection anchor link

Before: agent.yaml accepted name and coordinators, which selected enrolled mode. The controller refuses that credential on both the claim route and the offer route, so v0.50.2 made the agent refuse to start and name the state, and --allow-enrolled-preview started the unfinished path anyway.

After: both keys are gone from agent.yaml, and so are --allow-enrolled-preview and sparkwing fleet agents enroll, whose one-time output was a coordinators block. A file that still sets either key fails to load:

parse ~/.config/sparkwing/agent.yaml: enrolled mode has been removed;
delete name and coordinators from agent.yaml to run in claim mode, which
executes work

What to do: delete name and coordinators. What remains is claim mode, the mode that executes work. Set holder_prefix to the name you want in the dashboard; controller, logs, token, labels, max_concurrent, contribution, local_admission, local_reserve and the rest keep their meaning. sparkwing cluster runners add and install/service-install.sh write that shape.

Why: enrolled mode had no execution behind it in any release. Keeping the keys meant an operator could still write a config the runner would not run.

Edge cases: sparkwing fleet agents enroll is removed with the format it printed. It minted an executor-bound credential and printed it as a coordinators block, which no agent.yaml accepts. Add a machine that executes work with sparkwing cluster runners add. fleet.yaml keeps its executors list and every reader of it. Write that list by hand, and bind each entry to a live runner credential with sparkwing cluster agents enroll --token-prefix against a controller serving this machine's state database; a --sw-fleet run refuses to start when the list is empty or an entry has no binding, naming the file or the executor.

Metered runner seconds are priced by cpu classSection anchor link

Before: every metered second was charged at one controller-wide rate, credit_rate_micro_per_second, 20,000 micro-credits by default.

After: a node is billed at the smallest class of the rate table that covers its pinned cpu, and the default table is GitHub Actions' Linux x64 ladder: 2-core 10,000, 4-core 20,000, 8-core 36,667, 16-core 70,000, 32-core 136,667, 64-core 270,000 micro-credits a second. A 2-core node costs half what it did; an 8-core node and above costs more. Charge rows record the class and rate they were billed at, so history is never repriced.

What to do: nothing, if the ladder is what you want. To keep one flat rate, set every class to it:

sparkwing cluster credits settings --profile <name> --rate-table 2=20000,4=20000,8=20000,16=20000,32=20000,64=20000

Why: the operator's decision on 2026-09-14 to match GitHub's per-class pricing so a customer pays for the machine class they asked for.