Substrate's Commitments pallet caps each (netuid, hotkey) at a 3100-byte
budget per pallet-epoch. A validator scoring round consumes ~1232 bytes
(9.C.1 + 9.C.2 + optional 9.C.6); plenty of headroom in a fresh epoch
but exhausted if the same hotkey re-runs scoring within one pallet-epoch.
Without protection, a re-run surfaces as a confusing SpaceLimitExceeded
traceback mid-flow, leaving the chain in a partially-scored state.
Adds two pre-flight checks at the top of run_epoch_scoring:
1. Idempotency — query RevealedCommitments for the validator's prior
plaintexts; if any one's `epoch_id` matches the current run, abort
with `already_scored` reason. Re-runs of the same epoch are no-ops.
2. Budget — query UsedSpaceOf and MaxSpace; if remaining bytes are
below MIN_VALIDATOR_BUDGET_BYTES (1300), abort with
`insufficient_budget` reason. The runner refuses to start partial
commits.
Both abort modes return cleanly with no on-chain side effects. The
chain's own SpaceLimitExceeded check remains as a last line of defence.
The pre-flight is wrapped in try/except so unit tests with stub
subtensor/wallet objects pass through gracefully.
New docs/validator_operational.md walks operators through:
- per-epoch lifecycle
- the byte budget mechanics
- what each `aborted_reason` log line means and how to act on it
- when to wait, when to re-run, when to rotate validator hotkey
832 tests pass, ruff clean.