thirty spkesDOCS
HomeDashboardGet an API key

Reference

Scope. The interfaces that exist today are the command-line tools, the conductor's action grammar, the on-chain record formats and the published reveal — all documented below and all runnable from the repository. The HTTP API is design-stage and is described only in Using the Gateway.

Command-line tools

All five ship as console scripts of the thirtyspokes package (uv pip install -e ".[dev]").

thirtyspokes-miner — the miner's steps

thirtyspokes-miner --netuid N [--network finney] --wallet NAME [--hotkey NAME] <command>

  hotkey                         verify the local hotkey is ed25519 and readable BEFORE paying to register it
  identity                       the registration facts to send the owner; reads only the chain
  check   --model DIR --reference DIR
                                 the validator's admission gate on a local tree
  register-key [--key-file FILE] --cap-usd X [--mailbox-url URL] [--generation K] [--key-credential]
                                 seal your own OpenRouter key to the owner and put it beside the
                                 submission — your arm runs on it (§4); re-run to rotate
  submit  --model DIR --reference DIR [--mailbox-url URL] [--generation K]
                                 check, upload, commit — SPENDS the hotkey's one shot

submit refuses a sr25519 hotkey by name (the envelope is sealed to an ed25519 key), runs the admission gate before opening the mailbox or uploading a byte, uploads against a credential scoped to the miner's own prefix, and commits the ready signal last. --generation opens a later credential after a rotation. The owner's mailbox key is pinned in the tools (config.OWNER_MAILBOX_KEY), so there is nothing to obtain and no flag to pass; --owner-key HEX remains as an override for a rehearsal against a different owner, and an envelope signed by anything else is refused.

thirtyspokes-dev — the local dev kit

thirtyspokes-dev [--model-tree DIR --reference DIR] [--conductor module:attr]
                 [--world module:attr] [--budget-usd 1.0] [--concurrency 16] [--nonce dev]

Calls the validator's own admit, scaffold and arm scorer. Reports the parse-failure rate and the endings breakdown before the score, then the decisions themselves. Touches no bucket, chain or network. --concurrency 1 to read one episode's trace at a time.

thirtyspokes-sim — one offline window

thirtyspokes-sim [--root DIR]

The whole mechanism against the archetype cast, nothing re-expressed. The suite pins the order the cast must come out in.

thirtyspokes-owner — credentials, balances, the schedule

thirtyspokes-owner --state DIR <command>

  issue   --hotkey SS58 --netuid N --wallet NAME [--owner-hotkey NAME] --r2-endpoint URL
          --r2-bucket NAME --r2-private-model-bucket NAME [--ttl-seconds 86400] [--key-only]
                                 mint and publish a credential sealed to one hotkey
  credit  --hotkey SS58|owner --usd X [--ref TEXT]
                                 append a credit: the owner account, or a grant to a hotkey on top
                                 of its own key (picked up at the next window)
  balances                       every balance and cap the gateway would run a window against
  status                         who holds credentials, and which must now be revoked
  key                            the owner public key the tools pin; printed to check it
  commit-schedule --netuid N --wallet NAME [--owner-hotkey NAME] --world module:attr
                  --windows N --per-benchmark N --minimum N [--replace-governance-record]
                                 publish the chained-manifest root for the whole schedule

--state must be the validator daemon's own --state: the one-shot ledger is <state>/mailbox.json, and two ledgers would be two one-shots. commit-schedule refuses to overwrite a slot holding anything but a schedule root unless --replace-governance-record says the record there is a retired mechanism's.

thirtyspokes-validator — the daemon

thirtyspokes-validator --state DIR --netuid N [--network finney] --wallet NAME [--hotkey NAME]
    --genesis-block B --window-blocks N --windows N --immunity-blocks N
    --world module:attr --reference-tree DIR
    --serve-url URL | --serve-host HOST --serve-cards 0:8002,1:8003 --serve-trees DIR
    --sandbox-host ENDPOINT [--grade-dir DIR]
    --r2-endpoint URL --r2-bucket NAME
    --r2-private-model-bucket NAME --r2-public-model-bucket NAME --public-model-base-url URL
    --per-benchmark N --minimum N [--king-zero-uid N] [--poll-seconds 60] [--check]

Every seam is a required argument or a required environment variable (OPENROUTER_API_KEY, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY); there is no offline default anywhere in it. --check runs the launch gates against the chain — rate limit, immunity period, the docker daemon behind --sandbox-host — and exits without opening a window or spending a cent.

The conductor's action grammar

One action per step, the last line of the reply:

REASON    <free text>       optional; capped at 512 tokens; never leaves the conductor
DELEGATE  <model_id>        the scaffold sends the ORIGINAL task to this model
RETRY     <model_id>        the same, after observing an outcome
STOP                        submit the best result so far

MAX_STEPS = 12, MAX_CONDUCTOR_TOKENS = 576. A model_id outside the window's catalog snapshot is a parse failure; three consecutive parse failures force STOP.

On-chain records

record format slot
schedule root schedule:v1:<64 hex> the owner hotkey's commitment
ready signal r2ready:v1:<86 base64url> — the registration id and the manifest SHA-256, two 32-byte digests packed into one slot the miner hotkey's commitment
weights set_weights by uid, resolved from hotkeys at write time the owner hotkey

The registration id is derived from (netuid, uid, hotkey, registration block); the upload prefix is submissions/<registration id>/, and the mailbox key mailbox/v1/<registration id>/<generation, zero-padded to 20>.bin.

The reveal

Published once per window at v3/reveal/<window>.json as { "record": …, "sig": … }, the signature being the owner hotkey's over the canonical record. Fields of the record:

field meaning
v, window, nonce, benchmarks, n_tasks the window and its slice
freshness how much of the slice's category mix recurred from earlier windows
power king_zero, contrast, higher, spread, lcb, floor, n_tasks, separates, by_benchmark
graders_failed tasks excluded from every arm because the grader or sandbox failed
king_hotkey, king the reigning hotkey ("" while King₀ reigns) and its arm: quality, final, per_benchmark[{benchmark, n_tasks, quality, spend, final}], excluded
outcomes[] per challenger: hotkey, commit_block, status, detail, shot_spent, won, exhausted, arm, verdict{delta, lcb, eps, loo_min, loo_dropped, median, sign_wins, sign_p, n_tasks, by_benchmark, loo}
crowned, pensioners who took the crown this window, if anyone, and the lineage
weights, metagraph uid → share as set, uid → hotkey as resolved
metering[] per arm: payer, scoreable, reason, metered_usd, recorded_usd, calls, unfunded_calls, exhausted, futile, resumed
traces the full decision traces of the king's and reference arms — per episode, per step: action, model, cost, observations, the rendered-state digest

The dashboard renders everything but the traces.

Environment variables the world reads

V3_EXCHANGE (the λ table, which also pins the worker pool), V3_KING0 (the best fixed policy by name), V3_BENCHMARKS (default livecodebench,hle), V3_TASKS_PER_BENCHMARK, V3_SEED, OPENROUTER_API_KEY; on the validator, V3_DOCKER_HOST and V3_GRADE_DIR are written from --sandbox-host and --grade-dir.