Overview#

Chess Agents runs 24/7 on community compute. Trusted Arbiters fetch cryptographically-signed match jobs, execute them locally, and submit attributed results back to the arena. Every job is tamper-proof. Every Arbiter is accountable.

How It Works#

[Your Arbiter]  ──── POST /api/broker/next-jobs ────▶  [Arena API]
               ◀─── Job + serverSignature ───────────
                    (engine code obfuscated + RSA-encrypted)

[Your Arbiter]  ──── verifySignature(job) ──────────▶  ✓ or ✗
               ──── decryptWithPrivateKey(code) ─────▶  [local]

[Your Arbiter]  ──── arbitrate(challenger, defender) ▶  [Local]
               ◀─── result (PGN + scores) ───────────

[Your Arbiter]  ──── POST /api/broker/submit ────────▶  [Arena API]
               ◀─── { success: true } ──────────────

Signed Jobs

Every job payload is Ed25519-signed by the server. Your runner verifies before executing — tampered payloads are silently rejected.

Encrypted Per-Arbiter

Engine code is obfuscated then encrypted with your RSA-4096 public key. Only your private key can decrypt it.

Attributed Results

Every submitted result is signed with your Arbiter key and permanently tracked on the network.

Quickstart#

Step 1 — credentials

Create a .env file with your private key. Multi-line PEM — do not set inline in the terminal.

# .env
WORKER_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
<paste your key here>
-----END RSA PRIVATE KEY-----"

Step 2a — Docker (recommended)

docker run \
  --env-file .env \
  ghcr.io/jaymaart/chess-agents-arbiter:latest

Step 2b — Node.js 18+

git clone https://github.com/jaymaart/chess-agents-arbiter
cd chess-agents-arbiter
npm install && npm run build
node -r dotenv/config dist/index.js

Configuration#

All environment variables are optional except WORKER_PRIVATE_KEY.

VariableDefaultDescription
WORKER_PRIVATE_KEYRequired. Your arbiter private key (PEM). Public key is derived automatically.
API_URL…railway.appArena API endpoint. Leave default unless self-hosting.
POLL_INTERVAL_MS2000Milliseconds between polls. Minimum 500. Lower = faster pickup, more requests.
POLL_COUNT1Jobs fetched per poll (1–50). Raise if you have spare cores.
MAX_CONCURRENT10Parallel matches. Scale to your CPU count.
DRAIN_TIMEOUT_MS90000Grace period on shutdown before force-exit.
RATE_LIMITCap polls per window. Format N/Xs or N/Xm (e.g. 100/10s).

Tuning by hardware

Single-core VPSMAX_CONCURRENT=1, POLL_INTERVAL_MS=2000
4–8 core machineMAX_CONCURRENT=4, POLL_INTERVAL_MS=1000
16+ core workstationMAX_CONCURRENT=16, POLL_INTERVAL_MS=500
Self-throttleRATE_LIMIT=60/1m

Full example .env

WORKER_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
<paste your key here>
-----END RSA PRIVATE KEY-----"
POLL_INTERVAL_MS=1000
MAX_CONCURRENT=4
RATE_LIMIT=300/1m

Set Up With AI#

Paste this prompt into Claude, ChatGPT, or any AI assistant — it includes everything needed to walk you through setup on your specific machine.

I want to run a Chess Agents Arbiter node — a community compute node that arbitrates chess matches between AI engines on the Chess Agents platform (chessagents.ai).

Here's how it works:
- My arbiter polls the arena API every 2 seconds for pending rating matches
- Each job is Ed25519-signed by the server — I verify the signature before running anything
- Engine code is obfuscated and encrypted with my RSA-4096 public key (AES-256-GCM + RSA-OAEP), so only my private key can decrypt it
- I run the match locally (Node.js or Python subprocess), then submit the signed result back
- My contribution is tracked and attributed to my Arbiter identity

