AI Projects · CrossCase

Linkage blindness: why connecting police cases still depends on luck

An open-source proposal, a replication study, and a 3-minute demo.

TL;DR

A phone call that didn't have to happen

In April 2024, in a county in Wisconsin, two police agencies each held one half of the same murder.

One department had a missing-person report and a burned-out car. The county sheriff's office had human remains, found in a lakeside park. Same county. Same week. No system connected them.

What connected them was a patrol officer on the missing-person case who felt something was off about the timing, looked up a suspicious car fire, and called the other agency to ask: could these be related? They were. Weeks later, more remains surfaced on a beach 53 miles away, across the state line, in a third agency's jurisdiction. That link was made only because the case had become national news by then.

The case was widely covered, including a CBS 48 Hours episode, and the offender was convicted in 2025. I am deliberately not naming the victim here; this piece is about the system, not the tragedy. The facts are the argument: in 2024, in the same county, in the same week, the link between a body and a burned car came down to one officer's gut feeling and a phone call she didn't have to make.

Criminologist Steven Egger gave this failure mode a name in 1984: linkage blindness. That was forty years ago.

What exists today, and what it can't see

Cross-jurisdiction data sharing is not new. The FBI's N-DEx holds over a billion records and can notify an investigator when new records match a subscription. Commercial platforms aggregate records across agencies and answer searches. The Murder Accountability Project (MAP) clusters FBI homicide statistics and has famously flagged real serial patterns years before arrests confirmed them.

Each of these catches something. None of them catches the case above:

The gap is structural. A burned car is not a homicide, so it never enters homicide data at all. The linking evidence lives in specifics: a vehicle, a paint color, a debris match. And the two records sat with different agencies, which means no single database's internal checks would ever compare them.

I tested the best existing layer before proposing a new one

Before claiming a gap, I wanted to check how much the strongest existing approach can be pushed. MAP publishes both its data (the FBI Supplementary Homicide Report, 1976 to 2024, about 913,000 records) and its clustering algorithm. So I replicated it, and then tried to beat it.

The replication worked cleanly. On a 2010 time slice, the algorithm surfaces the Gary, Indiana cluster that MAP warned police about that year, four years before an arrest vindicated the warning. The famous clusters are all where they should be.

Then I layered on what my proposal uses: rarity weighting (a strangulation carries far more signal than a gunshot, because strangulation is about 1.5% of homicides), a within-county solve-rate baseline, and temporal burst density, with a full reasoning trace per cluster. The result surprised me: on the headline question of when the Gary cluster first enters the national top ten, my scoring and MAP's simple unsolved count tie, both in 2006.

I now think that tie is the most useful thing the study produced. At the aggregation level homicide statistics permit (county by sex by weapon), the unsolved count already carries most of the available signal. The statistical layer is close to saturated. Whatever headroom is left lives at the record level, in details that statistics structurally cannot represent. (The weighting does change which small clusters get surfaced, and a handful of highly anomalous ones that count-ranking buries have been offered privately to MAP, per the ethics policy below. The full study, including my failed first attempt, is public.)

One more thing the data showed: the 2014 Gary victims are absent from the homicide records entirely, because the agency didn't report to the FBI those years. In the most famous algorithmic-warning case on record, the offender's actual crimes are a hole in the data. Linkage blindness exists at the statistical layer too.

The proposal: CrossCase

CrossCase is an open-source concept and prototype for the record-level layer: every record is a node, and every new record automatically cross-matches against all others, across jurisdictions, the moment it is filed.

Concretely:

There is a 3-minute demo built on fictional data, and the engine, tests, and replication study are all public under Apache-2.0.

What CrossCase is not: it is not predictive policing (it links existing records; it forecasts nothing about people), it involves no facial recognition or biometrics, and the prototype contains no real case data.

The hard parts are real

The prototype proves the mechanics: a working matching engine, an API whose new-record endpoint rescans the whole store, an end-to-end demo. It does not prove deployment viability. Real police narratives are messier than synthetic ones. False-positive rates on real data are unknown. Data access is governed by CJIS compliance and agency agreements that an independent researcher cannot and should not shortcut.

Which is why it is open source. I studied financial economics, not forensics; I came to this out of curiosity and stayed because the gap would not leave me alone. I am not the right person to build the production version. The right builders are records-system vendors, state fusion centers, N-DEx, and the crime analysts who live in these systems daily. What I can contribute is a worked proposal: the scoring rules, the ethics constraints (advisory tiers, mandatory reasoning, audit logging, review-and-purge), a tested reference implementation, and a replication study bounding what the existing layer can do.

Auditability is the other reason. Policing AI has a black-box problem, and the tools in this space are overwhelmingly closed. A correlation layer that pushes alerts about people deserves to be inspectable, all the way down to why any alert fired. That is a property you can only fully have in the open.

If this resonates

The code, the demo, and the replication study are at the links below. If you work in records systems, crime analysis, or the relevant corners of academia and any of this is useful, take it. Fork it, tear the scoring apart, tell me what real-world constraint I've missed. The point of publishing is that a connection like the one in April 2024 should not have to wait for one officer's gut feeling.

Concept and code: github.com/katchenme/crosscase · Replication study: github.com/katchenme/crosscase-shr-validation · 3-minute demo: YouTube · katchen.me
— katchen