SCORPION/PDMSC/INTENT2/S1/MISUIC
Message intent

INTENT2 and INTENT/S1: reading what a message is for.

Two language models that judge the intent of a message rather than its wording. They exist because the next generation of spam and scams will be written by AI, and will no longer give themselves away with bad grammar and spelling.

Why intent

Scam emails have always been easy to spot by their mistakes. That stops being true once the text is generated by a model. Michelle Sullivan wrote about this in April 2025 in “Question 2” – Into AI, asking the right questions: How to Spot Email Scams.

Bayesian filtering has been the traditional answer, and the people sending the mail have long since learned to bury their message in blocks of legitimate text to fool or poison it. Vsevolod Stakhov of Rspamd has written about the continued misuse of Bayesian filtering and implemented a different approach, selective Bayesian filtering. It has had considerable success, though in production it still suffers some of the real problems of adversarial filter evasion.

For that reason the research here moved first to support vector machines and now to language models, custom and otherwise, on commodity hardware, measuring how well each identifies spam, malicious content, legitimate marketing, and ordinary personal and business mail. PDMSC is a direct result of that research, and INTENT2/S1 is its latest component.

The two models

A

INTENT2

Legacy/info only

The first of the two, built on a commercially available language model with specific prompts and tuning to tell bad mail from good. It takes around two seconds per message on an RTX 3060, down from 45 seconds on the older Quadro M2000. It has been good at phishing and scams, but it misses reply-quoting spam, where the message is dressed up as a reply to something you never sent, and, as the second example below shows, it can condemn a genuine newsletter and invent a reason for doing so. It is now a legacy component whose results are for information only, kept running so that INTENT/S1 can be compared against it directly.

B

INTENT/S1

In production

A much smaller model, created because of that gap. Its size and computational cost let it run in production on the M2000, a card with no tensor cores, at an average of 300 to 500 milliseconds per message. It separates malicious mail from bulk mail, from SEO spam, from legitimate mail, and in observation on live traffic it does so very well. Formal accuracy figures for INTENT/S1 are not yet published; what is said here comes from watching it on real mail.

What it runs on

Building, testing, and measuring have all been done on commodity hardware, some of it deliberately ancient. The reasoning is simple: if it performs reasonably well on that, it will perform at enterprise levels on enterprise hardware. This is the example setup.

Mail path
Dell R620 running bhyve, hosting three virtual machines of 2 CPUs and 4 GB each
VM 1
Incoming Postfix MX server
VM 2
Dedicated Rspamd instance
VM 3
Redis cluster node, holding the Rspamd and INTENT2 results
Engines
HP Z440 desktop, Ubuntu 24 LTS, 16 GB RAM
INTENT2
Pinned to a GeForce RTX 3060
INTENT/S1
Pinned to a Quadro M2000

Rspamd calls the engines over HTTP through its external services module.

Example 1: a cold sales pitch

This one arrived on 26 October 2026 and shows what the approach is for. It is a follow-up from a web design vendor, written as a reply to an earlier message that was never sent. In Apple Mail it looked like this.

Apple Mail showing a message titled RE: Secure and Smart Site, a follow-up from a web design vendor offering to redesign the recipient's website, with a quoted earlier message below.
The message as received, in Apple Mail.

It was delivered to the inbox, but because of deliberate settings and not because of the analysis. These are the relevant Rspamd headers, trimmed to the lines that matter.

X-PDMSC-Verdict: Ham
X-Rspamd-Action: no action
X-Spam-Status: No, score=-4.00
INTENT2_LEGITIMATE(-5.00)[The email is a follow-up from the sender offering website
    redesign services, which is a legitimate business inquiry.]
PDMSC_HAM_0(-1.00)[english x0.01 db6|v95 ...]
FAKE_REPLY(1.00)[]
RECEIVED_SPAMHAUS_XBL(1.00)[...:received]
PDMSC_S1_BULK(0.00)[p=0.71 329ms]
INTENT2_META(0.00)[via:queue,cat:legitimate,route:deep]

PDMSC itself called the message ham, HAM_0, which is not a confident enough verdict to stop there, so it passed the message to INTENT2, as it does for unknown and SPAM_0 results. INTENT2 returned legitimate (see INTENT2_META). That is the failure described above: it misses spam that is dressed up as conversation.

Blocklists did not help either. The message came through Gmail, so the connecting address was Gmail’s, and no mainstream blocklist will list that. One list did flag the original sender’s address further back in the headers, but at a score of 1.0 that was nowhere near enough.

