Skip to content

A spam filter trained on one person's mail: the evidence

The question: how should a spam filter trained on one person's own mail be built, so that it learns on that person's computer, judges mail on every device, a phone included, and never hides mail that matters? Which model, which facts from the headers, which labels, how to measure it honestly, what a model trained on a mailbox leaks, how adversaries attack it, and which Rust crates make it possible without Python or C++?

Researched on 7 October 2026, before the filter was built, from the primary sources listed at the end: papers, the reports of the TREC spam tracks, and the documentation and source code of the filters people use. Each finding carries a grade: strong when several independent primary studies or official documents agree; moderate for one solid primary source or consistent secondary reports; weak for a single small study, a blog post, or an inference, marked as such. "Public corpora only" marks a result measured on the Enron, Ling-Spam, SpamAssassin or TREC corpora rather than on a person's live mailbox. "Built", "decided otherwise" and "not built" say where Sioul stood on 8 October 2026 (version 0.0.3); spam-filter.md says how the filter works now, and virtual-secretary.md what it took from Virtual Secretary.

Where the design started

The author's design came from his Virtual Secretary: a fastText language model trained on the computer on the person's own mail; a linear SVM over facts read from the headers and the message's mean word vector (its centroid); the model shared with the phone through the sharing folder; everything in Rust. The research set that design against the literature, and found five things.

  • Virtual Secretary never had a learned spam filter. Its SVM sorted mail into folders, from the mean word vector of the subject and the plain text, with no header facts; its spam handling was rules. What carried over is its text pipeline, not a model (virtual-secretary.md, "What the spam filter took from Virtual Secretary").
  • All of it is feasible in Rust, with no Python and no C++: training with the pure-Rust fasttext crate, and a linear SVM in about 150 lines of Sioul's own code (Appendix A).
  • The phone does not need the language model: a linear model on a plain mean of word vectors folds into one number per row of fastText's input matrix, a table of one or two megabytes (Appendix B).
  • The evidence did not support a centroid as the whole content model (Q1 below): it asked for a measurement against a sparse model, or against fastText's own supervised classifier, on the person's mail and in time order.
  • The labels mattered most, and Sioul kept none of them then: the person's own "junk" and "not junk" were not logged, the keywords $Junk and $NotJunk were dropped at fetch, and junk was lost once the provider purged it. A label log had to come first, long before any model.

What was built, in that order: the label log and the kept keywords; a corpus kept beside the mail, so that junk outlives the provider's purge; Virtual Secretary's tokenizer, rewritten in Rust; the centroid with its SVM; then fastText's supervised classifier, which measured better on a real mailbox and became the filter's model with features version 3 (spam-filter.md, "The model, and how it folds").

1. What the research found, question by question

Q1. Does a fastText centroid with an SVM work, and how well?

  • The proven core of a personal filter is a linear model on sparse token features. In the TREC spam tracks of 2005 to 2007 (blind tests, messages replayed in time order, private one-person corpora among them), the best single filters were SVMs and logistic regression on binary character 4-grams of the first 3,000 or so characters, at a (1−AUC)% of 0.004 to 0.01. Linear models on bags of words scored 0.02 to 0.075, two to ten times worse. Compression models and OSB-Winnow came close. Strong.
  • The evidence for means of word vectors is indirect and mixed. Spam and phishing papers that use word2vec, fastText or GloVe report accuracies within one or two points of TF-IDF (98 to 99.5 %), all on random splits of public or mixed corpora. Weak. General text classification gives a clearer picture. Frozen averaged vectors trail bags of n-grams: a bag of means was the worst method on all eight datasets of Zhang, Zhao & LeCun (2015). A TF-weighted centroid with logistic regression plateaued at 70 to 80 % on IMDB, where an n-gram NBSVM reaches about 91 % (Lai et al. 2016; Wang & Manning 2012). Averages match strong models only when the vectors are trained with the labels (SWEM; fastText's supervised mode). Moderate. No study had evaluated an unsupervised fastText centroid with an SVM in time order at a low false-positive rate: Sioul had to measure it itself.
  • Transformers help mainly when labels are few. On the Spam-T5 benchmark (macro F1; random split, public corpora), TF-IDF with an SVM scored 0.33 with 32 labels, 0.86 with 256 and 0.95 with the full set, against 0.86, 0.94 and 0.97 for SetFit. Moderate. In Gmail, replacing the text vectoriser with RETVec, a character encoder of about 200,000 parameters robust to typos and lookalike letters, gave 38 % more spam detected and 19.4 % fewer false positives. Moderate (the vendor's claim).
  • What transfers to one person's mailbox is that person's own mail, not other people's. In TREC 2007's partial-feedback task, a filter trained on some users' mail was about a hundred times worse on everyone else's. In the ECML/PKDD 2006 challenge, training on other sources gave a (1−AUC)% of 3 to 5 %, against 0.01 to 0.1 % when learning inside the mailbox. A filter at 0 % false positives and 1.7 % missed spam on a collected test set scored 1.7 % and 20 % on the next week's live mail (Sahami et al. 1998). An AUC of 0.999 on Enron and TREC fell to 0.76 on recent mail (Kshirsagar, Rathi & Ryan 2025). Strong: public corpora are for unit tests only.
  • French and English together: no solid French evaluation was found. Character n-grams are language-independent (TREC 2006's Chinese corpus; Sculley's results). An in-domain corpus of 13 million tokens beat 2.8 billion general tokens for centroid features (Lai et al. 2016). fastText's subwords help with rich morphology and rare words. fastText splits on whitespace only (its source), so elisions (l', d', qu'), punctuation, case and Unicode must be handled before training. Moderate.
  • Ways to improve a centroid: SIF weights (a ≈ 10⁻³, Rspamd's default); label-aware weighting (TF-CR), since TF-IDF weighting is inconsistent and does not always beat the plain mean (Zubiaga 2020); mean and max pooled together (SWEM-concat; Rspamd's "mean_max"); subject and body kept apart, as separate vectors or as tokens tagged by field. Models per field combined by stacking did best (Bratko & Filipič 2006), and Graham's tokens tagged by field were stronger: "Subject*FREE" scored 0.9999 spam, against 0.65 for "FREE" in the body. Moderate.

Q2. Facts from the headers: which carry signal, and which are robust

  • Authentication:

    • A pass is almost no evidence: 89 % of unwanted mail passes SPF, DKIM or DMARC (Cloudflare 2023), and SpamAssassin's fitted scores are −0.1 for DKIM_VALID and −0.001 for SPF_PASS.
    • A failure, a missing record or misalignment is weak to moderate evidence of spam. Mailing lists and forwards fail legitimately; ARC (RFC 8617) can vouch for them.
    • Only the Authentication-Results header added under the account's own provider's id may be read (RFC 8601 §4.1, §5, §7.1); lower ones may be forged.
    • All 10 providers and 19 mail clients tested misread ambiguous From headers (Chen, Paxson & Jiang 2020). The ambiguity itself can be a feature: several From headers, a display name holding another address, a Sender or Resent-From shown in its place.
    • Hijacked legitimate accounts pass everything (lateral phishing: Ho et al. 2019).

    Strong.

  • The Received lines: only the line the provider's own server added is evidence (SpamAssassin's trust path). About that hop, useful facts are whether the connecting address has a reverse DNS name and whether it looks dynamic, a HELO given as a bare address, and the number of hops. The skew between the Date: header and the provider's arrival time is strong evidence: SpamAssassin's DATE_IN_FUTURE and DATE_IN_PAST rules score 1.2 to 3.4, and Rspamd has a "time skew" metatoken. The sender's network (its AS number) ranked first in SNARE, but it needs an offline table, it works at a provider's scale, and its false-positive rate on addresses never seen before was 5.2 % (Hao et al. 2009). Moderate.

  • Identity mismatches: a Reply-To at another domain than the From, or at a free mailbox (SpamAssassin's FREEMAIL_REPLYTO_END_DIGIT, about 1.2); a Message-ID made at another domain; links going elsewhere than the claimed or signing sender's domain. PILFER's "non-matching URLs" and its "here" links to other domains, with links to bare addresses and the age of linked domains, caught more than 96 % of phishing at about 0.1 % false positives (Fette, Sadeh & Tomasic 2007). A Return-Path other than the From is normal for bulk senders (bounce domains): it marks bulk mail, not spam. Moderate.
  • Mailer fingerprints (X-Mailer or User-Agent, the Message-ID's form, the case and count of header lines) were big wins in SpamBayes (X-Mailer was "a pure and significant win" for missed spam), but they drift as software and spam kits change: some techniques die out once filters catch them, others persist for years (Pu & Webb 2006). Moderate.
  • Bulk markers (List-Unsubscribe; List-Unsubscribe-Post, RFC 8058, required of Gmail's bulk senders since February 2024; List-Id, Precedence, Feedback-ID, Auto-Submitted) identify compliant bulk mail, gray mail, not spam. Strong.
  • The shape of the parts and the HTML: HTML only (SpamAssassin 0.7 to 2.2), images only, hidden or off-screen text, forms, the share of links on the sender's own domain, the kinds of attachments (Rspamd's metatokens). Gmail's TensorFlow models gained most on image-based mail, hidden content and newly created domains. Moderate.
  • Robust, fragile and leaky facts:
    • robust: the sender's identity as the provider verified it (an aligned DKIM d= or SPF domain), as a key for that sender's history; where the links really go; first contact (a sender never seen, never written to);
    • fragile or drifting: mailer strings, the forms of Date and Message-ID, length, time of day, wording. Phishing written by large language models cut a stylometric detector's F1 from 0.999 to 0.72 until its threshold was set again (Gutierrez, Villegas-Ch & Govea 2026);
    • leaky, which create a false accuracy: any header the provider's own filter adds (X-Spam-, X-Rspamd-, tags in the subject); date headers when ham and spam were collected at different times; To, Cc and Sender when the two classes come from different sources (SpamBayes).

Q3. Training on one person's mail

  • Labels, best first: (1) the person's own moves: Inbox to Junk marks spam the provider missed, and "not junk" (Junk to Inbox) marks a provider's false positive, the most valuable ham there is; (2) membership of the Junk folder, which holds the provider's labels, with about 1 to 6 % errors; (3) tacit ham (mail left in the inbox), the noisiest. Human labellers err 3 to 7 %, and tacit labels more (Cormack & Kołcz 2009); about 3 % of users' labels in Hotmail's data were wrong (Yih, Goodman & Hulten 2006). Strong.
  • Training on the provider's verdicts works only with learners that tolerate noise (Cormack & Mojdeh 2009). At a fixed false-positive rate, an SVM trained on the provider's labels missed 1.6 times less spam than the provider; logistic regression missed 1.1 times less on one stream and more on the one-person stream; naive Bayes missed 5 to 22 times less; fusing the personal score with the provider's verdict did best among filters without a person; and the recipient labelling about 1 % of their mail (active learning) gave 20 to 150 times less missed spam. Discriminative learners need a low C or a slow learning rate under label noise. Strong.
  • How many labels: SpamBayes is usable after 10 to 20 of each class, with many "unsure" at first; SpamAssassin's Bayes waits for 200 of each, Rspamd's neural module for 1,000 per class. TF-IDF with an SVM reaches an F1 of 0.86 with 256 labels and 0.95 with thousands. TREC's online filters needed no training set: their error rates "converged quickly". With uncertainty sampling, labelling about 1 to 1.5 % of messages reached about 2.6 times the error of full labelling. Moderate to strong.
  • Imbalance between the classes: SpamBayes keeps ham and spam within 4 to 1, and Rspamd balances them 1 to 1. Better: weight ham about ten times, and set the threshold for the share of ham one accepts to lose. Fitting a second stage on the region of low false positives gave up to 20 % (logistic regression) and 40 % (naive Bayes) less missed spam (Yih, Goodman & Hulten 2006). Moderate.
  • A cold start: the mailbox itself (10⁴ to 10⁵ messages, about 10 to 50 million tokens) is the right corpus for fastText (Lai et al. 2016); pre-trained French and English vectors are the fallback for a small mailbox (Rspamd ships them). Other people's labelled spam is a poor prior (ECML/PKDD 2006; TREC's partial feedback).
  • Drift and retraining: retraining often and weighting recent examples beat good-word attacks (Lowd & Meek 2005); sliding windows of the last 500 to 5,000 examples are enough (relaxed online SVMs); SpamAssassin's tokens live three weeks; DSPAM's training on errors alone is "too static". Content models age slowly, over months: with no labels after 20,000 messages, a TREC filter did not collapse, but was 13 times worse overall than with full feedback. Network features go stale within days (SNARE).
  • Active learning is the "unsure" band: asking for a label when the score is near the threshold won TREC 2007, and "train on mistakes and unsures" is SpamBayes' standing advice. Strong.
  • Overfitting to senders and sources: SpamBayes had to drop Sender:, whose mailing-list token "becomes the most powerful indicator in the whole database". A sender's history must use past messages only, and an evaluation must keep each sender and each campaign on one side of the split. Moderate.
  • Gray mail is a preference, not spam: 8 to 21 % of Hotmail's mail. People junk newsletters instead of unsubscribing, and a model per user recovers up to 40 % more of the spam hidden in gray mail (Yih, McCann & Kołcz 2007; Chang, Yih & McCann 2008). Strong.
  • Never train on one's own verdicts: when attackers control 1 % of the training mail, SpamBayes becomes unusable, sending about 36 % of ham to spam or unsure (Nelson et al. 2008); bogofilter's training on its own verdicts lets errors "accumulate until manually corrected"; RONI, which tests each training batch on held-out ham before accepting it, caught every dictionary attack. Strong. The author decided otherwise for Sioul, with his reasons (section 3).

Q4. How to measure it

  • Replay the person's history in time order (TREC's method), computing every feature from the past only (counts per sender, IDF, SIF or TF-CR statistics, a fastText model trained up to that date), and simulating the real retraining cadence. No random cross-validation: it ranks filters differently (Cormack & Bratko 2006), and 31.7 % of mail belongs to campaigns of near-duplicates (Hotmail), which leak across folds. Strong.
  • The numbers to report: the share of ham misclassified (ham sent to Junk), and missed spam at a fixed share of ham lost (0.1 % and 1 %); (1−AUC)% and lam%; 95 % confidence intervals, exact binomial for the two rates and bootstrap for the AUC; learning curves over time. Never accuracy or F1. Slices: by kind of mail (personal, a frequent correspondent, transactional or administrative, notification, newsletter), by language, and new senders only. Strong.
  • Rare errors: with no error among n ham messages, the 95 % upper bound is about 3/n (the rule of three), so a claim of at most 0.1 % ham lost needs 3,000 checked ham without an error.
  • Ground truth: folder labels hold 3 to 7 % errors, which mask a filter's true error: a true 0.5 % measures as 5.5 to 6.5 %. Train on natural labels and measure on an adjudicated set: the person checks again only the messages where filter and folder disagree, in rounds, as TREC's gold standards were made (G0 to G5). The labels of Mr X, the recipient of one of TREC's private corpora, had 421 spam marked as ham. Strong.
  • Unequal costs: TREC refuses to fix one ratio; older work used λ = 9, 99 or 999; Yih weighted ham ten times; Kołcz & Alspector set a cost per kind of ham. Graham's few false positives were transactional or automated mail. Hence limits per kind of mail, and protected kinds that are never hidden.
  • Calibration and thresholds: an SVM's scores bunch toward the middle, and Platt scaling on held-out data is enough (Niculescu-Mizil & Caruana 2005). Thresholds are best set on the most recent window, for the share of ham one accepts to lose, and set again at each retraining: drift breaks the exchangeability that conformal guarantees need.
  • "Unsure" as an outcome of its own: SpamBayes (ham below 0.20, spam above 0.90, unsure between, and "people usually agree that messages classed Unsure really are hard to categorize"); bogofilter's three states; FairEmail, which moves mail only above 15 % with a 50 % margin and otherwise leaves it where it is; Apple's patent, with an "ambiguous" outcome. Conformal reject classifiers estimate the accuracy of what they accept better than calibrated probabilities do (Johansson et al. 2023).

