Open-source agentic AI for transaction monitoring. Just ask Jooby.What's Jube? →

Unstructured Text Screening

Definition: the signal is hidden in free text, not a structured field.

Construction: String extensions (Contains, ContainsAny, ContainsAll) against a Payload text field, checked against a List of terms. Use it when a structured check, per Static and Match Screening, would not see the signal. See the Rule Taxonomy.

Question an analyst asks Rule Taxonomy type that answers it
Does the payment reference mention crypto or gift cards? Unstructured Text Screening: ContainsAny
Does the narrative mention both an invoice and an urgent request? Unstructured Text Screening: ContainsAll
Is the account number on the deny list? Not this type: Static and Match Screening
Is the name close to a sanctioned party? Not this type: Sanctions, in Static and Match Screening

Unstructured Text Screening: Construction Steps

Identify the free text field in the payload (a narrative, reference, memo or description), decide whether the terms are few and stable or many and changing, then write an Activation Rule using the String extensions. Terms that change belong in a List, so that they can be maintained without editing the rule. The String extension family is discovered by reflection from Jube.Dictionary/Extensions, and is described in Rule Compilation Tokens and Extensions.

Step 1: Match a Small Fixed Set of Terms

A few terms are written inline. Any one of them, ignoring case (ContainsAny is the case sensitive form). Every test is null safe, so an empty narrative fails the test and does not fault the rule. See the Rule Pipeline Reference:

Matched = Payload.Narrative.MatchContainsAnyIgnoreCase("crypto", "gift card", "wire")

All of them, for a combination that only matters together:

Matched = Payload.Narrative.MatchContainsAll("urgent", "invoice")

ContainsAll has no ignore case form, so lower the text first with Lower(), and write the terms in lower case.

Step 2: Match a Maintained List of Terms

Where the terms are maintained by analysts, hold them in a List (see Lists) and use the List extensions of the fluent family. For example, a case insensitive match against any term in a List:

Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.HighRiskTerms)

The related methods (ContainsAllInList, ContainsNoneInList, StartsWithAnyInList, InList, NotInList, EmailDomainInList) are in Jube.Dictionary/Extensions with a Flow.String. prefix, and their behaviour is defined there.

Step 3: Normalise Before Matching

Free text is dirty, and evasion is deliberate. Transform before testing. Lower() and Upper() begin a pipeline and are null safe. Trim() on a plain value is the plain string method, which throws on null and so faults the rule, so use Payload.Name.Start().Trim() where null is possible. The richer string transformers (RemoveDiacritics, Replace, ReplaceByEmpty, Extract) are plain extension methods, applied before the pipeline steps, per the Rule Authoring Methodology. Where a field is an identifier and not prose, EmailDomainEqual, EmailDomainIn, EmailAliasNormalisedEqual, IsValidEmail, IsValidIban, IsValidBic and IsValidLuhn are tests.

Matched = Payload.Narrative.RemoveDiacritics().MatchContainsAnyIgnoreCase("crypto", "gift card")

Step 4: Fuzzy Matching

Exact and substring matching miss deliberate or accidental misspelling, such as crypt0, g1ft card or Bitcoinn. Fuzzy matching accepts a near miss. The fuzzy steps fall into three groups, by what is being compared with what.

A short field against a term or another field. LevenshteinAtMost(other, distance) accepts a number of single character edits (insertions, deletions, substitutions), so zero is identical and smaller is closer. SimilarityAtLeast(other, threshold) is the same comparison as a 0 to 1 score, easier to threshold when the strings vary in length. JaroWinklerAtLeast(other, threshold) favours a shared start, often better for names, and SoundexEqual(other) compares how the words sound. These compare two whole strings:

Matched = Payload.PaymentReference.MatchLevenshteinAtMost("bitcoin", 1)
Matched = Payload.PaymentReference.MatchSimilarityAtLeast("gift card", 0.85)
Matched = Payload.PayeeName.MatchJaroWinklerAtLeast(Payload.AccountHolderName, 0.9)

A short field against a maintained List. The ...InList forms compare the value with every entry of a List, so the terms are maintained outside the rule: LevenshteinAtMostAnyInList, SimilarityAtLeastAnyInList, JaroWinklerAtLeastAnyInList, and the fuller SomehowInList, which folds case, accents and punctuation and accepts a Jaro-Winkler or token sort similarity of at least 0.92:

Matched = Payload.MerchantName.MatchSomehowInList(List.HighRiskMerchants)

A term inside long text. A whole string comparison finds nothing in a long narrative, as the distance from the narrative to the term is large. ContainsFuzzy(term, threshold) instead looks for a run of words in the text that is at least the Jaro-Winkler threshold similar to the term, so a misspelt name inside a narrative is found. ContainsFuzzyAny takes several terms, ContainsFuzzyAnyInList(list, threshold) takes a List, and ContainsSomehowInList is the fuller form:

Matched = Payload.Narrative.MatchContainsFuzzy("bitcoin", 0.9)
Matched = Payload.Narrative.MatchContainsFuzzyAnyInList(List.HighRiskTerms, 0.9)

An options string tunes the fuzzy List steps that end in With (SomehowInListWith, ContainsSomehowInListWith): the algorithm (Levenshtein, Damerau, Jaro-Winkler, Dice, token sort, token set, Soundex, initials), the normalisation (case, accents, punctuation, titles, company suffixes), and a minimum length. Each option is defined in the Rule Pipeline Reference. An invalid options string fails closed:

Matched = Payload.Narrative.MatchContainsSomehowInListWith(List.HighRiskTerms, "lev=1,minlength=5")
Question in text screening Step to use
Is a short field a near miss of one known term? LevenshteinAtMost, or SimilarityAtLeast for a 0 to 1 score
Is a short field a near miss of any term in a List? SomehowInList, or LevenshteinAtMostAnyInList
Do two name fields nearly match? JaroWinklerAtLeast, or SimilarityAtLeast
Do two names sound the same? SoundexEqual
Is a term, or a misspelling of it, inside long text? ContainsFuzzy, ContainsFuzzyAnyInList, ContainsSomehowInList
Do I want the score itself, to threshold or to store? FuzzyBestScore, FuzzyMatchCount, FuzzyBestMatch
Is a name a near match to a regulatory list? Not this type: Sanctions, in Static and Match Screening

