Recursive AI

Fidelity and compatibility

All onemail docs

What OneMail reads and writes today, how each format is checked, and the gaps we know about. This table is updated with every preview; a gap is listed here, never hidden.

Oracles (run as released programs, black-box): MimeKit 4.18.2 (NuGet), Python 3.13.17 email and mailbox, Go 1.26.8 net/mail and mime/multipart, Python icalendar 7.3.0 and vobject 0.9.9, libpff tools 20180714. Differences between OneMail and an oracle are each mapped to an entry in ambiguities.md, a documented oracle limit or a normalisation of the comparison; "unexplained" counts the rest.

Corpora: the CMU Enron maildir (May 2015 version, 517,401 messages), Dovecot's dovecot-crlf mbox (2,859 messages by the oracles' split), Apache James Mime4j test messages (80), our generated probes, and the calendar data files listed in THIRD-PARTY-NOTICES.md. None of these is committed; tools/corpus/ fetches them by pinned URL and hash.

0.2.0-preview.1

Added since 0.1. The results of the 0.1 rows below still hold; where a 0.1 gap names something a row above now covers, the row above replaces it. Further oracles for these rows, all run as released programs: Python extract-msg 0.55.0, compressed-rtf 1.0.7, RTFDE 0.1.2.2 and tnefparse 1.4.0; tnef 1.4.18 and ytnef 2.1.2 (distribution packages); recurring-ical-events 3.8.2 and python-dateutil 2.9.0; Ical.Net 5.2.3 (NuGet, public API). Further corpora, fetched and never committed: the NIST CFReDS Data Leakage case OST, and MSG, PST and TNEF test files from Apache Tika and Apache POI (THIRD-PARTY-NOTICES.md). No Outlook has been run yet.

FormatReadWriteDifferential (unexplained / compared)Round-tripFuzzedKnown gaps
MSG / OFT (MS-OXMSG)yesno0 against extract-msg on 58 files, 15,609 properties; view fields 0 on 53 files, 690 fieldsproperty streams re-encode identical 60 / 60yestwo fuzz-minimised files from the corpus are refused by the compound file reader (typed defect); writing comes later
PST Unicode, OST (MS-PST: NDB, LTP, messaging)yesnolibpff pffexport agrees on folders, items, recipients and attachments: 0 differences on the CFReDS OST, Tika testPST and testPST_variousBodyTypes, and generated ANSI and Unicode stores (128 items); property contexts and tables read with 0 defects (3,771 + 998 + 733 properties)n/anode database, tables, messagingno public ANSI or 512-byte-page Unicode PST from Outlook exists; those layouts and 4 KiB multi-map stores are checked only on files we generate. libpff cannot read 4 KiB tables whose rows sit in a data tree, so those have no differential yet. Associated (hidden) items are read but libpff does not export them
PST ANSIyesnogenerated stores only (see above)n/ayesno real-world sample
TNEF / winmail.dat (MS-OXTNEF)yesyes0 against tnefparse, tnef and ytnef: 563 checks, 125 explainedattributes identical 17 / 17; MAPI property-exact 17 / 17yesno TNEF-in-MIME message in the public corpora; checked on generated wrappers (64 messages)
Compressed RTF (MS-OXRTFCP)yesyesdecompression identical to compressed-rtf on 45 / 45 bodies, CRC 45 / 45; our output read back by both readers 45 / 4597 exact + 1 line-endingyes\objattph attachment positions not applied
HTML and text from RTF (MS-OXRTFEX)yesencapsulation onlyagainst RTFDE on 35 bodies: only line-ending and no-break-space differences (documented)n/ayesnative RTF to HTML (non-encapsulated bodies) comes later
MAPI and MIME conversion (MS-OXCMAIL)yesyessee the conversion table below0 silent losses both waysyes
ICS recurrence and time zones (RFC 5545 3.8.5, VTIMEZONE, IANA, Windows names)yesn/a2,384 recurring components: 0 unexplained against recurring-ical-events (2,372 compared), python-dateutil (2,378) and Ical.Net (2,188); every RFC 5545 example passes; DST transitions 108 / 108 in four zonesn/ayes
Outlook calendar and task items; OLMnot yetnot yetin progress