Q5. Privacy and safety

  • A fastText .bin stores every word of its vocabulary in plain text, with its count (its source, Dictionary::save), and a .vec export holds one word per line: a model of a mailbox is a frequency list of that mailbox, with names, places, medicines and recurring numbers. Words below minCount are dropped entirely in unsupervised training, but the supervised mode hashes unknown n-grams into buckets. Strong.
  • Leakage from embeddings, measured (Song & Raghunathan 2020): rare words leak membership, with an attack advantage of about 0.3 for the rarest tenth of words in word2vec, fastText and GloVe, and almost none for frequent words; inverting sentence embeddings, from encoders of mean-pooled word vectors to BERT, recovers 45 to 75 % of the input words (F1); authorship can be inferred from a handful of embeddings. Strong.
  • A linear SVM stores only its weights and its bias, which hold no single message; a kernel SVM stores support vectors, the vectors of real messages. Tables of each sender's history encode the person's contacts.
  • Precautions for the shared folder, inferred from the above: seal everything that travels with a key held on the devices, never in the folder; raise minCount (5 to 10) and keep only words seen in the mail of two or three senders or more; replace addresses, links, phone numbers, IBAN-like strings and long runs of digits with typed placeholders before training, which also generalises better; prefer hashed features, which store no vocabulary; quantise and prune (fastText.zip classifiers stay under 100 kB); never share raw centroids, support vectors or labelled examples.
  • Adversaries:
    • Good-word attacks: 150 added words at most (passive) or about 30 (active) let half of the blocked spam through naive Bayes and maximum-entropy filters (Lowd & Meek 2005). A mean is a convex combination, so benign text appended dilutes it linearly; the answers are max pooling, vectors per field, and frequent retraining.
    • Poisoning, through training on one's own verdicts: Q3.
    • Obfuscation: lookalike letters, zero-width characters, keyword stuffing. The answer is to normalise with NFKC and the UTS #39 skeleton of confusables, and to strip invisible characters.
    • Phishing written by large language models wears down style signals; the structure of links and identities matters more.

