Skip to content
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Unconst

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
15 changes: 5 additions & 10 deletions knowledge/INDEX.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ files_by_category:
sybil.realities.yaml: "coldkey NOT sybil-proof, UID pressure"
trust.assumptions.yaml: "what can/cannot be trusted"

reference:
sdk.quick_reference.yaml: "Python SDK — Subtensor, Wallet, Metagraph, Commitments"

specifications:
bittensor.core.yaml: "network, tokens, participants, keys, metagraph"
subnet.lifecycle.yaml: "creation, activation, hyperparameters, epochs"
Expand All @@ -38,21 +41,15 @@ files_by_category:
integrations:
chutes.integration.yaml: "SN64 LLM inference API"
basilica.containers.yaml: "container execution for agent subnets"
<<<<<<< HEAD
hippius.integration.yaml: "SN13 decentralized storage, S3/IPFS, provenance"
desearch.integration.yaml: "SN22 real-time search, Twitter/Reddit/web data"
=======
hippius.integration.yaml: "SN75 decentralized storage, S3/IPFS, provenance"
desearch.integration.yaml: "SN22 real-time search, Twitter/Reddit/web data"
dataverse.integration.yaml: "SN13 social data API, X and Reddit scraping"
>>>>>>> 51f1cec7a22db85aa7412760f35fc2c5cfc43b69
sdk.quick_reference.yaml: "Python SDK patterns, token trading"
btcli.reference.yaml: "CLI command reference"
local.development.yaml: "local subtensor setup"
ops.principles.yaml: "deployment, monitoring, operations"

guidance:
design_flow.yaml: "decision tree for mechanism selection"
load_order.yaml: "context loading sequences by task"

example_subnets:
example.affine_sn120.yaml: "Affine - multi-env Pareto scoring for reasoning models"
Expand Down Expand Up @@ -117,7 +114,6 @@ task_routing:
- provenance_verification
- large_file_distribution

<<<<<<< HEAD
desearch_real_time:
load:
- desearch.integration.yaml
Expand All @@ -128,11 +124,10 @@ task_routing:
- agent_context_enrichment
- event_verification
- sentiment_analysis
=======

dataverse_social_data:
load:
- dataverse.integration.yaml
>>>>>>> 51f1cec7a22db85aa7412760f35fc2c5cfc43b69

cli_operations:
load:
Expand Down
51 changes: 29 additions & 22 deletions knowledge/local.development.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

benefits:
- free_tao_via_faucet
- fast_blocks_6_seconds
- fast_blocks_4_per_second
- isolated_environment
- full_chain_control
- easy_debugging
Expand Down Expand Up @@ -39,7 +39,7 @@ starting_subtensor:
--name subtensor-local \
-p 9944:9944 \
-p 9933:9933 \
opentensor/subtensor-localnet:latest
ghcr.io/opentensor/subtensor-localnet:devnet-ready

connection:
cli: "btcli subnet list --network local"
Expand Down Expand Up @@ -82,18 +82,24 @@ subnet_creation:
--no-prompt

# SDK:
success, netuid = subtensor.register_network(wallet=owner)
resp = subtensor.register_subnet(wallet=owner)
assert resp.success, resp.message
# register_subnet does not return the new netuid; look it up via owner_hotkey:
owned = [s for s in subtensor.all_subnets()
if s.owner_hotkey == owner.hotkey.ss58_address]
netuid = max(owned, key=lambda s: s.network_registered_at).netuid
# On a fresh localnet, a fresh netuid will be likely 2, not 1

step_2_configure: |
btcli sudo set --netuid 1 --param tempo --value 10 --wallet.name owner --network local
btcli sudo set --netuid 1 --param max_allowed_uids --value 64 --wallet.name owner --network local
btcli sudo set --netuid 2 --param tempo --value 10 --wallet.name owner --network local
btcli sudo set --netuid 2 --param max_allowed_uids --value 64 --wallet.name owner --network local

step_3_register_neurons: |
btcli subnet register --netuid 1 --wallet.name miner --wallet.hotkey default --network local
btcli subnet register --netuid 1 --wallet.name validator --wallet.hotkey default --network local
btcli subnet register --netuid 2 --wallet.name miner --wallet.hotkey default --network local
btcli subnet register --netuid 2 --wallet.name validator --wallet.hotkey default --network local

step_4_stake_validator: |
btcli stake add --netuid 1 --wallet.name validator --wallet.hotkey default --amount 1000 --network local
btcli stake add --netuid 2 --wallet.name validator --wallet.hotkey default --amount 1000 --network local

local_miner_example: |
from fastapi import FastAPI, Request
Expand All @@ -115,8 +121,8 @@ local_miner_example: |
return {"status": "ok"}

if __name__ == "__main__":
if not subtensor.is_hotkey_registered(1, wallet.hotkey.ss58_address):
subtensor.burned_register(wallet=wallet, netuid=1)
if not subtensor.is_hotkey_registered(wallet.hotkey.ss58_address, 2):
subtensor.burned_register(wallet=wallet, netuid=2)
uvicorn.run(app, host="0.0.0.0", port=8091)