A fuzzy List match compares every event with every entry, so for a large List put an exact InList first, and use minlength for short values, where similarity is noisy. Sanctions use the same principle as a purpose built, indexed engine over regulatory lists, token by token and order insensitive, with distance and ratio controls. Prefer it for names against regulatory lists, and use these steps for the reference and narrative fields that Sanctions does not cover.

Step 5: Structural Signals

ShannonEntropyAbove(threshold) measures how random a string is, and is a useful signal for generated or obfuscated text. Matches(pattern) is a regular expression test for structured fragments hidden in text, and never throws on a bad pattern. HasSequentialDigits(minimumRunLength) and IsAllSameCharacter flag synthetic values.

Matched = Payload.Narrative.MatchShannonEntropyAbove(4.5)

Unstructured Text Screening: Common Faults

Symptoms of a misbuilt text rule, with the likely cause.

Symptom in a text rule Likely cause
A known term is missed Case, accents or spacing differ. Normalise the text first, or use a case insensitive comparison.
Far too many matches Substring matching: a short term matches inside longer words. Use longer terms or a pattern match.
A null narrative behaves unexpectedly Pipeline tests are null safe and fail on null. Only IsNull, IsNullOrEmpty and the IsNotValid... tests are true for null.
The term list is embedded in many rules Move the terms to a List and reference it.
A misspelt term is missed Exact matching. Use LevenshteinAtMost on a short field, or ContainsFuzzy for long text.
A fuzzy rule matches unrelated text The tolerance is too loose for the term’s length. Raise the threshold, or add minlength in an options string.
A fuzzy rule is slow A large List is compared on every event. Put an exact InList first, or add firstletter.

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.

7.1 Payment references and narratives (AML)

