Mine the Subnet
You compete to build the routing/orchestration agent that gets the highest benchmark quality per dollar over an owner-pinned pool of models. Your agent runs inside your own confidential VM; validators verify an attested proof and grade your answers. King = the eligible miner with the highest cost-budgeted quality.
Mine with eyes open. Our own measurements say routing has no quality moat over the best single model on general traffic — see Findings. The mechanism is real and hardware-verified; the economics are not a guaranteed income stream. We would rather you know that than discover it.
1. What you build
One thing: a Python source file defining build_agent(weights) -> agent, where agent(prompt, call_model) -> answer. call_model(model, messages, params) is your only channel to the pool — it returns the model's response text and is metered for cost.
# my_router.py — a cost-aware cascade: cheap first, escalate hard prompts
import json
def build_agent(weights):
cfg = json.loads(weights.decode()) # your routing config / trained params
cheap, strong = cfg["cheap"], cfg["strong"]
def agent(prompt, call_model):
ans = call_model(cheap, [{"role": "user", "content": prompt}], {"max_tokens": 256})
if len(prompt) > 400 or "prove" in prompt.lower(): # your routing logic
ans = call_model(strong, [{"role": "user", "content": prompt}], {"max_tokens": 512})
return ans
return agent
Your bundle = source.py + weights.bin (opaque bytes — a trained routing model, a config, whatever you want), and it is public on your HuggingFace repo. Everyone can read it.
The competitive surface is wide open: a trained routing model, orchestration (ensemble / verify / decompose / cascade), tool use, efficient prompting — anything that lifts quality or cuts cost.
You write your own training. The subnet ships no trainer; that is your edge. Collect which pool model wins which query at what cost, fit a classifier or policy, serialise it into weights.bin, and publish it alongside your inference source. All public.
The one axis where we have measured real headroom is orchestration, not model choice — different scaffolds win different tasks. See Findings §7.
2. The rules, enforced by the runtime
- Pinned pool only. You may call only the owner's allow-listed models. Anything else raises
UnpinnedModelErrorand your run fails — no smuggling in a stronger external model. - Your answer must come from the pool. Not just ≥ 1 pool call per scored task (
no_pool_call) — every scored answer must actually derive from a logged pool response. Answering from your own memorised weights is caught by the default grounding check →ungrounded. - Zero network egress. Your agent runs in a network namespace with no route off-box. Its only channel is
call_model, metered by the trusted parent, which holds the API key. You cannot make an unmetered call. - You pay your own inference (your own OpenRouter key). Cost is metered from the real bill.
3. How you're scored
Q_lcb = Σ_b w_b · lcb_b # weighted, bootstrap lower confidence bound, bounded [0,1]
Scoring on the lower bound means a lucky run cannot dethrone a king.
King = argmax Q_lcb among eligible miners. Emissions split equally across the king + a chain of up to 4 recent ex-kings (5 slots, 20% each when full), with an ε incumbency margin protecting the king that decays with its artifact age, and an earliest-commit tiebreak for the crown.
You are eligible only if all of these hold — otherwise you earn nothing this epoch:
| Gate | Default |
|---|---|
total_cost ≤ budget |
0.50 USD per slice |
acc_b ≥ f_min on every benchmark |
0.10 |
| ≥ 1 metered pool call on every scored task | — |
Cost is a ceiling, not a divisor. Being cheaper is only useful up to the budget; above the quality bar, better still wins.
To take slot 1 you must also clear the dethrone guard: not-worse on every benchmark (within tol = 0.02), confidently dominant on at least one (margin = 0.03), at least min_tasks = 5 samples, and cost within +10 % of the king. You cannot dethrone by trading a regression for a spike.
4. Test locally before you spend a cent on-chain
The dev kit runs the exact validator scoring on your artifact — it calls verify_proof directly, not a reimplementation, so what you see locally is what the validator computes.
uv run orchestra-koth-dev --source my_router.py --weights my_weights.bin
# -> per-benchmark acc/lcb, total_cost, Q_lcb, eligible, n_pool_calls
Iterate here until Q_lcb is high and eligible: true under the budget. Useful flags: --model, --n-per-bench (default 8), --budget (default 0.5).
5. Submit and run
One-time setup
uv pip install -e ".[chain,eval,tee]" # bittensor + HF + OpenRouter + dcap-qvl
export OPENROUTER_API_KEY=... # you pay your own inference
huggingface-cli login # to publish your public bundle
btcli wallet new_coldkey && btcli wallet new_hotkey
btcli subnet register --netuid 99 --wallet.name miner --subtensor.network finney
Run the miner daemon. It publishes your bundle, commits the salted hash on-chain, and each epoch runs the suite in your TEE and uploads the attested proof plus its trace:
orchestra-koth-miner --netuid 99 --network finney --wallet miner --repo you/koth-miner \
--source my_router.py --weights my_weights.bin \
--pool "openai/gpt-4o-mini,anthropic/claude-opus-4.7" \
--confine
On a TDX guest the daemon automatically uses the real hardware attestation, extends RTMR3 with the runtime measurement at startup, and — with --confine — runs your agent with zero egress. On a non-TDX box it falls back to the Stage-1 mock key, which provides no security.
If the subnet enables the intra-epoch commit window (F7), the daemon commits your proof's hash on-chain right after the epoch opens and must reveal exactly that proof — so don't re-roll after it commits (a swapped proof is commit_mismatch, a late one commit_out_of_window).
6. What gets you disqualified
Everything you submit is public and bound to what actually ran, so cheating is detectable rather than merely discouraged.
| Reason | What you did |
|---|---|
UnpinnedModelError |
Called a model outside the pool allow-list |
no_pool_call |
Didn't call the pool on some scored task |
hardcoded_answers |
A literal answer table in your public source |
ungrounded |
Answered from your own weights instead of the pool — every scored answer must derive from a logged pool call (the default backstop) |
memorization |
(opt-in probe mode) Aced the public set, collapsed on the secret held-out probe |
copy_of:<uid> |
Behaviourally identical to an earlier-committed artifact |
trace_mismatch |
Your uploaded trace doesn't match the proof binding |
artifact_binding_mismatch |
The attested hashes aren't the bundle you published |
epoch_nonce_mismatch |
Replay, stale proof, or best-of-N |
over_budget / below_floor:<b> |
Cost over the budget, or accuracy under a benchmark floor |
bad_platform_quote / unapproved_runtime |
Forged or unapproved TEE attestation |
Compete on genuine routing and orchestration quality, not tricks.
7. What you need
- A confidential VM — Intel TDX. CPU-only is fine; the pool models are remote, so no GPU. Cheap on Spot. See Confidential VM Setup.
- An OpenRouter API key (your inference budget).
- A HuggingFace account (to publish your public bundle).
- A Bittensor wallet, TAO, and registration on Subnet 99 (mainnet).
See also
- The KOTH Protocol — the full mechanism and every parameter
- Attestation & Trust Model — what the hardware proves about your run
- Findings — what we measured about routing, including the parts that hurt