Deliberately accepted
Audit rows are organizer-visible but not tamper-proof (no hash chain). State-changing APIs rely on SameSite=Lax httpOnly JSON cookies with no per-request CSRF tokens. Rate limits live in a single-process store, so multi-worker deploys need a shared store.
Pairwise Bradley-Terry stays an informational ranking method, not a voting mode. Pairwise voting would need a different abuse story.
Why disclose
Writing THREAT-MODEL.md made judging Q&A easier, not harder — every residual has a mitigation, an owner, and a next step. Login brute force gets 100/min per (IP, email) → 429 plus ~100ms bcrypt; API keys are bearer-style until revoked; organizer screenshots during voting are out of scope and stated as such.
Run it yourself
Every post maps to a real route or file in this repo. Start with the gallery, then the docs.
Keep reading
View allOct 3, 2026 · Company
Build the platform that will judge you: how we built DOGFOOD 2026
FastAPI + Next.js + Postgres with backend-enforced judge isolation, z-score calibration and one-command Docker — our Write-Up Quest build log.
Oct 3, 2026 · Engineering
Run the whole platform with one command: setup guide (main branch)
Clone main, docker compose up, seed fixtures, test accounts, and the 7/7 acceptance checker — everything to go from zero to judging in minutes.
Sep 28, 2026 · Engineering
Fair ranking is not an average: z-scores, Bradley-Terry and Borda
Raw averages reward lucky judge draws. How per-judge calibration plus two extra ranking views produce a ROBUST/FRAGILE verdict organizers can defend.