ZEMAIL-CORE // ENGINEERING REPORT

// module map · command surface · FFI exports · test status

Home Source
0.1.0version
3crate-types (rlib · staticlib · cdylib)
203engine commands
4C-ABI exports

zemail-core is in active development. The figures on this page are derived from the crate source as it stands today (Cargo.toml, src/commands.rs, src/ffi.rs): version, crate-types, the dotted commands in the COMMANDS table (kept in lockstep with Engine::invoke's match arms by a drift-guard test), and the exported C symbols. The "planned" column lists work that is not yet implemented — it is a roadmap, not a claim of coverage.

Module map

modulerole todayplanned
lib (Engine)one dotted command surface via Engine::invoke; event sink; folder seedingmore dispatch coverage as modules grow
modelaccount · identity · server config · folder · message · contact · filter typesricher flags, threading model
storeprofile load/save; persisted message store (messages.json); import eml · mbox · maildir; mbox export
mimeRFC 5322 / MIME parsing via mail-parser
encodingoutbound MIME: RFC 5322 builder (message.build_rfc5322), RFC 2047 header encode, quoted-printable, format=flowed (RFC 3676)
searchin-memory query over messages + persisted named queries (saved searches)
glodaglobal relevance-ranked search over an inverted TF-IDF index of the whole store (Thunderbird Gloda analogue); dependency-freepersistent index, phrase queries
filtersconditions + actions (mark · star · label · move · delete)scheduled runs, more conditions
junkadaptive junk filter — multinomial naive-Bayes over message tokens; trained counts persist in the profileheader features, per-account models
mailappscross-app pure logic: categorize · unsubscribe extraction and the stateful surface for snooze · send-later · mute · VIP · pin · scheduled send · self-destruct · Screener · templates · follow-up (Gmail, Apple Mail, Outlook, ProtonMail, Hey, Spark/Superhuman, RFC 8058)richer rules, server-side sync
threadingJWZ conversation threading (References / In-Reply-To reply tree) + list-aware canonical-subject normalization
thread_reconstruct⭐ rebuild a who-wrote-what timeline from one message's quote nesting (>-depth + On … wrote: / Outlook blocks)
quote_audit⭐ Quote Integrity Audit — verify a reply's quoted text against the original it claims to quote; flag altered wording, changed figures, flipped negations, fabricated lines
roster_audit⭐ Conversation Roster Audit — diff the To/Cc roster across a whole thread; flag who was silently CC'd in, silently dropped, or quietly demoted To→Cc
sender_identity⭐ Sender Identity Firewall — per-sender behavioural baselines (DKIM selectors, envelope sources, header field-order, MIME structure, send-hour histogram, writing-style sketch) + offline impersonation / account-takeover scoring
provenance⭐ Document Revision Ledger — BLAKE3-address every attachment across the archive (rayon-parallel, incremental), group revisions into rename-stable document families, and report stale holders / forks / resurrections / domain crossings; persists to its own ledger.json
revision_diff⭐ Revision Delta Ledger — extract each revision's text (plain text + HTML in-crate, richer formats via host-registered backends), align consecutive revisions with quote_audit's line matcher, and join material-drift / silent-revert / stale-on-a-moved-term findings onto the holder graph
doc_attestBody-to-attachment quote attestation — check prose in a mail body against the named attachment it claims to quote, before sending (compose.doc_attest) or after the fact (message.doc_attest)
exposure⭐ Knowledge Exposure Ledger — when each person was told a fact versus when they were merely copied on it (exposure.trace · exposure.room)
fork_ledger⭐ Conversation Fork Ledger — where one conversation split into two and whether the branches ended up disagreeing (fork.scan · fork.thread)
reading⭐ Divergent Reading Ledger — which recipients of a draft or a sent message hold a different reading of the values it states (reading.draft · reading.message)
phishing⭐ explainable phishing risk score — auth failures, display-name spoofing, brand impersonation, punycode/homoglyph domains, urgency language, link-text↔href mismatch, each with its own reason
headersAuthentication-Results (RFC 8601) + DKIM-Signature (RFC 6376) analysis
sieveSieve (RFC 5228) script parsing + filter → Sieve export
calendariCalendar (RFC 5545) meeting-invite parsing + METHOD:REPLY RSVP generation (Thunderbird/Lightning, Outlook, Apple Mail); VTODO · VJOURNAL · VALARM · VTIMEZONE parsing; free/busy merge; pure string handling
recurrenceRRULE expansion (FREQ/INTERVAL/COUNT/UNTIL/BYDAY) over self-contained proleptic-Gregorian date math — no chrono
addressbookvCard 3.0 ↔ 4.0 import/export; contacts; KIND:group cards; duplicate detection + merge
carddav (feature carddav)CardDAV address-book pull/push of vCards over WebDAV (ureq native-tls + quick_xml), reusing the addressbook parserincremental sync, ctag/etag
net (feature net)IMAP sync · SMTP send over one native-tls stack: UID-delta incremental fetch, folder discovery, server-side SEARCH, flag write-back, RFC 2177 IDLE, POP3 download, XOAUTH2 for IMAP + SMTP, and a stateless smtp_send_one for transactional mail
openpgp (feature openpgp)OpenPGP crypto via rPGP (pure-Rust): keygen, detached sign/verify, encrypt/decrypt over ASCII armorkey discovery, subkey management
smime (feature smime)S/MIME crypto — CMS (RFC 5652) over X.509 + RSA via RustCrypto: gen cert, sign/verify, encrypt/decrypt (PEM / base64 DER)cert chain validation, AES-GCM
errorengine Result + Error with stable machine tags for a {error:{tag,message}} FFI envelopemore granular tags
utildependency-free helpers — a standard Base64 (RFC 4648) codec for the JSON/FFI boundary
ffiC ABI: zml_init · zml_invoke · zml_set_event_callback · zml_string_freeheader generation, richer event payloads
tauri_plugin (feature tauri)Tauri v2 plugin glue for GUI hosts; the mountable view ships beside it as frontend/zemail.js (mountZemail(root))
commandsthe COMMANDS table — every dotted command Engine::invoke accepts, for automation-bus discovery; a drift-guard test fails if it falls behind invoke

The crate carries 52 source modules; the map above lists the principal ones. The remainder cover the protocol and analysis surfaces reached only through invokeimap_parse, jmap, dsn, tnef, sniff, tracking, policy, priority, schedule, querylang, quoting, listmgmt, mailmerge, mailto, forward, digest, html, addr_validate, contactphoto and crypto_mime.

Build surfaces

The crate declares crate-type = ["rlib", "staticlib", "cdylib"]. The rlib links natively into Rust/Tauri hosts; the staticlib/cdylib expose the C ABI for non-Rust hosts. The default net feature pulls in imap, native-tls and lettre; building --no-default-features yields a pure core with zero TLS/network deps that compiles in headless CI. The optional tauri feature adds the GUI plugin layer.

Verification

The crate carries 202 in-source unit tests plus 55 integration tests (tests/integration.rs) — 257 in all — across the engine and its modules: the command surface (version reporting, default-folder seeding, account add/list/remove, an import-then-filter flow, unknown-command error tagging, and a drift guard asserting COMMANDS covers every invoke arm), plus module-level tests in store, mime, search, filters, addressbook, util, gloda, junk, mailapps, threading, thread_reconstruct, quote_audit, roster_audit, sender_identity, provenance, revision_diff, tnef and tracking. Those counts are the default feature set; the carddav, openpgp and smime modules carry their own tests behind their feature flags. Tests for the pure core run without network access and are intended to pass identically in a headless Linux CI; the net module's transport is feature-gated so the default test path needs no live mail server.