Speed: PST/OST against XstReader.Api, MSG against MsgReader and TNEF against MimeKit all meet the bar on x64 and arm64 (geometric means 0.197 / 0.320, 0.096 / 0.101, 0.312 / 0.287; worst row 0.569). Working set stays near 100 MB (x64) from 1,000 to 50,000 messages (826 MB store). Details in benchmarks.md.

Windows

The suite also runs on win-x64. Two things behave differently there, both documented: IANA time zone names resolve through the Windows zone each maps to (CLDR), so instants before the last rule change (US dates before 2007) follow today's rules rather than IANA's (recurrence.md, Z5); and Maildir files are written with ; before the info section instead of :, which Windows file names cannot hold, while both are read everywhere (mailboxes.md, S19).

0.1.0-preview.1

FormatReadWriteDifferential (unexplained / compared)Round-trip of untouched inputFuzzedKnown gaps
MIME / EML (RFC 5322, 2045-2049, 2047, 2231, 6532)yesyes0 against each of MimeKit, Python, Go on 517,401 + 2,859 + 80 + 224 messagesbyte-identical: 517,401 / 517,401; 2,859 / 2,859; 80 / 80reader, treeambiguity resolutions are provisional until mail clients are observed
Charsets and encoded words (WHATWG encodings, UTF-7, IMAP UTF-7, ISO-2022-JP, RFC 2047/2231)yesyes0 against MimeKit (22,000 cases), Python (23,973), Go (21,412)n/ayes
Structured headers (addresses, dates, message ids, parameters)yesyesincluded in the MIME rown/avia tree
multipart/report: DSN (RFC 3464), MDN (RFC 8098), ARF (RFC 5965)yesyes0 against MimeKit and Python on 125 messages125 / 125yesno real-world reports in the corpora; checked on generated and RFC-derived fixtures
MHTML (RFC 2557)yesyes0 (same run); URL resolution 0 against Python urljoin on 218 pairsyesyes
Authentication-Results (RFC 8601), Received-SPF (RFC 7208)yesno0 against MimeKit (34 fields); Python has no parsern/ayesReceived-SPF has no oracle
mbox: mboxo, mboxrd, mboxcl, mboxcl2, Gmail Takeout labels (RFC 4155)yesyesmessage boundaries: 0 against Python and MimeKit on 17 files, 3,798 messagesrecord copy 16 / 16yesMMDF not supported
Maildir (Courier and Dovecot flags and keywords)yesyes0 against Python mailbox48 / 48via store testsCourier keyword file line format unverified against a real store; one directory listing held in memory
Outlook Express DBX (5/6)yesno0 against undbx 0.21: 2,053 real records (34 with text) in 13 folders, 3,512 generated messages in 12 foldersn/adbxone real store (a Windows XP laptop image, 28 files); OE4 files and deleted messages are not read
EMLX and Apple Mail .mbox bundlesyesyesground truth 14 / 1414 / 14yesflag bits unverified against a real Apple Mail store
ICS (RFC 5545, 5546, 7986), vCard 2.1 / 3.0 / 4.0yes (content lines, component trees, typed views; contacts below)yessee calendar.md1,372 / 1,372yesrecurrence expansion, time zones and j/x forms come later
The shared read view, Mail.Open, Mail.Parse, format sniffingyesn/aagrees with the tree on 8,566 messages; attachment lists agree with Python except documented choices (V1-V8)n/ayesMSG, PST, DBX and OLM items not in the view yet
PST / OST node database (MS-PST NDB)yes (lower layer only)noNIST CFReDS OST: every node and block enumerates, header agrees with libpffn/ayesno messages from PST yet; ANSI and 512-byte-page Unicode PSTs untested on real files (no public sample)
MSG/OFT, TNEF, OLM, compressed RTFnot yetnot yetplanned

Contacts (vCard typed view, Outlook contacts, MS-OXVCARD)

Method and rules: contacts.md. No Outlook has been run. The corpus has two contact items (Tika and POI MSG, the same contact) and no Outlook contact PST, so the MS-OXOCNTC properties are covered by 56 generated contacts and 8 lists (ContactTool gen, seed 20261031). Oracles run black-box: vobject 0.9.9, FolkerKinzel.VCards 8.2.0 (public API), extract-msg 0.55.0.