# Example Description Jube construction Fragment Notes
7.1-01 Sanctioned party names in narrative Names or aliases appear in free-text reference. List SanctionedPartyNames, searched inside the narrative with ContainsSomehowInListWith, whose scope is always within, using the nospaces option so spacing differences fold away. Short aliases give false positives, so add a minimum length to the options string and put the list through compliance review; screening the payment parties themselves is the Sanction construct, and this covers names inside free text only. Matched = Payload.Narrative.MatchContainsSomehowInListWith(List.SanctionedPartyNames, "nospaces") Tag: Text · AML · Payment narrative · per transaction
7.1-02 Sanctioned geography in narrative Narrative contains embargoed place names. List EmbargoedPlaceNames, case-insensitive containment in the narrative. Place names that double as common words or surnames need word-boundary handling, and the list must track the live embargo scope. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.EmbargoedPlaceNames) Check: Embargoed-place scope and place-name list must be confirmed against current authority lists (for example OFAC, EU, UK OFSI) by a human. Tag: Text · AML · Payment narrative · per transaction
7.1-03 Terrorism-related terms Narrative contains terrorism- or extremist-related keywords. List TerrorismTerms, case-insensitive containment. A keyword hit is weak alone, so a second rule reads counterparty geography or a sanctions-list result, and escalation needs both to fire. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.TerrorismTerms) Tag: Text · AML · Payment narrative · per transaction
7.1-04 Proliferation-related terms WMD/dual-use goods terms. List ProliferationTerms, case-insensitive containment. The list is built from dual-use control lists rather than free text, and a hit is a review cue. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.ProliferationTerms) Check: Dual-use control lists (for example EU Annex I, US Commerce Control List) are revised regularly; the term list must be checked against the current edition by a human. Tag: Text · AML · Payment narrative · per transaction
7.1-05 Drug trade slang Slang for narcotics. Word-boundary regex with the slang alternation written into the rule text, because short slang tokens sit inside unrelated words such as potato. The alternation terms are placeholders, and changing them is a rule edit rather than a list edit. Matched = Payload.Narrative.MatchMatches("(?i)\b(term1/term2/term3)\b") Tag: Text · AML · Payment narrative · per transaction
7.1-06 Human trafficking/smuggling indicators Terms associated with trafficking, escort services, “accommodation fees”. List TraffickingIndicatorTerms, case-insensitive containment. Terms such as escort and accommodation fees have lawful uses, so escalate only with a second signal, such as a TTL counter with Data Name PayeeId (placeholder field), Interval Hours / 1, Sum off, showing several payments to one payee in a short window. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.TraffickingIndicatorTerms) Tag: Text · AML · Payment narrative · per transaction
7.1-07 Child exploitation indicators Terms associated with CSAM purchase (escalated per law-enforcement protocols). List RestrictedIndicatorTerms, case-insensitive containment, kept access-restricted and sourced from specialist guidance. A hit routes to the law-enforcement escalation protocol rather than the ordinary alert handling. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.RestrictedIndicatorTerms) Check: Reporting obligation and receiving channel (for example NCMEC in the US or IWF in the UK) depend on jurisdiction and must be confirmed by a human. Tag: Text · AML · Payment narrative · per transaction
7.1-08 Weapons-related terms Firearms, ammunition, explosives. Word-boundary regex with the weapons alternation written into the rule, because short words such as gun sit inside other words. The alternation terms are placeholders. Matched = Payload.Narrative.MatchMatches("(?i)\b(term1/term2/term3)\b") Tag: Text · AML · Payment narrative · per transaction
7.1-09 Illegal wildlife trade terms Ivory, rhino horn, exotic species. List WildlifeTerms, case-insensitive containment. Product words such as ivory also occur in lawful names and brands, so a hit is a review cue. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.WildlifeTerms) Check: Species named in the list should be checked against CITES appendices by a human. Tag: Text · AML · Payment narrative · per transaction
7.1-10 Bribery/corruption phrases “commission”, “facilitation”, “gift for official”. List BriberyPhrases, case-insensitive containment, kept to specific multi-word phrases. Routine words such as commission and facilitation are left off, and escalation should also require a second rule reading a politically-exposed-person list on the payee. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.BriberyPhrases) Tag: Text · AML · Payment narrative · per transaction
7.1-11 Tax evasion phrases “off the books”, “cash only no invoice”. List TaxEvasionPhrases, case-insensitive containment. Multi-word phrases are specific enough to use as single hits. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.TaxEvasionPhrases) Tag: Text · AML · Payment narrative · per transaction
7.1-12 Hawala/informal value transfer terms References to informal systems. List InformalValueTransferTerms, case-insensitive containment. Some terms also name lawful remittance channels in certain corridors, so the hit is a risk signal and not a typology conclusion. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.InformalValueTransferTerms) Check: Legal status of informal value transfer differs by jurisdiction; a human should confirm the position before a term hit drives any reporting decision. Tag: Text · AML · Payment narrative · per transaction
7.1-13 Gambling/illegal betting terms Betting, odds, bookmaker. List BettingTerms, case-insensitive containment. Gambling is lawful in licensed markets, so combine the hit with a merchant-category field (Payload.MerchantCategory, placeholder) or licence status in a second condition, because odds and bookmaker are common elsewhere. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.BettingTerms) Tag: Text · AML · Payment narrative · per transaction
7.1-14 Loan-sharking/extortion terms Debt collection threats and “protection”. Fuzzy count of distinct entries of ExtortionTerms found within the narrative, with FuzzyMatchCountAtLeast in the within scope and a count of 2. Protection is generic alone, so two distinct listed terms are required rather than any single hit. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.ExtortionTerms, 2, "within") Tag: Text · AML · Payment narrative · per transaction
7.1-15 Ransom terms “ransom”, “decrypt”, “bitcoin payment” in narratives. List RansomTerms, case-insensitive containment. Ransom in insurance or incident text is common, so pair the hit in a second rule with an inbound-payment check on the existing Payload.Direction field. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.RansomTerms) Tag: Text · AML · Payment narrative · per transaction
7.1-16 Adult content/illicit service terms Narrative references. List IllicitServiceTerms, case-insensitive containment. Adult content is lawful in many markets, so the list targets illicit services specifically, and a hit routes to review rather than a block. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.IllicitServiceTerms) Check: Legality of adult services differs by jurisdiction; a human should confirm the term scope for each market. Tag: Text · AML · Payment narrative · per transaction
7.1-17 Generic placeholders (e.g. “test”, “payment”, “asdf”) Meaningless references on high-value transfers. Whole-value match of the narrative against PlaceholderNarratives, which avoids substring hits on the word payment, combined with a high-value test on Payload.CurrencyAmount. The threshold of 9000 is illustrative and is set per institution. Matched = Payload.Narrative.MatchInListIgnoreCase(List.PlaceholderNarratives) And Payload.CurrencyAmount.MatchGreater(9000) Tag: Text · Both · Payment narrative · per transaction
7.1-18 Same narrative on many payments Repeated unusual text (links to cardinality). TTL counter NarrativeRepeat: Data Name NormalisedNarrative (a placeholder Payload field that the upstream supplies already normalised), Interval Days / 7, Sum off. An incrementing rule Matched = True at Priority 1 counts every transaction, and this rule reads the counter at Priority 2 with a count above 3 (illustrative). Stretch: this works only if the entity analysis model accepts a narrative-derived key; if it does not, this row moves to C. Matched = TTLCounter.NarrativeRepeat.MatchGreater(3) Tag: Text · AML · Payment narrative · 7d
7.1-19 Invoice number and amount inconsistent with text Narrative amounts not matching payment. Stateless activation rule: it fires when the narrative contains a digit and no number in it is within 1 percent (illustrative) of Payload.CurrencyAmount. The Not form is used because NumberInTextWithinPercentOf returns true when an amount is found, and the rule needs the negation. The invoice-number half is not in this fragment. Matched = Payload.Narrative.MatchMatches("\d") And Not Payload.Narrative.NumberInTextWithinPercentOf(Payload.CurrencyAmount, 1) Tag: Text · Fraud · Payment narrative · per transaction
7.1-20 References to cryptocurrency terms “BTC”, “USDT”, wallet address in text. Word-boundary regex on the narrative for the ticker tokens, because BTC and USDT are short and would fire inside longer codes. The ticker alternation is written into the rule text. Matched = Payload.Narrative.MatchMatches("(?i)\b(btc/usdt)\b") Tag: Text · AML · Payment narrative · per transaction
7.1-21 Wallet address pattern in free text Regex for crypto addresses. Regex for address-shaped strings in the narrative: Bitcoin bech32 and legacy forms, and Ethereum-style hex. It finds shapes only, and checksum validation (Base58Check, bech32) would need its own stateless method. Matched = Payload.Narrative.MatchMatches("(?i)\b(bc1[a-z0-9]{25,62}/[13][a-km-zA-HJ-NP-Z1-9]{25,34}/0x[a-f0-9]{40})\b") Check: Address formats and length bounds should be verified against current chain specifications by a human. Tag: Text · AML · Payment narrative · per transaction
7.1-22 URL/domain in narrative Links in references used to move scam instructions. Regex for scheme-prefixed and www links in the narrative. Bare domains need a top-level-domain test that a regex cannot run, so they stay a separate rule edit. Matched = Payload.Narrative.MatchMatches("(?i)(https?:///www\.)\S+") Tag: Text · Fraud · Payment narrative · per transaction
7.1-23 Phone number in narrative Contact numbers embedded in reference. Regex for phone-shaped digit runs in the narrative. It also matches invoice and account numbers, so precision is limited, and the existing String.IsValidE164PhoneNumber applies to whole strings only. Matched = Payload.Narrative.MatchMatches("(\+/00)?\d[\d\s().-]{7,}\d") Check: E.164 caps a number at 15 digits and national formats vary; the length bounds in the pattern need human verification. Tag: Text · Fraud · Payment narrative · per transaction

7.2 Scam and fraud language

