Try it live: https://interval.timidan.xyz (no sign-in)

Inspiration

Two sets at the same time on different stages is normal. The overlaps that hurt are between acts whose audiences overlap too, because those fans must choose. Programmers judge that by gut feel and streaming stats, one pair at a time, while the draft keeps changing. Qloo's taste graph can score every pair on a bill at once.

What it does

  • Draws a real running order (Austin City Limits 2026 Weekend 1 Friday, and two days of III Points) as stages by time, and marks every overlap between acts Qloo links strongly.
  • Repairs it: a bounded search moves at most four sets, validates every proposal against holds, stage overlaps and billing bands, and draws the tested change on the grid before anything is applied. Apply and undo are one click each.
  • Shows its proof: both directed Qloo scores behind each warning, the request that produced them, and a comparison against three LLM-only repairs and a genre-only repair on the same metric.
  • Takes requests in plain words ("Keep both headliners where they are") through an agent that turns them into typed constraints and re-plans, answering only with facts its tools returned.
  • Imports your own draft as CSV, asks you to confirm each artist match, states the Qloo call cost before scoring, then runs the same flow.

How we built it

  • Qloo: /search for artist identity (a person confirms each match), then one /v2/insights request per act with filter.results.entities set to every other act on the bill. Scores are ranked within each act's row; a pair's weight is the mean of its two directed percentiles; 0.9 and above is a strong link; unscored pairs stay unknown, never zero.
  • Agent: single-turn strict-JSON tool calls to gpt-5.6-luna through a self-hosted Hermes gateway; the server executes the tools and renders every name and number from their results.
  • Search and validation: a worker-thread local search with a fixed seed and a 15,000-evaluation budget; every proposal is validated before it is returned.
  • Front end: React 19, Vite, Tailwind v4, motion, OGL shaders over real stage footage, Phosphor icons, SmoothUI and Inspira UI components.
  • Server: Node 22 built-ins only (http, sqlite, worker threads). Qloo responses are cached server-side and never committed.

Challenges we ran into

  • Qloo identifies fewer undercard acts than headliners (18 of 31 on ACL Friday), and names collide (ACL's Leon Thomas is "Leon Thomas III", not the jazz singer). Interval keeps every unknown pair unknown and asks a person to confirm matches.
  • A strict rule for unknown acts, which protects every unknown pair on its own, blocks the one fix ACL Friday needs. The default is a looser rule that stops the total overlap with unknown acts from growing; the strict rule is one click away, and the comparison shows both.

Accomplishments that we're proud of

  • On ACL Friday, Interval removes the strong clash (14 Qloo-weighted clash minutes to 0) by moving Paris Paloma 15 minutes. None of the three LLM-only repairs lowered it.
  • On III Points, the looser rule takes Friday from 137 to 100 and Saturday from 168 to 98.
  • An imported draft was matched, scored live and repaired end to end.
  • Ten visitors pressing Repair at once on III Points Saturday (119 sets) all get tested changes on a 1.5-CPU server: identical searches share one result and the rest queue.

What we learned

Affinity is a strong signal for which overlaps matter, but only once per-request normalisation, coverage gaps and name collisions are handled explicitly.

What's next for Interval

Put it in front of a festival programmer with their own draft, and price it only after they've reacted to real warnings.

Built With

Share this project:

Updates

Submission history