thirty spkesDOCS
HomeDashboardGet an API key

What is Thirty Spokes?

Thirty Spokes is a decentralized model router on Bittensor — Subnet 99. Every model is a spoke; the hub holds nothing. Miners compete to build the routing agent that extracts the most benchmark quality per dollar out of a pinned pool of frontier models — and they have to prove it. Each agent runs the owner's benchmark suite inside the miner's own confidential VM, and publishes a hardware-attested proof cryptographically bound to its public source and weights. Validators run no inference at all: they check one hardware signature and grade the answers against public gold. The best five hold the reign. The dishonest are caught by construction, not by trust.

Preview. Thirty Spokes is registered on Bittensor as Subnet 99. The user-facing gateway (api.thirtyspokes.ai) is not built yet, and secure enforce-mode mining still needs the measured image (see Status). What is implemented and verified on real Intel TDX hardware is the competition mechanism and its attestation stack.

The inversion

Every other benchmark-scored subnet runs evaluation on infrastructure you have to trust — the validator's, or the subnet owner's. Thirty Spokes moves benchmark execution into the miner's own TEE and keeps it trustworthy with hardware attestation plus a public, cryptographically bound artifact.

Two consequences fall out of that:

  • Validators do zero inference for scoring. They verify a proof and grade attested answers. Scoring cost is flat in the number of miners.
  • Static, public benchmarks become safe. Because the artifact (source and weights) is public and bound to what actually ran, cheating is publicly detectable rather than something we must prevent by hiding data.
Layer Trusted? Who writes it
TEE hardware root (Intel TDX) yes — vendor Intel
Measured enclave runtime yes — public, audited, on the approved list subnet owner
Benchmark suite + public gold yes — public subnet owner
Miner agent: routing model + orchestration source no — public, bound, run under attestation miner
Validator verify-only, holds no secret subnet owner

What the Proof Guarantees

One hardware signature over {measurement, report_data} asserts both "this approved enclave ran" and "it produced exactly this payload." Mutate any field and report_data() changes, breaking the quote.

Claim How it's verified
The approved runtime ran The quote carries MRTD + RTMR1/2/3. The validator gates them against an owner-published, on-chain measurement set. A different kernel, cmdline or rootfs ⇒ different RTMR ⇒ unapproved_runtime.
On genuine, current Intel silicon Full DCAP verification: cert chain to a pinned Intel SGX Root CA, CRL revocation, QE identity, and TCB status. Accepted levels default to UpToDate and SWHardeningNeeded; OutOfDate*, ConfigurationNeeded* and Revoked are rejected.
This exact public artifact produced this score The runtime hashes the bytes it loads and runs into source_hash/weights_hash, and report_data commits to them plus every result. The validator downloads the public bundle itself, re-hashes it, and binds it to the on-chain commit.
The cost is real Cost is metered inside the enclave, around the only channel the agent has. The agent runs with zero network egress (a private network namespace) — it cannot make an unmetered call, and it never holds the pool key.
Nobody knew the questions in advance The task slice is seeded from a per-epoch nonce derived from the block hash at epoch start — unknowable until that block is minted.
No replay, no best-of-N The proof binds (epoch, nonce). Anything else is epoch_nonce_mismatch. You get one slice per epoch.
No memorisation By default, every scored answer must derive from a pool response logged in the attested trace — an agent that answers from its own memorised weights matches nothing and is DQ'd ungrounded, with no re-execution. An opt-in owner-held secret probe bank (probe_commit, underivable by miners) adds a re-execution two-proportion collapse test for stronger adversaries.
No copying Hotkey-salted commit-reveal, plus behavioural dedup: near-identical answer vectors (≥ 95 % agreement) mean the later commit is disqualified.
No hardcoded answers The artifact is public, and its source is scanned. Anyone can audit it.

Attestation: verified on real hardware

The full stack is implemented and was verified end-to-end on a GCP C3 (real Intel TDX): a genuine TDX v4 quote pulled through the kernel configfs TSM interface, complete DCAP verification (chain → pinned Intel root, TCB status, CRL, QE identity), RTMR3 runtime self-measurement, no-egress confinement, and on-chain measurement governance. Live TCB status on that host: UpToDate.

Honest caveat. The measurement gate only discriminates once the reproducible, locked-down runtime image is built. Against a stock cloud CVM — whose MRTD is identical for every TDX guest on that provider — enforcement will admit any TDX guest. Building that measured image is the remaining ops step before secure enforce-mode mining, not an optional polish item.