# Example Description Jube construction Fragment Notes
7.2-01 Scam-related phrases in narrative “investment”, “guaranteed returns”, “fee to release”, “tax clearance”, “crypto trading”. Fuzzy count of distinct entries of ScamPhrases found within the narrative, in the within scope with a count of 2. Investment is common in lawful narratives, so two distinct phrases are required; one specific phrase such as guaranteed returns with a new-payee signal is the alternative. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.ScamPhrases, 2, "within") Tag: Text · Fraud · Payment narrative · per transaction
7.2-02 Romance-scam phrases “love”, “visa”, “flight ticket”, “hospital for my”. Fuzzy count of distinct entries of RomanceScamPhrases found within the narrative, in the within scope with a count of 2. Love and visa are ordinary words, so two phrases are required, or one phrase combined with a new-payee signal. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.RomanceScamPhrases, 2, "within") Tag: Text · Fraud · Payment narrative · per transaction
7.2-03 Impersonation phrases (bank/police/HMRC) “safe account”, “fraud team”, “police officer”. List ImpersonationPhrases, case-insensitive containment against the chat text. Payload.ChatText is a placeholder field name, and the chat text must be in the payload before the rule is useful. Matched = Payload.ChatText.MatchContainsAnyInListIgnoreCase(List.ImpersonationPhrases) Tag: Text · Fraud · Payment narrative/Chat · per transaction
7.2-04 Safe-account language “safe account”, “secure account”, “transfer to protect”. List SafeAccountPhrases, case-insensitive containment. Safe account is specific enough to be a single hit. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.SafeAccountPhrases) Tag: Text · Fraud · Payment narrative · per transaction
7.2-05 Advance-fee phrases “release fee”, “clearing fee”, “processing fee”. Fuzzy count of distinct entries of AdvanceFeePhrases found within the narrative, in the within scope with a count of 2. Processing fee is common in lawful lending, so require two phrases, such as a fee term with a release or clearing term. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.AdvanceFeePhrases, 2, "within") Tag: Text · Fraud · Payment narrative · per transaction
7.2-06 Invoice redirection (BEC) phrases “new bank details”, “updated account”, “urgent wire”. List BecPhrases, case-insensitive containment against Payload.MessageBody (placeholder field name). Urgent wire is weak alone, so a second rule combines the hit with a beneficiary change against the payee record, read from a Dictionary or TTL counter. Matched = Payload.MessageBody.MatchContainsAnyInListIgnoreCase(List.BecPhrases) Tag: Text · Fraud · Email/Message · per event
7.2-07 Gift card/voucher purchase instructions “buy iTunes cards”. List GiftCardInstructions, case-insensitive containment. Brand-specific phrases need upkeep as product names change, so pair the hit with a counterparty outside the merchant category in a second condition. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.GiftCardInstructions) Tag: Text · Fraud · Chat/Narrative · per event
7.2-08 Rental/deposit scam phrases “holding deposit”, “keys on receipt”. List RentalDepositPhrases, case-insensitive containment. Holding deposit is standard in some lettings markets, so the hit is a review cue and not a block. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.RentalDepositPhrases) Check: Holding-deposit practice is regulated differently by jurisdiction; a human should confirm before the phrase is treated as a red flag in a given market. Tag: Text · Fraud · Narrative · per transaction
7.2-09 Job scam phrases “task payment”, “equipment fee”, “work from home”. Fuzzy count of distinct entries of JobScamPhrases found within the narrative, in the within scope with a count of 2. Work from home is generic, so require two phrases, for example task payment with equipment fee. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.JobScamPhrases, 2, "within") Tag: Text · Fraud · Narrative · per transaction
7.2-10 Charity/disaster scam phrases Disaster-related terms combined with new payee. Narrative containment of DisasterTerms combined with TTL counter PaymentsToPayee, Data Name a placeholder field holding the account and payee pair, Interval Days / 90, Sum off. The read is for zero earlier payments, so the reading rule must sit at an earlier Priority than the incrementing rule. The DisasterTerms list is time-bound and is retired when events close. Stretch: the composite key must be supported by the entity model. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.DisasterTerms) And TTLCounter.PaymentsToPayee.MatchEqual(0) Tag: Text · Fraud · Narrative · per transaction
7.2-11 Purchase scam phrases (marketplace) “courier”, “shipping fee”, “item sold”. Fuzzy count of distinct entries of MarketplaceScamPhrases found within the narrative, in the within scope with a count of 2. Courier and shipping fee are common in genuine e-commerce, so a second condition also requires a payment to an individual rather than a merchant, read from a placeholder payee-type field. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.MarketplaceScamPhrases, 2, "within") Tag: Text · Fraud · Narrative · per transaction
7.2-12 Coercion/duress phrases Words in free text indicating duress. List DuressPhrases, case-insensitive containment against the chat text. The list must be written and reviewed by fraud operations before use, and generic everyday phrasing must not be on it. Payload field names here are placeholders. Matched = Payload.ChatText.MatchContainsAnyInListIgnoreCase(List.DuressPhrases) Tag: Text · Fraud · Narrative/Chat · per event
7.2-13 Money-mule recruitment phrases “easy money”, “receive and forward”. Fuzzy count of distinct entries of MuleRecruitmentPhrases found within the narrative, in the within scope with a count of 2. Easy money is common in marketing, so require two phrases, or one phrase combined with a pass-through pattern read from a TTL counter. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.MuleRecruitmentPhrases, 2, "within") Tag: Text · Both · Chat/Narrative · per event
7.2-14 Account-sale or “renting account” phrases Selling credentials. List AccountSalePhrases, case-insensitive containment against the chat text. Both the selling and the renting wordings belong on the list. Payload field names here are placeholders. Matched = Payload.ChatText.MatchContainsAnyInListIgnoreCase(List.AccountSalePhrases) Tag: Text · Both · Chat/Narrative · per event
7.2-15 Customer support chat indicating being coached Customer says on the phone with a third party. List CoachingPhrases, case-insensitive containment against the support chat text. It describes a third party on the call, which is a typology cue and not proof. Payload field names here are placeholders. Matched = Payload.ChatText.MatchContainsAnyInListIgnoreCase(List.CoachingPhrases) Tag: Text · Fraud · Chat · per event

7.3 Names, addresses and identity text

