Vector · The rules
What you submit
A Hugging Face repository at a commit sha holding one file: the weights of the pinned architecture, checked against a template and served by the organizer’s own code.
3 min read
The contract
A submission is to one contest: a Hugging Face model repository at a commit sha, holding model.safetensors and nothing else that matters. Everything a repository may hold is model.safetensors, README.md, .gitattributes; a repository holding anything more is refused, whatever it is. The weights are of one pinned architecture, bpp_robotwin_l1_v1, and the class that builds it and loads them is the organizer's: vector_runtime.policy:BPPPolicy.
So nothing of yours ever runs. There is no manifest, no image and no sandbox, because there is no code of yours to contain. What you are held to instead is the architecture: your file has to be the weights that architecture takes, and it has to fit under 8 GiB. What is inside those weights — how they were trained, on what, from which initialization — is your business entirely, and is never inspected.
The file
Your Hugging Face model repository, at the commit you name on chain
owner/name@<commit sha>
model.safetensors # the only file that may differ between two submissions
README.md # optional, read by nobody
.gitattributes # optional, read by nobodyThe file is safetensors, which holds tensors and a JSON header and cannot hold code or a pickle. Before a single tensor is read, its header is compared with the pinned template (cfg c2dcb559ab79…, tensors 15ec2516d150…): the exact key set, and every tensor's shape and dtype. A file that adds a tensor, drops one, renames one or changes a dtype is refused at that point, with the mismatch named — not silently coerced, and not discovered halfway through a duel. A file that passes the header check but does not load is refused too, before any unit is played.
That check is the whole of the architecture rule, and it is why no container is needed: the competition reads the file's header, builds its own model, and loads numbers into it.
From a checkpoint to the chain
From a training checkpoint to a commitment on chain
robotensor-miner convert --ckpt epoch0042.ckpt --out ./submission
robotensor-miner check --dir ./submission # the header, against bpp_robotwin_l1_v1
robotensor-miner upload --dir ./submission --repo owner/name --private
robotensor-miner commit --repo owner/name --revision <sha> --netuid <N> \
--wallet.name <coldkey> --wallet.hotkey <hotkey>
# then make the repository public, before the validator's window closesconvert takes a training checkpoint and writes the one file, keeping the EMA weights;
check runs the same header comparison the validator will, so a refusal costs you a minute
rather than a duel. Nothing of the conversion is trusted later: whatever you upload is checked
again on the way in.
Pin a commit
Upload to Hugging Face and name it on chain at a commit sha. A branch or tag name is refused:
a mutable name would let the weights that hold a crown quietly stop being the weights that were
scored. An abbreviated sha is refused too, because the submission key is a hash of
repo@revision and an abbreviation would be a different key for the same weights. The revision
you name is the revision that is evaluated, forever; a new commit is a new entry, at the back of
the queue.
Your weights stay yours
The file is public once the repository is, and the same content cannot be submitted twice: a file whose sha256 matches an earlier entry's is refused as a duplicate, and the earlier commitment keeps it. Whoever names weights on chain first owns them.
That is why the order matters. Upload to a private repository, name the commit on chain, and only then make the repository public. A repository the Hub will not show yet is given a window to appear — long enough to publish it deliberately, short enough that an entry cannot sit unopened forever — and is refused when the window closes.
What it is asked to do
The architecture fixes the interface, so there is nothing to declare: actions are ee, of dimension ee: 16, and the model is given one demonstration per unit — the frames, the action trajectory and the proprioception — then acts from a different initial state. A unit's seed is derived from the duel identifier and published with the record. Privileged prompt metadata — the scene seed, the success condition — never reaches the model.
It is served in a process of its own, speaking protocol 1: named numpy arrays and JSON fields over an authenticated socket, never a pickle. It has 600 s to build and load, 60 s to answer one observation, and 1,200 s over a whole unit. Running out of any of them loses the unit; a unit the orchestrator cannot complete inside its own wall clock is void, not a loss — see void units.
What every entry is held to, from spec.json
- Architecture
- bpp_robotwin_l1_v1
- Weights file
- model.safetensors
- Everything a repository may hold
- model.safetensors, README.md, .gitattributes
- The class that serves it
- vector_runtime.policy:BPPPolicy
- Template the header is checked against
- cfg c2dcb559ab79…, tensors 15ec2516d150…
- Policy protocol
- 1
- Repository size cap
- 8 GiB
Rendered from spec.json at build time — the same file the orchestrator reads.
Budgets
Wall clocks the orchestrator enforces, from spec.json
- Policy start budget
- 600 s
- Per-action budget
- 60 s
- Policy budget per unit
- 1,200 s
- Prompt materialization wall clock
- 2,400 s
- Per-unit wall clock
- 1,800 s
- Per-side wall clock
- 12 h
- Per-duel wall clock
- 24 h
Rendered from spec.json at build time — the same file the orchestrator reads.
Hard timeouts exist because a duel has to terminate, and because a per-action budget bounds test-time search without needing a separate rule about it.
Before you send it
Honest measurement says what is published about your entry and how to check the arithmetic on a duel page. Questions answers the rest.