Architecture

Role What it does
Miner Builds the routing agent — routing model + orchestration source, both public. Runs the epoch's benchmark slice inside its own confidential VM, publishes the bundle + attested proof + behavioural trace to its own HuggingFace repo, and commits a salted hash on-chain. Pays its own inference. CPU-only: the pool models are remote.
Validator Downloads the public bundle, recomputes the binding hashes, verifies one hardware quote, grades the attested answers against public gold, checks every answer is grounded in a logged pool call, dedups, applies the dethrone guard, and sets weights. By default runs no agent inference at all (an opt-in secret-probe mode re-executes the artifact).
Owner Pins the measured runtime image (MRTD/RTMR), the benchmark suite, the model-pool allow-list, the TCB policy, and the secret probe commitment — all published on-chain and rotatable.
Gateway (design) The user-facing, OpenAI-compatible API that would route live traffic through the reigning router. Not built.

The pool is an owner-pinned allow-list. An agent that calls a model outside it raises UnpinnedModelError and the run fails — there is no smuggling in a stronger external model.

The Epoch

One epoch = 100 blocks × 12 s ≈ 20 minutes. Miner and validator never talk to each other, so both derive the epoch and the task slice from on-chain state alone:

epoch = current_block // 100
nonce = sha256("koth-epoch|{epoch}|{beacon}")[:16]     # beacon = block hash at epoch start
seed  = sha256("{nonce}|{epoch}|{benchmark}")[:8]      # -> the exact tasks
sequenceDiagram
    participant C as Chain
    participant M as Miner (own TEE)
    participant R as Miner repo
    participant V as Validator

    M->>C: commit  koth1|repo|rev|salted-hash
    Note over C: reveal delay defeats front-running

    loop Every epoch (~20 min)
        C-->>M: beacon (epoch-start block hash)
        C-->>V: beacon (same)
        M->>M: run the slice in-enclave, meter every pool call
        M->>R: upload proof + trace
        V->>R: download bundle + proof
        V->>V: verify quote, bind artifact, grade vs public gold
        V->>V: grounding check, dedup, dethrone guard
        V->>C: set_weights()
    end

At n_per_bench = 8, the full four-benchmark suite grades 32 tasks per miner (the live loader currently wires two — math + mmlu — so a live epoch grades 16). Every miner in the epoch runs the same slice, so scores are directly comparable.

Scoring

The reign ranks on a single bounded scalar, the cost-budgeted quality Q_lcb:

Q_lcb = Σ_b  w_b · lcb_b            # bounded [0,1]
lcb_b = bootstrap lower confidence bound on benchmark b's accuracy
        (alpha = 0.05, 1000 resamples)

Using the lower bound, not the point accuracy, is deliberate: a lucky run cannot dethrone a king.

Benchmark Weight w_b Source
math 0.30 Hendrycks MATH · public gold
mmlu 0.22 MMLU · public gold
gpqa 0.23 GPQA Diamond · public gold
swe 0.25 SWE-bench Pro · public gold

The live loader currently wires math + mmlu at 0.5 / 0.5 (so a live epoch grades 16 tasks). GPQA is gated behind a HuggingFace token and SWE needs the Docker patch-apply loop; both are implemented behind the same interface. The four-weight suite above is what the offline sim and dev kit run.

Eligibility

A miner earns nothing this epoch unless all of these hold. Ineligible miners are excluded from the reign — they are not simply scored zero.

Gate Default Reason emitted
total_cost ≤ budget 0.50 USD per slice over_budget
acc_b ≥ f_min on every benchmark 0.10 below_floor:<benchmark>
≥ 1 metered pool call on every scored task no_pool_call

Cost is a ceiling, not a divisor. Being cheaper buys you nothing once you are under the budget — above the quality bar, better still wins. And you must actually orchestrate the pool: answering "for free" out of your own weights is disqualified.

Taking slot 1 — the dethrone guard

Beating the king on Q_lcb is not enough. A challenger must clear a Pareto-with-tolerance guard, or it is clamped strictly below the king:

Condition Default Failure
Not-worse on every benchmark: acc_c(b) ≥ acc_king(b) − tol tol = 0.02 regression:<b>
Confidently dominant on ≥ 1: lcb_c(b) > acc_king(b) + margin margin = 0.03 no_confident_gain
Enough samples: n_b ≥ min_tasks 5 thin_eval:<b>
Cost not-worse: cost_c ≤ cost_king × (1 + cost_tol) cost_tol = 0.10 cost_regression