# Example Description Jube construction Fragment Notes
7.3-01 Name contains company suffix on personal account Business activity on personal account (e.g. Ltd, LLC, GmbH). Regex for company suffixes on Payload.AccountName, combined with a test that the account is personal on Payload.AccountType (placeholder field name). The suffix list is jurisdiction-specific and is extended per market. Matched = Payload.AccountName.MatchMatches("(?i)\b(ltd/llc/gmbh/plc/inc/limited)\b") And Payload.AccountType.MatchEqualIgnoreCase("personal") Check: Company-suffix forms differ by jurisdiction; a human should confirm the list for each market. Tag: Text · AML · Account name · onboarding
7.3-02 Name contains high-risk keywords “exchange”, “remittance”, “forex”, “holdings”, “trading”. List HighRiskNameKeywords, case-insensitive containment against Payload.CustomerName. Exchange and trading appear in business names more than personal ones, so test the hit against account type in a second condition. Payload field names here are placeholders. Matched = Payload.CustomerName.MatchContainsAnyInListIgnoreCase(List.HighRiskNameKeywords) Tag: Text · AML · Customer name · onboarding
7.3-03 Name or address contains placeholder/test text “test”, “xxx”, “n/a”, “unknown”. Word-boundary regex on Payload.CustomerName for the placeholder words test, xxx, n/a and unknown, which avoids matches inside real surnames. A whole-value MatchInListIgnoreCase is stricter if preferred. Matched = Payload.CustomerName.MatchMatches("(?i)\b(test/xxx/n/a/unknown)\b") Tag: Text · Fraud · Application · onboarding
7.3-04 Gibberish name or keyboard-mash detection Randomly generated names. A consonant-run regex and a Shannon entropy test above 4.5 (illustrative), both on Payload.CustomerName. Real names with consonant clusters, such as Polish, Welsh or romanised Georgian, also fire, so the run length needs tuning on real data. Payload field names here are placeholders. Matched = Payload.CustomerName.MatchMatches("(?i)[bcdfghjklmnpqrstvwxz]{6,}") And Payload.CustomerName.MatchShannonEntropyAbove(4.5) Tag: Text · Fraud · Application · onboarding
7.3-05 Name and email username mismatch Email local-part unrelated to name. Stateless comparison: the email local part is folded with FoldedForMatching, which lowercases and removes separators and maps leetspeak digits and lookalike letters, then compared with the folded customer name by Jaro-Winkler at 0.9 (illustrative). A name must be present, and reversed name order is not handled. Payload.Email and Payload.CustomerName are placeholder field names. Matched = Payload.CustomerName.RequireIsNotNullOrWhiteSpace().Against(Payload.Email.EmailLocalPart().FoldedForMatching()).MatchJaroWinklerAtLeast(Payload.CustomerName.FoldedForMatching(), 0.9) Tag: Text · Fraud · Application · onboarding
7.3-06 Sequential or patterned emails user1234, user1235 patterns. Regex on Payload.Email for a letter stem followed by three or more digits, combined with TTL counter EmailStem, Data Name a placeholder field holding the stem with digits removed (supplied upstream), Interval Days / 30, Sum off, read above 2 (illustrative). The incrementing rule uses the same pattern, so the counter follows the sequence across applications, which the regex alone cannot see. Matched = Payload.Email.MatchMatches("(?i)^[a-z]+[._-]?\d{3,}@") And TTLCounter.EmailStem.MatchGreater(2) Tag: Text · Fraud · Application · onboarding
7.3-07 Address contains PO Box/mail forwarder/virtual office Non-physical address. Regex for PO box and postbox on Payload.Address, or a VirtualOfficeAndForwarderAddresses list matched case-insensitively. A PO box is not itself a fraud signal, so the forwarder list carries most of the weight. Payload field names here are placeholders. Matched = Payload.Address.MatchMatches("(?i)\b(p\.?\s?o\.?\s*box/postbox)\b") Or Payload.Address.MatchContainsAnyInListIgnoreCase(List.VirtualOfficeAndForwarderAddresses) Tag: Text · Both · Address · onboarding
7.3-08 Address contains hotel/hostel Transient address. List TransientAddressTerms on Payload.Address, case-insensitive containment. Hotels are a legitimate residence for some customers, so the hit is a review cue. Payload field names here are placeholders. Matched = Payload.Address.MatchContainsAnyInListIgnoreCase(List.TransientAddressTerms) Tag: Text · Fraud · Address · onboarding
7.3-09 Address contains “care of” third party Mail intercept. List CareOfMarkers on Payload.Address, case-insensitive containment. The markers c/o and care of are specific enough for a plain substring match. Payload field names here are placeholders. Matched = Payload.Address.MatchContainsAnyInListIgnoreCase(List.CareOfMarkers) Tag: Text · Fraud · Address · onboarding
7.3-10 Occupation text mismatches product Student with business turnover. Whole-value match of a coded occupation against NonBusinessOccupations, combined with Payload.AnnualTurnover (arrives as text, so it is read with ParseDouble) above 50000 (illustrative; a product parameter). Free-text occupation must be coded first, and that coding is outside this fragment. Payload field names here are placeholders. Matched = Payload.Occupation.MatchInListIgnoreCase(List.NonBusinessOccupations) And Payload.AnnualTurnover.ParseDouble().MatchGreater(50000) Check: The turnover threshold is a product parameter; no regulatory figure is set here. Tag: Text · AML · Customer · onboarding
7.3-11 Declared source-of-funds text vague “savings”, “gift”, “other”. Whole-value match of Payload.SourceOfFunds against VagueSourceOfFunds. Savings is a common legitimate answer, so it is a weak signal and not sufficient alone. Payload field names here are placeholders. Matched = Payload.SourceOfFunds.MatchInListIgnoreCase(List.VagueSourceOfFunds) Tag: Text · AML · Customer · onboarding
7.3-12 Declared purpose of account text indicates third-party use “on behalf of”, “for a friend”. List ThirdPartyPurposePhrases on Payload.AccountPurpose, case-insensitive containment. Multi-word phrases are specific enough as single hits. Payload field names here are placeholders. Matched = Payload.AccountPurpose.MatchContainsAnyInListIgnoreCase(List.ThirdPartyPurposePhrases) Tag: Text · AML · Customer · onboarding

7.4 Trade, shipping and goods descriptions

