Table of Contents
MailSweep Rules JSON Schema Specification
MailSweep uses a declarative JSON schema (rules.json) for email classification rules. The rules define custom domain immunities and safety tiers across 13 European languages.
This document describes the schema structure, field definitions, safety tier mappings, and validation procedures.
1. Design and Standards Background
MailSweep structures heuristic classification rules in an immutable JSON format. The schema adopts rules and headers from the following industry standards:
- IETF RFCs: RFC 6154, RFC 8058, RFC 2369, RFC 3834, and RFC 5322.
- SpamAssassin:
20_headers.cf(headers) and20_mailspike.cf(bulk signatures). - Rspamd:
TRANSACTIONAL_DOC(document verification) andMAILLIST(list detection).
2. Complete Schema Definition
A valid MailSweep rules file is a JSON object with the following structure:
{
"version": "1.3.0",
"last_updated": "2026-08-24",
"description": "MailSweep 13-Language European Categorization and Safety Rules",
"supported_standards": {
"ietf_rfcs": [
"RFC 6154 (IMAP SPECIAL-USE Mailbox Attributes)",
"RFC 8058 (One-Click List-Unsubscribe)",
"RFC 2369 (List Header URL Meta-Syntax)",
"RFC 3834 (Recommendations for Automatic Mail Responses)",
"RFC 5322 (Internet Message Format: Thread In-Reply-To/References)"
],
"rspamd_modules": [
"TRANSACTIONAL_DOC (PDF / Attachment Verification)",
"MAILLIST (Mailing List Detection)"
],
"spamassassin_rules": [
"20_headers.cf (Precedence & Mailer Headers)",
"20_mailspike.cf (ESP Bulk Fingerprints)"
]
},
"languages_supported": [
"FI", "SV", "NO", "DA",
"ET", "LV", "LT",
"EN", "DE", "NL",
"ES", "IT", "FR"
],
"custom_domains": [
"mycompany.com",
"partner.fi"
],
"personal_providers": [
"gmail.com",
"outlook.com",
"proton.me"
],
"property_management_keywords": [
"asunto oy",
"taloyhtiö",
"isännöin"
],
"critical_patterns": [
"työsopimus",
"employment contract",
"passi",
"veropäätös"
],
"receipt_invoice_patterns": [
"lasku",
"invoice",
"kuitti",
"receipt",
"tilausvahvistus"
],
"shipping_patterns": [
"seurantakoodi",
"tracking",
"paketti",
"track en trace"
],
"marketing_promo_patterns": [
"alennus",
"discount",
"uutiskirje",
"newsletter",
"spar"
],
"survey_patterns": [
"kysely",
"survey",
"feedback",
"kundeundersøkelse"
]
}
3. Field Reference
| Field | Type | Required | Description |
|---|---|---|---|
version |
string |
Yes | Semantic version string of the ruleset (for example, "1.3.0"). |
last_updated |
string |
No | ISO date of last modification in "YYYY-MM-DD" format. |
description |
string |
No | Text description of the ruleset. |
supported_standards |
object |
No | Standards metadata mapping RFCs and anti-spam heuristics. |
languages_supported |
array[string] |
Yes | List of uppercase ISO 639-1 language codes. |
custom_domains |
array[string] |
No | Domain names granted permanent Tier 0 Domain Immunity. |
personal_providers |
array[string] |
No | Public email domains excluded from private domain immunity. |
property_management_keywords |
array[string] |
No | Substrings identifying housing companies and utilities (Tier 3). |
critical_patterns |
array[string] |
Yes | Substrings for employment, legal, health, and tax protection (Tier 4). |
receipt_invoice_patterns |
array[string] |
Yes | Substrings identifying invoices, receipts, and order confirmations (Tier 3). |
shipping_patterns |
array[string] |
Yes | Substrings identifying parcel tracking numbers and delivery notices (Tier 5). |
marketing_promo_patterns |
array[string] |
Yes | Promotional and sales keywords targeting messages for cleanup (Clutter). |
survey_patterns |
array[string] |
Yes | Feedback and survey keywords targeting messages for cleanup (Clutter). |
4. Safety Tier Precedence and Classification Mapping
When classifying an email header, the ClassificationEngine evaluates rules in strict order:
- Tier 0: Domain Immunity (
custom_domains,USER_DOMAINS) -> KEEP - Tier 1: Human Conversation (
In-Reply-To/References, conversational prefix) -> KEEP - Tier 2: Transactional Documents (PDF attachment via
BODYSTRUCTURE/ headers) -> KEEP - Tier 5: Calendar Event (Meeting invitation via
BODYSTRUCTURE/.ics) -> KEEP - Tier 3: Invoices & Subscriptions (
receipt_invoice_patterns, payment terms) -> KEEP - Tier 3: Housing Management (
property_management_keywords) -> KEEP - Tier 4: Critical Personal & Legal (
critical_patterns) -> KEEP - Tier 5: Shipping & Delivery (
shipping_patterns, tracking codes) -> KEEP - Clutter: Feedback & Surveys (
survey_patterns) -> TRASH - Clutter: Marketing & Bulk (
marketing_promo_patterns,List-Unsubscribe,^smartlabel_promo) -> TRASH - Clutter: Social Notification (
^smartlabel_social) -> TRASH - Clutter: Automated Notification (
^smartlabel_notification, portal pings) -> TRASH - Clutter: Ephemeral Alert (Security alerts, login notifications) -> TRASH
- Clutter: Automated Senders (
noreply@, automated mailer prefixes) -> TRASH - Fallback: Direct Message -> KEEP
Safety tiers (Tiers 0 through 5) always evaluate before clutter rules. Gmail promotional or social labels never override safety tiers for receipts, invoices, or critical documents.
5. Testing and Validating Custom Rules
Validate custom rules files before deployment:
# Validate custom rules and run 27 multilingual heuristic test fixtures
mailsweep rules --rules path/to/my_rules.json --check
# Print the 13-language coverage scorecard for custom rules
mailsweep rules --rules path/to/my_rules.json --audit-languages
Validation Checks Performed
- Schema Integrity: Verifies that all required top-level keys exist with valid types.
- Pattern Syntax: Verifies that all substring patterns compile without regex errors.
- Language Matrix Test: Runs 27 multilingual test fixtures across 13 European languages. Verifies that the engine protects critical messages and flags clutter.
6. Programmatic Consumption (Rust API)
Load custom rules in Rust:
use mailsweep::classifier::ClassificationEngine;
use mailsweep::models::{Action, EmailHeader, SafetyTier};
use mailsweep::rules::RuleSet;
use std::path::Path;
// Load and validate custom rules
let ruleset = RuleSet::load(Path::new("my_custom_rules.json"))?;
// Initialize engine with custom rules
let engine = ClassificationEngine::new(ruleset);
let mut header = EmailHeader::default();
header.subject = "Työsopimus ja palkkalaskelma".to_string();
let decision = engine.classify(&header);
assert_eq!(decision.action, Action::Keep);
assert_eq!(decision.tier, SafetyTier::Tier4CriticalLegal);
7. External Rule Sources Manifest (sources.json)
Use sources.json to synchronize upstream SpamAssassin rules, Rspamd modules, IETF RFC definitions, and JSON overlays:
{
"version": "1.0.0",
"description": "MailSweep External Rule Sources Manifest",
"sources": [
{
"name": "SpamAssassin Headers Rules (20_headers.cf)",
"type": "spamassassin",
"url": "https://svn.apache.org/repos/asf/spamassassin/trunk/rules/20_headers.cf",
"enabled": true
},
{
"name": "SpamAssassin Mailspike Bulk (20_mailspike.cf)",
"type": "spamassassin",
"url": "https://svn.apache.org/repos/asf/spamassassin/trunk/rules/20_mailspike.cf",
"enabled": true
},
{
"name": "Rspamd Transactional & Mailing List Modules",
"type": "rspamd",
"url": "https://raw.githubusercontent.com/rspamd/rspamd/master/rules/misc.lua",
"enabled": true
},
{
"name": "IETF RFC 8058 One-Click List Unsubscribe",
"type": "ietf_rfcs",
"url": "https://www.ietf.org/rfc/rfc8058.txt",
"enabled": true
},
{
"name": "Custom Corporate Overlays",
"type": "mailsweep_json",
"url": "https://internal.corp.net/rules.json",
"enabled": true
}
]
}
Synchronize declared sources with the CLI:
mailsweep rules --sync-sources --sources sources.json