LEA: A court-admissible investigation graph

The problem

Link analysis is the core tool of every serious investigation: which people, vehicles, and locations connect to a suspect, and how. But most link-analysis tools produce a picture, not evidence. When the defence asks "how was this connection established, and can we verify it independently?", a screenshot of a graph doesn't answer that. Every edge needs a source, every hop needs a confidence score, and the whole export needs a signature that survives cross-examination.

The scenario

A vehicle theft ring case: investigators have a suspect's license plate from an ANPR hit near the scene, and need to build out the full network — associates, other vehicles, and communication patterns — before requesting a disclosure bundle the defence counsel can independently verify.

Build the graph, then export it as evidence

ANPR_TRACE, PATHS_BETWEEN, and DISPATCH_PRIORITY are SQL-reachable operators, not a separate case-management product bolted on top. WITH PROVENANCE attaches the source, method, and confidence of every edge the query returns.

PURPOSE 'investigation_specific:C-2026-04412'
 
-- 1. ANPR timeline for the plate that put the suspect at the scene
-- (WINDOW is a lookback in nanoseconds — 1209600000000000 = 14 days)
SELECT * FROM ANPR_TRACE('WB02-XX-1234', WINDOW => 1209600000000000, REGION => 'WB')
WITH PROVENANCE;
 
-- 2. Expand outward: every path from the suspect to a known associate,
--    up to 4 hops, with the confidence and source of each connecting edge
SELECT * FROM PATHS_BETWEEN('person-suspect-441', 'person-associate-118', 4)
WITH PROVENANCE;

Typed SDK snippet

from relata import RelataClient, AuditClient
 
with RelataClient(
    "http://localhost:9090",
    bearer_token="relata-dev",
    purpose="investigation_specific:C-2026-04412",
) as client:
    # Vehicle timeline from the ANPR hit — WINDOW is a lookback in ns
    sightings = client.query(
        "SELECT * FROM ANPR_TRACE('WB02-XX-1234', "
        "WINDOW => 1209600000000000, REGION => 'WB')"
    )
    for hit in sightings:
        print(hit["cell_id"], hit["timestamp"], hit["confidence"])
 
    # Every path connecting the suspect to a known associate
    paths = client.query(
        "SELECT * FROM PATHS_BETWEEN('person-suspect-441', 'person-associate-118', 4)"
    )
    for path in paths:
        print(path["hops"], path["score"], path["provenance"])
 
# Export a signed, defence-ready evidence package
with RelataClient("http://localhost:9090", bearer_token="relata-dev", purpose="legal_disclosure") as client:
    audit = AuditClient.from_client(client)
    pdf = audit.export_pdf(filter={"case_id": "C-2026-04412"})
    with open("case-04412-disclosure.pdf", "wb") as f:
        f.write(pdf)

Why the defence can verify this independently

  • Every edge has a source. WITH PROVENANCE attaches the originating record, the resolution method, and a confidence score to each connection — not just the connection itself. See Provenance.
  • The export is signed, not printed. AuditClient.export_pdf() produces a hash-chained, HSM-signable bundle, not a screenshot — the same primitive that stands behind Governance's audit trail.
  • History doesn't silently change. The bi-temporal model means a later correction to a record doesn't rewrite what the investigator saw on the day they built the case — AS OF reproduces exactly that state. See Bi-Temporal Model.
  • Purpose-bound access, logged. PURPOSE 'investigation_specific:C-2026-04412' scopes every read to this case and is recorded against the querying principal — the same access-control model that governs every protocol door, not a case-tool-specific bypass.

See also