Configuration
The validator reads configuration from environment variables (via .env). Defaults live in
validator/config.py, shared/chain.py, and validator/main.py.
Identity & wallet
| Variable | Default | Meaning |
|---|
NPA_NETUID | 98 | Subnet netuid |
NPA_NETWORK | finney | Subtensor network |
NPA_WALLET | default | Bittensor wallet name |
NPA_HOTKEY | default | Bittensor hotkey name |
NPA_BT_WALLET_DIR | — | Override wallet path |
NPA_API_URL | https://api.neverplayalone.ai | Backend API base URL |
Evaluation
| Variable | Default | Meaning |
|---|
NPA_MISSION_ID | resource_gathering | Local mission fallback (the roster wins) |
NPA_TASKS_PER_ROUND | 3 | Seeds per miner per round; score is the mean |
NPA_MAX_PARALLEL_AGENTS | 4 | Concurrent npabench agent slots |
NPA_WORKSPACE_ROOT | /tmp/npa_validator | Per-round workspace |
NPA_LOOP_POLL_SECONDS | 12 | Main loop poll cadence |
NPA_EVALUATION_START_CUTOFF_RATIO | 0.5 | Skip a round if starting past this fraction of it |
Weights
| Variable | Default | Meaning |
|---|
NPA_WEIGHT_EPOCH_BLOCKS | 360 | Blocks between weight updates within a round |
LLM proxy
| Variable | Default | Meaning |
|---|
OPENROUTER_API_KEY | — | OpenRouter key (proxy upstream) |
CHUTES_API_KEY | — | Chutes key (proxy upstream) |
NPA_PROXY_MAX_TOTAL_SPEND_USD | 0.01 | Spend cap per miner per task |
NPA_PROXY_UPSTREAM_TIMEOUT_SECONDS | 60 | Upstream request timeout |
NPA_PROXY_PORT | 8080 | Container-internal proxy port (never published to the host) |
Auto-update (scripts)
| Variable | Default | Meaning |
|---|
NPA_BENCH_REF | main | npabench git ref to vendor |
NPA_UPDATE_INTERVAL_SECONDS | 600 | Auto-update check interval |
NPA_UPDATE_EARLY_WINDOW_BLOCKS | 50 | Only restart within this window before a round |
NPA_VALIDATOR_PM2_NAME | validator | pm2 process name to restart |
Setting the mission
The active mission is chosen by the backend, not the validator. It is published in each
round's frozen roster as mission_id, and the validator reads roster["mission_id"]. Your local
NPA_MISSION_ID is only used as a fallback before a roster exists.
Mission changes apply next round
Because the roster is frozen at evaluation start, changing the backend mission only affects
the next round that freezes after the change. A round already under evaluation keeps the
mission it froze with. On a private test stack you can delete and regenerate the roster to force
the change immediately.