Bretton Lattice
A pipeline that reads a batch of closed financial-crime case files as one body of evidence, using Claude to surface shared entities across cases that no single review would catch.
- Tech
- Next.js, TypeScript, Claude (Anthropic API), Supabase (Postgres), pg_trgm, react-force-graph-2d
- Date
- Jul 31 to Aug 1, 2026
- Status
- Prototype — Live Demo
Financial-crime investigators review cases one at a time, and a case that passes review in isolation can still be part of a ring that spans several cases, six shell companies sharing a registered agent, say, with no individual review positioned to notice. I built Bretton Lattice, a Next.js pipeline that reads a whole batch of closed case files as one body of evidence and surfaces the network structure, shared addresses, phone numbers, registered agents, that a single-case review would never catch, sitting on top of per-case investigation rather than replacing it.
Pipeline Architecture
Extraction & Matching
A three-stage pipeline runs over a batch of case narratives: Claude extracts structured entities (names, addresses, phone numbers, registered agents) from each case's free text, a deterministic pass self-joins entities that match exactly, and a second pass runs a self-implemented trigram similarity function, tuned to mirror Postgres's own pg_trgm scoring, to catch near-matches worth sending to Claude for adjudication. Only pairs that clear a per-type similarity threshold reach the model, batched 15 at a time behind a forced tool call rather than free-text JSON, so a malformed model response can never silently corrupt a match.
Clustering & Reporting
Matched entities feed a union-find clustering pass that groups cases into networks, and each resulting network gets a Claude-generated investigative brief citing the specific evidence behind it. The brief generator is explicitly constrained to only cite connection IDs that exist in the real evidence set, filtering out anything the model invents, so a generated finding can never reference a connection that isn't actually there.
Visualization
Results render as a force-directed graph, canvas-based, no dependency on a heavier visualization stack, with unconnected cases sitting on an outer ring and clustered cases colored by network. Edges are solid for rule-based matches and dashed for model-adjudicated ones, so an investigator can tell at a glance which links are certain and which are judgment calls, and clicking an edge shows the shared value and the reasoning behind the match.
Technical Challenges
The union-find clustering had a correctness bug that stayed invisible until a larger test batch surfaced it: because union-find merges two cases on any connection between them, a single weak, low-confidence match, two unrelated businesses that happened to share a suite number in the same office building, was enough to chain two otherwise unrelated networks into one falsely oversized ring. I fixed it by moving the confidence threshold into the union step itself rather than just the extraction step: only connections above a confidence floor are allowed to merge two components, while lower-confidence matches still get stored and surfaced as supporting evidence inside a brief, without being allowed to reshape the network's actual structure.
A second issue showed up when I re-ran the pipeline against the same case batch mid-development: without an idempotency key, every run inserted a fresh set of connection rows instead of reconciling against what already existed, so pressing 'run' twice didn't just waste model calls, it silently doubled the evidence count backing every finding and made a network look more corroborated than it actually was. The fix was a deterministic upsert key on the case pair, entity type, and normalized value, so a rerun always converges to the same connection set instead of accumulating duplicates.
Results
Running the pipeline against a seeded set of 18 synthetic cases (11 clean, 7 across two planted rings) extracted 143 entities, surfaced 12 connections (10 caught deterministically, 2 requiring model adjudication), and correctly clustered them into 2 networks with 7 generated findings, end to end from a single button press in the UI.
Other
- Built and shipped solo in a single sitting, from schema design through a working, deployed demo.
- Row-level security enforced at the database layer, not just in application code.