A challenge is an independent repository and Docker image. It owns its logic, public routes, submissions, scoring data, database schema, and challenge-local files.
Challenge state is SQLite on the challenge /data Swarm volume: BASE injects
CHALLENGE_DATABASE_URL=sqlite+aiosqlite:////data/challenge.sqlite3 and mounts
/data. There is no Postgres server per challenge; the /data volume is the
single home for the database, artifacts, analyzer output, and uploaded files.
The challenge runs on the manager node as a Swarm replicated service (placement
node.role==manager) on an encrypted overlay network. The /data volume is
retained by default when the service is removed.
GET /health
GET /version
GET /internal/v1/get_weights
The internal endpoint is authenticated with a per-challenge shared token mounted by the master.
uv run base challenge create code-arena --out ../code-arena
cd ../code-arena
uv run --extra dev pytestPublic routes are exposed through /challenges/{slug}/.... The master blocks
/internal/*, /health, /version, Agent Challenge internal launch paths such
as POST /internal/v1/submissions/{submission_id}/launch, and generic benchmark
execution-shaped routes such as /benchmark-executions from the public proxy.
The BASE proxy preserves challenge-origin non-2xx responses when the challenge
answered safely. Transport failures, unreachable services, Swarm service DNS
failures, and connection timeouts become safe 502 responses. Frontends should
render unavailable copy and retry with backoff instead of showing raw text such
as BASE request failed with status 502.
Operator checklist for challenge 502s:
- Confirm ingress includes
/challengesand routes it to the BASE proxy. - Confirm the slug maps to a running challenge service.
- Confirm challenge health, the Swarm service name, service DNS on the overlay network, the service port, and at least one running task.
- Determine whether the response came from proxy transport handling or the challenge origin. Only transport failures should be rewritten to 502.
Agent Challenge env and public launch routes are public proxy routes, but BASE
stores neither their request bodies nor per-submission env values. Allowed BASE
paths are GET/PUT /challenges/agent-challenge/submissions/{id}/env,
POST /challenges/agent-challenge/submissions/{id}/env/confirm-empty, and
POST /challenges/agent-challenge/submissions/{id}/launch; the challenge-local
paths are GET/PUT /submissions/{id}/env,
POST /submissions/{id}/env/confirm-empty, and POST /submissions/{id}/launch.
Only the signed miner headers X-Hotkey, X-Signature, X-Nonce, and
X-Timestamp are preserved for those routes.
POST /internal/v1/submissions/{submission_id}/launch is a bridge/internal API
only, not a public miner API, and the proxy must not expose generic benchmark
execution routes. The generic BASE broker remains the execution substrate for
controlled BASE SDK jobs behind the challenge boundary.
