Rules and versions
Ce contenu n’est pas encore disponible dans votre langue.
A rule is a question SpeculaPro asks about every transaction or customer — for example, “has this account received money from more than 15 different senders in the last 3 days?” When the answer is yes, the rule hits.
This page explains how rules are changed. Changing a rule is the most sensitive thing anyone does in a monitoring system: a careless edit can silence alerts for thousands of customers without anyone noticing. Everything below exists to make that impossible.
A rule and its versions
Section titled “A rule and its versions”A rule has two parts:
- The rule itself — its identity: a key, a name, a category, a mode, and what it looks at. This never changes.
- Its versions — the logic: the expression, the parameter values, the severity, the score and the action. Every change to any of these creates a new version.
| Part | Holds | Example |
|---|---|---|
| Rule | Key, name, description, category, typology, mode, entity scope | core.fan_in · Many senders into one account · network · post_event · customer |
| Version | Expression (CEL), declared features, parameter schema and values, severity, score, action, alert explanation, change note | v2: min_senders = 40, severity high, action alert |
Mode is when the rule runs:
| Mode | Runs | Typical use |
|---|---|---|
realtime |
Before the payment completes, inside the decision API | Fraud: block or step up |
post_event |
After each transaction arrives | Most AML rules |
scheduled |
On a timetable (a cron schedule is required) | Network patterns across many transactions |
Entity scope is what the rule is about, which decides whose alert its hits join. Today’s
rules use customer, account or counterparty.
The life of a version
Section titled “The life of a version” draft ──submit──▶ pending_approval ──approve──▶ approved ──deploy──▶ in the shadow or active slot │ └──reject──▶ rejected| State | What it means | Can it change? |
|---|---|---|
| Draft | Written, not yet submitted. | There’s no editing in place: to change it, draft another version. |
| Pending approval (on screen: Awaiting approval) | Submitted, waiting for a second person. | No. If it needs changes, the reviewer rejects it and the author drafts again. |
| Approved | Accepted by a second person. Can be deployed to shadow or active, now or later. | No. The logic is frozen. |
| Rejected | Not accepted. Kept on record with who rejected it and their note. | No; it can’t be resubmitted. Draft a new version. |
| Retired | Taken out of use for good. | No, and it can never be brought back. (There’s no retire action on screen or in the API yet.) |
Versions are kept forever, because hits point at them. Replacing the active version doesn’t retire the old one: it stays approved, so you can deploy it again to roll back.
Approval needs a second person
Section titled “Approval needs a second person”The person who approves or rejects a version must not be the person who created it. This is the 4-eyes principle, and the database refuses a version where the two are the same.
With the built-in roles, a Rule author writes versions and a Rule approver or the MLRO approves them. On screen, the author uses Tune and the approver uses Approve or Reject in the rule’s Versions list. See Approving a rule change.
Active and shadow
Section titled “Active and shadow”Approval alone does not switch a version on. A rule has two slots:
- Active (shown as live on screen) — the version whose hits create alerts (post-event) or decide payments
(real-time). A version whose action is
tag,score_onlyorallowrecords its hits without creating alerts. - Shadow — a version that runs on the same live transactions and records its hits, but never creates an alert or changes a decision.
Both slots can be filled at once. That is the point: you can run a proposed change next to the current rule on real traffic and compare. On a rule’s page, Make live deploys an approved version to the active slot and Shadow test deploys it to the shadow slot.
The rule must also be enabled to run at all, and that includes its shadow version. A newly
installed rule arrives with version 1 approved and in the active slot, but disabled until
someone with rules.approve turns it on. Deploying, enabling and disabling all reach the running
system within about 15 seconds.
Any approved version of the rule can be deployed to either slot. Promoting the shadow version to active empties the shadow slot. Deploying an older approved version to active is how you roll back.
How to change a rule safely
Section titled “How to change a rule safely”- Tune the rule: a rule author selects Tune on the rule’s page, changes the parameters and writes a change note saying why — “raise fan-in threshold from 10 to 15: 92% of last month’s alerts were salary payments to agents”.
- Backtest it: replay the new version over up to 180 days of history and see how many alerts it would have produced, and for whom, next to the live version. See Backtesting.
- Submit it for approval. On screen, Submit for approval does this in the same step as saving the new version.
- The approver reviews the change note, the difference from the active version and, if available, the backtest — then approves or rejects it.
- Put it in shadow for an agreed period — a week or two is common — alongside the active version.
- Compare the shadow hits with the active hits. Is it catching what it should? Has it stopped catching anything that mattered?
- Promote it by deploying it to active. The previous active version stays on record, still approved, ready if you need to roll back.
Step by step, on screen: Tuning a rule, Approving a rule change and Shadow mode. The equivalent API calls are in the Rules API.
Worked example
Section titled “Worked example”Kweku Pay’s D1 Fan-in rule (core.fan_in, pack default min_senders = 25 over 7 days)
produces about 140 alerts a month, and analysts close 90% as false positives. Most are market
traders receiving many small payments from their customers.
| Step | Version | State | Slot |
|---|---|---|---|
Installed from core |
v1: 25 senders / 7 days | approved | active |
| Author drafts change | v2: 40 senders / 7 days | draft | — |
| Submitted | v2 | pending approval | — |
| MLRO approves | v2 | approved | — |
| Deployed to shadow for 14 days | v2 | approved | shadow |
| Comparison: v2 would have hit 48 times, including all 9 customers whose cases went to an STR | |||
| Deployed to active | v2 | approved | active (shadow slot empties) |
| Old version | v1 | approved | — (available for rollback) |
Every alert raised before the change still points at v1; every alert after points at v2. For the market traders themselves, a time-boxed suppression might have been better than raising the threshold for everyone.
What every hit records
Section titled “What every hit records”Every rule hit stores:
- the exact version that produced it, and whether it was a shadow hit;
- the subject — customer, account, counterparty or device;
- the transaction, or for scheduled rules the list of contributing transactions as evidence;
- the severity and score;
- the feature values the rule saw and the parameters it used.
That is what makes every alert reproducible: given the hit, anyone can see exactly what the rule saw and why it fired.
Rules that come from packs
Section titled “Rules that come from packs”Rules installed from a rule pack remember which pack and
which library rule they came from (for example gh-psp · B2). Tuning them works exactly as
above: you create new versions with different parameters. The pack’s own definition is never
changed, and reinstalling a pack never overwrites your rules.
SpeculaPro records a SHA-256 digest of every pack it installs. Pack updates also come as signed bundle files that an installation verifies before reading, so a self-hosted or air-gapped site can take new rule versions without upgrading the program. See Signed rule-pack updates.