Q6. What the filters people use do

  • SpamAssassin: rules and a Bayes part, whose tokens come from the headers, the visible and invisible text, and the links; bayes_ignore_header keeps a provider's verdict headers out of training; Bayes starts after 200 of each class, and BAYES_99 (+3.5 to 3.8) is among its heaviest scores; an authentication pass scores about 0.
  • SpamBayes and bogofilter: Robinson and Fisher's chi-squared combining, with three outcomes; train on mistakes and unsures, keep ham to spam within 4 to 1, use recent mail. bogofilter has the lowest false-positive rate, but misses much spam at its default threshold.
  • DSPAM: training on everything, on errors only, or until mature; dormant, and weak at TREC.
  • Rspamd: its neural module reads by default which rules fired, and 39 or more numeric metatokens (size, images, parts, recipients, the Received lines' count, time skew and invalid relays, links, word statistics, link-domain ratios, forms, hidden text); its documentation calls that "clustering by filter fingerprint", not a model of content. Version 4.0 (28 March 2026) adds a fastText embedding mode: pre-trained quantised models per language (cc.*.300.q.ftz), SIF on by default, mean and max pooling, an optional convolution, fused with the metatokens. It also adds a fastText reader without dependencies that maps the model into memory, and multiclass Bayes. Training waits for 1,000 examples per class, balanced 1 to 1. No accuracy is published.
  • Gmail: more than 99.9 % of spam blocked; machine learning personalised per user ("what one person considers spam another person might consider an important message"); TensorFlow models that catch image-based mail, hidden content and new domains; RETVec (Q1); a sender's reputation keyed on the authenticated domain (Taylor 2006, read second-hand); the rules of 2024 for bulk senders.
  • FairEmail (Android): Bayes on the phone, each folder a class, learning from the person's moves; thresholds of 15 % and a 50 % margin, unsure mail left in place; it never moves mail out of the server's spam folder by itself; the person's rules run first; it calls itself "not a replacement for the spam filter of the email server".
  • Apple Mail: LSA vectors compared with two centroids, with an "ambiguous" outcome (US patent 7,076,527). Practitioners reported that it learned slowly and that its threshold could not be adjusted (TidBITS 2004): the nearest precedent to a design built on centroids alone, and a warning against classifying by the nearest centroid.
  • What practice suggests for one person: a model of tokens as the workhorse; header facts as tagged tokens, with a few numeric metatokens; three outcomes; learning from mistakes and unsures; the provider's verdict treated as one input, not as the truth; never fighting the server; small models.

2. What it meant for Sioul's design, and where Sioul stands

The research's recommendations of 7 October 2026, each with what Sioul does on 8 October 2026.

  1. Measure the centroid against a sparse model before relying on it.
    • A sparse block (hashed character 4-grams of the subject and of the first 3,000 visible characters, with tokens tagged by field: subj:, from-dom:, dkim-dom:, replyto-dom:, link-dom:, mailer:, list:, auth:, mime:): not built. A plain hashed n-gram model is still to measure (spam-filter.md, "Not built").
    • A dense block (fastText vectors, a SIF-weighted mean with a max, subject and body apart, about 30 numeric metatokens): decided otherwise. The centroid is a plain mean, which folds into the table, and its header facts are 35 named features.
    • The classifier (a linear SVM or logistic regression, ham weighted 5 to 10 times, a low C while labels come from the provider's folders, Platt's calibration, the provider's verdict as an input): built for the centroid (a linear SVM by dual coordinate descent, ham weighing 5, its cost chosen by the AUC on the newest fifth, Platt on forward folds). For the provider's verdict, decided otherwise: it is never a feature, and the Porch applies it as a rule of its own, so that the model does not learn to copy the provider.
    • The head-to-head test, fastText's supervised mode among the candidates: built. Measured on a real mailbox, in time order, fastText's classifier ranked spam above ham better than the centroid, on the newest mail and on an older filter's held-out material, and gave the same numbers from one training to the next. It became the filter's model with features version 3, the header facts read as words.
  2. Labels and their weights.
    • The person's own "junk" and "not junk", at full weight: built (the label log, and the keywords kept; the person's word beats every other label).
    • The Junk folder and the inbox's history at a low weight: decided otherwise. Mail in a Junk folder is spam, however it got there, and mail in other folders is ham; no label is weighted down.
    • Tacit ham at the lowest weight, and only once the person has seen it: decided otherwise for training. The evaluation's "settled numbers" leave out inbox ham younger than 30 days.
    • Never the filter's own verdicts: decided otherwise (section 3).
    • Each training batch tested on held-out ham (RONI), and the weight of any one sender or campaign capped: not built. What exists is coarser: a new table replaces the one in place only when it takes no more ham for spam, at the person's threshold, on the newest mail the table in place never learned from.
    • The provider's verdict headers kept out of the words: built. Its tags are taken off the subject, and X-Spam* and X-Rspamd* never enter as words or features.
  3. Reading the headers.
    • Only the Authentication-Results under the account's own id: built; since features version 4, Sioul's own checks come first (SPF, DKIM, DMARC, ARC and the reverse DNS, by mail-auth).
    • Only the hop the provider added, and the date's skew from it: built in Sioul's way: the skew is measured against the server's arrival time (INTERNALDATE), and the hop where mail entered the provider gives the HELO fact.
    • Ambiguous From headers and identity mismatches as features: built in part (a Reply-To elsewhere or at a free mailbox, a Message-ID made elsewhere, a display name naming another domain, links going elsewhere); several From headers are not a feature.
    • A history per sender, keyed on the authenticated domain: not built in the filter. The Porch's protections play that part: mail from people you know, from your lists, on a project's routes, and the codes you asked for are never judged.
  4. Three outcomes, with the doubt said plainly.
    • Spam, unsure and ham, with protective signals that never let a known correspondent's mail be hidden: built (two thresholds, the matrix of what is done with each class, and the protections: spam-filter.md, "Where it acts").
    • Unsure mail feeding a small daily queue to label (active learning on about 1 % of mail): decided otherwise. Doubts wait on the Porch, unlabelled until the person says, and nothing asks for a label: the author's rule is that spam detection must not become one more job.
    • Thresholds set at each retraining for a target share of ham lost: decided otherwise. The thresholds are the person's settings (95 % and 50 % until changed); sioul spam eval prints the lowest threshold that takes at most one ham in two hundred for spam, to help choose.
  5. Gray mail as a class of its own, unsubscribed rather than junked: built in part. One-click unsubscribing exists (client.md, "Unsubscribing"), and the bulk headers are facts the model weighs; there is no separate class.
  6. Evaluation before anything moves.
    • A chronological replay, with the retraining cadence simulated: built in a simpler form: each account's ham and spam are split in time, the oldest 80 % learned from and the newest 20 % tested on.
    • Ham lost and spam caught at each threshold, with exact 95 % intervals, and the AUC: built.
    • Slices by kind of mail, by language, and for new senders: not built.
    • An adjudicated test set: not built (section 3).
    • A shadow mode until 3,000 checked ham show no loss: decided otherwise. Until the person chooses, the filter moves nothing: it flags spam and doubts on the Porch ("flag only"), and sioul spam dry-run says what "Move to spam" would move before it is chosen.
  7. Retraining.
    • The linear model daily or as it goes, fastText monthly: decided otherwise. The whole model learns again by itself once a week at most, on the computer that made the table, on mains power and idle, and by hand at any time.
    • The language model and the classifier versioned as a pair: built. The table carries the tokenizer's and the features' versions, and is replaced whole.
  8. Privacy of what travels.
    • Sealed with a key held on the devices: built (the sharing's seal).
    • A minCount of 5 or more: built. Only words seen from two or three senders or more: not built.
    • Placeholders for addresses, links, numbers, IBANs and phone numbers: built (Virtual Secretary's 36, with _PHONE_ and _IBAN_).
    • Only weights stored, never examples: built. The folded table holds 64-bit hashes of words with their scores, never a word, and the language model stays on the computer that made it.
  9. Robust reading.
    • NFKC, lookalike letters folded, invisible characters out, visible text read from the HTML, French elisions split: built (spam::tokenize).
    • The share of hidden text as a feature: not built.

3. What the evidence asks that Sioul does not do

  • "Never train on one's own verdicts", the literature's strongest warning about poisoning (Q3). The author decided otherwise on 7 October 2026: the filter's own moves and its "probably spam" flags count as spam at the next training, until the person corrects them. His reasons: the person looks at the Junk folder now and then; the filter is trained again regularly, so that growing mail and corrections outweigh its mistakes; and asking the person to confirm what the filter did would make spam detection one more job (spam-filter.md, "The labels"). Doubts ("maybe spam") never count until the person says.
  • The defences against poisoning, which matter more since the filter learns from its own verdicts: a gate that tests each training batch on held-out ham before accepting it (RONI: Nelson et al. 2008), and a cap on the weight of any one sender or campaign. Neither is built.
  • An adjudicated test set (Cormack & Kołcz 2009), the honest measure of a filter's error, since folder labels hold 3 to 7 % errors. It needs someone to check the messages where the filter and the folder disagree, which the author's rule against validation chores keeps away from users; a developer can still do it on their own mail.
  • Slices: the numbers per kind of mail (personal, transactional, notification, newsletter), per language, and for new senders only, with each campaign kept on one side of the split, since 31.7 % of mail belongs to campaigns of near-duplicates.
  • The shape of the HTML as features: hidden or off-screen text, forms, the share of links on the sender's own domain (Rspamd's metatokens; Gmail's gains on image-based mail and hidden content).
  • A French evaluation: the literature has none, and Sioul's own numbers come from one mailbox mixing French and English.
  • A fallback for the fasttext crate, which has one maintainer and no commit since April 2026 (Appendix A): the archived C++ fastText on computers, or a reader of Sioul's own. The table that devices read depends on no crate.
  • Old tables on a phone synced by eDrive: eDrive never deletes a file deleted elsewhere, so each sealed table, one or two megabytes a week, stays on the phone for good (database.md, "What the sync app must do").

4. Gaps in the evidence

  • No time-ordered study, at low false-positive rates, of an unsupervised fastText centroid with an SVM for mail. Sioul measured it against fastText's own classifier on one real mailbox (section 2); a plain hashed n-gram model remains unmeasured.
  • No good evaluation of spam filters on French mail.
  • Implicit feedback (mail deleted unread) has only patents behind it: as far as the evidence goes, it is unlabelled mail.
  • Rspamd's fastText mode publishes no accuracy.
  • Most papers on embeddings for spam use random splits of public corpora and report accuracy, so their numbers do not transfer.

5. Source notes

The notes as read on 7 October 2026, source by source, with the numbers, quotations and grades the sections above rest on. Their "for Sioul" lines are the study's inferences of that day, before the decisions of section 2. Full references are in "Sources", at the end.

The TREC spam tracks, and Cormack's review

TREC 2005 Spam Track overview (Cormack & Lynam 2005), read in full. https://trec.nist.gov/pubs/trec14/papers/SPAM.OVERVIEW.pdf

  • The protocol: messages fed in time order, one at a time; each filter returns a verdict and a "spamminess" score; the gold label is given to the filter right after (ideal feedback). There is no separate training set: filters start empty and learn online. "Error rates converged quickly"; the overall misclassification was not dominated by early errors.
  • The numbers: hm% (ham misclassified, sent to the spam folder), sm% (spam misclassified), (1−ROCA)% (the area above the ROC curve, free of any threshold), lam% (the logit-average of hm% and sm%), and sm% at hm% = 0.1 % as the headline. Accuracy is deliberately not reported: "optimizing accuracy incents filters to use thresholds at odds with their purpose". Ham misclassification "is considerably more deleterious than spam misclassification", but the track refuses to fix a ratio of costs. 95 % intervals: exact binomial for hm% and sm%, bootstrap for (1−ROCA)%.
  • The corpora: trec05p-1 (39,399 Enron ham and 52,790 spam, the spam's headers rewritten to look delivered to Enron in 2001–02; artefacts found and removed, such as wrong daylight saving and wrong server versions in headers, so header artefacts can leak the label in synthetic corpora). Private ones: Mr X (49,086 messages, 82 % spam), S.B. (7,006, 89 % ham, its ham mostly four mailing lists and three frequent correspondents), T.M. (170,201).
  • User feedback is a noisy gold standard: Mr X's labels, taken from his own SpamAssassin feedback (G0), had 421 spam marked ham and 8 ham marked spam; left uncorrected, they would over-report false positives "by more than an order of magnitude for the best filters". The gold standards needed four or five rounds of filter disagreements adjudicated by a person.
  • Adjudication was hard for sports pools, stock tips, religious bulk mail and vendors' advertisements with a tenuous relationship: much bulk mail is ham to one person and spam to another (gray mail).
  • Results (aggregate, best): ijsSPAM2 (compression models, Bratko) (1−ROCA)% 0.051, sm% 3.78 % at 0.1 % ham lost; crmSPAM2 (CRM114) 0.115 and 3.46 %; bogofilter 0.210 and 9.86 %; SpamAssassin's Bayes alone 0.220 and 6.72 %; DSPAM 0.99 to 1.38.
  • A small personal corpus is harder: on S.B. (775 spam), the best (1−ROCA)% was 0.23 to 0.29, and sm% at 0.1 % ham lost was 11 to 12 %, against 1.8 % on the large public corpus. Verdicts at default thresholds missed 7 to 73 % of S.B.'s spam (bogofilter: 0 % ham lost, 73 % spam missed).
  • The kinds of ham misclassified: automated, commercial, encrypted, frequent correspondent, list, newsletter, personal; "a misclassified personal message or a message from a frequent correspondent is more likely to have serious negative consequences than a misclassified newsletter".
  • Public and private results differed no more than private corpora among themselves, to the organisers' surprise.
  • Grade: strong for the protocol and the numbers to report, which became the field's standard; the filters are content filters of 2005, without embeddings.

TREC 2007 Spam Track overview (Cormack 2007), read. https://trec.nist.gov/pubs/trec16/papers/SPAM.OVERVIEW16.pdf

  • Four feedback regimes, on trec07p (75,419 messages to one server, April to July 2007) and MrX3 (161,975 messages to one person, December 2006 to July 2007, 95 % spam). Best (1−ROCA)%:

    Regime trec07p MrX3
    immediate feedback (every label, at once) 0.0055 0.0042
    delayed: labels for the first 10,000 (20,000) messages, then none 0.0086 0.0568
    partial: labels for some recipients only 0.0425 n/a
    active learning, a quota of 1,000 label requests 0.0144 n/a
  • "SVM and logistic regression on character features" were "exceptionally strong", "for the first time shown to be superior for spam". Delayed and partial feedback lowered performance; "learning curves do not show substantial de-learning as delay increases" (MrX3's delayed run is about 13 times worse overall because it stopped learning after 20,000 of 162,000 messages).

  • The active-learning winners used uncertainty sampling, asking for a label only when the score is near the threshold: with 1,000 labels for 75,000 messages (1.3 %), they reached about 2.6 times the error of full feedback. Other runs with the same quota scored 0.12 to 0.16, about ten times worse: how labels are chosen matters as much as how many.
  • Grade strong (blind, in time order, with intervals), on public corpora and one private personal corpus.

TREC 2006 Spam Track overview (Cormack 2006). https://trec.nist.gov/pubs/trec15/papers/SPAM06.OVERVIEW.pdf

  • Its batch active-learning task is "the situation in which a spam filter is first deployed": many historical messages available but not adjudicated; a 9 to 1 split in time, label budgets of 100, 200, 400, 800 (results only as graphs). The Chinese corpus trec06c was "much easier"; the small personal SB2 harder.

"Email spam filtering: a systematic review" (Cormack 2008, Foundations and Trends in Information Retrieval 1(4)), key chapters read. doi:10.1561/1500000006

  • Feature engineering outweighs the choice of learner: "be skeptical regarding claims for any learning method that fails to note the feature representation or the mode of learning".
  • (1−AUC)% on TREC's public corpora (lower is better): an SVM on character 4-grams 0.008 (trec05p-1); relaxed online SVMs on 4-grams 0.009, 0.024 and 0.009 (2005, 2006, 2007); online logistic regression on 4-grams 0.012 and 0.006; DMC compression 0.013; bogofilter 0.048; SpamAssassin's Bayes 0.059; logistic regression on words 0.068, an SVM on binary words 0.075; SpamAssassin's rules with Bayes 0.345. On Mr X's corpora, a relaxed online SVM on 4-grams scored 0.004 (MrX3). Linear classifiers on character n-grams are about ten times better than on bags of words, at TREC's scale with full feedback.
  • Synthetic words: tagging a token by its field (subject:money, body:money) is "an effective use" (Graham). Any feature, a rule's hit or a header fact, can enter a bag as a synthetic word.
  • Character n-grams (n = 3 to 4) "capture inter-word and intra-word interactions" and are "robust to spelling errors and morphological variants". Stemming, case and stop words "do not matter much". From Drucker, Wu & Vapnik (1999): do not remove stop words; an SVM needs no selection of terms; binary features beat term frequencies for an SVM; an SVM reaches low false-positive rates better than boosted trees; a large C (50 or more) does better.
  • Feature selection and corpus-wide statistics (TF-IDF, IDF) "are not adaptive and may preclude on-line learning": every new message changes every IDF term.
  • The evaluation's protocol matters as much as the method: on trec05p-1, ten-fold cross-validation, a 90 to 10 split in time and online evaluation gave substantially different rankings (Cormack & Bratko 2006); under cross-validation, logistic regression, the SVM and bogofilter were about equal, and under a split in time, compression models clearly beat them. A naive Bayes filter at 0 % false positives and 1.7 % missed spam on a collected set fell to 1.7 % false positives and 20 % missed spam on the following week's live mail (Sahami et al. 1998).
  • Corpus artefacts: Ling-Spam's ham comes from one linguistics list, separable by topic and stripped of headers, and real filters behave pathologically on it. Spambase is 57 numeric features only. SpamAssassin's public corpus (4,147 messages with full headers) and TREC 2005 to 2007 ("exactly the messages delivered to one server over three months") are the realistic public ones. Enron-Spam (Metsis et al. 2006) is the ham of six Enron users with spam from other sources, split in time.
  • TREC 2006 and 2007's variants: delayed feedback and partial feedback (labels for some recipients only) both lowered performance, "the partial feedback task remarkably so". The active-learning task (a quota of labels) was won by relaxed online SVMs and online logistic regression with uncertainty sampling.
  • The ECML/PKDD 2006 Discovery Challenge (training on mail from other sources, testing on individual users' inboxes, no user labels): the best (1−AUC)% was 3.3 % (task A) and 5.4 % (task B, 100 training messages per user), two orders of magnitude worse than learning inside the mailbox at TREC (0.01 to 0.1 %): a model trained on other people's mail transfers badly to a person's inbox; semi-supervised and transductive methods helped (covariate shift).
  • Outputs: a hard or soft classifier, or an "ordinal categorical scale (sure spam, likely spam, unsure, likely non-spam, sure non-spam)". Deployments include deferred classification (judged again when more evidence arrives) and an "unsure" folder that the user adjudicates, which yields labels.
  • Allow lists from the address book are standard but can be spoofed: "almost all spam is sent from real harvested addresses", and the author received spam spoofed as from his co-authors. Received headers are "not easy to parse, not easy to verify they are not forged".
  • The numbers: accuracy, weighted accuracy and TCR (λ = 9, 99, 999) are poor; report pairs of (false-positive, false-negative) rates, ROC curves and (1−AUC)%, with 95 % confidence intervals. Equivalences at a constant lam%: 0.3 % ≈ 1 % missed spam at 0.1 % false positives ≈ (1−AUC) 0.01 %; 1 % ≈ 10 % missed at 0.1 % ≈ 0.08 %; 2 % ≈ 30 % missed at 0.1 %.
  • Grade strong (a systematic review by TREC's organiser), from before embeddings (2008).

"Relaxed online SVMs in the TREC spam filtering track" (Sculley & Wachman 2007, TREC 2007; with the SIGIR 2007 paper on relaxed online SVMs), read. https://trec.nist.gov/pubs/trec16/papers/tuftsu.spam.final.pdf

  • A linear SVM, C = 100, on binary character 4-grams of the first 3,000 characters, normalised to unit length; "binary valued features out-perform count-based and TFIDF-based feature scoring"; 4-grams "give significantly improved performance over a word-based feature space", are independent of language and robust to obfuscated words. Gappy and wildcard features added nothing.
  • A cheap online SVM: a sliding window of the 500 to 5,000 most recent examples, retrained only when y·f(x) ≤ 0.8 rather than at every message, one SMO pass per update, the weights of examples leaving the window frozen. The full trec07p run took 214 to 3,087 seconds for 75,000 messages, on the hardware of 2007.
  • Results, (1−ROCA)%: trec07p full feedback 0.0093 to 0.0103; delayed 0.021 to 0.023; active (1,000 labels) 0.0144; MrX3 full 0.0042; SpamProbe as a baseline, 0.0617.
  • Partial feedback (trained on some users' mail only): 0.010 to 0.019 on those users' own mail, 1.75 to 1.94 on everyone else's, about a hundred times worse. Spam filters are specific to a mailbox: a model trained on other people's mail is a poor prior for this person.
  • Active learning: fixed-margin uncertainty sampling, a label requested when |f(x)| < 0.8 (< 0.2 when fewer than 50 requests remain).
  • Grade strong (TREC's blind evaluation; one private personal corpus).

Representations: averaged word vectors against bags of n-grams

  • Zhang, Zhao & LeCun (2015), NeurIPS (arXiv:1509.01626), eight large datasets, multinomial logistic regression: a "bag of means" (word2vec trained on the dataset, 5,000 k-means clusters) had the worst error of all methods on every dataset (AG News 16.9 % against 7.6 % for TF-IDF of n-grams; DBpedia 9.6 % against 1.3 %). The authors: "such a simple use of a distributed word representation may not give us an advantage"; TF-IDF of n-grams with a linear model "remain strong candidates for datasets up to several hundreds of thousands". Grade moderate (a k-means variant, not a centroid).
  • Shen et al. (2018), "Baseline needs more love" (ACL; SWEM, arXiv:1805.09843): averaging word embeddings (SWEM-aver) matches CNNs and LSTMs on topic tasks over long documents (Yahoo 73.1 %, AG 91.7 %, DBpedia 98.4 %), and lags on sentiment and other tasks that depend on word order; concatenating max and mean helps. Caveat: the embeddings were initialised from GloVe and then refined with the labels, not frozen unsupervised vectors. Grade moderate.
  • Joulin et al. (2017), "Bag of tricks for efficient text classification" (EACL; fastText supervised, arXiv:1607.01759): averaged embeddings of words (and word pairs) into a linear classifier, trained together with the label, "on par with deep learning classifiers" (AG 92.5 %, DBpedia 98.6 % with word pairs). It is a linear model of low rank over n-gram features; a linear bag of words with the right features "often obtain[s] state-of-the-art" (citing NBSVM, Wang & Manning 2012).
  • Joulin et al. (2016), "FastText.zip" (arXiv:1612.03651): pruning features, product quantisation, hashing and retraining give classifiers often under 100 kB with little loss of accuracy, aimed at phones. Pruning keeps only the most useful words and n-grams, which also drops rare tokens: a gain for privacy.
  • Inference (grade weak to moderate): a frozen, unsupervised skip-gram centroid encodes topic and register, not spamminess; averaging dilutes the few decisive tokens (a link's domain, a brand's name, "IBAN"). Averages work when the vectors are trained with the label (fastText supervised, SWEM). For spam, TREC's evidence favours sparse character 4-grams or word features with a linear model. Hence: keep the centroid as one dense block beside sparse features, or use fastText's supervised mode, which is a linear model over hashed words and character n-grams.

"How to generate a good word embedding" (Lai, Liu, He & Zhao 2016, IEEE Intelligent Systems 31(6); arXiv:1507.05523), the corpus sections read. Their task "avg" is a term-frequency-weighted average of word vectors with logistic regression, exactly a centroid classifier, on IMDB reviews. A corpus of 13 million in-domain tokens (IMDB's own unlabelled reviews) beat 100 million to 2.8 billion tokens of Wikipedia and news on "avg" (PGR 100 against 51 or less): "corpus domain is more important than corpus size … choose a corpus in a suitable domain, then larger is better"; for embeddings used as features, "a dimensionality of 50 is sufficient"; simple models (skip-gram, CBOW) suffice. But "avg" stayed at 70 to 80 % on IMDB whatever the embedding: the representation caps performance, where an NBSVM on word pairs reaches about 91 % on the same data (Wang & Manning 2012). Grade moderate to strong. A person's mailbox (10⁴ to 10⁵ messages, about 10 to 50 million tokens) is in the range where training in-domain beats general pre-trained vectors for averaged features; general vectors (Rspamd uses cc.en.300 and cc.fr.300) are the fallback when the mailbox is small, or for words it lacks. Neither lifts the cap of the averaged representation.

Studies of embeddings for spam and phishing, the direct evidence for the first design:

  • Somesha & Pais (2022), Journal of Cyber Security and Mobility 11(3), read in summary: the text is only four header fields, From, Return-Path, Subject and Message-ID; Word2Vec and fastText (CBOW and skip-gram, 50 to 300 dimensions) trained on the same corpus, against TF-IDF and counts; random forests, SVM, logistic regression, decision trees, XGBoost; a random 70 to 30 split. Accuracy: random forests 99.26 to 99.50 % for every representation (fastText CBOW 99.50 % at 0.053 % false positives; TF-IDF 99.37 % at 0.4 %); SVM 97.2 to 98.9 %. The datasets mix public phishing (Nazario's) with ham collected in-house from students and family, so artefacts in the Message-ID and Return-Path domains likely inflate the scores; how word vectors were aggregated is not documented. Grade weak (random split, mixed sources); it does show that header strings embedded by a corpus-trained fastText carry strong signal, and that embeddings equal TF-IDF once a good classifier is used.
  • Mohammed & Ahmed (2024), Journal of Electrical Systems and Information Technology 11, from the abstract only: hybrid features of TF-IDF and word embeddings; accuracy on SpamAssassin's corpus: GloVe 99.50, Word2Vec 99.16, fastText 98.83, no embedding 97.16; on Enron-Spam 99.28, 99.16, 99.02 and 98.01. Embeddings added one or two points of accuracy over TF-IDF, on a random split. Grade weak.
  • Kshirsagar, Rathi & Ryan (2025) (below): every model at about 0.99 AUC inside its corpus, 0.76 on recent unseen mail.
  • Bratko & Filipič (2006), Information Processing & Management 42(3), from the abstract: for documents made of fields, such as mail, separate models per field (subject, body, headers…) combined by stacking gave the best results, improved further by adding the flat model of the whole text. Graham (2003), "Better Bayesian filtering": tokens marked by field ("Subject*FREE" 0.9999 spam against "FREE" in the body at 0.6546); ignoring the headers was "a perverse decision"; his false positives, 0.06 % (5 of about 7,740 ham), were newsletters from companies that switched to bulk senders, a message in capitals, a back-order notice and an invitation's reminder: automated and commercial ham is where false positives live. Subject and body as separate vectors, or tagged tokens, are supported. Grade moderate.
  • Searched and not found: an evaluation in time order, at low false-positive rates, of an unsupervised fastText centroid with an SVM against linear models on character n-grams, on the same mailbox. The first design's core representation was therefore untested in the form proposed; the nearest evidence (TREC's SVMs and logistic regression on character n-grams, Zhang's bag of means, Lai's "avg", Apple's LSA anchors, Rspamd 4.0's fastText mode without numbers) suggested that the centroid alone would be weaker than sparse n-gram features, and should be one input among several. Sioul had to measure it itself.

Weighting the centroid:

  • Arora, Liang & Ma (2017), ICLR (SIF): weight each word by a/(a + p(w)), with a ≈ 10⁻³, and subtract the projection on the first principal component: 10 to 30 % better than plain averages on tasks of textual similarity, a "baseline to beat", "especially when labelled data is scarce". A known caveat: it weighs frequent words down, negations among them, so the gains are small for classifying sentiment. Rspamd 4.0 uses SIF with a = 10⁻³ by default in its fastText mode. Grade moderate (similarity tasks, not spam).
  • Zubiaga (2020), "TF-CR: weighting embeddings for text classification" (arXiv:2012.06606; 16 datasets, one with a spam class; SVM and logistic regression; word2vec trained in-domain): weighting by labels (term frequency times category ratio) consistently beat unweighted averages; TF-IDF, KLD and TF-TRR were "largely inconsistent … not always outperforming the unweighted baseline"; TF-CR's gain grows with the size of the training set. Grade moderate. TF-CR uses the labels, so it must be computed on the training part only, and, like IDF, it is a corpus statistic to refresh at each retraining.
  • Max pooling, or mean and max concatenated (SWEM-concat; Rspamd's default "mean_max"), keeps a trace of the extreme words that the mean dilutes: the cheap answer to dilution by good words.

Spam-T5 (Labonne & Moran 2023, arXiv:2304.01238; code at github.com/jpmorganchase/llm-email-spam-detection), read in full.

  • Datasets: Ling-Spam (2,876 after removing duplicates, 16 % spam), the SMS Spam Collection (5,169), SpamAssassin's public corpus (6,051, 31 % spam), Enron-Spam (30,493, 48 % spam). A random 80 to 20 split (not in time), duplicates removed. The number reported: F1, not the error at low false-positive rates.
  • Baselines: TF-IDF (Porter-stemmed, 150 to 3,000 features chosen by five-fold cross-validation) with naive Bayes, logistic regression, KNN (k = 1), an SVM with a sigmoid kernel (an odd choice), XGBoost, LightGBM. Language models: RoBERTa-base, SetFit (MPNet sentence embeddings with a contrastive fine-tuning and a head), and Flan-T5-base fine-tuned ("Spam-T5", 250 million parameters).
  • With the full training set, macro F1 over the four sets: SVM 0.952 (the best baseline), LightGBM 0.948, naive Bayes 0.930, logistic regression 0.927; RoBERTa 0.970, SetFit 0.967, Spam-T5 0.974. On Ling-Spam and SpamAssassin, the baselines were as good as the language models or better (Ling-Spam: naive Bayes and SVM at an F1 of 1.00; SpamAssassin: LightGBM 0.98 against RoBERTa's 0.97).
  • Few labelled samples (k), macro F1: SVM 0.155 (4), 0.334 (32), 0.531 (64), 0.732 (128), 0.858 (256), 0.952 (full); SetFit, from pre-trained sentence embeddings, 0.855 (32), 0.887 (64), 0.929 (128), 0.941 (256); Spam-T5 0.544 (4), 0.806 (64), 0.933 (256). With fewer than about 500 labels, pre-trained representations beat TF-IDF with linear models; the gap closes with thousands of labels.
  • Caveats: a random split, F1 rather than errors at low false-positive rates, baselines lightly tuned, English only, public corpora. Grade moderate (one benchmark).

Header features

  • Kulkarni, Saini & Acharya (2020), IJACSA 11(3), read: 17 binary header features made by hand (To empty or undisclosed, Bcc without To, the number of recipients, the number of Received lines, the time from the first to the last Received line, symbols in From and Subject, Received-SPF fail or softfail, Authentication-Results dkim=fail, a Message-ID at another domain than the From, a Reply-To at another domain, X-Mailer present and valid, Content-Transfer-Encoding present, a Return-Path holding "bounce" or at another domain). Ten-fold cross-validation, Weka; accuracy only 83 to 95 % (a personal set of 6,532 messages: random forest 93.6 %; part of SpamAssassin's corpus 85.7 %; CSDMC2010 94.8 %). The most weighted: Authentication-Results, Content-Transfer-Encoding, symbols in Subject and From; Received-SPF and the number of recipients in the minimal set of five. Header flags made by hand are far weaker than models of content; their value is as extra evidence. Grade weak (small sets, cross-validation, accuracy only).
  • Hao, Syed, Feamster, Gray & Krasser (2009), "Detecting spammers with SNARE", USENIX Security, results read. https://www.usenix.org/legacy/event/sec09/tech/full_papers/hao.pdf
    • 13 network-level features at a large provider (McAfee's TrustedSource, 25 million messages a day). From a single packet (the sender's AS number, ranked first; the distance between sender and receiver; the density of the address's neighbourhood; the time of day; open ports): 70 % detection at 0.44 % false positives; with features of the single message (recipients, length), 0.29 %; with aggregates over 24 hours, 0.20 %. On addresses never seen before, the false-positive rate at 70 % detection rose to 5.2 %. Trained on three days and tested on the next ten, staleness showed within days. Evasion: length and time of day are cheap to change; the AS and the neighbourhood need changes of botnet.
    • For a personal client: only the first external Received hop can be observed; the AS needs an offline table from addresses to AS numbers; the signals work at a provider's scale. Grade moderate (server side, data of 2007).

Authentication headers (SPF, DKIM, DMARC, ARC): how robust they are

  • Most unwanted mail authenticates. Cloudflare's 2023 phishing threats report (13 billion messages, May 2022 to May 2023): 89 % of unwanted messages "passed" SPF, DKIM or DMARC, and more than 30 % of phishing used newly registered domains. https://www.cloudflare.com/press-releases/2023/cloudflare-harnesses-the-power-of-its-global-network-to-identify-top · Grade moderate (an industry report, a large sample). Since February 2024, Gmail and Yahoo require SPF, DKIM, DMARC and one-click unsubscribing from bulk senders, so a pass is now nearly universal for legitimate bulk mail and organised spam alike: a pass carries little evidence, and a failure, a missing record or misalignment more, while much legitimate mail from small senders, lists and forwards still fails.
  • "Composition kills" (Chen, Paxson & Jiang 2020, USENIX Security, a distinguished paper; abstract and mitigations read): 18 kinds of exploit, and all 10 providers and 19 mail clients tested were vulnerable: several From headers (11 clients show the first, others the last), a From surrounded by spaces, a missing From replaced on screen by Sender or Resent-From, DKIM replay. "Even a conscientious security professional using Gmail cannot with confidence readily determine whether it is forged." https://www.usenix.org/conference/usenixsecurity20/presentation/chen-jianjun · Its advice: mail clients should show authentication explicitly; an RFC 8601 Authentication-Results "can be forged by attackers"; servers should pass the verified identity to clients. For Sioul: ambiguities of parsing can be features in themselves (more than one From, a missing From, a From with odd spaces or encoded words, a display name holding an address other than the real one).
  • RFC 8601 (Authentication-Results), §4.1: "MUAs and downstream filters SHOULD NOT interpret this header field unless the authentication service identifier … is used within the ADMD as configured by the user"; §5: border servers MUST delete instances that claim their own id; §7.1 warns of forged ids. So only the topmost Authentication-Results whose id is the user's own provider's may be read (learned per account, mx.google.com for Gmail), and those below ignored. The same holds for Received-SPF and ARC-Authentication-Results (RFC 8617; ARC lets a forwarder vouch for the original result, useful for mailing lists, but only when the sealer is trusted).
  • Ho et al. (2019), "Detecting and characterizing lateral phishing at scale", USENIX Security (113 million messages, 92 organisations): phishing sent from hijacked legitimate accounts, authenticated and from a known sender; one organisation in seven was hit within seven months. Facts about a known sender or a pass must not override strong evidence in the content, such as a link that harvests credentials. https://www.usenix.org/conference/usenixsecurity19/presentation/ho · Grade strong.

More evidence from headers and structure

  • SpamAssassin 3.3's rules, with their fitted scores (https://spamassassin.apache.org/old/tests_3_3_x.html; four sets of scores: base, network, with Bayes, with Bayes and network; fitted by SpamAssassin's perceptron on large contributed corpora, around 2010), a practical measure of each signal's weight: DKIM_VALID −0.1, DKIM_VALID_AU −0.1, SPF_PASS −0.001 (a pass is almost no evidence of ham); SPF_FAIL 0 to 0.92, SPF_SOFTFAIL 0 to 0.97 (weak evidence of spam); DATE_IN_FUTURE_03_06 2.4 to 3.4 and DATE_IN_PAST_96_XX 1.2 to 3.4 (the skew between Date and Received is strong); MIME_HTML_ONLY 0.7 to 2.2; HTML_IMAGE_ONLY_08 0.6 to 1.8; SUBJ_ALL_CAPS 0.5 to 1.6; MISSING_HEADERS (no To) 0.9 to 1.2; FREEMAIL_REPLYTO_END_DIGIT about 1.2; RDNS_LOCALHOST up to 3.7; RCVD_IN_PBL (a relay in Spamhaus's list of end-user addresses) 3.3 to 3.6; URIBL_BLACK 1.7; RCVD_IN_DNSWL_HI −5; BAYES_99 +3.5 to 3.8 and BAYES_00 −1.5 to −1.9 (the model of content is the heaviest single part). Grade moderate (practice; an old set of scores; the rules on network lists need live DNS lookups).
  • Gmail's requirements for senders (https://support.google.com/a/answer/81126, from 1 February 2024): for all senders, SPF or DKIM, valid forward and reverse DNS, TLS, the RFC 5322 format, a spam rate under 0.3 %; above 5,000 a day, SPF and DKIM, DMARC, a From aligned with the SPF or DKIM domain, and one-click unsubscribing (List-Unsubscribe-Post: List-Unsubscribe=One-Click with List-Unsubscribe: <https…>, RFC 8058) for marketing and subscribed mail. A List-Unsubscribe-Post therefore marks a compliant bulk sender (gray mail, not spam); its absence on bulk-looking mail from a large sender is an anomaly.
  • PILFER (Fette, Sadeh & Tomasic 2007, "Learning to detect phishing emails", WWW): ten features of phishing, namely links to bare addresses, the age of linked domains (WHOIS), non-matching links (the text shows one address and the link goes to another), "here" or "click" links to a domain other than the sender's, HTML mail, the number of links, the number of domains, the most dots in a domain, JavaScript, and a spam filter's score; they caught more than 96 % of phishing at about 0.1 % false positives, on about 860 phishing and 6,950 ham messages (random forest). Grade moderate (a small set, 2007); the features comparing links with the claimed identity remain the core of phishing detection today (compare Rspamd's metatokens: the share of links on the same registrable domain, domains per link, forms).
  • Pu & Webb (2006), "Observed trends in spam construction techniques", CEAS, from the abstract: three years of SpamAssassin's rule hits on spam show some techniques dying out once filters caught them, and others lasting for years. Hand-made features age; the learned model must be retrained, and the features' definitions revisited.
  • SpamAssassin's trust path (https://cwiki.apache.org/confluence/display/SPAMASSASSIN/TrustPath): Received headers are trustworthy only down to the boundary of the receiving organisation; network tests (DNS lists, SPF) use "the first IP in the untrusted relays", the host that handed the mail to the first trusted server. Everything below is written by the sender and may be forged. In a mail client reading IMAP, only the Received line added by the provider's own server, and the provider's Authentication-Results, are evidence; the lower hops are claims at best, and their inconsistencies (time order, private addresses, a HELO that is an address, an implausible number of hops) are features in themselves.

The filters people use: documentation and source read

Rspamd's neural module (https://docs.rspamd.com/modules/neural ; its 4.0.0 changelog, released 28 March 2026: https://docs.rspamd.com/changelog/4.0.0/), the closest precedent to Sioul's first plan:

  • Its default input is the set of rule symbols that fired (scores normalised from 0 to 1) and 39 or more numeric "metatokens": a size bucket; the counts and shares of images, PNG and JPEG, large and small images; the shares of text parts and attachments; the shares of UTF-8 and ASCII parts; the MIME and SMTP recipient counts; the number of Received lines, invalid ones, the time skew, secure relays; the number of links; word statistics (average length, short words, capitals, numbers, the rate of non-ASCII); HTML links (count, share over HTTP, share with queries, share on the same registrable domain, domains per link, the most links to one domain); HTML forms (count, share posting elsewhere); shares of call-to-action and tracking links; hidden, transparent or off-screen text, a meta refresh. Its documentation: the symbol mode "learns correlations between filter patterns, effectively clustering messages by their 'filter fingerprint' … two completely different messages might produce identical vectors if they trigger the same set of filters": not a model of content.
  • fastText's embedding mode (4.0 and later): type = "fasttext_embed", models pre-trained per language on Common Crawl (cc.en.300.q.ftz, quantised); pooling "mean_max" (the default) or "mean"; SIF weighting on by default (sif_a = 1e-3); an optional convolution over the first 32 words (kernels 1, 3 and 5); fusion of the embedding providers with the metatokens (fusion { normalization = "zscore"; include_meta = true }). Providers of embeddings from language models (OpenAI, Ollama) exist too, trained by hand through an ANN-Train header.
  • 4.0 replaced libfasttext with its own reader of fastText models, which maps them into memory and needs no dependency (500 MB to 7 GB of memory saved across its workers): reading .bin and .ftz files without the C++ library is practical.
  • Training: automatic, from verdicts or score thresholds; it starts once each class reaches max_trains = 1000; balanced 1 to 1 by default (classes_bias up to 0.25); a network retrained up to max_usages = 10 times, then a new profile; ann_expire two days; its output symbols NEURAL_SPAM and NEURAL_HAM can take thresholds from a ROC analysis (roc_enabled). 4.0 also adds multiclass Bayes.
  • Grade strong as a description of practice; no accuracy is published for the fastText mode.

SpamAssassin's Bayes (its configuration documentation, 4.0): Bayes does not start until 200 ham and 200 spam are learned (bayes_min_ham_num, bayes_min_spam_num); it learns automatically from rule scores; its token database holds at most 150,000 tokens, and expiry keeps 75 %; bayes_token_ttl is three weeks; bayes_use_hapaxes 1; its tokens come by default from header visible invisible uri; bayes_ignore_header "prevents upstream-added headers from skewing classification", such as a provider's own X-Spam verdict headers. Cormack (2008): SpamAssassin's Bayes alone scores a (1−AUC)% of 0.059 on trec05p-1, and its rules with Bayes differ little from Bayes alone.

SpamBayes (its source and FAQ, https://github.com/smontanaro/spambayes): Robinson and Fisher's chi-squared combining, with S and H as outputs; three outcomes, ham, unsure and spam, with defaults ham_cutoff 0.20 and spam_cutoff 0.90, which "should not be close together (say 0.4 and 0.6)". A low S and a low H means "I don't know what this message is"; "people usually agree that messages classed Unsure really are hard to categorize". Its advice for training: start with 10 to 20 of each, then train only on mistakes and unsures; keep ham to spam within 4 to 1; use recent mail ("characteristics of your email change over time"); check training folders for wrong labels. Its tokenizer's comments, tested in the field by its developers:

  • generic header:word tokens are "simple and effective, but also very sensitive to biases in the ham and spam collections … if ham and spam were collected at different times, several headers with date/time information will become the best discriminators (Date, Received, X-From_)"; the generic pass skips received date x-.* by default;
  • Sender: had to be dropped: the token sender:email name:python-list-admin "becomes the most powerful indicator in the whole database", an artefact of a mailing list;
  • From "helps both rates"; To and Cc "can help if your ham and spam are sourced from the same location. If not, they'll be horrible"; the number of recipients and the common prefix of their addresses (alphabetical blasts) as tokens; X-Mailer "a pure and significant win for the f-n rate, f-p not affected"; Received mined for hosts and addresses (good results); the host part of the Message-ID, "small win";
  • the count of header lines by their case ("all-caps SUBJECT strong spam clue, X-Complaints-To strong ham clue"), which "can be too strong a discriminator for accidental reasons" when the sources differ;
  • no allow list is needed: the tokens of addresses act as one by themselves.
  • Grade moderate (practitioners' cross-validation experiments on mail of 2002 to 2004).

bogofilter (its manual page, https://man.archlinux.org/man/bogofilter.1.en): Robinson and Fisher; two states by default, three (ham, unsure, spam) when ham-cutoff is above 0; robx, the prior spamminess of unseen tokens, and robs, its weight; min_dev ignores tokens near 0.5; -u trains on its own verdicts, and "any classification errors … will be preserved and will accumulate until manually corrected". The recommended flow: start from an empty word list, check the unsure folder regularly, and train from it. At TREC 2005, bogofilter lost the least ham (0.01 to 0.11 %) but missed 6 to 73 % of spam at its default threshold: it trades recall for very few false positives.

FairEmail (Android, open source, FAQ 163: https://github.com/M66B/FairEmail/blob/master/FAQ.md#faq163), the precedent on a phone: an experimental local Bayesian classifier, each folder a class; it learns from new messages in the inbox and the spam folder, and from the person's moves into and out of a folder; it moves mail by itself only when the class's probability is above 15 % (default) and its margin over the next class above 50 % (default); "if the classifier is unsure, it will simply leave an email where it is"; it never moves mail out of the spam folder by itself, "to prevent the email server from moving a message into the spam folder again and again"; the person's rules run first and skip classification; its data are per account; it says explicitly that it is "not a replacement for the spam filter of the email server" and "can result in false positives". Grade strong as practice; no accuracy data.

Gmail and RETVec (Google's security blog, 29 November 2023, https://security.googleblog.com/2023/11/improving-text-classification.html ; a NeurIPS 2023 paper; open source): replacing the text vectoriser of Gmail's spam classifier with RETVec (about 200,000 parameters, character-level, trained against typos and lookalike letters with metric learning, UTF-8 and more than 100 languages, no preprocessing) raised spam detection by 38 % and cut the false-positive rate by 19.4 % against the baseline, with 83 % less TPU use. Adversaries "use homoglyphs, invisible characters and keyword stuffing". Robustness at the level of subwords and characters is worth much in production; fastText's character n-grams absorb typos and morphology, but not lookalike letters and invisible characters, which must be normalised (NFKC, the skeleton of confusables, zero-width characters stripped) before tokenising. Grade moderate (the vendor's claim, relative numbers, no absolute rates).

DSPAM (its manual page, https://manpages.org/dspam; the project is dormant): training modes TEFT (train on everything, "standard for most users", but volatile), TOE (train on errors, only after 2,500 ham learned; stable but "too static, unable to ease into a different type of behaviour"), TUM (train until mature: tokens with fewer than 25 hits, and every token on an error). At TREC 2005, DSPAM's variants scored a (1−ROCA)% of about 1.0 to 1.4 overall, among the weaker filters.

Apple Mail's junk filter, a precedent built on centroids of embeddings: US patent 7,076,527 (Bellegarda, Naik & Silverman; filed in 2001, granted in 2006 to Apple, expired in 2023): messages mapped into an LSA (SVD) vector space; two "semantic anchors" (centroids), legitimate and unsolicited; a decision by cosine closeness, with an explicit "ambiguous" outcome; the user's corrections added back, and the anchors computed again from time to time. A practitioner's report (TidBITS 2004, https://tidbits.com/2004/05/24/getting-to-know-apple-mails-spam-filter/): it "learned more slowly than Bayesian filters", "errs on the cautious side, with no way to adjust its threshold", and marking a message "Not Junk" silently allowed its sender (Previous Recipients). Grade weak for performance (anecdote), but it shows how classifying by the nearest centroid of dense topic vectors fails: one "ham centroid" cannot stand for a person's many kinds of good mail. Hence a discriminative classifier (SVM or logistic regression) over the vector, with sparse evidence of tokens kept.

Gmail's sender reputation (Taylor 2006, "Sender reputation in a large webmail service", CEAS; not read in full): reputation is keyed on the authenticated domain (SPF, DomainKeys) rather than on addresses. The authenticated domain (DKIM's d=, an aligned SPF domain) is therefore a good key for a sender's history in a personal filter (past ham and spam from that domain), better than the From shown.

"Spam does not bring us joy" (Google Workspace's blog, 6 February 2019, https://workspace.google.com/blog/product-announcements/ridding-gmail-of-100-million-more-spam-messages-with-tensorflow): the models in place and other protections block "more than 99.9 percent of spam, phishing and malware"; TensorFlow models added about 100 million messages blocked a day, catching image-based messages, hidden embedded content, and messages from newly created domains that hide low volumes among legitimate traffic; machine learning "helps us personalize our spam protections to each user — what one person considers spam another person might consider an important message (think newsletter subscriptions or regular email notifications from an application)". Grade moderate (a vendor's post, with no rates for personalisation).

Personal training, feedback and drift

Gray mail (Yih, McCann & Kołcz 2007, "Improving spam filtering by detecting gray mail", CEAS, https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/YihMcKo07.pdf ; and Chang, Yih & McCann 2008, "Personalized spam filtering for gray mail", CEAS, https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/ChangYiMc20-20CEAS-08.pdf):

  • Gray mail is "messages that could reasonably be considered either spam or good" (newsletters, legitimate advertisements). About two thirds of users want unsolicited commercial mail from businesses they dealt with, and one third call it spam; users "begin reporting newsletters as spam rather than unsubscribing"; a user's own preference changes over time. So some label noise is really preference.
  • Hotmail's feedback data (2.67 million messages, 2007): at least 8.1 to 21.2 % of all messages are gray (campaigns of near-duplicates labelled inconsistently by different users); "even an optimal [global] filter will inevitably perform unsatisfactorily on gray mail unless user preferences are taken into account"; a light model per user catches up to 40 % more spam from gray mail at low false-positive rates. Detecting gray mail: the filter's uncertainty, 0.5 − |p(x) − 0.5|, or campaigns with mixed labels (best). Grade strong (large real data) for the phenomenon.

Personalisation by feature hashing (Attenberg, Weinberger, Dasgupta, Smola & Zinkevich 2009, "Collaborative email-spam filtering with the hashing trick", CEAS; with Weinberger et al. 2009, ICML; https://www.cs.cornell.edu/~kilian/papers/haschisch_old.pdf): Yahoo, 3.2 million messages, hashed token features global and per user (the token joined with the user's id, 2²² buckets, SGD); the threshold set at 1 % of ham misclassified; the personalised model cut uncaught spam by up to 30 % against a global one; hashing also bounds the model's size, with no vocabulary to store. Grade moderate to strong. For one user, the person's labels are the personalisation, and the risk is the reverse: too few labels for a purely personal model. A prior helps only when it is the person's own unlabelled mail (for fastText) or a general language model, not other people's spam labels, which transfer poorly (ECML/PKDD 2006).

"Autonomous personal filtering improves global spam filter performance" (Cormack & Mojdeh 2009, CEAS, https://cormack.uwaterloo.ca/ceas09.pdf), read: a personal filter trained only on the output of a global filter (the provider's Junk and Inbox, no human input), against the global filter itself, at the same false-positive rate:

CEAS 2008 stream (123,100 messages), at 0.63 % false positives Missed spam % Factor against the provider
a commercial collaborative desktop plug-in (the "provider") 6.64 1.0
logistic regression trained on the provider's labels 5.98 1.1
an SVM trained on the provider's labels 4.00 1.6
DMC (compression) on the provider's labels 3.07 2.1
naive Bayes on the provider's labels 0.29 21.9
naive Bayes's score plus the provider's (summed) 0.25 25.6
logistic regression with a (simulated) person, active learning on 0.8 % of messages 0.04 149.8
MrX-5 (one person's mail), at 4.24 % false positives
a commercial webmail's own filter 0.81 1.0
logistic regression on the provider's labels 1.03 0.8 (worse)
naive Bayes on the provider's labels 0.14 5.3
DMC with the webmail's filter 0.05 14.6
logistic regression trained by the real recipient, active learning on 1.4 % of messages 0.04 20.2
  • "For ideal feedback the best methods are discriminative (LR, SVM) … but they perform very poorly with noisy feedback unless learning rate and regularisation are adjusted"; naive Bayes is "hardly affected by 5 % training noise"; a weaker or differently built personal learner is less likely to copy the global filter's errors, which are not random; fusing the personal score with the provider's verdict did best among the filters without a person. "Even among the messages actually labelled by users, error rates of 5 % or more are typical." Grade strong (controlled, two streams).

"Spam filter evaluation with imprecise ground truth" (Cormack & Kołcz 2009, SIGIR, https://cormack.uwaterloo.ca/cormacksigir09-spam.pdf), introduction and conclusion read: human labellers err 3 to 7 %, and tacit labels (a "report spam" button, the rest taken for ham) more. Measuring against natural labels masks a filter's real error: a filter with a true error of 0.5 % measures 5.5 to 6.5 % against labels with 6 % noise, and a 1.0 % filter 5.0 to 7.0 %; rankings can invert. The remedies: train on natural labels, and measure on a small adjudicated sample, adjudicating only a small part, such as the disagreements. Training that tolerates noise (an SVM with a low C, slower learning, bagging) "perform[s] not quite as well as the best filters with clean data, but not nearly as poorly as previously reported". Grade strong. For Sioul, the study inferred on 7 October: the Junk folder and the inbox are the provider's labels, usable with strong regularisation and the provider's verdict as a feature or a fused score; the person's own moves and an "unsure" queue (active learning on about 1 % of mail) are worth 20 to 150 times less missed spam, the most valuable input; and the evaluation belongs on a hand-checked sample, not on the folders. Section 2 says what was decided instead.

Evaluation, costs, thresholds, calibration and the reject option

  • "Learning at low false positive rates" (Yih, Goodman & Hulten 2006, CEAS, https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/YihGoodmanHulten-ceas06.pdf), read: "users are much more concerned about not losing good mail than about receiving a few pieces of spam", yet filters are trained for accuracy and only given a threshold afterwards. Two fixes: (1) weighting ham about ten times spam in the loss (no effect on a hard-margin SVM; for a soft margin, it is the class-weighted C); (2) training in two stages: drop the training messages that are surely ham, and train again on the region that matters. Missed spam at the same low false-positive rate fell by up to 20 % (logistic regression) and 40 % (naive Bayes), relatively; trained on July to November 2005, tested on December 2005 (in time order). In Hotmail's feedback loop, "very roughly 3 % of user labels are errors"; identical messages were labelled spam by 20, 50 or 80 % of users; "most 'false positives' at a false-positive rate of 3 % or below turn out to be labelling errors, not filter errors". Grade strong (765,000 training messages, real users).
  • Kołcz & Alspector (2001), "SVM-based filtering of e-mail spam with content-specific misclassification costs" (TextDM workshop at ICDM), from the abstract: legitimate mail split into kinds (personal, business, e-commerce, mailing list, promotional) with different costs of loss. Cormack (2008): "computing an evaluation measure on each genre separately" is the practical substitute.
  • Duplicates and leaks in random splits: Chang, Yih & McCann (2008) found that 31.7 % of Hotmail's messages belong to campaigns of near-duplicates of five messages or more, so a random split puts copies of one campaign on both sides; Cormack & Bratko (2006) showed that cross-validation and a split in time rank filters differently; and Sahami et al. (1998) measured the gap between collected and live mail (above). Evaluate in time order, and remove duplicates or keep each campaign (the same normalised subject and sender, or a SimHash or MinHash of the body) in one fold.
  • Calibration: max-margin methods (SVMs, boosting) push scores away from 0 and 1, a sigmoid-shaped distortion, while naive Bayes pushes them to the extremes; Platt scaling (a sigmoid fitted on held-out scores) suits SVMs and needs little data; isotonic regression needs more (about 1,000 calibration points or more); after calibration, SVMs give among the best probabilities (Niculescu-Mizil & Caruana 2005). Grade strong (a standard result); Platt (1999) is the original.
  • The reject option: Chow (1970) gave the optimal rule trading error against rejection; for SVMs, Bartlett & Wegkamp (2008) give a hinge loss with a reject option. Conformal prediction (Vovk et al.) gives sets of predictions; accepting only single labels yields a classifier with a reject option whose error on what it accepts is controlled, under exchangeability. Johansson, Sönströd, Löfström & Boström (2023, COPA): conformal reject classifiers "clearly outperform both calibrated and uncalibrated probabilistic predictors" at estimating the accuracy or precision of what they accept. Caveat: drift breaks exchangeability, so calibrate again on the most recent labelled window. Precedents of three outcomes in practice: SpamBayes (0.20 and 0.90), bogofilter's three states, FairEmail (left in place when unsure), Apple's patent ("ambiguous"), Cormack's ordinal scale.
  • Recent evidence of drift, from public corpora to new mail: Kshirsagar, Rathi & Ryan (2025), Frontiers in Artificial Intelligence: a meta-learner with an AUC of 0.999 on Enron-Spam and TREC 2007 (a random 80 to 20 split, five-fold cross-validation) fell to an accuracy of 0.634 and an AUC of 0.76 on a recent unseen set of 2,000 messages, without retraining. Grade weak to moderate (a small recent set), consistent with Sahami et al. (1998) and ECML/PKDD 2006: scores on public corpora say little about a live mailbox.

Privacy of models trained on a person's mail

  • fastText's file format (its source, src/dictionary.cc in facebookresearch/fastText, read): Dictionary::save writes every word of the vocabulary as a plain string followed by its count (a 64-bit integer) and its type, and the .vec export is one line per word. A fastText model trained on a mailbox is literally a list of that mailbox's words with their frequencies: correspondents' names, street names, account numbers that recur at least minCount times, names of medicines. In unsupervised training, tokens below minCount are skipped entirely (getLine: if (wid < 0) continue;) and influence nothing; in supervised mode, unknown tokens still add the hashes of their character n-grams and word n-grams (addSubwords, addWordNgrams), so rare strings update hashed buckets. Grade strong (source code).
  • "Information leakage in embedding models" (Song & Raghunathan 2020, CCS; arXiv:2004.00053), results read: (1) membership inference on word2vec, fastText and GloVe trained on Wikipedia, over windows of five words: almost no leak for frequent words (an advantage under 0.1), but an advantage of about 0.3 for the rarest tenth: rare contexts are memorised; (2) inverting sentence embeddings, plain mean-pooled word vectors among them, recovers about 45 to 75 % of the input words (F1); (3) attributes such as authorship can be extracted from a handful of labelled embeddings. Adversarial training cut inversion by about 30 % and attribute inference by about 80 %, at a small cost in utility. Grade strong.
  • A linear SVM against a kernel SVM: a kernel SVM's file stores support vectors, the feature vectors of real training messages (their centroids and header features), which the inversion results show to be partly invertible to words; a linear SVM can be stored as one weight vector and a bias, which hold no single message. Inference from the above and from how SVMs work; grade moderate.
  • Related, not fetched, well known: Carlini et al. (2019), "The secret sharer" (USENIX Security): neural language models memorise rare secrets (planted canaries, strings shaped like credit card numbers), and differential privacy removes it. Morris et al. (2023), "Text embeddings reveal (almost) as much as text" (EMNLP): iterative inversion recovers 92 % of 32-token inputs exactly from modern sentence embeddings.

Adversaries

  • Good-word attacks (Lowd & Meek 2005, CEAS; abstract and introduction read): against naive Bayes and maximum-entropy (logistic) filters, passive attacks (without feedback) get half of the blocked spam through with 150 added words or fewer; active attacks (probing the filter) need about 30 words; "a list of words whose weights sum to −1 is sufficient to get the median blocked spam past the filter". The defence: frequent retraining, weighting the most recent examples (preliminary, but effective). Grade strong. For a mean-pooled centroid, the attack is structurally easy: the centroid is a convex combination, so N appended ham-like words pull it linearly toward the ham region (inference). The answers: SIF or max pooling, features for the subject and the first N words apart, vectors per part, length features, and the detection of hidden text, as in Rspamd's metatokens.
  • Poisoning (Nelson et al. 2008, "Exploiting machine learning to subvert your spam filter", USENIX LEET, on SpamBayes): if the victim trains on spam the attacker sent, controlling 1 % of the training messages (a dictionary attack) made the filter unusable: about 36 % of ham went to spam or unsure; a focused attack that knows 30 to 50 % of a target message's words blocked that message about 60 % of the time. RONI (reject on negative impact: never train on a message whose inclusion hurts a held-out set of ham) caught 100 % of the dictionary attack's messages, but not focused attacks. Biggio, Nelson & Laskov (2012, ICML): poisoning an SVM by gradient raises its error sharply with few points. Training automatically from the Junk folder, or from the filter's own verdicts, is a surface of attack: the study's advice was to train only on the person's deliberate acts, to cap the weight of each sender and campaign, and to test candidate training batches on held-out ham before accepting them. Grade strong.
  • Obfuscation: lookalike letters, invisible characters, keyword stuffing (Google's post on RETVec). Character 4-grams and fastText's subwords absorb typos and edits such as "v1agra" (Sculley; Cormack), but not Unicode's confusables, which must be normalised first.
  • Phishing written by large language models: Gutierrez, Villegas-Ch & Govea (2026, Frontiers in Big Data): detectors trained on phishing written by people (CEAS-08, TREC-07, Nazario, Nigerian, Enron) had an F1 of about 0.999 within their own distribution, but a mean F1 of 0.719 on phishing generated by GPT-4.1, DeepSeek and Llama 3.3 at their default threshold, a gap of 28 points, mostly recovered (to 4 points) by setting the threshold again. Thapa et al. (2025, arXiv:2507.07406): "LLM-rephrased emails can significantly degrade the performance of both ML and LLM-based detectors". Grade weak to moderate (stylometric features, synthetic sets). The style of the body loses value; structural evidence (links' real domains against the claimed sender, a diverging Reply-To, a sender writing for the first time, requests for credentials or payment) matters more.

Appendix A. The Rust stack

A survey of the crates, made on 7 October 2026 from crates.io's API, docs.rs and the crates' repositories, before anything was installed. Inferences are marked so. What Sioul uses now: spam-filter.md, "The model, and how it folds"; the training is the sioul-learn crate, on computers only.

Training fastText's models: the fasttext crate, now pure Rust

  • What changed: messense's fasttext crate used to bind Facebook's C++ (cfasttext-sys). A rewrite merged on 17 April 2026 replaced it with a pure-Rust implementation, released as 0.8.0 on 18 April 2026 ("fastText pure Rust implementation"). https://github.com/messense/fasttext-rs · https://crates.io/crates/fasttext
  • Its dependencies are rayon and thiserror only (clap behind its cli feature): no C or C++, no BLAS. The C++ is a development dependency, used only for parity tests and benchmarks.
  • What it does: skip-gram, CBOW and supervised models; the hierarchical softmax, negative sampling, softmax and one-against-all losses; fastText's hyperparameters with fastText's defaults (100 dimensions, a window of 5, 5 epochs, minCount 5, 2,000,000 buckets, n-grams of 3 to 6 characters, 12 threads); supervised models started from unsupervised vectors; quantisation (a cut-off by norm and a product quantiser) into .ftz; autotuning; saving and loading fastText's own .bin and .ftz format, so models move both ways with the C++ tool; word and sentence vectors, prediction, nearest neighbours, the vocabulary, training that can be stopped.
  • Faithfulness: its tests compare predictions and probabilities with the C++ program's outputs (|Δp| < 10⁻⁴), and its subword hash keeps fastText's FNV-1a over sign-extended bytes. Its unsupervised sentence vector is the mean of word vectors normalised to unit length; its supervised one, the mean of input rows (words, n-grams, the end of the line), not normalised.
  • SIMD: scalar, NEON (aarch64), SSE2, AVX, AVX2 with FMA and AVX-512F kernels, chosen at run time on x86_64 and NEON always on aarch64: a phone gets the NEON path, with no C++ to cross-compile.
  • Limits read in its code: quantisation refuses unsupervised models, as the C++ does; models are read whole into memory, never mapped; training allocates fastText's 30-million-slot dictionary (120 MB), though loading resizes it; training reads its corpus from a file.
  • Maintenance: one maintainer; a burst of commits on 16 to 18 April 2026 and nothing since; on 7 October 2026, 0.8.0 had 35,268 downloads in all, against more than a million in 90 days for 0.7.8, the old C++ bindings: young adoption.
  • The part Sioul needs was not tested against C++: the parity model was trained without subwords, so the character n-grams, the heart of fastText for spam, needed a check of Sioul's own. Sioul checks its hashing of n-grams against the crate's own get_subwords (spam-filter.md).
  • Toolchain: no minimum Rust version is declared, but the AVX-512 kernels need the intrinsics stabilised in Rust 1.89, Sioul's own minimum.
  • A whitespace trap: training splits on ASCII whitespace bytes, while the unsupervised sentence vector splits on Unicode whitespace, so non-breaking spaces would tokenise differently: all spaces must become U+0020 before both. Sioul's tokenizer does it.
  • Licence: MIT, with fastText's own notice; fastText itself is MIT and archived since March 2024. Both fit GPL-3.0-or-later.
  • Fallbacks: fasttext-pure-rs 0.1.0 (MIT) reads .bin and .ftz files and predicts, without training; its README states why it exists: "Facebook's fastText C++ library does not cross-compile cleanly for Android and iOS without maintaining a custom fork". https://github.com/silvermine/fasttext-pure-rs . finalfrontier (skip-gram trainers with subwords) stalled in 2023, its last release on crates.io dating from 2020; finalfusion (a format with memory mapping and product quantisation) has been frozen since October 2023, its format documented (https://finalfusion.github.io/spec). Older crates (cfasttext-sys, fast_text, word2vec, rust2vec) are superseded or dead.

The classifier: why Sioul wrote its own linear SVM

  • linfa-svm 0.8.1, the crate docs/architecture.md named then, builds the full dense n×n kernel matrix before fitting, even for a linear kernel (read in linfa-kernel's dense_from_fn): 0.8 GB in f64 at 10,000 messages, 3.2 GB at 20,000, 20 GB at 50,000. It is usable up to about 10,000 samples and unusable beyond. Its Platt probabilities are fitted on the training set's own decision values, where LIBSVM uses five-fold cross-validation, and Platt (1999) warns that an SVM's outputs on its own training data are biased: they come out over-confident (inference from the code).
  • smartcore 0.6 gives no probabilities for its SVM or its logistic regression.
  • libsvm-rs 0.9.0, a pure-Rust LIBSVM with Platt by internal cross-validation, passed 237 of 250 differential tests against LIBSVM, but has one maintainer; fine for trying an RBF kernel on a computer.
  • light-svm has no public repository; the liblinear bindings date from 2019.
  • What Sioul built instead: a linear SVM by dual coordinate descent, the method of liblinear (Hsieh et al. 2008), about 150 lines of its own code with no dependency, and Platt's calibration fitted on forward folds. Hsieh et al. report an L1-SVM within 1 % of the optimum in 2.6 seconds on rcv1 (677,399 documents, 49.6 million non-zero values) on the hardware of 2008; 200,000 messages with about 310 dense features is the same order (inference). Since features version 3, the filter's model is fastText's supervised classifier, and this SVM serves the centroid, on request.
  • Stalwart, a mail server in Rust, moved in its version 0.15 (its post "Marginal gains", 16 December 2025) from a Bayes classifier to FTRL-Proximal logistic regression with hashed features (2²⁰ features, about 4 MB), a precedent in production for "a linear model with hashing". https://stalw.art/blog/marginal-gains/ · https://stalw.art/docs/spamfilter/classifier/ . Its licence is AGPL-3.0-only, or its enterprise licence: GPL-3.0 §13 allows combining with AGPL-3.0 code, but the AGPL's network clause would then apply to the combination. Sioul read it for ideas and wrote its own.
  • A linear model explains itself: with a centroid that is a mean of word vectors, the content's score splits exactly into each word's share, and each header feature adds its own. An RBF kernel loses that. The window shows no "why" by the author's decision, but sioul spam why prints those shares in a terminal.

Reading text, on the computer and the phone alike

The decisive point: the same tokenizer runs where the filter learns and where it judges, so the vocabulary matches by construction. fastText only splits on whitespace, so every normalisation is Sioul's.

  • Normalisation: icu_normalizer (NFKC), already in Sioul; Sioul's own skeleton of lookalike letters (UTS #39) and its folding of accents.
  • Splitting words: UAX #29 (unicode-segmentation) keeps "l'information" and "aujourd'hui" as one word each, so French elisions must be split by hand, as Sioul's tokenizer does.
  • Patterns: the regex crate runs in linear time but has no look-around and no back-references, which Virtual Secretary's patterns use throughout; fancy-regex supports them. Sioul rewrote the patterns without look-around (spam-filter.md, "Reading a message: the tokenizer").
  • Stemming and stop words: not needed for fastText, whose subwords carry morphology (Bojanowski et al. 2017); Sioul keeps Virtual Secretary's own French and English suffix stemmer and stop words, for parity with its design.
  • Languages: whatlang or whichlang would suffice for French and English; fastText's own language model (lid.176.ftz, 917 kB) would reuse code already linked. Sioul detects no language: one model learns both.

Appendix B. Why the phone reads a folded table

A phone judges mail too: in the window, and in the background step that fetches new mail every quarter of an hour (android.md). The research of 7 October 2026 weighed what a model costs there.

  • Memory: the window put away holds about 140 MB, and the background step, Sioul's library without Qt's window, an estimated 30 to 50 MB (android.md). A fastText model's input matrix is (words + buckets) × dimensions × 4 bytes: about 840 MB at fastText's defaults (100 dimensions, 2,000,000 buckets), about 120 MB with 200,000 buckets and 100,000 words, still 30 to 60 MB quantised (31 MB in int8, about 10 MB by product quantisation). Read into the heap, such a model would double or triple the background process, and Android's low-memory killer takes the largest background processes first.
  • Mapping the file into memory (memmap2) would keep only the rows a message touches: a few hundred words times about ten n-grams each, some 5,000 rows, up to 20 MB of 4 KiB pages in the worst case, dropped under pressure, for about a millisecond of arithmetic per message on a small phone core (inference). It works, but it needs the model copied out of the sharing folder before mapping, since a file the sync replaces while mapped can crash the process.
  • The fold: a linear model on a plain mean of word vectors, where each word's vector is the mean of its rows, needs one number per row and nothing else: each row's score (w · row) is computed once on the computer, and a message's score is then the mean of its words' scores plus the header terms. The fold is exact, not an approximation; standardising and removing a principal component fold too, being linear, and SIF weights fold as one weight per word. What breaks it: an RBF kernel, max pooling, or vectors normalised to unit length for words the vocabulary lacks (fastText's unsupervised sentence vector normalises each word's vector, which is why Sioul's centroid is the plain mean, never normalised). fastText's supervised classifier folds as well, as a mean of its rows' scalars (spam-filter.md, "The fold, the classifier's").
  • Size: the folded table is one or two megabytes, against 30 to 60 MB for a quantised embedding, and it holds 64-bit hashes of words, never a word.
  • The sharing: on 7 October 2026, sealed files up to 64 MiB travelled only in whole exchanges, records up to 16 MiB in any; with Sioul keeping the folder in step with a Nextcloud itself, a sealed file had to go up within 60 seconds, so a model of 20 to 100 MB would need 0.4 to 1.7 MB/s of upload, and, sent before the records, would hold back the doses' answers behind it. eDrive never deletes a file deleted elsewhere, so a 50 MB model trained weekly would leave 2.6 GB a year on the phone. A table of a megabyte or two avoids all of it. Built since: the table travels sealed apart, in every exchange, quick ones and the background step included, and a device's records go up before its sealed files (database.md, "The spam filter's table and label logs").
  • Verdicts made on the computer and shared by Message-ID would cover only the mail the computer fetched first; the phone needs its own model for mail that comes while the computer is off.
  • Rules that follow, built: nothing loads on the start path; the table is read once per process, off the window's thread, and read again only when its size or time changes; each message's verdict is kept per message file and per table; with no table, the Porch judges mail as it did before the filter (spam-filter.md, "The phone").

Sources

  • Andersen, K., Long, B., Blank, S. & Kucherawy, M. (2019). The Authenticated Received Chain (ARC) protocol. RFC 8617. doi:10.17487/RFC8617
  • Arora, S., Liang, Y. & Ma, T. (2017). A simple but tough-to-beat baseline for sentence embeddings. ICLR 2017. https://openreview.net/forum?id=SyK00v5xx
  • Attenberg, J., Weinberger, K., Dasgupta, A., Smola, A. & Zinkevich, M. (2009). Collaborative email-spam filtering with the hashing trick. CEAS 2009. https://www.cs.cornell.edu/~kilian/papers/haschisch_old.pdf
  • Bartlett, P. L. & Wegkamp, M. H. (2008). Classification with a reject option using a hinge loss. Journal of Machine Learning Research 9, 1823–1840. https://www.jmlr.org/papers/v9/bartlett08a.html
  • Bellegarda, J. R., Naik, D. & Silverman, K. E. A. (2006). Method and apparatus for filtering email. US patent 7,076,527 (Apple Computer; filed 2001, granted 2006). https://patents.google.com/patent/US7076527B2
  • Biggio, B., Nelson, B. & Laskov, P. (2012). Poisoning attacks against support vector machines. ICML 2012. arXiv:1206.6389. https://arxiv.org/abs/1206.6389
  • Bojanowski, P., Grave, E., Joulin, A. & Mikolov, T. (2017). Enriching word vectors with subword information. Transactions of the Association for Computational Linguistics 5, 135–146. doi:10.1162/tacl_a_00051
  • Bratko, A. & Filipič, B. (2006). Exploiting structural information for semi-structured document categorization. Information Processing & Management 42(3), 679–694. doi:10.1016/j.ipm.2005.06.003
  • Bursztein, E., Zhang, M., Vallis, O., Jia, X. & Kurakin, A. (2023). RETVec: resilient and efficient text vectorizer. NeurIPS 2023. arXiv:2302.09207, https://arxiv.org/abs/2302.09207 ; Google's post: https://security.googleblog.com/2023/11/improving-text-classification.html
  • Carlini, N., Liu, C., Erlingsson, Ú., Kos, J. & Song, D. (2019). The secret sharer: evaluating and testing unintended memorization in neural networks. USENIX Security 2019. https://www.usenix.org/conference/usenixsecurity19/presentation/carlini
  • Chang, M.-W., Yih, W. & McCann, R. (2008). Personalized spam filtering for gray mail. CEAS 2008. https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/ChangYiMc20-20CEAS-08.pdf
  • Chen, J., Paxson, V. & Jiang, J. (2020). Composition kills: a case study of email sender authentication. USENIX Security 2020. https://www.usenix.org/conference/usenixsecurity20/presentation/chen-jianjun
  • Chow, C. K. (1970). On optimum recognition error and reject tradeoff. IEEE Transactions on Information Theory 16(1), 41–46. doi:10.1109/TIT.1970.1054406
  • Cloudflare (2023). Phishing threats report (press release). https://www.cloudflare.com/press-releases/2023/cloudflare-harnesses-the-power-of-its-global-network-to-identify-top
  • Cormack, G. V. (2006). TREC 2006 spam track overview. TREC 2006. https://trec.nist.gov/pubs/trec15/papers/SPAM06.OVERVIEW.pdf
  • Cormack, G. V. (2007). TREC 2007 spam track overview. TREC 2007. https://trec.nist.gov/pubs/trec16/papers/SPAM.OVERVIEW16.pdf
  • Cormack, G. V. (2008). Email spam filtering: a systematic review. Foundations and Trends in Information Retrieval 1(4), 335–455. doi:10.1561/1500000006
  • Cormack, G. V. & Bratko, A. (2006). Batch and online spam filter comparison. CEAS 2006. https://www.ceas.cc/2006/listabs.html
  • Cormack, G. V. & Kołcz, A. (2009). Spam filter evaluation with imprecise ground truth. SIGIR 2009, 604–611. doi:10.1145/1571941.1572045
  • Cormack, G. V. & Lynam, T. R. (2005). TREC 2005 spam track overview. TREC 2005. https://trec.nist.gov/pubs/trec14/papers/SPAM.OVERVIEW.pdf
  • Cormack, G. V. & Mojdeh, M. (2009). Autonomous personal filtering improves global spam filter performance. CEAS 2009. https://cormack.uwaterloo.ca/ceas09.pdf
  • Drucker, H., Wu, D. & Vapnik, V. N. (1999). Support vector machines for spam categorization. IEEE Transactions on Neural Networks 10(5), 1048–1054. doi:10.1109/72.788645
  • FairEmail, FAQ 163 (the local classifier). https://github.com/M66B/FairEmail/blob/master/FAQ.md#faq163
  • Fette, I., Sadeh, N. & Tomasic, A. (2007). Learning to detect phishing emails. WWW 2007, 649–656. doi:10.1145/1242572.1242660
  • Google (2019). Spam does not bring us joy: ridding Gmail of 100 million more spam messages with TensorFlow. https://workspace.google.com/blog/product-announcements/ridding-gmail-of-100-million-more-spam-messages-with-tensorflow
  • Google (2024). Email sender guidelines. https://support.google.com/a/answer/81126
  • Graham, P. (2003). Better Bayesian filtering. http://www.paulgraham.com/better.html
  • Gutierrez, R., Villegas-Ch, W. & Govea, J. (2026). Cross-model evaluation of phishing detectors against LLM-generated emails. Frontiers in Big Data 9. doi:10.3389/fdata.2026.1883452
  • Hao, S., Syed, N. A., Feamster, N., Gray, A. G. & Krasser, S. (2009). Detecting spammers with SNARE: spatio-temporal network-level automatic reputation engine. USENIX Security 2009. https://www.usenix.org/legacy/event/sec09/tech/full_papers/hao.pdf
  • Ho, G. et al. (2019). Detecting and characterizing lateral phishing at scale. USENIX Security 2019. https://www.usenix.org/conference/usenixsecurity19/presentation/ho
  • Hsieh, C.-J., Chang, K.-W., Lin, C.-J., Keerthi, S. S. & Sundararajan, S. (2008). A dual coordinate descent method for large-scale linear SVM. ICML 2008, 408–415. doi:10.1145/1390156.1390208
  • Johansson, U., Sönströd, C., Löfström, T. & Boström, H. (2023). Confidence classifiers with guaranteed accuracy or precision. COPA 2023, Proceedings of Machine Learning Research 204. https://proceedings.mlr.press/v204/
  • Joulin, A., Grave, E., Bojanowski, P., Douze, M., Jégou, H. & Mikolov, T. (2016). FastText.zip: compressing text classification models. arXiv:1612.03651. https://arxiv.org/abs/1612.03651
  • Joulin, A., Grave, E., Bojanowski, P. & Mikolov, T. (2017). Bag of tricks for efficient text classification. EACL 2017, 427–431. doi:10.18653/v1/E17-2068
  • Kołcz, A. & Alspector, J. (2001). SVM-based filtering of e-mail spam with content-specific misclassification costs. TextDM 2001, the workshop on text mining of the IEEE International Conference on Data Mining (no DOI or stable address found; read at the abstract only).
  • Kshirsagar, Rathi & Ryan (2025). Meta-learner-based frameworks for interpretable email spam detection. Frontiers in Artificial Intelligence 8. doi:10.3389/frai.2025.1569804
  • Kucherawy, M. (2019). Message header field for indicating message authentication status. RFC 8601. doi:10.17487/RFC8601
  • Kulkarni, P., Saini, J. R. & Acharya, H. (2020). Effect of header-based features on accuracy of classifiers for spam email classification. International Journal of Advanced Computer Science and Applications 11(3). doi:10.14569/IJACSA.2020.0110350
  • Labonne, M. & Moran, S. (2023). Spam-T5: benchmarking large language models for few-shot email spam detection. arXiv:2304.01238. https://arxiv.org/abs/2304.01238
  • Lai, S., Liu, K., He, S. & Zhao, J. (2016). How to generate a good word embedding. IEEE Intelligent Systems 31(6), 5–14. doi:10.1109/MIS.2016.45
  • Levine, J. & Herkula, T. (2017). Signaling one-click functionality for list email headers. RFC 8058. doi:10.17487/RFC8058
  • Lowd, D. & Meek, C. (2005). Good word attacks on statistical spam filters. CEAS 2005. https://www.ceas.cc/papers-2005/125.pdf
  • McMahan, H. B. et al. (2013). Ad click prediction: a view from the trenches. KDD 2013, 1222–1230. doi:10.1145/2487575.2488200
  • Metsis, V., Androutsopoulos, I. & Paliouras, G. (2006). Spam filtering with naive Bayes: which naive Bayes? CEAS 2006 (the Enron-Spam corpus). https://www.ceas.cc/2006/listabs.html
  • Mohammed, M. A. & Ahmed, M. A. (2024). A semantic-based model with a hybrid feature engineering process for accurate spam detection. Journal of Electrical Systems and Information Technology 11. doi:10.1186/s43067-024-00151-3
  • Morris, J. X., Kuleshov, V., Shmatikov, V. & Rush, A. M. (2023). Text embeddings reveal (almost) as much as text. EMNLP 2023, 12448–12460. doi:10.18653/v1/2023.emnlp-main.765
  • Nelson, B., Barreno, M., Chi, F. J., Joseph, A. D., Rubinstein, B. I. P., Saini, U., Sutton, C., Tygar, J. D. & Xia, K. (2008). Exploiting machine learning to subvert your spam filter. USENIX LEET 2008. https://www.usenix.org/legacy/event/leet08/tech/full_papers/nelson/nelson.pdf
  • Niculescu-Mizil, A. & Caruana, R. (2005). Predicting good probabilities with supervised learning. ICML 2005, 625–632. doi:10.1145/1102351.1102430
  • Platt, J. C. (1999). Probabilistic outputs for support vector machines and comparisons to regularized likelihood methods. In Smola, Bartlett, Schölkopf & Schuurmans (eds.), Advances in Large Margin Classifiers, MIT Press (a book chapter, without DOI).
  • Pu, C. & Webb, S. (2006). Observed trends in spam construction techniques: a case study of spam evolution. CEAS 2006. https://www.ceas.cc/2006/listabs.html
  • Rspamd. The neural network module. https://docs.rspamd.com/modules/neural ; changelog 4.0.0. https://docs.rspamd.com/changelog/4.0.0/
  • Sahami, M., Dumais, S., Heckerman, D. & Horvitz, E. (1998). A Bayesian approach to filtering junk e-mail. AAAI workshop on learning for text categorization, technical report WS-98-05. https://cdn.aaai.org/Workshops/1998/WS-98-05/WS98-05-009.pdf
  • Sculley, D. & Wachman, G. M. (2007). Relaxed online SVMs for spam filtering. SIGIR 2007, 415–422. doi:10.1145/1277741.1277813 ; and their TREC 2007 report: https://trec.nist.gov/pubs/trec16/papers/tuftsu.spam.final.pdf
  • Shen, D. et al. (2018). Baseline needs more love: on simple word-embedding-based models and associated pooling mechanisms. ACL 2018, 440–450. doi:10.18653/v1/P18-1041
  • Somesha, M. & Pais, A. R. (2022). Classification of phishing email using word embedding and machine learning techniques. Journal of Cyber Security and Mobility 11(3). doi:10.13052/jcsm2245-1439.1131
  • Song, C. & Raghunathan, A. (2020). Information leakage in embedding models. CCS 2020, 377–390. doi:10.1145/3372297.3417270
  • SpamAssassin. Configuration documentation (Bayes); the 3.3.x rule list with scores, https://spamassassin.apache.org/old/tests_3_3_x.html ; the trust path, https://cwiki.apache.org/confluence/display/SPAMASSASSIN/TrustPath
  • SpamBayes. Source and FAQ. https://github.com/smontanaro/spambayes ; bogofilter, manual page, https://man.archlinux.org/man/bogofilter.1.en ; DSPAM, manual page, https://manpages.org/dspam
  • Stalwart Labs (2025). Marginal gains. https://stalw.art/blog/marginal-gains/
  • Sun, Z. et al. (2020). MobileBERT: a compact task-agnostic BERT for resource-limited devices. ACL 2020, 2158–2170. doi:10.18653/v1/2020.acl-main.195
  • Taylor, B. (2006). Sender reputation in a large webmail service. CEAS 2006. https://www.ceas.cc/2006/listabs.html
  • Thapa, J., Chahal, G., Gabreanu, S. V. & Otoum, Y. (2025). Phishing detection in the Gen-AI era: quantized LLMs vs classical models. arXiv:2507.07406. https://arxiv.org/abs/2507.07406
  • TidBITS (2004). Getting to know Apple Mail's spam filter. https://tidbits.com/2004/05/24/getting-to-know-apple-mails-spam-filter/
  • Vovk, V., Gammerman, A. & Shafer, G. (2005). Algorithmic Learning in a Random World. Springer. doi:10.1007/b106715
  • Wang, S. & Manning, C. D. (2012). Baselines and bigrams: simple, good sentiment and topic classification. ACL 2012. https://aclanthology.org/P12-2018/
  • Weinberger, K., Dasgupta, A., Langford, J., Smola, A. & Attenberg, J. (2009). Feature hashing for large scale multitask learning. ICML 2009, 1113–1120. doi:10.1145/1553374.1553516
  • Yih, W., Goodman, J. & Hulten, G. (2006). Learning at low false positive rates. CEAS 2006. https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/YihGoodmanHulten-ceas06.pdf
  • Yih, W., McCann, R. & Kołcz, A. (2007). Improving spam filtering by detecting gray mail. CEAS 2007. https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/YihMcKo07.pdf
  • Zhang, X., Zhao, J. & LeCun, Y. (2015). Character-level convolutional networks for text classification. NeurIPS 2015. arXiv:1509.01626. https://arxiv.org/abs/1509.01626
  • Zubiaga, A. (2020). TF-CR: weighting embeddings for text classification. arXiv:2012.06606. https://arxiv.org/abs/2012.06606