Live demo · Fraud-ring search

Search fraud-ring connections with Chalk graph resolvers

This demo shows how to run PII normalization and graph queries on Chalk to inspect an applicant’s connections to labelled rings and high-risk accounts. Select a fictional applicant and inspect the matches, then explore the code to see how it works.

Compare an ordinary shared address with a risky connection

Use the applicant examples to separate normalized identity links from the scoring policy applied to them.

Try this experiment · expected results

  1. 1Start with a normalization-only match

    Select Only normalization sees it and compare raw and normalized values.

    Expected: The graph reveals links that exact matching on the submitted strings would miss.

  2. 2Remove one matching attribute

    After the query finishes, untick a phone, email, or address and compare the graph and score.

    Expected: The result shows which attribute carries the connection; shared contact data alone does not establish fraud.

The fictional book contains 29,967 people. Normalization groups 28,986 phone strings into 25,745 numbers and 26,659 addresses into 20,235.

Different-looking contact details can belong to the same fraud ring. Chalk normalizes the values, follows shared contacts, and returns the connections behind this fictional application’s score.

Applications · Brightwater Lending
29,967 synthetic people, 3 labelled rings, one ring nobody has labelled, and plenty of families and apartment buildings that share contact details for ordinary reasons.
APP-107 · Only normalization sees it
Tove Briarwood
Every link to this labelled ring is written differently: a reformatted phone, a plus-tagged email.
decline
risk 0.94 · recorded · 5890 ms
UseRaw, as submittedNormalized by Chalk
(500) 555-0154
+15005550154
Digits only, country code 1, E.164
milo.brindlewick+apply@example.com
milo.brindlewick@example.com
Lowercase, drop +tag, fold mbx.test into mailbox.test, drop dots there
901 Thimbleberry Road, Lower Quillbrook, ZZ 00052
901 thimbleberry rd lower quillbrook zz 00052
Lowercase, fold punctuation, USPS abbreviations, units as apt
building: 901 thimbleberry rd lower quillbrook zz 00052
2
Links, normalized
0
Links, raw strings
7
People within 2 hops
1
High-risk among them
Comparing raw strings finds 0 of these 2 links, and never reaches the ring: every link to it is written differently.
Milo Brindlewick · P29946 · ring KR-03 · risk 0.32 · via phone + emailYara Saltmarsh · P29954 · ring KR-03 · risk 0.84 · 1 chargebacks · via addressGil Rushwater · P29947 · ring KR-03 · risk 0.62 · 1 chargebacks · via addressJuno Foxglove · P29949 · ring KR-03 · risk 0.53 · 1 chargebacks · via addressTam Rushwater · P29951 · ring KR-03 · risk 0.41 · via addressPim Saltmarsh · P29952 · ring KR-03 · risk 0.50 · 1 chargebacks · via addressOrla Nettlecombe · P29955 · risk 0.35 · via addressapplicant
PhoneEmailAddressBuildingTie between risky people Labelled ring High riskDashed: found only after normalization
Labelled rings in reach
Score
Known ring0.90
Nearest labelled ring 1 hop away, weakest link weight 1.0.
Unlabelled cluster0.04
0 high-risk people one hop away and 1 two hops away (weighted 0.3); 0% of them are tied to each other.
Risk 0.94: review at 0.35, decline at 0.7. Graph walk 74 ms · query cmv8kqchb01520hp36a9dq7pb.

Brightwater Lending, its customers and applicants are fictional: phones are in the reserved 555-01xx range, emails use example and .test domains, and the streets are invented. The population is stored as Vortex, SpiralDB's open columnar format, in a Chalk Volume, and loaded from there into a real Neo4j database running as a Chalk scaling group; it is not read through SpiralDB itself. Every decision above is a real Chalk online query against a branch that holds these feature definitions, and each applicant shows a recorded run of the same query instantly while the live one runs. The approve, review and decline labels come from the example’s hand-written policy; they are not validated fraud predictions or real lending decisions.

Built on Chalk

Chalk runs the normalization, graph resolver and scoring expressions in one online query. The example defines which identifiers match, how links are weighted and which scores produce approve, review or decline.

  • Reuse normalization expressions

    The applicant and stored population use the same Chalk feature expressions for phones, email aliases and addresses. The example’s matching rules determine which raw values collapse together.

  • Graph context from Python

    A Chalk Python resolver calls Neo4j with Cypher and returns graph results as features. The query combines them with the example’s scoring expressions.

  • Rules in the feature definitions

    Chalk evaluates the example’s weights and thresholds as native feature expressions. The application defines the policy, and the query returns its score alongside the supporting features.

  • Return the matching subgraph

    The query returns graph features and the subgraph alongside the decision. The application shows which normalized values link the applicant to the accounts it found.

Deploy your own

Run it on your own

You will need uv, the Chalk CLI and a Chalk environment. Clone the example, log in, deploy the features to a branch, normalize and upload the population, then deploy the graph and set FRAUD_GRAPH_URL.

The population is synthetic. Adapt the normalization rules to your identifiers and review the graph traversal, link weights and decision thresholds against your own labelled cases before using the results in an onboarding workflow.

chalk-ai/fraud-ring-search
git clone https://github.com/chalk-ai/fraud-ring-search
cd fraud-ring-search

# Features, normalization and scoring on a branch.
chalk apply --branch fraud-rings

# Normalize the population with the same Chalk expressions, store it as Vortex in a Chalk Volume.
./build_population.py normalize --branch fraud-rings
./build_population.py upload

# Neo4j loads the Vortex tables and serves the PII graph read-only, inside your cluster.
./deploy_graph.py
chalk secret set FRAUD_GRAPH_URL=http://<graph service>:7474

chalk query --branch fraud-rings --in applicant.id=APP-106 \
  --out applicant.decision --out applicant.risk_score

Build identity graph features on Chalk

Identity graphs, device signals and bureau data: talk to an engineer about turning them into features your onboarding decisions can act on.