Start here

A real, live web application. Here's the whole thing.

This is Tourney — a March Madness pool where you draft individual college basketball players and coaches, not just teams, and your score updates automatically as real games happen. (New to the pool? Read the instructions — how to join, pay, and how scoring works.) It's built end to end, top to bottom: the product, the live-scoring engine, two different AI integrations, and the security model underneath all of it. This page is the fast tour. Everything on it is real and running — click through and try it. Coming soon: Runway — an agentic AI tool that asks you questions to help figure out if you can retire.

01The idea

This started as a way to actually dive deep into AI — hands-on enough to work toward Anthropic's Claude certification, not another toy project. The idea was simple: take the pool I've run for 15+ years and upgrade the greatest pool ever into a real, live application.

A normal bracket pool asks you to predict which teams win. This one asks you to draft individual players — 22 of them, across five groups, seeded 1–4 through 13–16 plus head coaches — and your score comes from what those specific people actually do in real games. Two people who agree on every game winner can still land on completely different scores, because they drafted different players off the same teams. It rewards knowing the players, not just the bracket.

The pool itself has run for 15+ years, on paper, then spreadsheets, then a semi-automated Google Sheet. This year it became this. The full origin story is worth the five minutes if you want the "why" before the "how."

02Try it yourself, right now

Nothing below is a mockup or a demo environment. It's the live app — mid-tournament right now, with games played through the Sweet 16.

03The build — what actually went into this

None of this started as expertise. It became expertise by getting built.

Every layer here is something learned to make this real: a Flask web app backed by MySQL, containerized with Docker and served through Nginx; a frontend that updates itself live via HTMX instead of full page reloads; a background scheduler that talks to ESPN's live APIs; the Model Context Protocol wired up so an AI client and an AI server can hand tool calls back and forth safely; email delivery through AWS SES; a second DuckDB warehouse, rebuilt from the live database, for analysis that never touches production; a real CI/CD pipeline that won't let a change reach production without passing tests first. None of it existed a year ago. All of it runs today, for real people, during a live tournament.

It isn't a one-off build, either — there's an actual process behind it: specs before code, an independent review pass before anything ships, a deploy pipeline that gates on tests, not vibes. The Process page → shows how that loop actually runs.

04The AI, running on hardware most people don't have

Two different AI setups, running side by side, generating the same daily commentary — a genuine build-vs-buy comparison, not a gimmick.

  • Anthropic's Claude, called through a real agentic loop: the model is handed live tools (standings, today's results, top movers) and decides for itself what to fetch. The prompt deliberately contains no data.
  • A self-hosted, open-weight model running on a dedicated NVIDIA DGX Spark — a physical GPU box most builders never get hands-on time with. Same tools, same task, run independently so the two approaches can be compared honestly.

Read the full AI page → — it includes the actual tool-call sequence diagram and the security constraints the AI worker runs under. Or try it live from the CTAs above.

05Built to be safe, not just built to work

A side project that handles real names, emails, and phone numbers doesn't get to skip security because it's small.

  • Passwords are hashed with scrypt — not stored, not recoverable, not even by an admin.
  • The AI worker connects with its own least-privilege database account: one table, no PII, outbound-only, rate-limited, with hard caps on tool calls, timeout, and payload size.
  • Every deploy runs through an automated test suite and CI/CD pipeline gate before it reaches production — nothing ships on faith.

Full security page → covers the rest: session handling, CSRF, rate limiting, and secret rotation.

06What "live" actually means here

This isn't a static bracket you fill in once and forget. It's a running system.

  • Games update in real time. A background scheduler polls ESPN every few minutes during live windows — no one is refreshing a spreadsheet by hand.
  • Scores link straight to the players who earned them. Every game result ties back to the individual player stat lines that fed it, so you can trace a point total to the exact play that produced it.
  • Your entry shows real player points, not just a final number. Open any bracket and see per-player scoring, not a black-box total.

See it end to end on the Big Picture page — that's where the actual data-flow diagram lives.

07Where to go deeper

This page is the trailer. Everything under /about is the full picture.

  • Origin story — fifteen years of paper brackets and spreadsheets, and why this year was the leap to a real application.
  • Big Picture — the whole architecture, one AWS box plus a private GPU box, diagrammed by hand.
  • The Process — how a solo developer ships safely: specs, review, and a real CI/CD gate.
  • AI: Foundation vs. Open-Weight — the full agentic build, tool calls, and the DGX Spark comparison.
  • Security — what protects real player data, in plain language.
  • Everything else — the full engineering hub, if you want to keep going.
Every specific capability named on this page is real, running in production, and linked to the page that proves it — nothing here is a mockup. Built solo, learned along the way, with real people's data treated as a reason to be careful rather than a reason to slow down. Click around — that's the point of this page.