You cannot dethrone by trading a regression for a spike.

The Reign

Up to 5 slots — the king plus the last 4 ex-kings still registered — share emissions equally (20% each when full; fewer paid slots means a bigger share each, e.g. the king alone earns 100%). The reward for climbing is entering the chain at all — the only door in is taking the crown — so the gradient lives at the coronation, not in the slot weights: a dethroned king keeps earning while it decays out of the chain instead of dropping straight to zero.

  • Incumbency margin. Only the king's slot is contested: a challenger must beat the king by ε, which decays with the king's artifact age — so a stale king gets easier to unseat, and a fresh one is protected from noise:
    eps(age) = 0.002 + (0.02 - 0.002) * exp(-age / 8)
    
  • Tiebreak. Exact ties for the crown go to the earliest commit block. Copying late never pays.
  • Burn. Weight burns to uid 0 only if nobody in the chain is still registered — a deregistered ex-king's share is just re-split among the rest, not burned.

Disqualifications

Everything you submit is public and bound to what actually ran, so the failure modes are enumerable. This is the full set a validator can emit:

Reason What happened
bad_platform_quote · mock_quote_rejected Not a genuine hardware quote (the mock vendor key is refused in enforce mode).
unapproved_runtime MRTD or RTMR1/2/3 not in the owner's approved set.
tcb_out_of_date · tcb_revoked · … Platform TCB outside the owner's accepted levels.
mrtd_gate_unset · rtmr_gate_unset · tcb_policy_unset The validator itself is misconfigured — it fails closed rather than silently accepting.
artifact_binding_mismatch The attested hashes are not the bundle the validator downloaded.
report_data_mismatch · measurement_mismatch The payload was tampered with after attestation.
epoch_nonce_mismatch Replay, stale proof, or best-of-N.
hotkey_mismatch · bad_commit Resubmitting someone else's proof; commit doesn't bind your artifact.
trace_mismatch The published call trace doesn't match its binding hash.
no_pool_call A scored task with no metered pool call.
hardcoded_answers A literal answer table in your public source.
ungrounded A scored answer didn't derive from any logged pool response — answered from memorised weights, not the pool. The default memorisation backstop (proof-inspection only).
memorization (opt-in probe mode) Aces the public set, collapses on the secret held-out probe.
copy_of:<uid> Behaviourally identical to an earlier-committed artifact.
over_budget · below_floor:<b> Cost above the budget; accuracy under a benchmark floor.
no_proof_commit · commit_out_of_window · commit_mismatch (when an intra-epoch commit window is enabled) No on-chain commit, committed too late, or revealed a different proof than committed.
unpinned model (UnpinnedModelError) Called a model outside the owner's allow-list.

Drop-in API

Not live. This is the intended interface. The gateway is design-stage.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.thirtyspokes.ai/v1",   # one line changed
    api_key=THIRTY_SPOKES_KEY,
)

r = client.chat.completions.create(
    model="auto",                                 # the wheel picks the spoke
    messages=[{"role": "user", "content": "..."}],
)

Your SDK, one line changed. We hold no model and do no inference, so we can connect everything.

Status

Component Status
TEE attestation — real Intel TDX quote, full DCAP (chain → pinned Intel root, TCB, CRL, QE identity) Verified on real hardware (GCP C3, TCB UpToDate)
Runtime measurement (RTMR3) + MRTD/RTMR1/2/3 validator gate Implemented + verifieddiscriminates only once the measured image is built
No-egress agent confinement (netns, hidden secrets, parent-side metering) Implemented + verified (egress blocked, on-disk secrets hidden)
On-chain measurement governance + fail-closed enforce mode Implemented
Grounding check — default memorisation backstop, no re-execution Implemented
Secret held-out probe + evidence accumulation + anti-grind windows (F7/F2) Implemented, opt-in
KOTH competition — commit-reveal, grading, dethrone guard, reign, weight-setting Implemented, runs end-to-end offline
Reproducible, locked-down measured image Remaining ops step (gates secure enforce-mode mining)
Bittensor mainnet registration Registered — Subnet 99 (chain code SDK-verified against bittensor 10.x)
Gateway api.thirtyspokes.ai Design — not built