When an entity stops looking like itself
Every cashier, pump, terminal or account gets its own order-k Markov compression model, fit on its ownhistory. Score = the surprise of its recent window in the entity’s ownbits-per-event units. A legitimately refund-heavy lane is never flagged for being refund-heavy — only one that changes. Extends observe from one whole-stream model to one model per entity.
- per-entity
- each entity is watched against ITSELF, not a global average
- 2 nulls
- a label-shuffle and a no-injection control-world null, every run
- calibrated
- threshold set at the Nth pct of clean-world noise, not z≥3
- refuse-on-null
- signal fails its own null → zero alerts emitted
Baseline the entities, then scan
at1 fingerprint baseline pos.csv --entity cashier -o lanes.at1fp # 40 entities, calibrated threshold z>=3.79 @ far 0.01 at1 fingerprint scan pos.csv --entity cashier --baseline lanes.at1fp # RANKED REVIEW QUEUE (a rank is a review, NOT a verdict) # #1 cashier_16 z=11.5 <ALERT #2 cashier_08 z=11.0 <ALERT # NULL 2 control world: naive z>=3 fires on 3% of clean windows (the trap) # -> CALIBRATED threshold z>=3.79, base false-alarm rate 0.011 # NULL 1 label-shuffle: AUC 1.00, 3.7 sd above null, p=0.001 # SIGNAL PASSES ITS NULL -> 3 calibrated alerts. Every alert needs a human.
Self-relative, by design
A returns desk does lots of refunds; a fuel lane almost none. One global model buries the returns desk in false alarms. A per-entity model only reacts to an entity deviating from its own norm.
Two nulls, every run
A per-entity model alwaysfinds “some change” in a recent window. So we run a label-shuffle null (is the ranking real?) and a no-injection control-world null (what does pure noise cost?) on everyscan — and print both. This is a feature, not fine print.
Calibrated, not magic
The threshold is set at the Nth percentile of the control world’s own out-of-sample noise, so the false-alarm rate is chosen and measured, never a hard-coded z≥3 (which fires on noise alone).
A behaviour change is not a crime
- • The output is a ranked review queueand a calibrated alert set — never a “fraud” label. Every alert needs a human.
- • New POS software, a trainee, a promotion, a reassigned role, or just a bad day all shift an entity’s pattern. This is a top-of-queue triage aid measured in investigator-hours saved, not in “fraud caught.”
- • If the signal does not clearly beat its own null, the engine emits zero alerts (kill-criterion) and says so. No accusation, no automated adverse action against any person.
- • Real fraud is rare, so precision at the operating point on live data will sit below any clean-simulation number. We ship the calibration, honestly, alongside the signal.
Extends AT-1 Observe from one whole-stream baseline to one baseline per entity. Runs local, stdlib-only. “Detected” means statistically surprised versus its own history and its own null, not proven wrongdoing.