# Example Description Jube construction Fragment Notes
7.4-01 Goods description vague or generic “goods”, “merchandise”, “spare parts”. Whole-value match of Payload.GoodsDescription against GenericGoodsDescriptions, combined with a length limit of 20 characters (illustrative tuning parameter). Payload field names here are placeholders. Matched = Payload.GoodsDescription.MatchInListIgnoreCase(List.GenericGoodsDescriptions) And Payload.GoodsDescription.MatchLengthLess(20) Tag: Text · AML · Trade · per transaction
7.4-02 Goods description inconsistent with HS code Mismatch between text and code. HS-heading category derived from the HS code does not agree with the category implied by the goods text. Upstream fields: Payload.HsHeadingCategory (derived from the code) and Payload.GoodsTextCategory (the text classification), supplied before Jube or by an inline-script hook. Headings must be verified against the current tariff before use. Matched = Payload.HsHeadingCategory.RequireIsNotNullOrWhiteSpace().MatchNotEqual(Payload.GoodsTextCategory) Check: HS headings are set by customs authorities; a human must verify the heading against the current tariff before the reference data is used. Tag: Text · AML · Trade · per transaction
7.4-03 Controlled/dual-use goods terms “centrifuge”, “valves”, “titanium”, “encryption”. List DualUseGoodsTerms on Payload.GoodsDescription, case-insensitive containment. Valves, titanium and encryption are ordinary goods, so a hit is a review cue, and a controlled-item decision needs the control-list entry. Payload field names here are placeholders. Matched = Payload.GoodsDescription.MatchContainsAnyInListIgnoreCase(List.DualUseGoodsTerms) Check: Dual-use control lists (for example EU Annex I, US Commerce Control List) decide whether an item is controlled; a human must verify each term against the current edition. Tag: Text · AML · Trade · per transaction
7.4-04 Luxury goods and precious materials terms “gold”, “diamonds”, “bullion”. List PreciousGoodsTerms on Payload.GoodsDescription, case-insensitive containment. Gold and diamonds are everyday trade words, so pair the hit with a value or new-counterparty test in a second condition. Payload field names here are placeholders. Matched = Payload.GoodsDescription.MatchContainsAnyInListIgnoreCase(List.PreciousGoodsTerms) Tag: Text · AML · Trade · per transaction
7.4-05 Port/vessel names in text linked to sanctioned routes Free-text vessel and port detection. List SanctionedVesselAndPortNames on Payload.ShipmentText, case-insensitive containment. Vessel names are reused and change, so key the list on IMO numbers wherever the payload carries them. Payload field names here are placeholders. Matched = Payload.ShipmentText.MatchContainsAnyInListIgnoreCase(List.SanctionedVesselAndPortNames) Check: Vessel and port designations must be verified against the current authority lists by a human. Tag: Text · AML · Trade · per transaction
7.4-06 Ship-to-ship transfer and flag-hopping terms “STS”, “flag change”. Word-boundary regex on Payload.ShipmentText for STS, ship-to-ship and flag change. STS is a short token, and the boundaries stop hits inside longer words. Payload field names here are placeholders. Matched = Payload.ShipmentText.MatchMatches("(?i)\b(sts/ship[- ]to[- ]ship/flag change)\b") Tag: Text · AML · Trade · per transaction
7.4-07 Phantom shipment indicators Terms indicating no physical movement. List NoMovementTerms on Payload.ShipmentText, case-insensitive containment. Trade narratives also use not shipped in exception notes, so treat a hit as a cue. Payload field names here are placeholders. Matched = Payload.ShipmentText.MatchContainsAnyInListIgnoreCase(List.NoMovementTerms) Tag: Text · AML · Trade · per transaction
7.4-08 Duplicate invoice descriptions Same description used across invoices. TTL counter InvoiceDescriptionRepeat, Data Name a placeholder field holding the account and the normalised description together, so the count is per account and description, Interval Days / 30, Sum off. The incrementing rule is Matched = True at Priority 1, and this rule reads above 3 (illustrative) at Priority 2. The same stretch as 7.1-18 applies: if the entity model cannot key on text, this row moves to C. Matched = TTLCounter.InvoiceDescriptionRepeat.MatchGreater(3) Tag: Text · AML · Trade · 30d

7.5 Case notes, alerts and communications

# Example Description Jube construction Fragment Notes
7.5-01 Employee notes referencing known typologies Case notes with terms for pattern linking. List TypologyPatternTerms on Payload.CaseNote (placeholder field), case-insensitive containment. Notes are written after alerts, so the rule sees only notes that already exist at evaluation time, and it may belong only as an analyst aid. Matched = Payload.CaseNote.MatchContainsAnyInListIgnoreCase(List.TypologyPatternTerms) Tag: Text · Both · Case · per case
7.5-02 Customer complaint/dispute text indicating unauthorised use “I did not authorise”, “not me”. Regex on Payload.DisputeText (placeholder field) for the phrases I did not authorise and not me, with word boundaries so that the phrase does not sit inside other words. Matched = Payload.DisputeText.MatchMatches("(?i)\b(i did not authorise/not me)\b") Tag: Text · Fraud · Dispute · per event
7.5-03 Customer messages with obfuscated text (leetspeak, unicode homoglyphs) Evasion of text screening. FoldedForMatching lowercases the chat text, maps leetspeak digits and Cyrillic or Greek lookalikes to Latin letters, and removes separators, then the List RestrictedTerms is matched. List entries must be stored in the same folded form (no separators), and because the fold removes spaces a term can match across a word boundary, so keep terms long. Apply the fold to text fields only, never to amounts or identifiers. Payload field names here are placeholders. Matched = Payload.ChatText.FoldedForMatching().MatchContainsAnyInListIgnoreCase(List.RestrictedTerms) Tag: Text · Both · Narrative · per transaction
7.5-04 Narrative containing emoji/symbols used as codes Coded communication. Regex on Payload.Narrative for symbol and surrogate Unicode categories, which cover most pictographs. Emoji are common in lawful chat, so the fragment flags symbols in general and does not decide whether one is used as a code. Matched = Payload.Narrative.MatchMatches("[\p{So}\p{Cs}]") Tag: Text · Fraud · Narrative · per transaction
7.5-05 Narrative in unusual script (mixed alphabets) Homoglyph spoofing. Regex on Payload.Narrative for Latin letters and Cyrillic in the same text, which is the common homoglyph case. Bilingual names fire too, so pair it with a name-versus-address check. Matched = Payload.Narrative.MatchMatches("(?=.*\p{IsCyrillic})(?=.*[A-Za-z])") Tag: Text · Fraud · Narrative · per transaction
7.5-06 Support ticket requesting limit/contact change with urgency language Urgency and authority phrases. Fuzzy count of two distinct entries of UrgencyAuthorityPhrases within Payload.TicketText (placeholder field), combined with a ticket type of limit or contact change on Payload.TicketType, which must be coded. Matched = Payload.TicketText.MatchFuzzyMatchCountAtLeast(List.UrgencyAuthorityPhrases, 2, "within") And Payload.TicketType.MatchEqualIgnoreCase("limit or contact change") Tag: Text · Fraud · Ticket · per event
7.5-07 Email subject/body phishing indicators in bank-originated forwarding Phishing reports. Fuzzy count of two distinct entries of PhishingIndicatorPhrases within the forwarded message body in Payload.EmailBody (placeholder field). Sender-authentication results (SPF, DKIM, DMARC) are message headers and sit outside this text fragment, so the rule is incomplete without them in the payload. Matched = Payload.EmailBody.MatchFuzzyMatchCountAtLeast(List.PhishingIndicatorPhrases, 2, "within") Tag: Text · Fraud · Email · per event

