Cardinality (Same and Different)
Definition: how many distinct, or how many identical, values an entity has produced for an attribute. Variety, not volume, is the signal.
Construction: an Abstraction Rule with the Search Key set to the entity, and the Function Type set to Distinct Count or Same Count. Cardinality relies heavily on transaction data being stored in the cache, and on the range of aggregation functions that breadth of cached data makes available. See the Rule Taxonomy for how this type differs from its neighbours.
| Question an analyst asks | Rule Taxonomy type that answers it |
|---|---|
| How many different devices has this account used in 7 days? | Cardinality: Distinct Count on the device field, Search Key the account |
| How many times has this card been used at this same merchant? | Cardinality: Same Count on the merchant field, Search Key the card |
| How many different accounts has this device been used by? | Not this type: Link and Network, the same rule with the Search Key inverted to the device |
| How many payments in the last hour, regardless of variety? | Not this type: Velocity and Volume |
Cardinality: Abstraction Rules, Not TTL Counters
A TTL Counter can only count and sum, so it cannot answer a question of variety. Cardinality therefore uses Abstraction Rules, which keep the event picture in the cache and evaluate a function over the matching records. This carries a cache and memory cost that a TTL Counter does not, which is why Abstraction Rules are reserved for cardinality and complex aggregations, and not used for plain counts.
Cardinality: Construction Steps
A Cardinality rule is built in four steps: make the entity a Search Key, define the Abstraction Rule, threshold it in an Activation Rule, then test it with a sequence of events.
Step 1: Make the Entity a Search Key
The entity being profiled must be a Search Key in the Request XPath definition (Models » References » Request XPath). A Search Key drives a single keyed retrieval of matching records from the cache, so the number of Search Keys is the number of cache queries per invocation. Abstraction Rules that share a Search Key share the one retrieval.
Step 2: Define the Abstraction Rule for Cardinality
| Abstraction Rule field | Cardinality setting |
|---|---|
| Search | On. The rule is tested against records returned from the cache, not only the current transaction. |
| Search Key | The entity whose variety is measured, for example AccountId. Inverted to a shared attribute, this becomes Link and Network. |
| Search Interval | The window reaching back from the Reference Date, for example 7 Days. Applied to records after retrieval, not in the cache query, so retrieval is bounded by the fetch limit in the model definition. |
| Rule fragment | A Boolean filter selecting which cached events are eligible, for example Matched = Payload.TxnType.MatchEqual("CardPayment"). Use Matched = True to include everything. |
| Function Type | Distinct Count for “how many different values”, or Same Count for “how many times has this current value been seen before”. |
| Function Key | The payload field whose values are counted, for example DeviceId. |
| Offset Type and Value | Optional. First, Last, Skip First or Take Last narrow the matches to a position, for example the last five events. |
Distinct Count returns the number of unique values of the Function Key across the matches. Same Count returns how many matches carry the same Function Key value as the transaction currently being processed. Other Function Types (Average, Median, Max, Min, Standard Deviation, Since, Actual Value, First and Last positions via Offset) belong to Behavioral Baseline and Ratio, or to the “take first” and “take last” cardinality questions, for example “is this the first time this account has used this country”.
Step 3: Threshold the Abstraction Rule in an Activation Rule
The aggregated value is available to Activation Rules as Abstraction.<Name>, and is a number, so the numeric pipeline
steps apply. See the Rule Pipeline Reference. A Distinct Count threshold:
Matched = Abstraction.DistinctDevices7d.MatchGreater(3)
A Same Count used to detect repetition against a single counterparty:
Matched = Abstraction.SameBeneficiary30d.MatchGreaterOrEqual(5)
A cardinality signal combined with a payload condition, using Require as the guard and Against to switch value, per
the Rule Authoring Methodology:
Matched = Abstraction.DistinctDevices7d.RequireGreater(3).Against(Payload.CurrencyAmount).MatchGreater(1000)
Step 4: Test Cardinality with a Sequence of Events
Cardinality is a property of history, so a test must post several events for one entity with differing values of the
attribute, then assert the response on the event that crosses the threshold. Confirm on the target instance whether the
current event is included in the aggregation, using a two event case, as this decides whether the threshold is
> 3 or >= 3. The behaviour is defined in
Jube.Engine/EntityAnalysisModelInvoke/Context/Extensions/AbstractionRulesWithSearchKeysExtensions.cs, which is the
authority where this page and the code disagree.
Cardinality: Common Faults
Symptoms of a misbuilt Cardinality rule, with the likely cause.
| Symptom in a Cardinality rule | Likely cause |
|---|---|
| The Abstraction value is always 0 | The entity field is not a Search Key; the model was not synchronised; the rule fragment filter excludes every event. |
| The count is lower than expected for a long window | The fetch limit in the model definition truncates retrieval before the Search Interval is applied. |
| Cardinality slows the invocation | Too many Search Keys, or an unbounded fetch limit. Each Search Key is a cache query. |
| A plain count is being built as Distinct Count | The question is Velocity and Volume. Use a TTL Counter instead. |
Examples by Sub-Class
Validated. Every fragment in this section is compiled individually through the Jube Parser, with its payload fields and its TTL Counter, Abstraction, Calculation, List and Sanction tokens declared, so each extension method and argument type is checked against the engine. Compilation does not validate a rule’s logic or its thresholds, which are illustrative placeholders to be tuned on data.
2.1 Distinct counts (variety is the signal)
| # | Example | Description | Jube construction | Fragment | Notes |
|---|---|---|---|---|---|
| 2.1-01 | Many distinct beneficiaries in a short window | Payments to a high number of different payees (fan-out/layering, scam payouts). | Abstraction Rule with Search Key AccountId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key BeneficiaryId (placeholder field). The Activation Rule reads it as Abstraction.DistinctBeneficiaries24h; the threshold 10 is the source’s example and is illustrative. The beneficiary identifier must be on every payment event. | Matched = Abstraction.DistinctBeneficiaries24h.MatchGreaterOrEqual(10) |
Tag: Cardinality · Both · Account · 24h, distinct payees ≥ 10 |
| 2.1-02 | Many distinct senders into one account | Funds collected from many different payers (fan-in/mule collection). | Abstraction Rule with Search Key AccountId (the receiving account), Search Value 72 and Search Interval Hours, Function Type Distinct Count and Function Key SenderId (placeholder field). The Activation Rule reads Abstraction.DistinctSenders72h; the threshold is illustrative. The sender identifier must be on every credit event. | Matched = Abstraction.DistinctSenders72h.MatchGreaterOrEqual(10) |
Tag: Cardinality · AML · Account · 72h, distinct senders ≥ 10 |
| 2.1-03 | Many distinct cards used on one device | One device transacting with several cards (carding). | Abstraction Rule with Search Key DeviceId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key CardId. The Activation Rule reads Abstraction.DistinctCardsDevice24h; the threshold is illustrative. The card field should be a token or keyed hash, never the PAN (see 2.4-21). | Matched = Abstraction.DistinctCardsDevice24h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Device · 24h |
| 2.1-04 | Many distinct cards at one merchant from one IP | Same IP across many card numbers. | Abstraction Rule with Search Key IpMerchantKey (placeholder field) and Search Value 1 and Search Interval Hours, Function Type Distinct Count and Function Key CardId. The Abstraction takes one Search Key, so the IP and merchant must be combined into one upstream field; no Jube construct composes keys. The Activation Rule reads Abstraction.DistinctCardsIpMerchant1h; the threshold is illustrative. | Matched = Abstraction.DistinctCardsIpMerchant1h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · IP+Merchant · 1h |
| 2.1-05 | Many distinct accounts logged in from one device | Device accessing many accounts (credential stuffing, mule farm). | Abstraction Rule with Search Key DeviceId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key AccountId. The Activation Rule reads Abstraction.DistinctAccountsDevice24h; the threshold is illustrative. Fed by login events, so the account must be on each login event. | Matched = Abstraction.DistinctAccountsDevice24h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Device · 24h |
| 2.1-06 | Many distinct accounts logged in from one IP | IP accessing many accounts. | Abstraction Rule with Search Key IP, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key AccountId. The Activation Rule reads Abstraction.DistinctAccountsIp24h; the threshold is illustrative. Normalise the IP upstream with String.NormaliseIpAddress, because the distinct set compares raw strings, and expect false positives from shared or carrier-grade NAT addresses. | Matched = Abstraction.DistinctAccountsIp24h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · IP · 24h |
| 2.1-07 | Many distinct devices per account | One account accessed from many devices. | Abstraction Rule with Search Key AccountId, Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key DeviceId. The Activation Rule reads Abstraction.DistinctDevices7d; the threshold is illustrative. | Matched = Abstraction.DistinctDevices7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Account · 7d |
| 2.1-08 | Many distinct IP addresses per account | Account used from many networks. | Abstraction Rule with Search Key AccountId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key IP. The Activation Rule reads Abstraction.DistinctIps24h; the threshold is illustrative. Normalise with String.NormaliseIpAddress upstream. | Matched = Abstraction.DistinctIps24h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Account · 24h |
| 2.1-09 | Many distinct countries per account | Activity from many countries in a short time. | Abstraction Rule with Search Key AccountId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key ActivityCountry (placeholder field). The Activation Rule reads Abstraction.DistinctActivityCountries24h; the threshold is illustrative. This works only if each event carries an activity country; normalise the codes upstream. | Matched = Abstraction.DistinctActivityCountries24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Account · 24h |
| 2.1-10 | Many distinct countries of beneficiary | Payments to many destination countries. | Abstraction Rule with Search Key AccountId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key BeneficiaryCountry. The Activation Rule reads Abstraction.DistinctBeneficiaryCountries30d; the threshold is illustrative. The beneficiary country must be an ISO code on the payment; String.CountryAlpha2 maps alpha-3 to alpha-2 and returns empty for unknown input. | Matched = Abstraction.DistinctBeneficiaryCountries30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Account · 30d |
| 2.1-11 | Many distinct ISPs/ASNs per account | Hopping across networks (proxy/VPN). | Count of distinct ASNs per account over 24 hours, from an Abstraction Rule (Search Key AccountId, Search Value 24, Search Interval Hours, Function Type Distinct Count, Function Key Asn). Upstream field: Payload.Asn, supplied before Jube or by an inline-script hook. Count 5 is an illustrative placeholder. | Matched = Abstraction.DistinctAsns24h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Account · 24h |
| 2.1-12 | Many distinct user agents per account | Multiple browser/OS fingerprints on one account. | Abstraction Rule with Search Key AccountId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key UserAgent (placeholder field). The Activation Rule reads Abstraction.DistinctUserAgents24h; the threshold is illustrative. The user agent comes from the request; hash it only if policy requires. | Matched = Abstraction.DistinctUserAgents24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Account · 24h |
| 2.1-13 | Many distinct merchants in a short time | Unusually broad merchant spread (card compromise). | Abstraction Rule with Search Key CardId, Search Value 2 and Search Interval Hours, Function Type Distinct Count and Function Key MerchantId (placeholder field). The Activation Rule reads Abstraction.DistinctMerchants2h; the threshold is illustrative. | Matched = Abstraction.DistinctMerchants2h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Card · 2h |
| 2.1-14 | Many distinct MCCs in a short time | Broad category spread typical of card misuse. | Abstraction Rule with Search Key CardId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key Mcc (placeholder field). The Activation Rule reads Abstraction.DistinctMccs24h; the threshold is illustrative. | Matched = Abstraction.DistinctMccs24h.MatchGreaterOrEqual(4) |
Tag: Cardinality · Fraud · Card · 24h |
| 2.1-15 | Many distinct ATMs used | Withdrawals at many ATM locations. | Abstraction Rule with Search Key CardId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key AtmId (placeholder field). The Activation Rule reads Abstraction.DistinctAtms24h; the threshold is illustrative. | Matched = Abstraction.DistinctAtms24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Card · 24h |
| 2.1-16 | Many distinct merchant cities | Spend in many locations (see also geospatial). | Abstraction Rule with Search Key CardId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key MerchantCity (placeholder field). The Activation Rule reads Abstraction.DistinctMerchantCities24h; the threshold is illustrative. City spelling varies between acquirers, so normalise upstream with String.NormalisedForMatching or the distinct count inflates. | Matched = Abstraction.DistinctMerchantCities24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Card · 24h |
| 2.1-17 | Many distinct email addresses per device | Device used with many email identities. | Abstraction Rule with Search Key DeviceId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key Email. The Activation Rule reads Abstraction.DistinctEmails30d; the threshold is illustrative. Normalise upstream with String.NormalizeEmailAlias, otherwise dot and plus aliases of one mailbox count as several emails. | Matched = Abstraction.DistinctEmails30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Device · 30d |
| 2.1-18 | Many distinct phone numbers per device | Device associated with many mobile numbers. | Abstraction Rule with Search Key DeviceId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key Phone. The Activation Rule reads Abstraction.DistinctPhones30d; the threshold is illustrative. Normalise upstream with String.PhoneNumberDigits so formatting variants do not inflate the count. | Matched = Abstraction.DistinctPhones30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Device · 30d |
| 2.1-19 | Many distinct names per account | Account used under different names (mule). | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key Name (placeholder field). The Activation Rule reads Abstraction.DistinctNames90d; the threshold is illustrative. Normalise upstream with String.NormalisedForMatching, and justify the retention of names held as personal data in the abstraction cache. | Matched = Abstraction.DistinctNames90d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Account · 90d |
| 2.1-20 | Many distinct delivery addresses per card | Orders shipped to many addresses. | Abstraction Rule with Search Key CardId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key DeliveryAddress (placeholder field). The Activation Rule reads Abstraction.DistinctDeliveryAddresses30d; the threshold is illustrative. Address spelling variants inflate the distinct count, so normalise upstream. | Matched = Abstraction.DistinctDeliveryAddresses30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Card · 30d |
| 2.1-21 | Many distinct billing addresses per device | Multiple billing addresses entered. | Abstraction Rule with Search Key DeviceId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key BillingAddress (placeholder field). The Activation Rule reads Abstraction.DistinctBillingAddresses30d; the threshold is illustrative. Normalise upstream, as for delivery addresses. | Matched = Abstraction.DistinctBillingAddresses30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Device · 30d |
| 2.1-22 | Many distinct usernames tried per IP | Username enumeration. | Abstraction Rule with Search Key IP, Search Value 15 and Search Interval Minutes, Function Type Distinct Count and Function Key Username (placeholder field). The Activation Rule reads Abstraction.DistinctUsernames15m; the threshold is illustrative. Usernames are not secrets and may be carried. | Matched = Abstraction.DistinctUsernames15m.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · IP · 15m |
| 2.1-24 | Many distinct payee names for one payee account | Confirmation-of-payee mismatches/mule routing. | Abstraction Rule with Search Key PayeeAccountId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key PayeeName (placeholder field). The Activation Rule reads Abstraction.DistinctPayeeNames30d; the threshold is illustrative. Normalise names upstream with String.NormalisedForMatching; the name-match verdict itself is the scheme’s confirmation-of-payee result, not a cardinality. | Matched = Abstraction.DistinctPayeeNames30d.MatchGreaterOrEqual(3) |
Check: Confirmation of Payee is named in the source as a UK scheme control; verify the scheme rules before the rule cites it. Tag: Cardinality · Fraud · Beneficiary account · 30d |
| 2.1-25 | Many distinct payment references | Unique references across transactions of an account. | Abstraction Rule with Search Key AccountId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key Reference (placeholder field). The Activation Rule reads Abstraction.DistinctReferences30d; the threshold is illustrative. | Matched = Abstraction.DistinctReferences30d.MatchGreaterOrEqual(10) |
Tag: Cardinality · AML · Account · 30d |
| 2.1-26 | Many distinct counterparties across jurisdictions | Wide international counterparty set for a small business. | Abstraction Rule with Search Key CustomerId (placeholder field), Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key CounterpartyCountry (placeholder field). The Activation Rule reads Abstraction.DistinctCounterpartyCountries90d; the threshold is illustrative. This counts countries, not counterparties; distinct counterparties need a separate Abstraction Rule on the counterparty field. | Matched = Abstraction.DistinctCounterpartyCountries90d.MatchGreaterOrEqual(4) |
Tag: Cardinality · AML · Customer · 90d |
| 2.1-27 | Many distinct currencies used | Account transacts in many currencies. | Abstraction Rule with Search Key AccountId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key Currency (placeholder field). The Activation Rule reads Abstraction.DistinctCurrencies30d; the threshold is illustrative. | Matched = Abstraction.DistinctCurrencies30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Account · 30d |
| 2.1-28 | Many distinct channels used | Account active across many channels in a day. | Abstraction Rule with Search Key AccountId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key Channel (placeholder field). The Activation Rule reads Abstraction.DistinctChannels24h; the threshold is illustrative. | Matched = Abstraction.DistinctChannels24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Account · 24h |
| 2.1-29 | Many distinct agent/branch locations used | Cash deposits at many branches (smurfing). | Abstraction Rule with Search Key AccountId, Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key BranchOrAgentId (placeholder field). The Activation Rule reads Abstraction.DistinctBranches7d; the threshold is illustrative. | Matched = Abstraction.DistinctBranches7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Account · 7d |
| 2.1-30 | Many distinct depositors at ATMs | Cash deposits from many individuals. | Abstraction Rule with Search Key AccountId, Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key Depositor (placeholder field). The Activation Rule reads Abstraction.DistinctDepositors7d; the threshold is illustrative. The depositor identifier, the card or ID presented at the ATM, must be on the deposit event. | Matched = Abstraction.DistinctDepositors7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Account · 7d |
| 2.1-31 | Many distinct wallet addresses | Crypto withdrawals to many addresses. | Abstraction Rule with Search Key CustomerId (placeholder field), Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key WithdrawalAddress (placeholder field). The Activation Rule reads Abstraction.DistinctWithdrawalAddresses7d; the threshold is illustrative. Distinct sets compare case-insensitively (OrdinalIgnoreCase), which is safe for hex addresses but merges distinct base58 addresses that differ only by case, so confirm before relying on it for those chains. | Matched = Abstraction.DistinctWithdrawalAddresses7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Customer · 7d |
| 2.1-32 | Many distinct exchanges used | Customer sends to many virtual asset providers. | Abstraction Rule with Search Key CustomerId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key Vasp (placeholder field). The Activation Rule reads Abstraction.DistinctVasps30d; the threshold is illustrative. The VASP identity comes from the travel-rule counterparty data. | Matched = Abstraction.DistinctVasps30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Customer · 30d |
| 2.1-33 | Many distinct securities traded | Broad-and-fast trading consistent with layering or manipulation. | Abstraction Rule with Search Key AccountId, Search Value 1 and Search Interval Days, Function Type Distinct Count and Function Key Isin. The Activation Rule reads Abstraction.DistinctIsins1d; the threshold is illustrative. Validate the identifiers upstream with String.IsValidIsin if the feed is untrusted. | Matched = Abstraction.DistinctIsins1d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Account · 1d |
| 2.1-34 | Many distinct invoice numbers per supplier | Fictitious/numerous invoice patterns. | Abstraction Rule with Search Key SupplierId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key InvoiceNumber (placeholder field). The Activation Rule reads Abstraction.DistinctInvoices30d; the threshold is illustrative. | Matched = Abstraction.DistinctInvoices30d.MatchGreaterOrEqual(10) |
Tag: Cardinality · AML · Customer · 30d |
| 2.1-35 | Many distinct corporate signatories | Frequent changes in authorised users. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key Signatory (placeholder field). The Activation Rule reads Abstraction.DistinctSignatories90d; the threshold is illustrative. Signatory changes arrive as mandate-change events. | Matched = Abstraction.DistinctSignatories90d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Account · 90d |
| 2.1-36 | Many distinct devices per user session cookie | Cookie reuse across devices. | Abstraction Rule with Search Key CookieHash (placeholder field), Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key DeviceId. The Activation Rule reads Abstraction.DistinctDevicesCookie7d; the threshold is illustrative. The key must be a keyed hash of the cookie (String.HmacSha256Hex), not the raw value, because the cache holds field values. | Matched = Abstraction.DistinctDevicesCookie7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Cookie · 7d |
| 2.1-37 | Many distinct SIM/IMSI per device | SIM swaps in a short period. | Count of distinct IMSIs per device over 30 days, from an Abstraction Rule (Search Key DeviceId, Search Value 30, Search Interval Days, Function Type Distinct Count, Function Key Imsi). Upstream field: Payload.Imsi, supplied before Jube or by an inline-script hook. Count 3 is an illustrative placeholder. | Matched = Abstraction.DistinctImsisDevice30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Device · 30d |
| 2.1-38 | Many distinct application ids per document | Same document across applications. | Abstraction Rule with Search Key DocumentKey (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key ApplicationId (placeholder field). The Activation Rule reads Abstraction.DistinctApplicationsDocument30d; the threshold is illustrative. DocumentKey must be a keyed hash of the document number (String.HmacSha256Hex), because the raw number is personal data. | Matched = Abstraction.DistinctApplicationsDocument30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Document · 30d |
| 2.1-39 | Many distinct dates of birth per phone number | Mismatched identity attributes on a contact. | Abstraction Rule with Search Key Phone, Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key DateOfBirth (placeholder field). The Activation Rule reads Abstraction.DistinctDatesOfBirthPhone90d; the threshold is illustrative. Normalise the date to one format upstream, because the distinct set compares raw strings. | Matched = Abstraction.DistinctDatesOfBirthPhone90d.MatchGreaterOrEqual(2) |
Tag: Cardinality · Fraud · Phone · 90d |
| 2.1-40 | Many distinct employers per address | Synthetic identity indicator. | Abstraction Rule with Search Key AddressKey (placeholder field), Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key Employer (placeholder field). The Activation Rule reads Abstraction.DistinctEmployersAddress90d; the threshold is illustrative. Employer is application-form data, so normalise names upstream, and treat the synthetic-identity reading as a model judgement that the count does not prove. | Matched = Abstraction.DistinctEmployersAddress90d.MatchGreaterOrEqual(2) |
Tag: Cardinality · Fraud · Address · 90d |
2.2 Same counts (repetition is the signal)
| # | Example | Description | Jube construction | Fragment | Notes |
|---|---|---|---|---|---|
| 2.2-01 | Same beneficiary repeated | The same payee receives many payments (drip-feed, scam continuation). | Abstraction Rule with Search Key AccountId, Search Value 7 and Search Interval Days, Function Type Same Count and Function Key BeneficiaryId (placeholder field). The Activation Rule reads Abstraction.SameBeneficiary7d; the threshold is illustrative. Same Count is exact string equality against prior events in the window, so keying on the account and counting the beneficiary gives the account plus beneficiary pair. | Matched = Abstraction.SameBeneficiary7d.MatchGreaterOrEqual(5) |
Tag: Cardinality · Both · Account+Beneficiary · 7d, same count ≥ 5 |
| 2.2-02 | Same amount repeated | Identical amounts repeated many times (structuring, scripted fraud). | Abstraction Rule with Search Key AccountId, Search Value 24 and Search Interval Hours, Function Type Same Count and Function Key CurrencyAmount. The Activation Rule reads Abstraction.SameAmount24h; the threshold is illustrative. Equality is on the raw string, so 100 and 100.00 do not match; format the amount upstream to one representation. | Matched = Abstraction.SameAmount24h.MatchGreaterOrEqual(4) |
Tag: Cardinality · Both · Account · 24h, same amount ≥ 4 |
| 2.2-03 | Same amount to different beneficiaries | The same amount sent to different payees (mule payout). | Two Abstraction Rules on AccountId with Search Value 24 and Search Interval Hours: a Same Count on CurrencyAmount read as Abstraction.SameAmount24h, and a Distinct Count on BeneficiaryId (placeholder field) read as Abstraction.DistinctBeneficiaries24h. This is an approximation, because search-key abstractions have no per-row filter and it fires on any repeated amount plus any spread of payees; the exact form needs a conditional distinct count, which no construct provides. Thresholds are illustrative. | Matched = Abstraction.SameAmount24h.MatchGreaterOrEqual(4) And Abstraction.DistinctBeneficiaries24h.MatchGreaterOrEqual(4) |
Tag: Cardinality · AML · Account · 24h |
| 2.2-04 | Same reference text repeated | Identical reference used on many payments. | Abstraction Rule with Search Key AccountId, Search Value 7 and Search Interval Days, Function Type Same Count and Function Key Reference (placeholder field). The Activation Rule reads Abstraction.SameReference7d; the threshold is illustrative. Normalise the reference upstream with String.NormalisedForMatching, or case and spacing variants escape the count. | Matched = Abstraction.SameReference7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Account · 7d |
| 2.2-05 | Same merchant repeated at high count | Many transactions at a single merchant in a short window. | Abstraction Rule with Search Key CardId, Search Value 1 and Search Interval Hours, Function Type Same Count and Function Key MerchantId (placeholder field). The Activation Rule reads Abstraction.SameMerchant1h; the threshold is illustrative. This is an exact same count on the merchant field. | Matched = Abstraction.SameMerchant1h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Card · 1h |
| 2.2-06 | Same merchant, same amount repeated | Duplicate/replay transactions. | Abstraction Rule with Search Key CardId, Search Value 1 and Search Interval Hours, Function Type Same Count and Function Key MerchantAmountKey (placeholder field). The Activation Rule reads Abstraction.SameMerchantAmount1h; the threshold is illustrative. The exact replay check needs one upstream composite field of merchant plus amount, because two separate same counts would be an approximation. | Matched = Abstraction.SameMerchantAmount1h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Card · 1h |
| 2.2-07 | Same IP on repeated payments | Many payments from one IP. | TTL Counter with Data Name IP, Interval Type Hours and Value 1, and Sum off, so each payment adds one. The Activation Rule that matches a payment increments TTLCounter.PaymentsIp1h and a second Activation Rule reads it, with the incrementing rule given the earlier Priority if the count should include the current payment; the threshold is illustrative. Counting payments needs no same count, and the IP should be normalised upstream with String.NormaliseIpAddress. | Matched = TTLCounter.PaymentsIp1h.MatchGreater(5) |
Tag: Cardinality · Fraud · IP · 1h |
| 2.2-08 | Same device across customers | Same device appears for multiple customers (see Link & Network). | Abstraction Rule with Search Key DeviceId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key CustomerId (placeholder field), read by the Activation Rule as Abstraction.DistinctCustomersDevice30d; the threshold is illustrative. The source describes one device shared by several customers, which is a distinct count, and the graph view belongs to Link and Network. | Matched = Abstraction.DistinctCustomersDevice30d.MatchGreaterOrEqual(2) |
Tag: Cardinality · Fraud · Device · 30d |
| 2.2-09 | Same ATM repeatedly | Repeated withdrawals at a single ATM. | Abstraction Rule with Search Key CardId, Search Value 24 and Search Interval Hours, Function Type Same Count and Function Key AtmId (placeholder field). The Activation Rule reads Abstraction.SameAtm24h; the threshold is illustrative. | Matched = Abstraction.SameAtm24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Card · 24h |
| 2.2-10 | Same cash deposit amount repeated | Cash deposits of identical amounts. | Abstraction Rule with Search Key AccountId, Search Value 7 and Search Interval Days, Function Type Same Count and Function Key CashAmount (placeholder field). The Activation Rule reads Abstraction.SameCashAmount7d; the threshold is illustrative. Format the amount upstream, as for 2.2-02. | Matched = Abstraction.SameCashAmount7d.MatchGreaterOrEqual(3) |
Check: No threshold is given. If a structuring threshold is set, verify the jurisdiction’s current cash-reporting figure. Tag: Cardinality · AML · Account · 7d |
| 2.2-12 | Same invoice amount repeated | Repeated identical invoice value to one counterparty. | Abstraction Rule with Search Key CounterpartyId (placeholder field), Search Value 30 and Search Interval Days, Function Type Same Count and Function Key InvoiceAmount (placeholder field). The Activation Rule reads Abstraction.SameInvoiceAmount30d; the threshold is illustrative. Keyed on the counterparty, so it spans all customers paying that counterparty; to scope it per customer too, use an upstream customer plus counterparty composite key. | Matched = Abstraction.SameInvoiceAmount30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Customer · 30d |
| 2.2-13 | Same trade price/size repeated | Repeated identical order sizes (wash/layering). | Abstraction Rule with Search Key AccountId, Search Value 1 and Search Interval Days, Function Type Same Count and Function Key OrderSize (placeholder field). The Activation Rule reads Abstraction.SameOrderSize1d; the threshold is illustrative. Price and size can be separate rules, or one upstream composite price plus size field, and price strings should be normalised to the tick size. | Matched = Abstraction.SameOrderSize1d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Account · 1d |
| 2.2-14 | Same time-of-day repeated | Transactions at identical times each day (automation). | Abstraction Rule with Search Key AccountId, Search Value 14 and Search Interval Days, Function Type Same Count and Function Key TimeOfDay (placeholder field). The Activation Rule reads Abstraction.SameTimeOfDay14d; the threshold is illustrative. The comparison is on raw strings, so time of day must be a payload field in the account’s zone (for example HH:mm); the event timestamp alone never matches, and the abstraction has no conversion step. | Matched = Abstraction.SameTimeOfDay14d.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Account · 14d |
| 2.2-16 | Same session token reused from different devices | Session hijack. | Abstraction Rule with Search Key SessionKey (placeholder field), Search Value 1 and Search Interval Hours, Function Type Distinct Count and Function Key DeviceId. The Activation Rule reads Abstraction.DistinctDevicesSession1h; the threshold of 2 is the reuse test itself. SessionKey must be a keyed hash of the session token (String.HmacSha256Hex), never the raw token. | Matched = Abstraction.DistinctDevicesSession1h.MatchGreaterOrEqual(2) |
Tag: Cardinality · Fraud · Session · 1h |
| 2.2-17 | Same OTP code requested repeatedly | OTP replay patterns. | TTL Counter with Data Name AccountId, Interval Type Minutes and Value 30, and Sum off. The Activation Rule that matches an OTP request increments TTLCounter.OtpRequests30m and a second Activation Rule reads it; the threshold is illustrative. The counter counts requests and never compares OTP values, so the code itself must not be stored. | Matched = TTLCounter.OtpRequests30m.MatchGreater(3) |
Tag: Cardinality · Fraud · Account · 30m |
2.3 Cardinality ratios and “first-seen” signals
| # | Example | Description | Jube construction | Fragment | Notes |
|---|---|---|---|---|---|
| 2.3-01 | First transaction with a new country | Country never seen for this account. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest window the model retains, since lifetime cannot be expressed), Function Type Same Count and Function Key ActivityCountry (placeholder field), read as Abstraction.SameCountry90d. Zero prior same-value events means first seen, but the current event must not yet be in the window when the count runs, because the zero depends on that ordering. | Matched = Abstraction.SameCountry90d.MatchEqual(0) |
Tag: Cardinality · Fraud · Account · lifetime |
| 2.3-02 | First transaction with a new MCC | Merchant category never used before. | Abstraction Rule with Search Key CardId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key Mcc (placeholder field). The Activation Rule reads Abstraction.SameMcc90d, where zero means first seen. Same bound and ordering caveat as 2.3-01. | Matched = Abstraction.SameMcc90d.MatchEqual(0) |
Tag: Cardinality · Fraud · Card · lifetime |
| 2.3-03 | First use of a new device | Device not seen for this account. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key DeviceId. The Activation Rule reads Abstraction.SameDevice90d, where zero means first seen. Same bound and ordering caveat as 2.3-01. | Matched = Abstraction.SameDevice90d.MatchEqual(0) |
Tag: Cardinality · Fraud · Account · lifetime |
| 2.3-04 | First use of a new IP/ISP | Network not seen before. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key IP, read as Abstraction.SameIp90d, where zero means first seen. This covers the IP half only; the ISP half needs an ASN field and is C (see 2.1-11), and the same bound and ordering caveat as 2.3-01 applies. | Matched = Abstraction.SameIp90d.MatchEqual(0) |
Tag: Cardinality · Fraud · Account · lifetime |
| 2.3-05 | First payment to a new beneficiary | Payee not previously paid. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key BeneficiaryId (placeholder field). The Activation Rule reads Abstraction.SameBeneficiary90d, where zero means first seen. Same bound and ordering caveat as 2.3-01. | Matched = Abstraction.SameBeneficiary90d.MatchEqual(0) |
Tag: Cardinality · Fraud · Account · lifetime |
| 2.3-06 | First payment to a new beneficiary country | Beneficiary country not used before. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key BeneficiaryCountry. The Activation Rule reads Abstraction.SameBeneficiaryCountry90d, where zero means first seen. Same bound and ordering caveat as 2.3-01. | Matched = Abstraction.SameBeneficiaryCountry90d.MatchEqual(0) |
Tag: Cardinality · AML · Account · lifetime |
| 2.3-07 | First high-value payment after new device | Large payment on a first-seen device. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key DeviceId, read as Abstraction.SameDevice90d. The ‘after new device’ reading is first seen at the time of payment. The high-value limit 5000 is an illustrative placeholder, because the threshold is institution-specific and not given in the source. | Matched = Abstraction.SameDevice90d.MatchEqual(0) And Payload.CurrencyAmount.MatchGreaterOrEqual(5000) |
Tag: Cardinality · Fraud · Account · lifetime |
| 2.3-08 | New beneficiary plus high value | New payee combined with value above threshold. | Abstraction Rule with Search Key AccountId, Search Value 90 and Search Interval Days (a placeholder for the longest retained window), Function Type Same Count and Function Key BeneficiaryId (placeholder field), read as Abstraction.SameBeneficiary90d. The high-value limit 5000 is an illustrative placeholder, the same reading and threshold as 2.3-07. | Matched = Abstraction.SameBeneficiary90d.MatchEqual(0) And Payload.CurrencyAmount.MatchGreaterOrEqual(5000) |
Tag: Cardinality · Fraud · Account · lifetime |
| 2.3-09 | Distinct-to-total ratio near 1 | Almost every transaction is to a different counterparty (fan-out). | Two Abstraction Rules on AccountId with Search Value 30 and Search Interval Days: a Distinct Count on CounterpartyId (placeholder field) read as Abstraction.DistinctCounterparties30d, and a Count with no Function Key read as Abstraction.CountTransactions30d. Double.RatioOf divides one by the other, and the count floor stops single-event accounts, which would have a ratio of 1 trivially. The 0.9 and 5 are placeholders. | Matched = Abstraction.DistinctCounterparties30d.RatioOf(Abstraction.CountTransactions30d).MatchGreaterOrEqual(0.9) And Abstraction.CountTransactions30d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Account · 30d |
| 2.3-10 | Distinct-to-total ratio near 0 | Almost every transaction is the same counterparty/amount (scripted). | Two Abstraction Rules on AccountId with Search Value 30 and Search Interval Days: a Distinct Count on CounterpartyId (placeholder field) read as Abstraction.DistinctCounterparties30d, and a Count with no Function Key read as Abstraction.CountTransactions30d; Double.RatioOf divides one by the other, with the same count floor as 2.3-09. The amount-based variant swaps the distinct field for a distinct amount, and the 0.1 and 5 are placeholders. | Matched = Abstraction.DistinctCounterparties30d.RatioOf(Abstraction.CountTransactions30d).MatchLessOrEqual(0.1) And Abstraction.CountTransactions30d.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Account · 30d |
2.4 Sector-specific cardinality
| # | Example | Description | Jube construction | Fragment | Notes |
|---|---|---|---|---|---|
| 2.4-01 | Many distinct claimants sharing one bank account (insurance) | Claim payouts to one account for many claimants. | Abstraction Rule with Search Key PayoutAccountId (placeholder field), Search Value 365 and Search Interval Days, Function Type Distinct Count and Function Key ClaimantId (placeholder field). The Activation Rule reads Abstraction.DistinctClaimants365d; the threshold is illustrative. The source says 12 months; Abstraction windows have no months, so 365 Days is used, and calendar-month semantics would need a different design. | Matched = Abstraction.DistinctClaimants365d.MatchGreaterOrEqual(3) |
Check: 12 months is set as 365 days here; confirm if the business rule means calendar months. Tag: Cardinality · Fraud · Payout account · 12m |
| 2.4-02 | Many distinct policies sharing one beneficiary | Same beneficiary on many unrelated policies. | Abstraction Rule with Search Key BeneficiaryId (placeholder field), Search Value 365 and Search Interval Days (a placeholder for the longest retained window), Function Type Distinct Count and Function Key PolicyId (placeholder field). The Activation Rule reads Abstraction.DistinctPolicies365d; the threshold is illustrative. The source says lifetime, which is bounded by the longest retained window, as in 2.3-01. | Matched = Abstraction.DistinctPolicies365d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Beneficiary · lifetime |
| 2.4-03 | Many distinct vehicles/properties insured by one person in short time | Rapid portfolio growth. | Abstraction Rule with Search Key PolicyholderId (placeholder field), Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key AssetId (placeholder field). The Activation Rule reads Abstraction.DistinctAssets90d; the threshold is illustrative. The asset identity arrives on new-policy events. | Matched = Abstraction.DistinctAssets90d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Policyholder · 90d |
| 2.4-04 | Many distinct players sharing a payment card (gaming) | Card used across accounts. | Abstraction Rule with Search Key CardId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key PlayerId (placeholder field). The Activation Rule reads Abstraction.DistinctPlayersCard30d; the threshold is illustrative. The card must be a token or keyed hash, not the PAN. | Matched = Abstraction.DistinctPlayersCard30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Card · 30d |
| 2.4-05 | Many distinct opponents losing to one player (chip dumping) | Player gains from many unique losers. | Abstraction Rule with Search Key PlayerId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key OpponentId (placeholder field). The Activation Rule reads Abstraction.DistinctOpponents30d; the threshold is illustrative. No per-row filter exists, so this works only if the model is fed the player’s winning pots as its events; otherwise it counts every opponent. | Matched = Abstraction.DistinctOpponents30d.MatchGreaterOrEqual(10) |
Tag: Cardinality · AML · Player · 30d |
| 2.4-06 | Many distinct deposit methods per player | Rapid cycling of funding methods. | Abstraction Rule with Search Key PlayerId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key DepositMethod (placeholder field). The Activation Rule reads Abstraction.DistinctDepositMethods30d; the threshold is illustrative. | Matched = Abstraction.DistinctDepositMethods30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Player · 30d |
| 2.4-07 | Many distinct wallet addresses funding one exchange account | Inbound from many addresses. | Abstraction Rule with Search Key ExchangeAccountId (placeholder field), Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key SourceWallet (placeholder field). The Activation Rule reads Abstraction.DistinctSourceWallets7d; the threshold is illustrative. Distinct sets compare case-insensitively, so confirm before relying on it for base58 addresses (see 2.1-31). | Matched = Abstraction.DistinctSourceWallets7d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Account · 7d |
| 2.4-08 | Many distinct exchange accounts withdrawing to one address | Convergence on one wallet. | Abstraction Rule with Search Key WithdrawalAddress (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key ExchangeAccountId (placeholder field). The Activation Rule reads Abstraction.DistinctExchangeAccounts30d; the threshold is illustrative. The same case-folding caveat as 2.1-31 applies. | Matched = Abstraction.DistinctExchangeAccounts30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Address · 30d |
| 2.4-09 | Many distinct counterparties in P2P crypto trades | Broad peer set. | Abstraction Rule with Search Key AccountId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key CounterpartyId (placeholder field). The Activation Rule reads Abstraction.DistinctCounterparties30d; the threshold is illustrative. | Matched = Abstraction.DistinctCounterparties30d.MatchGreaterOrEqual(10) |
Tag: Cardinality · AML · Account · 30d |
| 2.4-10 | Many distinct securities moved via journals | Variety of assets moved between accounts. | Abstraction Rule with Search Key AccountId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key SecurityId (placeholder field). The Activation Rule reads Abstraction.DistinctSecurities30d; the threshold is illustrative. Journal events carry the security identifier. | Matched = Abstraction.DistinctSecurities30d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Account · 30d |
| 2.4-11 | Many distinct agents used by one remitter | Agent-hopping. | Abstraction Rule with Search Key SenderId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key AgentId (placeholder field). The Activation Rule reads Abstraction.DistinctAgents30d; the threshold is illustrative. | Matched = Abstraction.DistinctAgents30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · AML · Sender · 30d |
| 2.4-12 | Many distinct receivers per sender (remittance) | One sender to many recipients. | Abstraction Rule with Search Key SenderId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key ReceiverId (placeholder field). The Activation Rule reads Abstraction.DistinctReceivers30d; the threshold is illustrative. | Matched = Abstraction.DistinctReceivers30d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Sender · 30d |
| 2.4-13 | Many distinct senders per receiver (remittance) | Collector pattern. | Abstraction Rule with Search Key ReceiverId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key SenderId (placeholder field). The Activation Rule reads Abstraction.DistinctSenders30d; the threshold is illustrative. | Matched = Abstraction.DistinctSenders30d.MatchGreaterOrEqual(5) |
Tag: Cardinality · AML · Receiver · 30d |
| 2.4-14 | Many distinct SIMs per mobile-money wallet holder | Wallet accessed across SIMs. | Count of distinct SIMs per wallet over 30 days, from an Abstraction Rule (Search Key WalletId, Search Value 30, Search Interval Days, Function Type Distinct Count, Function Key SimId). Upstream fields: Payload.WalletId and Payload.SimId, supplied before Jube or by an inline-script hook. Count 2 is an illustrative placeholder. | Matched = Abstraction.DistinctSimsWallet30d.MatchGreaterOrEqual(2) |
Tag: Cardinality · Fraud · Wallet · 30d |
| 2.4-15 | Many distinct vendors created by one user (corporate) | Vendor-master changes by one person. | Abstraction Rule with Search Key CreatedByUserId (placeholder field), Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key VendorId (placeholder field). The Activation Rule reads Abstraction.DistinctVendorsCreated90d; the threshold is illustrative. The model is fed vendor-creation events only, and the creating user must be on each event. | Matched = Abstraction.DistinctVendorsCreated90d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · User · 90d |
| 2.4-16 | Many distinct employees paid to one bank account (payroll) | Ghost employees. | Abstraction Rule with Search Key PayoutAccountKey (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key EmployeeId (placeholder field). The Activation Rule reads Abstraction.DistinctEmployeesPayout30d; the threshold is illustrative. Payroll events must carry the payee account, and the key should be a keyed hash, since account numbers are personal data. | Matched = Abstraction.DistinctEmployeesPayout30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Account · 30d |
| 2.4-17 | Many distinct shipping names for one address (e-commerce) | Reshipping hub. | Abstraction Rule with Search Key ShippingAddressKey (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key ShippingName (placeholder field). The Activation Rule reads Abstraction.DistinctShippingNames30d; the threshold is illustrative. Normalise names and addresses upstream. | Matched = Abstraction.DistinctShippingNames30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Address · 30d |
| 2.4-18 | Many distinct buyers paying one seller from one device (marketplace) | Seller self-dealing/collusion. | Abstraction Rule with Search Key SellerDeviceKey (placeholder composite of seller and device), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key BuyerId (placeholder field). The Activation Rule reads Abstraction.DistinctBuyersSellerDevice30d; the threshold is illustrative. The composite key is needed because the abstraction takes a single Search Key. | Matched = Abstraction.DistinctBuyersSellerDevice30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Seller · 30d |
| 2.4-19 | Many distinct drivers using one vehicle/phone (gig platforms) | Account sharing. | Abstraction Rule with Search Key VehicleOrPhoneId (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key DriverId (placeholder field). The Activation Rule reads Abstraction.DistinctDriversVehicle30d; the threshold is illustrative. | Matched = Abstraction.DistinctDriversVehicle30d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Vehicle/Phone · 30d |
| 2.4-20 | Many distinct BNPL merchants in one day | Rapid spend across providers. | Abstraction Rule with Search Key CustomerId (placeholder field), Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key MerchantId (placeholder field). The Activation Rule reads Abstraction.DistinctBnplMerchants24h; the threshold is illustrative. It requires the BNPL provider’s own cross-merchant events. | Matched = Abstraction.DistinctBnplMerchants24h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Customer · 24h |
| 2.4-21 | Many distinct card tokens for one PAN | Token sprawl. | Abstraction Rule with Search Key PanKey (placeholder field), Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key CardToken (placeholder field). The Activation Rule reads Abstraction.DistinctCardTokens30d; the threshold is illustrative. PanKey must not be the clear PAN, because a bare SHA-256 of a PAN is brute-forceable: use a keyed HMAC (String.HmacSha256Hex) or the PSP’s own token. | Matched = Abstraction.DistinctCardTokens30d.MatchGreaterOrEqual(3) |
Check: PCI DSS governs storage of account data: verify with the QSA whether a keyed hash of the PAN counts as rendering it unreadable. Tag: Cardinality · Fraud · PAN · 30d |
| 2.4-22 | Many distinct PANs per wallet device | Multiple cards loaded on one device. | Abstraction Rule with Search Key DeviceId, Search Value 30 and Search Interval Days, Function Type Distinct Count and Function Key PanKey (placeholder field, a keyed hash as in 2.4-21). The Activation Rule reads Abstraction.DistinctPansDevice30d; the threshold is illustrative. | Matched = Abstraction.DistinctPansDevice30d.MatchGreaterOrEqual(3) |
Check: PCI DSS governs storage of account data: verify with the QSA that the keyed-hash approach is acceptable. Tag: Cardinality · Fraud · Device · 30d |
2.5 Card-scheme and acquiring cardinality
| # | Example | Description | Jube construction | Fragment | Notes |
|---|---|---|---|---|---|
| 2.5-01 | Many distinct issuers declining at one merchant | Broad decline spread suggests card testing. | Abstraction Rule with Search Key MerchantId, Search Value 1 and Search Interval Hours, Function Type Distinct Count and Function Key IssuerBin (placeholder field). The Activation Rule reads Abstraction.DistinctDecliningIssuers1h; the threshold is illustrative. No per-row filter exists, so the model must be fed declined authorisations alone. | Matched = Abstraction.DistinctDecliningIssuers1h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Merchant · 1h |
| 2.5-02 | Many distinct terminal IDs for one merchant in a day | Terminal sprawl or MID misuse. | Abstraction Rule with Search Key MerchantId, Search Value 24 and Search Interval Hours, Function Type Distinct Count and Function Key TerminalId (placeholder field). The Activation Rule reads Abstraction.DistinctTerminals24h; the threshold is illustrative. | Matched = Abstraction.DistinctTerminals24h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Merchant · 24h |
| 2.5-03 | Many distinct MIDs for one merchant owner | MID cycling. | Abstraction Rule with Search Key OwnerId (placeholder field), Search Value 90 and Search Interval Days, Function Type Distinct Count and Function Key Mid (placeholder field). The Activation Rule reads Abstraction.DistinctMids90d; the threshold is illustrative. The owner identifier comes from merchant onboarding master data. | Matched = Abstraction.DistinctMids90d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Owner · 90d |
| 2.5-04 | Many distinct countries of cards at a small merchant | Unusual international card mix. | Abstraction Rule with Search Key MerchantId, Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key CardIssuerCountry (placeholder field), read as Abstraction.DistinctCardCountries7d; the threshold is illustrative. It needs the issuer country on the authorisation record, a BIN-table lookup done upstream is reference data rather than an in-rule step, and the small-merchant qualifier needs an upstream merchant-size attribute. | Matched = Abstraction.DistinctCardCountries7d.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Merchant · 7d |
| 2.5-05 | Many distinct card BIN ranges at one terminal in a short window | Terminal compromise. | Abstraction Rule with Search Key TerminalId, Search Value 1 and Search Interval Hours, Function Type Distinct Count and Function Key Bin (placeholder field). The Activation Rule reads Abstraction.DistinctBins1h; the threshold is illustrative. The BIN is the first six digits, derived upstream with String.CardIssuerPrefix(6), because the abstraction counts the stored field and does not evaluate an expression. | Matched = Abstraction.DistinctBins1h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · Terminal · 1h |
| 2.5-06 | Many distinct refund recipients per merchant | Refund fraud spread. | Abstraction Rule with Search Key MerchantId, Search Value 7 and Search Interval Days, Function Type Distinct Count and Function Key RefundRecipientId (placeholder field). The Activation Rule reads Abstraction.DistinctRefundRecipients7d; the threshold is illustrative. | Matched = Abstraction.DistinctRefundRecipients7d.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Merchant · 7d |
| 2.5-07 | Same cardholder, many distinct merchants in one MCC quickly | Rapid category hopping. | Abstraction Rule with Search Key CardMccKey (placeholder composite of card and MCC), Search Value 2 and Search Interval Hours, Function Type Distinct Count and Function Key MerchantId (placeholder field). The Activation Rule reads Abstraction.DistinctMerchantsCardMcc2h; the threshold is illustrative. The composite key is needed because the abstraction takes a single Search Key. | Matched = Abstraction.DistinctMerchantsCardMcc2h.MatchGreaterOrEqual(5) |
Tag: Cardinality · Fraud · Card · 2h |
| 2.5-08 | Many distinct card expiry dates attempted for one PAN | Expiry enumeration. | Abstraction Rule with Search Key PanKey (placeholder field, a keyed hash as in 2.4-21), Search Value 1 and Search Interval Hours, Function Type Distinct Count and Function Key CardExpiry (placeholder field). The Activation Rule reads Abstraction.DistinctExpiriesPan1h; the threshold is illustrative. Expiry is cardholder data, so its retention in the cache must be justified. | Matched = Abstraction.DistinctExpiriesPan1h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · PAN · 1h |
| 2.5-10 | Many distinct amounts attempted for one PAN at one merchant | Limit probing. | Abstraction Rule with Search Key PanMerchantKey (placeholder composite of the keyed PAN hash and merchant), Search Value 1 and Search Interval Hours, Function Type Distinct Count and Function Key CurrencyAmount. The Activation Rule reads Abstraction.DistinctAmountsPanMerchant1h; the threshold is illustrative. The composite key is built as in 2.4-21. | Matched = Abstraction.DistinctAmountsPanMerchant1h.MatchGreaterOrEqual(3) |
Tag: Cardinality · Fraud · PAN+Merchant · 1h |