local_validator_example: |
Expand All @@ -127,7 +133,7 @@ local_validator_example: |

wallet = Wallet(name="validator")
subtensor = Subtensor(network="local")
metagraph = Metagraph(netuid=1, network="local")
metagraph = Metagraph(netuid=2, network="local")
MINER_ENDPOINTS = {} # hotkey -> url

async def query_miner(url: str, payload: dict) -> dict | None:
Expand Down Expand Up @@ -159,21 +165,21 @@ local_validator_example: |
total = sum(weights)
if total > 0:
weights = [w / total for w in weights]
subtensor.set_weights(wallet=wallet, netuid=1, uids=uids, weights=weights)
subtensor.set_weights(wallet=wallet, netuid=2, uids=uids, weights=weights)

await asyncio.sleep(30)

asyncio.run(validate())

debugging:
metagraph_state: |
metagraph = Metagraph(netuid=1, network="local")
metagraph = Metagraph(netuid=2, network="local")
metagraph.sync()
for uid in range(metagraph.n):
print(f"UID {uid}: {metagraph.hotkeys[uid][:16]}... stake={metagraph.S[uid]} incentive={metagraph.I[uid]}")

chain_state: |
btcli subnet show --netuid 1 --network local
btcli subnet show --netuid 2 --network local
btcli wallet overview --wallet.name miner --network local

logging: |
Expand All @@ -200,7 +206,7 @@ common_issues:
- "inspect metagraph for validator_permit"

slow_blocks:
- "normal: ~6 seconds per block"
- "normal: ~250ms per block"
- "if stuck: restart docker container"

full_test_script: |
Expand All @@ -227,23 +233,24 @@ full_test_script: |
for w in [owner, miner, validator]:
subtensor.faucet(wallet=w)

# Create subnet
if not subtensor.subnet_exists(netuid=1):
success, netuid = subtensor.register_network(wallet=owner)
# Create subnet (netuid 2 on fresh localnet)
if not subtensor.subnet_exists(netuid=2):
resp = subtensor.register_subnet(wallet=owner)
assert resp.success, resp.message

# Register neurons
for w in [miner, validator]:
if not subtensor.is_hotkey_registered(1, w.hotkey.ss58_address):
subtensor.burned_register(wallet=w, netuid=1)
if not subtensor.is_hotkey_registered(w.hotkey.ss58_address, 2):
subtensor.burned_register(wallet=w, netuid=2)

# Stake validator
subtensor.add_stake(wallet=validator, hotkey_ss58=validator.hotkey.ss58_address, amount=1000)

# Set weights
metagraph = bt.Metagraph(netuid=1, network="local")
metagraph = bt.Metagraph(netuid=2, network="local")
metagraph.sync()
miner_uid = metagraph.hotkeys.index(miner.hotkey.ss58_address)
subtensor.set_weights(wallet=validator, netuid=1, uids=[miner_uid], weights=[1.0])
subtensor.set_weights(wallet=validator, netuid=2, uids=[miner_uid], weights=[1.0])

# Wait for epoch
await asyncio.sleep(120)
Expand Down
8 changes: 4 additions & 4 deletions knowledge/sdk.quick_reference.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ subtensor:
balance: "subtensor.get_balance(coldkey_ss58)"
subnet_exists: "subtensor.subnet_exists(netuid)"
hyperparams: "subtensor.get_subnet_hyperparameters(netuid)"
is_registered: "subtensor.is_hotkey_registered(netuid, hotkey_ss58)"
uid_for_hotkey: "subtensor.get_uid_for_hotkey_on_subnet(netuid, hotkey_ss58)"
is_registered: "subtensor.is_hotkey_registered(hotkey_ss58, netuid)"
uid_for_hotkey: "subtensor.get_uid_for_hotkey_on_subnet(hotkey_ss58, netuid)"
metagraph: "subtensor.metagraph(netuid)"

transactions:
Expand Down Expand Up @@ -327,9 +327,9 @@ epistula:

common_patterns:
ensure_registered: |
if not subtensor.is_hotkey_registered(netuid, wallet.hotkey.ss58_address):
if not subtensor.is_hotkey_registered(wallet.hotkey.ss58_address, netuid):
subtensor.burned_register(wallet=wallet, netuid=netuid)
uid = subtensor.get_uid_for_hotkey_on_subnet(netuid, wallet.hotkey.ss58_address)
uid = subtensor.get_uid_for_hotkey_on_subnet(wallet.hotkey.ss58_address, netuid)

weight_setting_with_rate_limit: |
params = subtensor.get_subnet_hyperparameters(netuid)
Expand Down
3 changes: 1 addition & 2 deletions knowledge/subnet.lifecycle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ phases:
check_cost: "subtensor.get_subnet_burn_cost()"

2_creation:
method: "subtensor.register_network(wallet=wallet)"
returns: "(success, netuid)"
method: "subtensor.register_subnet(wallet=wallet) -> ExtrinsicResponse"
cost: "dynamic burn/lock"
limit: "may prune lowest-emission subnet if full"

Expand Down