CASCADE seal 692d499018e53e07 · measured, then frozen
Appendix A · Monitoring Method and reproducibility ← Back to the findings

One grid, every scenario. Written cases, declared scales.

A matte aluminium balance with two pans at exactly the same height; the right pan is the tool's deep lapis blue.

This page shows what the monitoring numbers are made of: which cases, which scenarios, which scales, and where each figure refuses to be quoted. No real transaction exists in the public record, and the page says so before anything else: the measurement that counts is yours, on your own dispositioned alerts, at your desk.

Written cases, twin by twin

The measured half rests on cases we wrote and we declare: six suspicious archetypes (structuring, rapid movement, dormant burst, round-tripping, cash-intensive, layering fan-out) and, deliberately, their six benign twins: payroll that moves money fast, a market season that looks like a dormant account waking, a loan instalment that repeats the same amount to the cent, rents that cluster like structuring. What separates each twin from its archetype is in the data, history and rhythm, never only in the label, and a test pins that structurally.

A set without twins would flatter every scenario: anything alarms when the benign cases are easy. The twins are the point, and the findings above say which scenario trips on which twin, measured.

Verify the cases

The suite revalidates every written case, its nature and its window, and the twin structure itself.

run it yourself
npm test84 cases revalidated, twin invariants pinned

Where it livessrc/cas-etiquetes.test.ts:11 · src/cas-etiquetes.test.ts:41 · src/cas.ts:47

Generated variants, apart by construction

The synthetic half is generated from the written cases under an explicit seed, and the jitter obeys one rule above all others: it must not undo the nature it varies. Structuring deposits stay under the reporting threshold, round-trip amounts and loan instalments move by a common factor so their equalities survive, round savings amounts stay round. Every variant is revalidated before it exists.

The two halves are never blended: the record holds them under two provenances, and on cells where the generated set scores friendlier than the written one, that gap is shown on the page rather than averaged away.

Verify the separation

Open the record: the two blocks carry their provenance in the data itself.

run it yourself
python3 -c "import json; d=json.load(open('releve-public.json')); print(d['authored']['provenance'], '/', d['synthetic']['provenance'])"prints: authored / synthetic

Where it livessrc/synthetic.ts:31 · src/synthetic.ts:51 · src/measure.ts:5

Scales are declared, never discovered in the code

Two scenarios need a scale to turn a raw number into a score: the amount scale and the velocity scale. Both are assumed values with declared bounds and provenance, written in one file with the reason for each, not constants scattered where nobody reads them. Change a scale and the record must be re-measured and re-sealed: the seal makes a silent retune impossible.

Verify the declarations

The scales file carries value, provenance and bounds for every assumption.

run it yourself
npm testthe assumptions cases pin provenance and bounds

Where it livessrc/assumptions.ts:29 · src/assumptions.ts:76 · src/assumptions.ts:97

Wilson everywhere, and refusals where n is small

Every rate travels with its Wilson interval at 95 percent and its n; below twenty observations a rate is noted rather than quoted. On your own history, recall is refused outright with fewer than five confirmed suspicious cases: the tool says so in those words instead of printing a figure that rests on almost nothing.

The threshold grid is shared by every scenario, 0.50 to 1.00 in steps of 0.01, and a case counts as an alert when its score is at or above the threshold: inclusive, so the strictest cell still means something for a scenario that answers exactly 1.

Verify the refusals

Both thresholds live in code, and the suite exercises them.

run it yourself
npm testinterval and refusal cases run with the rest

Where it livessrc/interval.ts:102 · src/optimise.ts:170 · src/rapport.ts:25 · src/measure.ts:71