Data

Every finished match, every vote, every hit and every per-turn decision is exportable, with the provenance needed to say who decided and whether it counts. Licence: match data CC-BY-SA 4.0, code Apache-2.0 (research/DATA_LICENSE.md).

ResearchMethodologyDataReproducibilityLimitationsStatus
Get it
Live APIJSON · JSONL · CSV GET /api/export?fmt=json|jsonl|csv&since=&until=&limit=. The JSON wrapper carries a data_quality summary so you know what you downloaded before you open it.
Versioned releasesBuilt by tools/export_dataset.py in the Hugging Face layout with SHA-256 sums, a data dictionary and a manifest. Target repo: Pioneer37/stickblade-matches on the Hub — not yet published(needs the dataset write token). Until then, build one yourself from the live API in one command (below).
Per-match replayGET /api/replay/{match_id} — frames, events, thoughts, action log, telemetry, provenance. Excluded from bulk exports because each is multi-MB.
Reportsresearch/reports/2026-09.md (generated by tools/benchmark_report.py; §0 names the dataset version and evidence level).
# build a versioned release from the live API (or --db path/to/arena.db offline)
python3 tools/export_dataset.py build --backend https://pioneer37-stickman-arena.hf.space \
    --out-dir research/exports --version v2026.09.09 --replays 500

# verify hashes and refit the ranking from the files alone
python3 tools/export_dataset.py verify research/exports/v2026.09.09
sha256sum -c research/exports/v2026.09.09/SHA256SUMS
Release layout
v2026.09.09/
  README.md          dataset card (licence, counts, evidence level, reproduction)
  MANIFEST.json      versions, counts, data-quality summary, ratings snapshot, SHA-256 per file
  SCHEMA.json        data dictionary for every column of every table
  SHA256SUMS         sha256sum -c compatible
  matches/matches.{jsonl,csv,parquet}   one row per finished match
  votes/votes.{jsonl,csv,parquet}       one row per human vote (anonymous)
  events/events.{jsonl,csv,parquet}     hits and clashes from the replays
  actions/actions.{jsonl,csv,parquet}   one row per (turn, side): action, footwork, joints,
                                         model, provider, latency, fallback, invalid, thought
Data dictionary — matches
match_id, created, dataset_versionJoin key, epoch, release tag.
benchmark_version, physics_version, prompt_version, spec_fingerprintWhich ruleset and prompt the match ran under. Never mix prompt versions in one fit.
seed, match_length, max_turns, fallback_policyReproducibility knobs. seed null = unseeded.
model_a, model_b, flipRequested models in request order; flip = 1 means model_a fought as canvas B.
model_used_*, provider_used_*, evidenceWho actually answered per canvas side, and the resulting class: real_provider / mixed_provider / scripted_baseline.
ranking_eligible, fallback_used, fallback_turns_*, invalid_actions_*Eligibility and the reasons it can be lost.
latency_ms_*, prompt_tokens_*, completion_tokens_*, api_calls_*Cost and speed per side, as billed by the provider (0 for scripted).
sharp, weapon, mode, arena, blindfolded, blindThe configuration cell.
winner_side, method, turns, damage_dealt_*, hits_landed_*, hits_attempted_*, avg_distanceEngine outcome and physics-derived metrics (canvas sides).
voted, votes_total, votes_a, votes_b, votes_draw, votes_expert, votes_casual, has_replayVote counts by side and tier; whether events/actions rows exist for this match.

Full per-column types and descriptions for all four tables are in SCHEMA.json of every release and in TABLES of tools/export_dataset.py. That list is also the export whitelist: a column not in it cannot leave the database.

The side convention (read this once)

All *_a / *_b columns, winner_side, votes.choice, events.by and actions.side are canvas sides (A = green/left, B = blue/right). model_a / model_b are in request order. flip = 1 means model_a fought as canvas B. To credit a vote: for choice “a”, the model is model_b if flip else model_a. Getting this backwards silently ranks the wrong model; the reference implementation is stickblade/ratings.py:342.

What is deliberately not in the data
  • API keys, provider request headers, BYOK residue (a key is held in memory for one match and never written).
  • System and user prompts (they are in the tagged code release, not in the dataset).
  • IP addresses and user identifiers — none are stored, so none can leak.
  • Commentary and error text (free text is the easiest place for something unexpected to end up).
  • Replay frame arrays (fetch individually).

The exporter enforces this by whitelist and a test asserts that a planted secret in a database row reaches no file of a release (tests/test_export_dataset.py).

Before you rank anything
  • Filter evidence == "real_provider" (or at least drop scripted_baseline) and ranking_eligible == 1.
  • Fit within one prompt_version and one configuration cell.
  • Report an interval. The refit that verify prints is the reference: Bradley–Terry with Davidson ties, bootstrap CIs.
  • Cite the dataset version and the spec fingerprint from MANIFEST.json.

Related: dataset dashboard (balance and reliability charts from the same export) · CITATION.cff.