7.6 Sector-specific text screening

# Example Description Jube construction Fragment Notes
7.6-01 Claim description matches staged-accident phrasing (insurance) Templated narratives across claims. Fuzzy count of two distinct entries of StagedAccidentPhrasing within Payload.ClaimDescription (placeholder field). The list is built from observed claims, and the fuzzy count tolerates small wording changes. Matched = Payload.ClaimDescription.MatchFuzzyMatchCountAtLeast(List.StagedAccidentPhrasing, 2, "within") Tag: Text · Fraud · Claim · per claim
7.6-02 Claim narrative near-duplicate of another claim Text similarity across claims. Count of claim narratives sharing the same text fingerprint bucket over 24 months, from a TTL Counter keyed on the fingerprint. Upstream field: Payload.NarrativeFingerprint, a SimHash or MinHash bucket, supplied before Jube or by an inline-script hook. Count 1 means at least one earlier claim in the bucket plus this one; the bucket count is an illustrative placeholder. Matched = TTLCounter.NarrativeFingerprintCount24m.MatchGreater(1) Tag: Text · Fraud · Claim · 24m
7.6-04 Chat/support text mentioning “bonus”, “arb”, “matched betting” (gaming) Abuse indicators. Word-boundary regex on Payload.ChatText for arb, matched betting and bonus abuse. Arb sits inside arbitrary without boundaries, and bonus alone is too common to be a hit. Payload field names here are placeholders. Matched = Payload.ChatText.MatchMatches("(?i)\b(arb/matched betting/bonus abuse)\b") Tag: Text · Fraud · Chat · per event
7.6-05 Player chat indicating collusion (“dump”, “transfer chips”) Collusion language. Word-boundary regex on Payload.ChatText for dump and transfer chips. Dump is a substring of other words without the boundaries, and transfer chips is specific. Payload field names here are placeholders. Matched = Payload.ChatText.MatchMatches("(?i)\b(dump/transfer chips)\b") Tag: Text · AML · Chat · per event
7.6-06 Token/contract name mimics well-known project (crypto) Lookalike naming. Two tests on Payload.TokenName (placeholder field) against WellKnownProjectNames at 0.92 (illustrative): Jaro-Winkler on the whole name catches close copies, and contains-fuzzy catches a known project name embedded with extra words. Matched = Payload.TokenName.MatchJaroWinklerAtLeastAnyInList(List.WellKnownProjectNames, 0.92) Or Payload.TokenName.MatchContainsFuzzyAnyInList(List.WellKnownProjectNames, 0.92) Tag: Text · Fraud · Asset · per listing
7.6-07 Memo field contains “mixer”, “tumbler”, “darknet” terms On-chain memo screening. List MixerTerms on Payload.Memo (placeholder field), case-insensitive containment. Mixer appears in lawful product memos, so pair the hit with the on-chain transaction type or counterparty in a second condition. Matched = Payload.Memo.MatchContainsAnyInListIgnoreCase(List.MixerTerms) Tag: Text · AML · Memo · per transaction
7.6-09 Order comments with “guaranteed”, “insider” (brokerage) Suspicious trading commentary. List OrderCommentTerms on Payload.OrderComment (placeholder field), case-insensitive containment. Insider is specific, but guaranteed is common, so pair it with order size or account type in a second condition. Matched = Payload.OrderComment.MatchContainsAnyInListIgnoreCase(List.OrderCommentTerms) Tag: Text · Both · Account · per event
7.6-10 Mobile-money reference contains “loan”, “repay”, “agent” repeatedly Informal lending via wallets. TTL counter LendingNarratives, Data Name Wallet (placeholder field), Interval Days / 30, Sum off, read above 3 (illustrative). The incrementing rule is Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.InformalLendingTerms, 2, "within") at an earlier Priority, so only matching narratives increment the counter, because an incrementing rule counts only when it matches. If the counter counted every transaction, the rule would have to be restated as a ratio. Matched = Payload.Narrative.MatchFuzzyMatchCountAtLeast(List.InformalLendingTerms, 2, "within") And TTLCounter.LendingNarratives.MatchGreater(3) Tag: Text · AML · Wallet · 30d
7.6-11 Vendor name close match to existing vendor (corporate) Lookalike vendor names (“Acme Ltd” vs “Acme Ltd.”). A vendor name that is identical to an ExistingVendorNames entry is rejected first, so the rule flags only lookalikes such as Acme Ltd against Acme Ltd. The fuzzy step with the nosuffixes option drops company forms, so the two normalise equal, and the Jaro-Winkler default covers near misses. The vendor-master list size bounds the per-record cost. Payload field names here are placeholders. Matched = Payload.VendorName.RejectInListIgnoreCase(List.ExistingVendorNames).MatchSomehowInListWith(List.ExistingVendorNames, "nosuffixes") Tag: Text · Fraud · Vendor · onboarding
7.6-12 Invoice text with altered bank details phrasing “please note our new account”. List AlteredBankDetailsPhrases on Payload.InvoiceText (placeholder field), case-insensitive containment. The phrasing is specific and belongs to the same family as the message phrases in 7.2-06. Matched = Payload.InvoiceText.MatchContainsAnyInListIgnoreCase(List.AlteredBankDetailsPhrases) Tag: Text · Fraud · Invoice · per invoice
7.6-13 Email domain lookalike (homoglyph/typosquat) of supplier BEC domain spoof. Stateless comparison on Payload.SenderEmail (placeholder field). The raw domain is rejected first when it is identical to a SupplierDomains entry, so only a domain that is not identical is tested. The remaining domain is folded with FoldedForMatching, which maps homoglyphs and removes separators, and then fuzzy-matched against the same list at the default 0.92 similarity (illustrative). Matched = Payload.SenderEmail.EmailDomain().RejectInListIgnoreCase(List.SupplierDomains).Against(Payload.SenderEmail.EmailDomain().FoldedForMatching()).MatchSomehowInList(List.SupplierDomains) Tag: Text · Fraud · Email · per event
7.6-14 Product listing text with counterfeit markers (e-commerce) “replica”, “AAA grade”. List CounterfeitMarkers on Payload.ListingText (placeholder field), case-insensitive containment. Replica also describes lawful reproductions, so a hit is a review cue, while AAA grade is specific. Matched = Payload.ListingText.MatchContainsAnyInListIgnoreCase(List.CounterfeitMarkers) Tag: Text · Fraud · Listing · per listing
7.6-16 Job advert text matching mule-recruitment templates “financial agent”, “payment processor”. Fuzzy count of two distinct entries of MuleRecruitmentTemplates within Payload.ListingText (placeholder field). It shares phrases with the mule family in 7.2-13, and the fuzzy count tolerates template variants. Matched = Payload.ListingText.MatchFuzzyMatchCountAtLeast(List.MuleRecruitmentTemplates, 2, "within") Tag: Text · Both · Listing · per listing
7.6-17 Loan purpose text implausible or templated Identical purpose across applications. TTL counter LoanPurposeRepeat, Data Name a placeholder field holding the normalised loan purpose (supplied upstream), Interval Days / 30, Sum off, read above 3 (illustrative), with an incrementing rule Matched = True at Priority 1. Stretch: the same text-derived key as 7.1-18 applies. The implausible part of the example needs model-based judgement and is not covered. Matched = TTLCounter.LoanPurposeRepeat.MatchGreater(3) Tag: Text · Fraud · Application · 30d
7.6-18 SWIFT field 70/72 containing codewords Remittance information with coded instructions. List SwiftField70And72Codewords on Payload.RemittanceInfo (placeholder field), case-insensitive containment. Codewords come from the bank’s own instruction catalogue, and short codes need word boundaries, which a containment list does not give; move a short code into a word-boundary Matches pattern. Matched = Payload.RemittanceInfo.MatchContainsAnyInListIgnoreCase(List.SwiftField70And72Codewords) Check: Field 70 and 72 structure and codes are defined by SWIFT MT standards; a human must verify the codeword list against the current standard. Tag: Text · AML · Payment · per transaction
7.6-19 Donation reference naming conflict regions or armed groups (NPO) TF text. List ConflictRegionAndArmedGroupNames on Payload.Narrative, case-insensitive containment. The list should come from designated-entity lists rather than free text, because armed-group names overlap with place names and humanitarian references. Matched = Payload.Narrative.MatchContainsAnyInListIgnoreCase(List.ConflictRegionAndArmedGroupNames) Check: Designated armed-group and conflict-region lists must be verified against current authority lists by a human. Tag: Text · AML · Donation · per transaction
7.6-20 Narrative describing “gift” from unrelated adult to many recipients Grooming/trafficking indicator. Narrative containment of gift combined with TTL counter GiftNarrativeSends, Data Name Sender (placeholder field), Interval Days / 30, Sum off, read above 5 (illustrative). The incrementing rule Matched = Payload.Narrative.MatchContainsIgnoreCase("gift") at an earlier Priority counts each send. Without a relationship flag in the payload (placeholder), the rule fires on any gift narrative from one sender; recipient spread can use a distinct-count Abstraction Rule instead of a count. Matched = Payload.Narrative.MatchContainsIgnoreCase("gift") And TTLCounter.GiftNarrativeSends.MatchGreater(5) Tag: Text · AML · Narrative · 30d

