Inspiration

On October 15, the FTC sued a ticket broker that it says used 1,300 accounts to buy 7,624 tickets to one Beyoncé concert, then made $833,000 reselling them (FTC). Accounts are cheap to make, and AI keeps making the bots behind them better. Friends who want to go together end up paying resale prices for seats that sold out in seconds.

We wanted a seat that only a real person can pick up. So we built Gus, a small robot penguin that gives each face-value seat to one live face, in person. A broker with 1,300 accounts still has one face.

The name comes from Argus, the hundred-eyed watchman of Greek myth. Gus only needs one look.

What it does

Gus is an iPhone app and a robot. The app finds shows for you and your friends, and the robot hands out the seats.

  1. Tell Gus what you like. Pick your city, when you're free, genres, a vibe, and artists, or type one sentence and Gus drafts your profile. Gus asks one or two follow-up questions.
  2. Gus picks three shows. Gus scores every Bay Area music show on Ticketmaster for the next 30 days, and Claude Haiku picks three. Each pick says why, citing your profile, your friends' profiles, and the event, and shows the resale price you'd skip.
  3. Gus builds the squad. For the show you choose, Gus picks which friends the show fits, names the squad, writes a line for each friend, and drafts the first message for the group chat.
  4. Hold a face-value seat. Each friend agrees to the face check and holds their own seat on their own phone. The card is charged only after Gus checks it's you.
  5. Pick it up from Gus. A compass arrow leads you to Gus. Scan the code on Gus's stand, confirm with your phone's Face ID, and face Gus's camera. Gus calls your name and asks for a random move (blink, or turn your head), so a photo or a recording can't follow along.
  6. One face, one seat. Gus turns your face into a template, a list of 512 numbers, never a photo. The backend refuses a face that already holds a seat in the deal. At the door, Gus matches you to your template and deletes the template in the same step. Your face is the ticket until the door, so there's nothing to resell.

Real and stand-in: the shows, Haiku's picks, Gus's face check, and the templates are real. The deals and seat counts are ours, and the app's checkout is a test screen that charges no card. At our table, check-in pairs Face ID with Gus's move check; step 6's template match runs end to end in the backend but isn't joined to that check-in yet.

How we built it

The iPhone app and Gus (an iPad, a webcam, and a robot body) share one Convex backend.

  • iPhone app: SwiftUI on Convex's Swift client. Live queries push Gus's progress and the check-in result to the phone as they happen. There's no sign-in: each phone makes a random session token, and the backend stores only its hash.
  • Backend (Convex, TypeScript): default-deny access rules on every table, the Rate Limiter and Workpool components, scheduled cleanup, and the functions Gus calls to check a fan in, enroll a face, and verify at the door. Templates are sealed per deal with AES-GCM and compared inside Convex, so any Gus can check any fan and no Gus keeps face data. Stripe holds and captures run in test mode as retried Workpool jobs.
  • Gus's picks: Ticketmaster's Discovery API, refreshed every 6 hours, feeds a scoring step in code. Claude Haiku picks 3 of the top 10 through a forced tool call, so it can only return shows we sent it. Its web search tool finds resale prices, and template text covers a Haiku failure. A full run takes 19 seconds cold and 4 with caches.
  • Gus's face check: YuNet finds the face, MediaPipe's Face Landmarker watches for the move, and InsightFace's small recognizer (w600k_mbf on ONNX Runtime) makes the template. Our match threshold of 0.30 gave 1 false match in 25,000 pairs on the LFW benchmark. The check runs in Python on a laptop, and our Swift port runs it on the iPad.
  • Gus's screen and body: a SwiftUI app on the iPad shows what Gus says. Above it, a penguin designed in OpenSCAD sits on a deck with a USB webcam in its front edge, a small LCD, and three servos for the flippers and a swivel, driven by an Arduino.

Challenges we ran into

  • Finding a home for the face check. A Coral dev board came first, but its NPU runtime didn't match the compiler, and the models that did load ran it out of memory. A Raspberry Pi 5 couldn't get online through a Wi-Fi login page. We moved the check to a laptop, then ported it to the iPad in Gus's stand, which joins Wi-Fi like any phone. The laptop stays as the fallback.
  • Speed. Our first model took 17 to 24 seconds to rank shows, too slow while a fan waits. We split the job: code scores every show, and Claude Haiku only picks and explains, in 4.4 seconds.
  • Where face data lives. Templates first stayed on the laptop at pickup, so the door had to be the same machine. We moved them into the backend, sealed per deal, compared there, and deleted at the door or at 11:59 PM on show day.

Accomplishments that we're proud of

  • A real pickup and door check with Sam's face through the live backend: verified 5.7 seconds after Gus looked up the pass, matched at the door in 4.45 seconds, and the template deleted in the same step.
  • The face check ported to the iPad: about 20 ms a frame, the same template as the laptop (cosine similarity 0.999996 on a test photo), and a full check-in through the backend.
  • What we store is small: 512 numbers instead of a photo, "on site until" instead of a location, and a delete time on every template.
  • 178 backend tests. For the access rules, we broke each guard on purpose and checked that a test caught it.

What we learned

  • Check edge hardware before planning around it. An NPU only helps if its runtime matches your compiler, and a device without a browser can't get through a Wi-Fi login page.
  • A fast model doing a narrow job beat a slower model doing the whole job. Code is better at filtering dates and prices; the model is better at explaining why a show fits your squad.
  • We ran many Claude Code agents in parallel, coordinated through one live plan file and a decision record for every costly choice (13 so far). Writing those decisions down let us change course several times in one night and still know why.

What's next

  • Join the template match to the table check-in, so one flow runs the whole one-face, one-seat check.
  • A card screen in the app on top of the backend's Stripe holds.
  • Gus's brain fully on the iPad, talking to the body over Bluetooth.
  • Squad check-in: every friend's face in one frame, one move together.
  • Group discounts that grow as more friends commit, and a console for promoters to set up deals and drops.

Built With

Share this project:

Updates

Submission history