INTENT/S1, on the other hand, classified it correctly as bulk, with a probability of 0.71, in 329 milliseconds on the M2000.

Example 2: a genuine newsletter

This one is the other way round. It is a marketing email from The Lott advertising a lottery draw: a genuine message from a real sender, and it passed authentication. In Apple Mail it looked like this.

Apple Mail showing a colourful marketing email from The Lott for the Oz Lotto draw, with a banner reading $50 tonight and a Play now button. Apple Mail notes that the message is from a mailing list.
The message as received, in Apple Mail.

Rspamd marked it as spam, with a score of 17.39, and nearly all of that came from INTENT2. These are the relevant headers, trimmed.

X-PDMSC-Verdict: Ham
X-Rspamd-Action: add header
X-Spam-Status: Yes, score=17.39
INTENT2_MALICIOUS(12.00)[The email claims to be from The Lott and mentions account
    security upgrades, but the links are suspicious and may be phishing for
    credentials.]
SCAM_MONEY_MAGNITUDE(3.50)[]
SUBJECT_HAS_CURRENCY(1.00)[]
MANY_INVISIBLE_PARTS(1.00)[10]
ZERO_FONT(0.50)[5]
PDMSC_HAM_0(-1.00)[unknown x0.07 db6|v463 ...]
DMARC_POLICY_ALLOW(-0.50)[thelott.com,reject]
R_DKIM_ALLOW(-0.20)[e.thelott.com:s=tatts]
R_SPF_ALLOW(-0.20)[...]
HAS_LIST_UNSUB(-0.01)[]
PDMSC_S1_BULK(0.00)[p=0.77 416ms]
INTENT2_META(0.00)[via:queue,cat:phishing,route:deep,flag:hidden_text_high]

INTENT2 called it malicious and added 12.00 of the 17.39; without that one symbol the score would have been 5.39. The reason it gave describes account security upgrades and suspicious links, but the message is an advertisement for a lottery draw and mentions neither. The model produced a confident, fluent explanation for a verdict the email does not support.

Everything that could be checked said the message was genuine. The sender’s domain publishes a reject policy and the message passed DMARC, DKIM, and SPF, and it carried a list-unsubscribe header. The hidden-text flags that sent it to a deep scan are common in commercial email, which routinely hides preview text and spacing.

INTENT/S1 classified it as bulk, with a probability of 0.77, in 416 milliseconds on the M2000. That is the right answer: a genuine mass mailing. Its score was 0.00 in both examples, so it did not change either outcome, and INTENT2 did.

What we changed after the first example

Rspamd had correctly marked the message as a fake reply, FAKE_REPLY, even though it was sent with the original quoted. That marker is exactly the kind of signal the language model should not be second-guessing, so the INTENT2 service has since been changed to treat it as an instruction not to scan the message with the LLM at all. This message, and any future iteration of it, will now be classified as spam.

That is the approach to the whole stack: use each component for what it is good at, and feed what one learns back into the others.

Why a general-purpose LLM is not enough

Put the two messages side by side. In the first, a general-purpose language model waved through a cold sales pitch dressed up as a reply. In the second, it condemned a genuine newsletter as phishing and invented a reason. It was wrong in both directions, and fluent and confident each time. A general model has no particular knowledge of the difference between a mass mailing, spam, and phishing; it has a plausible story for whatever label it lands on.

That is why a general-purpose LLM cannot simply be dropped into the mail path, and why INTENT/S1 exists. It is a model built for one job, telling malicious mail from bulk mail from SEO spam from legitimate mail, and it is small enough to answer in a few hundred milliseconds on an old GPU with no tensor cores.

INTENT2 is the comparison. It stays in the stack so the two can be measured side by side on real mail, and it is now a legacy component whose results are for information only.

Try it against your own mail first

Like the rest of the stack, INTENT2 and INTENT/S1 can run in observe-only mode beside your existing filtering, so you see what they would have decided on your own traffic before anything they say affects a message.

The quickest way to see it is the live test service at pdmsc.com/live.html. A module for your own rspamd sends each message to live.pdmsc.com and gets back the cascade verdict and both intent classifiers' opinions, scoring at zero until you decide otherwise. It is for evaluation at low volume, not production mail flow, and it sends the whole message off your system, so use it only with mail that is allowed to leave your network. Everything else about the stack is at www.pdmsc.com.

enquiries@misullivan.com