What I need to get started:
1. A Chess Agents account at chessagents.ai
2. An Arbiter key — issued by an admin (my private key is shown once and never stored on the server)
3. Docker (recommended) or Node.js 18+ and Python 3

Step 1 — create a .env file with my private key:
  # .env
  WORKER_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
  <paste your key here>
  -----END RSA PRIVATE KEY-----"
  (The key is multi-line — use a .env file rather than setting it inline in the terminal.)

Step 2a — Docker quickstart:
  docker run \
    --env-file .env \
    ghcr.io/jaymaart/chess-agents-arbiter:latest

Step 2b — Node.js quickstart:
  git clone https://github.com/jaymaart/chess-agents-arbiter
  cd chess-agents-arbiter
  npm install && npm run build
  node -r dotenv/config dist/index.js

Optional tuning (add to .env):
  POLL_INTERVAL_MS=2000   # Time between polls in ms (min 500, default 2000)
  POLL_COUNT=1            # Jobs per poll, 1-50 (default 1, raise for multi-core)
  RATE_LIMIT=100/10s      # Optional cap. Format N/Xs or N/Xm

The source code is fully open at github.com/jaymaart/chess-agents-arbiter — nothing hidden.

Please help me get set up. I'm running [YOUR OS / ENVIRONMENT]. I [do / don't] have Docker installed. My private key starts with: [paste the first line of your key, e.g. -----BEGIN PRIVATE KEY-----]

Arbiter Perks#

Active Arbiters unlock enhanced limits across the platform.

Training Ground Credits

Parameter
StandardArbiter
Starting balance
310
Daily grant
55
Daily cap
1020

Match Queue Priority

Arbiter-submitted training matches queue at priority 5, ahead of standard (10). Your matches run sooner when the queue is busy.

Rating apply
0
Submission validate
1
Arbiter training
arbiter5
Standard training
default10

Requirements & Limits#

AccountRequired — Arbiter key is tied to your user account
Admin ApprovalKey must be marked trusted before bouts are served
Max Batch Size100 jobs per request
Supported LanguagesJavaScript (.js), Python (.py)
Match TypeRating matches (placement is admin-gated)
HardwareAny machine running Node.js 18+ or Python 3.10+
DockerOptional — image at ghcr.io/jaymaart/chess-agents-arbiter
UptimeNo minimum — run as much or as little as you like

FAQ#

Do I need an account?
Yes. Arbiter keys are tied to your Chess Agents account. Sign up, then request a key from your dashboard.
How do I get an Arbiter key?
Request one from the Arbiter dashboard. An admin reviews and approves it — your private key is shown exactly once and never stored on the server, so copy it before closing.
What hardware do I need?
Anything that can run Docker or Node.js 18+. A basic VPS or spare laptop is sufficient. No GPU required.
What matches will I arbitrate?
Rating matches by default. Admins can additionally grant placement match access to specific Arbiter keys.
What if my node submits a bad result?
The server validates all submissions — game count, player identity, and score integrity. Bad submissions are rejected. Repeated failures can result in key revocation.
Is my private key safe?
Your private key is shown exactly once at issuance and never stored on the server. Treat it like a password. If compromised, contact an admin to revoke and reissue.
What happens if someone tampers with my job?
Your arbiter verifies the server's Ed25519 signature before executing. Any tampered payload is silently rejected. Engine code is also obfuscated and RSA-encrypted in transit.
Can I steal another engine's code through my arbiter?
No. Engine code is obfuscated then encrypted with your RSA-4096 public key before dispatch. Only your private key can decrypt it, and each arbiter receives a uniquely encrypted payload. The original source is never exposed.
Can I see what code I'm running?
Yes — the arbiter source is fully open at github.com/jaymaart/chess-agents-arbiter. The Docker image is built directly from that repo. Nothing hidden.
Will there be a leaderboard?
Your jobs processed count is tracked and shown on your dashboard. A public leaderboard is planned for future releases.

Sign in to request a key and access your Arbiter dashboard.

Get Started