CheckAgainstResult
vCard typed view, fetched corpus (28 .vcf)vobject / FolkerKinzel.VCardsvobject: 25 compared (3 it cannot parse), 365 agree, 17 explained, 0 unexplained; FolkerKinzel: 28 compared, 417 agree, 37 explained, 0 unexplained
vCard typed view, generated 2.1/3.0/4.0 (60) + RFC examples + hand fixtures (86 files)vobject / FolkerKinzel.VCardsvobject: 83 compared, 998 agree, 31 explained, 0; FolkerKinzel: 86, 909 agree, 81 explained, 0
vCards we produce (132 files from the 2 real and 64 generated items, 3.0 and 4.0)vobject / FolkerKinzel.VCardsboth parse all 132; vobject 2,393 agree, 17 explained, 0 unexplained; FolkerKinzel 2,204 agree, 254 explained, 0
Contact fields (2 real + 56 generated MSG)extract-msg58 contacts, 4,408 field checks, 0 differences
Contact to vCard to contact (3.0 / 4.0)every property exact, derived or in the loss reportreal (2): 44 / 42 exact, 168 / 170 reported, 16 derived, 0 mismatch, 0 silent; generated (56): 2,016 / 2,002 exact, 713 / 717 reported, 103 / 113 derived, 0 mismatch, 0 silent
vCard to contact to vCard (138 cards)every card property carried or reported; contact stable on a second round1,311 carried, 0 not carried and not reported; 137 / 138 stable (the one: a card without FN gets one composed from N)
Byte-identical round trip of untouched vCardsthe content-line tree28 + 86 corpus and generated files and 132 produced cards: all byte-identical
Fuzz vcard-view600 s, Checked build5,049,889 executions, 0 findings

Gaps: no Outlook-produced contact PST or MSG with the full property set, and no Outlook import/export of vCards to compare against (the Outlook oracle, before 0.5). The slot order of telephone numbers and email addresses is approximated by a vCard and reported (PhoneSlotChanged, EmailSlotChanged).

MS-OXCMAIL conversions (MAPI to MIME and back)

Checked on the 45 Tika and POI MSG files and the 25 Tika and CFReDS PST/OST items that are mail, and on message files for the other direction. Method and rules: conversion.md. No Outlook has been run; the oracles are MimeKit 4.18.2 and Python 3.13.17 email, black-box.

DirectionChecked againstResultKnown gaps
MAPI to MIME (EML)OneMail, MimeKit and Python read each exported EML; subject, From, To, Cc, Date, Message-ID, text and HTML body hashes, attachment names, sizes and SHA-256 compared with the source item's70 / 70 items parse with no defect the received headers did not already have; 0 unexplained differences in 630 fields per oracle (MSG 405 + PST 225); one field in MimeKit differs for a received Subject that uses the charset label Cp1251 (listed in tools/oxcmail/explained.tsv; Python and OneMail agree with the source)EX addresses with no SMTP form in the item are left out and reported (30 AddressUnresolved entries over the 70 items); Bcc is not written by default
MAPI to MIME to MAPIevery property of the source: exact, same text under another string type, or in the loss report11,142 properties: 6,406 exact, 446 same text, 4,290 reported, 0 silentPidTagTransportMessageHeaders is rewritten (reported)
MIME to MAPI to MIMEten fields before and after (subject, From, To, Cc, Date, ids, bodies, attachments) on Mime4j 80, Dovecot 1,430, Enron sample 5,032 messages65,420 fields: 65,392 equal, 28 differ and each has a loss entry, 0 silentBcc dropped on the way out (reported); display-name spelling of a kept received header
The viewMapiMailItem senders and recipientsall 50 EX recipients and 16 of 28 EX senders resolve to SMTP with the X.500 address kept; the other 12 senders (all in the MSG set) have no SMTP form; a further 9 PST senders have no address at allno directory lookup

Speed

MIME rows against MimeKit 4.18.2: see benchmarks.md (geometric mean of the OneMail/MimeKit time ratio 0.091 on x64 and 0.093 on arm64; worst row 0.584).