Repository navigation
Why this release matters
Three independent silent-failure paths converged into "I ran benchmarks and nothing showed up." All three are fixed here, plus a substantial quality-of-life pass while we were in the area. First update in two weeks.
Reliability fixes
- CLI submissions now include
hardware_tier+attestation— previously every CLI row landed in Supabase withhardware_tier="", leaving tier-filtered dashboard views (Consumer-Mid, Consumer-High, Cloud) systematically empty. - MCP fingerprint is environment-aware. Real
collect_fingerprint()on desktop MCP clients (Gemini CLI, Claude Desktop, Cursor); placeholder only on Vercel. Was throwing away real RAM/CPU/GPU data and submittingunknown/0. submit_resultrejection logs bumped DEBUG → WARNING with response body included. API rejections were silent before; now you actually see what the server didn't like.- CTRL-C-safe submission ordering. Payload is enqueued to
~/.gauntlet/pending/before the network call; only HTTP 200 deletes the file. Mid-flight kill no longer loses the result. - Hardware fingerprint collected once per multi-model run (was rebuilt per model — pointless
psutil/sysctl/nvidia-smicalls on every iteration).
New commands & flags
gauntlet --version/-V— long overdue.gauntlet doctor— env-var detection,.envdiscovery, Supabase reachability, hardware preview, recent runs, retry queue. Drains the queue on its way through. Designed to answer "why didn't my last run show up?" in five seconds.gauntlet history— Rich table of past local runs with--limit Nand--model <substr>filtering.--no-submitflag andGAUNTLET_PRIVATE=1— opt out of community submission for iteration runs.- MCP startup banner prints
Community push: ENABLED/DISABLEDto stderr so misconfiguration surfaces upfront, not after a 20-minute run.
New plumbing
- dotenv-style env loader at package import. Searches
$GAUNTLET_ENV_FILE→.env.vercel.local/.env.local/.envwalking up to repo root →~/.gauntlet/.env. Allowlist of 10 keys; never overwrites parent-process env. Fixes the Gemini-CLI / Claude-Desktop subprocess env-blindness on macOS. - Persistent retry queue at
~/.gauntlet/pending/. Failed submissions queue to disk and replay on the next CLI invocation. Permanent 4xx rejections drop after one warning. Capped at 200 files. Self-healing without user intervention. - MCP write path now goes through the same validator as
/api/submit. Newgauntlet/mcp/submit_validator.pyenforces score-range, model-name length, category sanity, score-consistency, probe-count, attestation shape, probe-details size caps, and dedup. Closes the gap where/mcpaccepted unvalidated payloads. /api/versionendpoint returns{server, min_supported, recommended, latest, upgrade_command, upgrade_url, release_notes}.GAUNTLET_API_URLenv override for self-hosting / staging.- Auto-update notification on benchmark runs.
Performance
- Read endpoint cache TTLs:
max-age=30, s-maxage=60→max-age=300, s-maxage=900, stale-while-revalidate=86400. /api/predict+/api/recommendshare a 60s in-memory matrix cache with stale-fallback. Was fetching 2000 rows per request; now once per minute. Serves stale on Supabase outage instead of 503.- Dashboard polling pauses when the tab is hidden, refetches on focus. Background tabs no longer churn Supabase + Vercel functions.
Code health
- HMAC submit key deduplicated to
gauntlet.core.config.get_submit_key().gauntlet.basaltlabs.appURL also deduplicated; 5 hardcoded callsites consolidated. submit_handlerrefactored to use the shared validator. Single source of truth across/api/submitand the MCP write path.str(e)leakage plugged in three API handlers.MIN_CLI_VERSIONbumped 1.3.5 → 2.0.0. Anything below pre-dates the fingerprint + attestation fields and was being silently accepted withhardware_tier="".
Tests
- 42 new tests covering env-loader behavior, save-status formatting, and every validator rule.
- Total: 540 passing, 0 failures.
Docs
- New README section: Running gauntlet as a local MCP server. Per-client config blocks for Gemini CLI / Claude Desktop / Cursor, the macOS Dock-launch gotcha, and the
GAUNTLET_ENV_FILEoverride for CI. - Clarified MCP data-quality language: desktop MCP runs now produce real fingerprints; the "serverless" caveat applies only to the hosted endpoint.
Breaking change
MIN_CLI_VERSION is now 2.0.0. Submissions from CLI versions below 2.0.0 will be rejected with HTTP 400 and a clear "run pipx upgrade gauntlet-cli" message. If you've been pinned, this is the moment to upgrade.
Upgrade
pipx upgrade gauntlet-cli
gauntlet --version # → gauntlet 2.1.2
gauntlet doctor # confirm everything is wiredDeferred to a follow-up
- Splitting
gauntlet/dashboard/server.py(>1200 lines) into per-feature modules.TODO(refactor)block at the top of the file names the natural split points. Pure mechanical move — should land as its own focused PR.
22 files changed · +1,969 / −179 · 540 tests passing