Inspiration

Two players each deposit $10,000. For one it is a normal week, and for the other it is 50 times their usual month. A threshold rule treats them the same and cannot say why either one matters. At the OLG anti-money-laundering workshop we heard that an investigator's first question is always "why this score?", so we built UltraByte around that question.

What it does

UltraByte ranks players for review across fraud, anti-money laundering (AML) and safer gambling, and it explains every number.

  • Four context checks, 25 points each: does spending fit the income band, is it a change from the player's own history, is it unusual for similar players (same age band and income band), and is activity coming from places that make no sense. Every point comes with a plain-English reason.
  • Labels on top of the score: STR candidate for FINTRAC indicators (deposits just under $10,000, little play before a withdrawal, a shared card or bank account, a payout to someone else), URGENT for impossible travel plus a new card or account, and Safer Gambling for rising deposits and night play.
  • Review queue that works like an inbox: URGENT and STR candidates on top, a to-do count in the menu, search and filters, and cases with an investigator comment pinned first.
  • One-screen decision: the player page shows the score breakdown, the reasons, a 6-month chart against similar players, and where they played. The investigator picks Escalate, Monitor, or Dismiss and adds a note.
  • Hand-off to compliance: compliance picks up escalated cases and resolves them. A handled case leaves the investigator's queue and moves to Overview, so each role only sees its own work.
  • Overview, shared cards and Report: cases grouped by the team that owns them, a diagram of cards and bank accounts shared between players, and a report with counts per status and category, handling time, and a CSV export.
  • Append-only audit trail: every decision and hand-off is saved with who, when, why, and the score at that moment, and the database rejects edits and deletes.

Version 1.0 to Version 2.0 (Main Track)

  • Version 1.0 is a simplified reconstruction of a typical threshold routine, not OLG's actual rule: alert on any single deposit of $10,000 or more, with no ranking and no reason. It runs as a separate console at /v1.
  • Version 2.0 is UltraByte.
  • Measured on our synthetic data: Version 1.0 caught 1 of 9 risky planted cases, wrongly flagged 1 of 2 normal controls, and missed $28,500 deposited as three deposits of $9,500. Version 2.0 caught 9 of 9 and cleared both controls. Out of 490 background players, only 6 reached the queue, and none scored High. Deciding case H took 7 clicks in Version 1.0 and 2 in Version 2.0, counted by an on-screen step counter.
  • Honest reading: we designed the planted cases ourselves to test each check, so this proves the logic works, not real-world performance.
  • Switching over: run Version 2.0 in shadow mode beside the old rule, compare on the validation page, let compliance tune the thresholds (every change is versioned), then make it the queue.

How we built it

Python with FastAPI and Jinja templates, PostgreSQL 16, Docker, and Nginx with TLS on a self-hosted server. Scoring is rule-based and explainable, with no machine-learning model. A deterministic generator creates 501 synthetic Ontario players over six months, including 10 planted cases, and the scorer never reads the case labels. An optional AI summary runs through n8n behind a switch, and it only summarises scores that were already calculated. Investigators and compliance sign in with separate roles, and test data can be added through manual entry or an Excel import.

Challenges we ran into

Keeping every number explainable without hiding weak spots. For example, the peer check gave automatic points to the top player in very small peer groups. We measured it (14 of 490 normal players flagged), added a rule that the peer check needs at least 20 comparable players, and reported the new result (6 of 490) instead of tuning the data to look perfect.

Building solo on the technical side for about 40 hours also meant often cutting scope. We locked a backlog on day one and logged every change and decision in BUILD-LOG.md.

Accomplishments that we're proud of

  • A live demo that runs end to end, from alert to resolved case to report.
  • Every score answers "why?", in words an investigator can read.
  • Governance by design: synthetic data labeled on every screen, data minimization (age band and income band only, no exact age, gender, or ethnicity), humans make every decision, and an audit trail a regulator can read.

What we learned

Context changes the meaning of the same transaction, and investigators trust a score they can read more than one they are told to accept. We also learned to report our own false positives openly, because that builds more trust than a perfect-looking number.

What's next for UltraByte

A shadow-mode pilot on real data under OLG's controls, investigator feedback on the reasons and thresholds, and validation on real outcomes before we make any claim about performance.

AI disclosure

We used AI coding assistants (Claude, by Anthropic) during the event to help write code, the synthetic data generator, and documentation. The team made the design decisions and reviewed and tested all output. Details are in the README.

Built With

Share this project:

Updates

Submission history