7.7 Obfuscation and evasion detection in text

# Example Description Jube construction Fragment Notes
7.7-01 Character substitution (0 for O, 1 for l) in sanctioned names Homoglyph evasion. Folded name match: FoldedForMatching lowercases, removes separators, and maps leetspeak digits and lookalike letters, then the folded name is fuzzy-matched by whole value against the internal SanctionedNames list. Regulatory names belong to the Sanction construct in Static and Match Screening, and because the fold changes genuine digits it applies to name fields only. Payload field names here are placeholders. Matched = Payload.CustomerName.FoldedForMatching().MatchSomehowInList(List.SanctionedNames) Tag: Text · AML · Narrative · per transaction
7.7-02 Spaces or punctuation inserted inside key terms “B I T C O I N”. Containment of KeyTerms inside the narrative with the nospaces option, so that B I T C O I N matches bitcoin in both the text and the entries. Punctuation is already stripped by the default normalisation. Matched = Payload.Narrative.MatchContainsSomehowInListWith(List.KeyTerms, "nospaces") Tag: Text · AML · Narrative · per transaction
7.7-03 Transliteration variants across scripts Cyrillic/Arabic/Latin mixes. Cyrillic and Greek letters are transliterated to Latin with TransliterateToLatin, then case-insensitive containment of KeyTerms is applied. Arabic is not in the transliteration table, so Arabic script is not covered, and the mapping is approximate. Matched = Payload.Narrative.TransliterateToLatin().MatchContainsAnyInListIgnoreCase(List.KeyTerms) Tag: Text · AML · Narrative · per transaction
7.7-04 Abbreviations of restricted terms “crypto” as “cr”, country codes. Word-boundary regex on Payload.Narrative for the known abbreviations, written into the rule text, because cr is a substring of many words. Only known abbreviations are caught, and the alternation terms are placeholders. Matched = Payload.Narrative.MatchMatches("(?i)\b(abbrev1/abbrev2)\b") Check: Two-letter country-code abbreviations are highly ambiguous; a human should review any such entry before it is used. Tag: Text · AML · Narrative · per transaction
7.7-05 Emoji substitution for words Pictographs replacing terms. Narrative contains emoji replaced by their names. Upstream field: Payload.NarrativeEmojiNamed, the narrative with emoji replaced by names by the hook, supplied before Jube or by an inline-script hook. List: List.RestrictedTerms. Matched = Payload.NarrativeEmojiNamed.MatchContainsAnyInListIgnoreCase(List.RestrictedTerms) Tag: Text · Both · Narrative · per transaction
7.7-06 Base64/hex encoded strings in memo Encoded payloads. Regex on Payload.Memo (placeholder field) for base64-shaped runs and for long hex runs. It detects encoded-looking text, not what it decodes to, and long digit runs also match the hex pattern. Matched = Payload.Memo.MatchMatches("[A-Za-z0-9+/]{24,}={0,2}") Or Payload.Memo.MatchMatches("(?i)\b[0-9a-f]{32,}\b") Tag: Text · Both · Memo · per transaction
7.7-07 Narrative length anomaly (very long reference) Instructions embedded. Length test on Payload.Narrative against a placeholder limit of 140 characters (illustrative). The payment scheme reference-field limit is the real parameter, and very long is not defined by the section. Matched = Payload.Narrative.MatchLengthGreater(140) Check: Payment-scheme reference-field length limits must be verified against the scheme in use by a human. Tag: Text · Fraud · Narrative · per transaction