Ligne actuelle : v0.30 (2026)
Début octobre- La fédération entre organisations, servie de bout en bout (ADR-124 Am. 8 et 9) : un appairage enregistre désormais comment joindre le pair.
oximail federation pairprend son point d’accès (--endpoint), ses épingles TLS (--tls-pin) et, pour un tunnel que vous avez posé vous-même, une adresse privée littérale (--address), et n’épingle qu’une fois confirmée l’empreinte de transport que l’autre administrateur a lue à voix haute (--transport-fingerprint). Le point d’accès et les épingles de ce nœud se déclarent dans une nouvelle section[federation], dont la porte est fermée par défaut. Chaque requête fédérée est signée selon le profil RFC 9421 du brouillon de fédération : elle nomme les deux realms, porte son nonce et le certificat de la clé de travail, et se vérifie sur ses champs d’en-tête avant que son contenu soit lu. Un pair se trouve par son propre enregistrement_jmap-federation._tcp, jamais par le_jmap._tcpdes clients, et seulement si cet enregistrement est signé par DNSSEC ; l’assistant le publie une fois la fédération activée (fédération). - Ce qu’une organisation appairée peut lire (ADR-168) : chercher un créneau avec quelqu’un d’une organisation appairée lit ses heures occupées sur son propre serveur.
Event/proposeTimesinterroge le pair qui sert le domaine du participant et n’utilise la réponse qu’une fois sa signature vérifiée ; un pair muet pendant quatre secondes place le participant dansunreachableEmails, jamais en « libre ». Le serveur qui répond donne des plages occupées fusionnées, jamais un événement, et enregistre une divulgation par personne avant de répondre. L’opérateur peut partager un dossier ou un fichier du Drive, en lecture, avec une organisation appairée (oximail federation shares add,list,remove, simulation par défaut) ; la racine d’un Drive est refusée, si bien qu’un partage n’ouvre jamais un Drive entier. Le pair le lit par la porte de fédération, borné au sous-arbre partagé, le contenu en blocs signés de 1 Mio, sous un budget par classe et par appairage ; un partage retiré est journalisé et poussé au lecteur. Côté lecteur, un compte miroir (oximail federation mirror add) montre ces dossiers dans son Drive : la copie vit dans la mémoire du serveur seulement, jamais dans la base ni sur le disque de ce nœud, n’a jamais plus demirror_staleness_secs(120 s), refuse toute écriture parmirror-read-only, et montre un fichier d’état nommé plutôt qu’un dossier vide tant que le propriétaire est injoignable. Un fichier miroir se télécharge bloc par bloc chez le propriétaire, derrière un cache en mémoire qui ne touche jamais le disque (content_cache_secs,content_cache_mib,content_cache_file_mib) (fédération, partage). - Une identité de fédération qui survit à une restauration ou à une clé papier perdue (ADR-127 Am. 5 à 7) : un pair qui réémet une époque sous une autre clé est refusé ; une nouvelle clé de travail prend une époque supérieure à la fois à la précédente et à l’horloge, si bien qu’une boîte restaurée depuis une base plus ancienne ne réutilise jamais une époque que ses pairs ont vue ; la clé papier d’une racine retirée n’ouvre plus rien, et
oximail federation roots retireefface son séquestre. Une identité dont la chaîne ne se vérifie plus se recertifie avec la clé papier d’une racine sœur enrôlée (oximail federation working-key repair), etoximail federation roots deleteen abandonne une volontairement, après quoi chaque pair refait l’appairage. La juridiction de fédération d’un locataire est son pays d’établissement déclaré :oximail federation identityla lit à voix haute à côté des empreintes, un appairage enregistre ce qui a été déclaré à chaque pair, etdoctorsignale un pays changé depuis (fédération). - La recherche plein texte dit vrai (ADR-167) : un index qu’on ne peut pas ouvrir n’est plus un repli silencieux.
doctorle nomme,oximail_search_index_statele publie, etEmail/querydéclare une réponse donnée sans lui (fullTextIndexUnavailable). Après une mise à jour, l’index se reconstruit seul sur sa propre tâche, servi en entier pendant ce temps, etoximail reindexle reconstruit serveur arrêté, environ huit fois plus vite qu’avant. L’index tient désormais à part le sujet, les adresses From, To et Cc et le corps :bodycherche dans le corps seul,textdans les cinq, et un mot du sujet ou de l’expéditeur pèse davantage. Au-delà de 10 000 messages trouvés, un total est un vrai compte et non le plafond, une liste triée par date contient chaque résultat, et un mot exclu ou un OR s’évalue exactement. Un mot pris dans un filtre AND, OR ou NOT se cherche dans l’index et non plus dans l’aperçu de 256 caractères, etSEARCH BODYetSEARCH TEXTen IMAP passent par le même index : Thunderbird, Apple Mail et Outlook trouvent un mot n’importe où dans le corps. Une recherche de ponctuation ne renvoie plus toute la boîte, le surlignage marque le mot trouvé (reunionmarqueRéunion), et une note détruite quitte l’index même quand l’index était fermé à ce moment (courrier, exploitation). - Un MX de secours jugé sur le vrai client (ADR-166) : le courrier relayé par un MX de secours est désormais jugé sur l’adresse du client que le secours a servi, avec SPF, DMARC et DNSBL appliqués comme pour un client direct. Le primaire reconnaît ses secours d’après les enregistrements MX de ses propres domaines, sans réglage, et n’en traite jamais un comme un pair de confiance ; le secours écrit sa propre ligne
Receivedavant de relayer, comme l’exige la RFC 5321, si bien que le primaire peut lire cette adresse. L’assistant du MX de secours ne génère ni ne publie plus de clé DKIM pour le domaine (avec un jeton Cloudflare, il pouvait remplacer la clé du primaire et casser ses signatures), ni d’enregistrements SRV clients, etdoctorne demande plus à un secours le SPF et le DKIM du domaine. La ligne de journal d’un message accepté nomme le client sur lequel il a été jugé et les verdicts SPF, DKIM et DMARC (courrier et SMTP, anti-spam). - Un DNS auquel la boîte peut se fier et qu’elle peut republier (ADR-165) : le serveur résout par le résolveur validant local et ne croit une réponse DNSSEC qu’une fois ce résolveur prouvé par une sonde (
oximail resolver check). Un déploiement refuse une boîte non prouvée, et les livraisons DANE attendent plutôt que de partir sans authentification (oximail dane suspendlève cette règle pour une durée bornée). La configuration du résolveur ne nie plus pendant une demi-heure un enregistrement tout juste publié (oximail resolver ensure --applyréécrit une ancienne configuration), et l’assistant vide le cache local après publication.oximail setup dnsrelancé lit d’abord la zone et ne double jamais un enregistrement (un second TXT_mta-stslaissait le domaine sans politique MTA-STS), tourne sans terminal (--replace-spf,--replace-dmarc,--public-ipv4), et trouve la zone Cloudflare d’un sous-domaine délégué.doctorcontrôle chaque domaine de courrier par rapport au vrai nom d’hôte (oximail check-dns --hostname), et une DNSBL qui refuse ou ne sait pas répondre n’est plus lue comme « non listé » (installation, exploitation). - Connexion, bannissements et appareils (ADR-031 Am. 1) : un bureau derrière une seule adresse n’est plus banni à cause d’un invité ou d’un téléphone resté sur un ancien mot de passe. fail2ban bannit une adresse quand cinq identifiants différents y échouent en quinze minutes, comptés à part pour le courrier, le web et la fédération ; un identifiant qui s’est connecté depuis là dans les 30 derniers jours, ou le même mauvais mot de passe retenté, ne compte pas. L’IPv6 se compte par /64, les bannissements répétés montent d’une heure à un jour, un jeton valide fonctionne encore depuis une adresse bannie, et
oximail ban listmontre la classe et la raison. Un nouveau mot de passe d’application se vérifie en une lecture et un HMAC au lieu de cinq hachages Argon2, et les anciens continuent de fonctionner. Un client de messagerie sur mot de passe d’application voit de nouveau les boîtes partagées avec son utilisateur, et chaque ligne de connexion IMAP, SMTP, CalDAV et CardDAV nomme l’identifiant et l’adresse du client, si bien qu’un administrateur distingue un appareil d’un autre. Le profil Apple, l’autoconfig Mozilla et l’Autodiscover Microsoft échappent toute valeur qu’ils écrivent au lieu de recopier la requête dans leur XML (anti-spam, protocoles historiques). - Une clé privée gardée sur le serveur, jamais lisible par lui : le titulaire d’un compte personnel peut garder une copie de sa clé privée OpenPGP ou S/MIME déjà protégée par sa phrase de passe (
PrivateKeyEnvelope/get,PrivateKeyEnvelope/set,PrivateKeyEnvelope/changes). Le serveur en refuse une en clair, ne la déchiffre jamais, et ne la révèle, ne la remplace ou ne la supprime qu’après une connexion récente de la session. Une preuve manquante répondstepUpRequired, si bien qu’un client distingue un refus qui se corrige d’un refus définitif. Un compte sans passkey reprouve son mot de passe sur la session ouverte (POST /auth/password/reauth) au lieu de se reconnecter, et un mot de passe ne vaut jamais preuve de passkey (courrier). - Chat et appels : un appel laisse sa trace dans son salon, un message d’appel par session (audio ou vidéo, durée, qui a répondu, manqué, refusé), non lu seulement pour qui l’a manqué.
ChatRoom.lastMessageCallpermet à une liste de salons d’écrire « appel manqué » sans charger de message, et l’appelant lit qui n’a pas répondu (MeetSession.missed). Une personne peut trouver les salons où elle peut demander à entrer (ChatRoomDirectory/getetChatRoomDirectory/query, annoncés parroomDirectorydans la capacité chat), avec leur nom, leur description et leur nombre de membres seulement.ChatMessage/querylit une ancre comme le dit la RFC 8620 (anchorNotFound), un fil lu depuis une ancre ne liste que ce fil, et une recherche répond le total demandé (chat, Meet). - Des connexions qui se terminent proprement : à un redémarrage, les écoutes SMTP, IMAP et HTTPS cessent d’accepter, une session inactive reçoit
421 4.3.2ou* BYE [UNAVAILABLE], une session en pleine transaction la termine, et l’arrêt nomme les tâches qu’il attendait encore. La limite SMTP de cinq minutes devient une limite d’inactivité, réarmée à chaque commande (421 4.4.2pour un pair muet, une heure au plus par session). Chaque connexion acceptée désactive Nagle, ce qui retire 40 ms à chaque commande IMAP sur une boîte sans proxy. Le serveur sonde chaque WebSocket et ferme celle qui ne répond plus, si bien qu’un téléphone en veille retrouve son Web Push, et un patch de push ditnullquand une propriété est vidée (exploitation). - Observabilité : où passe le temps d’une écriture (attente du verrou SQLite, verrou tenu,
COMMIT, écritures hors transaction), la latence IMAP par commande et par résultat, le délai SMTP après les données par écoute et par classe de réponse, la barrière de durabilité, les push retenus, les réponses DNSBL par nature et la confiance dans le résolveur sont des séries Prometheus aux libellés fermés, jamais une adresse ni un compte. Un administrateur voit, pour chaque appareil d’un compte, s’il a un abonnement push vivant et quand son service de push a accepté une notification pour la dernière fois, jamais l’URL du point d’accès (exploitation). - Et aussi : un nom que Windows réserve (
CON,NUL,aux.txtet autres) est refusé dans le Drive à la création et au renommage, puisque le partage SMB le servait et que l’Explorateur ne pouvait ensuite ni l’ouvrir ni le supprimer ; l’autocomplétion d’adresse cherche d’abord dans le pays du locataire ; la fin d’une installation dit comment un appareil reçoit ses réglages.
- Des sauvegardes pour une boîte sans hyperviseur :
oximail backup --toécrit un dépôt incrémental chiffré par age, que la boîte peut écrire mais jamais lire, et qui se restaure avec le seul outilage. Dans un buckets3://, il exige l’Object Lock et refuse une clé qui pourrait supprimer ou lire (un bucket en mode GOVERNANCE reçoit un avertissement). Une exécution peut être bornée en débit et en durée, envoie les gros objets par parties et date ses instantanés à l’horloge du dépôt, et une vérification complète laisse un reçu daté quedoctorlit.oximail account import --from-backupramène un compte à côté de ce qu’il contient, notes comprises, etoximail chat restore-room --from-backupaccepte un dépôt. Un plan de sauvegarde que rien n’a jamais confirmé est un avertissement, plus un vert. Après une restauration, les clés DKIM déléguées sont remplacées, et les clients IMAP se resynchronisent au lieu d’attacher un UID réutilisé à un autre message (exploitation). - Un effacement qu’une restauration ne défait pas : chaque effacement achevé est inscrit dans un registre qui voyage avec les sauvegardes ; une personne qu’une restauration a ramenée est gelée, et
oximail erasure replayl’efface de nouveau. Les copies de son courrier que conserve la conservation légale d’un collègue restent telles quelles et sont caviardées quand elle prend fin, et la fermeture d’un compte retire sa fiche de l’annuaire des personnes et de chaque carnet d’adresses (conformité). - Le filtrage, c’est Rules seulement, appliqué à la remise : les filtres de courrier sont des Rules typées (déplacement par boîte ou par rôle, mots-clés, en-têtes nommés, comparateurs). Les méthodes SieveScript, la capacité JMAP Sieve et ManageSieve sont retirées, et les scripts actifs stockés sont importés en Rules au démarrage. Les règles répondent automatiquement et la réponse d’absence est envoyée ; une règle en échec laisse le message dans la boîte de réception ; une règle dont la cible est détruite devient inerte ; les notifications s’arrêtent à trente par heure et par compte.
Rule/testteste une règle non enregistrée ou l’ensemble,Rule/applynomme ses messages et figure dans la piste d’audit, et sa borne par appel est[rules] max_apply_emails_per_call(règles). - Le transfert gardé comme un identifiant, et vérifié (ADR-162, ADR-163) : poser un transfert exige une preuve de passkey récente quand le compte a une passkey, et se refuse avec un mot de passe d’application. Un mot de passe réinitialisé par un administrateur désactive toutes les règles de transfert et annule les copies encore en file, et chaque transfert posé ou retiré figure dans la piste d’audit sous une empreinte de l’adresse. Avec
[rules] forward_policy = "verified", une règle ne transfère qu’à une adresse dont le titulaire l’a confirmée : le compte demande parForwardConfirmation/set, le titulaire reçoit un code valable sept jours, etForwardConfirmation/confirmouvre la destination. Le message du code nomme le responsable du traitement, les pays où l’adresse est traitée, à qui écrire et comment rendre le code ; une demande restée sans réponse est effacée à l’expiration de son code, et l’opérateur peut retirer et bloquer une adresse à la demande de son titulaire (règles). - Qui est responsable, déclaré (ADR-164) : un locataire déclare sa nature, sa raison sociale, son adresse, son pays d’établissement et des contacts typés (
oximail tenant identity set,legalIdentitysurTenant/set) ; l’instance déclare qui l’exploite et où les données sont traitées (oximail admin instance identity set, à la console seulement). Un champ laissé vide hérite de celui de l’instance, etdoctor legal_identitynomme les champs manquants, jamais leurs valeurs. Les textes envoyés aux tiers nomment ce responsable, et un opérateur peut installer une variante nationale qui ajoute, après le texte mondial, les paragraphes citant sa loi ; aucune n’est livrée tant qu’un praticien n’en a pas validé une. Les comptes reçoivent la langue par défaut du locataire (multi-tenant, conformité). - Les clients JMAP standard reçoivent ce que promettent les RFC : une création répond les propriétés que le serveur a posées (valeurs par défaut, valeurs calculées, adresses normalisées) sur tous les types, comme le demande la RFC 8620 §5.3, et un objet entier reçu de
Foo/getest un patch de mise à jour valide.Email/getsert les en-têtes dans l’ordre du message etheader:<Name>sous les sept formes de la RFC 8621, ettextBodyethtmlBodysuivent le §4.1.4.EmailSubmission/setenvoie un brouillon créé par un client standard et répond des refus typés ;Thread/changessignale les conversations créées et détruites. Une requête peut ranger un message dans une boîte créée plus tôt dans la même requête (#creationId) ou modifier un enregistrement par sa référence de création ;alreadyExistsnomme l’enregistrement existant (existingId) ; une méthode hors deusingrépondunknownMethod. Chaque capacité propre à OxiMail est servie sous son URN et sous son URL (https://oximail.ch/jmap/<name>), et une collection restée sans changement pendant 90 jours garde son état au lieu de répondrecannotCalculateChangespour toujours (cœur JMAP, courrier). - Conformité IMAP, CalDAV et CardDAV (mesurée avec imaptest et de vrais clients) :
\Draftest un drapeau permanent, les clients IMAP4rev1 voient\Recent,LISTsuit LIST-EXTENDED etCREATEn’abonne plus.SORTsuit les RFC 5256 et 5957,THREADne garde plus un parent que les propresReferencesd’un message contredisent,APPENDgarde sa date, les changements de drapeaux et les suppressions d’une autre session atteignentNOOP, etENVELOPEécrit les groupes d’adresses comme l’en-tête les écrivait. Le sujet, l’adresse ou le nom de fichier d’un expéditeur ne peuvent plus écrire une réponse IMAP à eux, une ligne de commande a un plafond, et IMAP tient au plus 20 connexions par compte et par adresse. Les clients d’agenda peuvent renommer et recolorer un agenda ou une liste de tâches, les requêtes CalDAV et CardDAV respectent le composant, la collation, la limite, les en-têtes conditionnels et la profondeur, un événement récurrent sans fin reste au-delà de sa première année, et une suppression atteint les autres appareils (protocoles historiques). - SMTP, DMARC, ARC et MTA-STS, refermés :
DATAne se termine qu’à<CRLF>.<CRLF>, si bien qu’une transaction porte un seul message ; la porte entrante répond comme le dit la RFC 5321, etpostmaster@etabuse@atteignent le locataire sur chacun de ses domaines. UnFrom:falsifié ne passe plus DMARC et un message sans auteur unique est refusé ; les signaturesc=simplese vérifient, un domaine à exactement dix termes SPF passe, et une signature dont lel=laisse une partie du corps non signée vautdkim=policy. L’exception ARC à DMARC n’honore que les scelleurs nommés dans[spam] arc_trusted_sealers, vide par défaut, si bien qu’un message ne peut plus se cautionner lui-même avec une chaîne qu’il a scellée. MTA-STS ne fait correspondre un motif générique qu’à un label entier. Une recherche DANE en échec ne peut plus revenir en « pas de TLSA » par la liste de recherche de l’hôte, et la mise à jour de la bibliothèque DNS permet de nouveau la validation des domaines sous un TLD signé en RSASHA1-NSEC3-SHA1. Les ports de courrier refusent un client TLS qui demande un autre protocole et coupent une session après trois commandes inconnues avant authentification, et chaque écoute borne une poignée de main TLS à 10 secondes. Derrière un proxy inverse local, OxiMail peut servir le HTTP sur une socket Unix que seul le groupe du proxy peut ouvrir ([server] bind = "unix:<path>"). Un message envoyé depuis un client de messagerie ne révèle plus à ses destinataires le nom et l’adresse du poste de travail (courrier et SMTP, authentification du courrier). - Des comptes sous attaque : une passkey ne peut plus s’enrôler depuis un mot de passe d’application ou un mot de passe seul, les actes sensibles exigent une preuve de passkey des dix dernières minutes, et un mot de passe réinitialisé par un administrateur ferme tous les mots de passe d’application et toutes les passkeys du compte. Un compte attaqué est ralenti sur tous les protocoles, jamais verrouillé, et un client CalDAV ou CardDAV ne coûte plus six hachages de mot de passe par requête. Un appel composé dans un autre (
Core/queryStream, les patchs de push) passe la garde des comptes partagés et laisse sa ligne dans le journal des accès. Les secrets gardés sous la clé du locataire sont scellés, liés à leur champ et à leur ligne. L’annuaire de clés ne sert jamais une clé OpenPGP révoquée ou expirée, et OpenPGP passe à rPGP 0.20, qui borne la décompression d’un message importé. Un client de chat ne peut plus forger la réaction d’un autre membre ni cacher qu’un message a été modifié (conformité). - L’envoi à grande échelle (ADR-157) : le courrier sortant attend dans trois classes, si bien que le message d’une personne part avant une campagne en cours, même vers le même hôte, et le répartiteur fait tourner les 16 créneaux de remise prévus au lieu de 4. Un compte peut porter des flux d’envoi (
oximail account flow create), chacun pouvant partir de sa propre adresse ([[smtp.egress_pool]],oximail account flow set-pool), jugés par un objet d’admission unique qui tourne pour l’instant en observation (doctorcompte les jours où il est d’accord). Le relais signe le courrier d’un client avec le propre domaine du client (oximail account signing-domain add, deux CNAME à publier), et répond aux exigences des grands fournisseurs envers les expéditeurs : les plaintes comptent contre le flux qui a envoyé, un flux se met en pause à 0,3 % de plaintes, le courrier de masse exige un désabonnement en un clic signé et un domaine doté de DMARC, et le courrier d’origine porte unFeedback-ID. La preuve d’un domaine d’envoi appartient au propre domaine du locataire, et le courrier sortant part en IPv4 dès que la destination en a une. Un250après les données signifie désormais que le message survit à une coupure de courant : une barrière de durabilité s’exécute avant lui sur les portes nommées dans[storage] durable_doors(relais sortant, envoi de masse). - Les pièces jointes dangereuses, observées d’abord (ADR-155) : exécutables, images disque, extensions listées, macros et archives illisibles peuvent être refusés avant le
250, sur le port 25, dans la file du MX de secours et à la soumission, et la même politique couvre le courrier du client web, les pièces jointes du chat et les téléversements ; les imports et l’APPENDIMAP sont tracés, jamais refusés. Les anciens documents Office, les messages Outlook etwinmail.datsont lus, et un fichier du Drive dont le contenu est un exécutable est servi enapplication/octet-stream. Une nouvelle boîte observe et compte avant qu’aucune règle ne soit armée (politique des pièces jointes). - Courrier, notifications et octrois : un message chiffré porte le mot-clé
$encrypted(oximail email backfill-encryptedmarque ceux déjà stockés) et ne déclare plus un statut S/MIME « unknown ». Un aperçu est le texte du message, sans les annotations de liens ni les marqueurs d’images qu’un convertisseur y avait écrits (oximail email reindex-bump --link-previewrecalcule ceux qui sont stockés), etSenderBrand/getdonne le logo vérifié d’une adresse sans aucune requête sortante. Une notification de nouveau message dit si l’expéditeur est un collègue, un contact ou un inconnu, si le message est un envoi de masse et s’il répond à l’un de vos messages ; « Plus tard » sur une alerte la fait sonner de nouveau, une fois, à l’heure choisie ; un appel entrant peut être refusé et sonne 45 secondes sur un appareil dont l’appli est fermée. Un octroi de compte (oximail account grant) ouvre désormais chaque objet de sa collection à son niveau, y compris ceux créés après lui, et ne partage ni n’administre jamais (courrier, CLI).
- Les signatures S/MIME reçues sont vérifiées (ADR-156) : la RFC 9219 telle qu’écrite, sous
urn:ietf:params:jmap:smimeverify, avecsmimeStatus,smimeStatusAtDelivery,smimeErrors,smimeVerifiedAtet trois filtres. Les deux verdicts sont stockés et réévalués à leurs échéances (fin du chemin de certificats, prochaine CRL), si bien qu’une expiration ou une révocation atteintEmail/changes. La révocation se contrôle par CRL, jamais par OCSP. Le magasin de confiance est celui des racines « email » de Mozilla plus les intermédiaires du CCADB, et le détail du signataire estsmimeSignersousv2:mail. Le serveur ne déchiffre jamais : un message chiffré se vérifie côté client. Le courrier stocké avant la fonction se marque paroximail smime backfill(messages signés, côté opérateur). - Les clés OpenPGP trouvées par le serveur :
RecipientKey/lookupessaie le WKD du domaine du destinataire, puis le serveur de clés, et distingue « introuvable » de « injoignable » ;PgpKey/publishpublie sa propre clé. Annoncé sousrecipientkeyset réglable dans[pgp_directory], il suit la règle selon laquelle le navigateur ne parle qu’à sa propre origine (clés OpenPGP). - Un DANE qui tient dans la durée : un renouvellement ACME garde la clé TLS, si bien que l’épingle
3 1 1ne bouge plus tous les 60 à 90 jours.oximail dane rotatechange la clé volontairement, en publiant l’épingle suivante avant la bascule. Les enregistrements TLSA peuvent se publier sur votre propre DNS par mise à jour dynamique RFC 2136 (TSIG). Les épingles ne couvrent que les ports SMTP (un MX de secours n’épingle que le port 25), et la clé que sert réellement chaque port épinglé se lit sur le fil, pardoctoret par une sonde horaire. Un renouvellement raté garde en service le certificat encore valide au lieu de le remplacer par un auto-signé. Le démarrage refuse un résolveur incapable de prouver une non-existence, et une réponse TLSA invérifiable rend la destination injoignable plutôt que « sans DANE ». Les boîtes qui terminent elles-mêmes le TLS offrent HTTP/2 (TLS et ACME, enregistrements DANE). - L’envoi, les défauts qu’une revue du relais a trouvés : un domaine relais ou d’expéditeur d’enveloppe dont la preuve DNS a été suspendue, ou n’a pas été confirmée depuis 72 heures, diffère désormais en
451 4.7.1au lieu d’autoriser pour toujours ou de rebondir, etdoctor sender_domain_proofsle surveille. Une soumission sansDate:niMessage-ID:en reçoit un du serveur, et un deuxièmeFrom:est refusé et jamais signé. Un domaineFrom:internationalisé est signé par sa clé. Un message qu’une règle fait suivre n’est signé par la clé d’un domaine hébergé que si son auteur a été authentifié. La vérification DKIM entrante est bornée (8 signatures, 30 secondes). Un rapport de rebond porte de nouveau leMessage-IDd’origine, si bien que les outils de traitement des rebonds peuvent le rattacher. Un rapport de remise qui ne vient pas de l’expéditeur nul ne change rien (courrier et SMTP, relais sortant). ADR-157 dit où cela mène : boîtes et relais sur un seul serveur, la décision d’envoi prise à l’admission. C’est un design, et seuls ses premiers lots de défauts sont servis. - Le départ d’un collaborateur, depuis la surface d’administration : suspendre, envoyer son courrier à un collègue jusqu’à une date, et donner à ce collègue la lecture de la boîte (
Principal/setAdmin {forwardTo, forwardUntil, mailboxGrantTo, grantUntil}). Poser le mot de passe de quelqu’un derrière un second facteur strict (Principal/setPasswordAdmin), voir et couper une session d’appareil ou un mot de passe d’application d’un autre compte, et suivre une demande d’effacement jusqu’à son enregistrement d’achèvement (ErasureJob/queryAdmin). Chaque acte est journalisé sous son sujet (API d’administration). - La santé de la boîte, lisible en JMAP (ADR-154) : un minuteur enregistre la ronde
doctortoutes les 15 minutes, etHealthReport/queryetHealthReport/getla servent. Sur une boîte à un seul locataire, l’administrateur du locataire la lit ; sur une boîte à plusieurs locataires, seul un opérateur d’instance la lit, un rôle posé à la console seulement (oximail admin instance grant) sur un administrateur doté d’un second facteur.doctor --jsondonne à chaque contrôle sa famille, ses faits datés et, sur un avertissement, le verbe à taper (l’opérateur d’instance, la ronde doctor). - Organisations, comptes et identifiants : un administrateur déclare quels groupes sont les entités de l’organisation, les employeurs qu’une fiche de profil peut citer (
isEntity,oximail admin organization create,set-entity,list,set). Un compte de service se déclare, il ne se déduit jamais, et ses octrois ne portent pas d’échéance. Un mot de passe d’application peut être en lecture seule : JMAP seulement, toute écriture répondantaccountReadOnly. Un mot de passe d’applicationmailpeut envoyer par JMAP comme il le faisait déjà par SMTP.GET /healthne compte que l’organisation de l’appelant, et la suppression d’une organisation est refusée tant qu’elle porte un compte ou un blob (multi-tenant). - L’assistant d’installation finit le travail : en plein écran sur un terminal capable, il mesure l’hôte, demande comment la boîte sera sauvegardée (un snapshot de l’hyperviseur confirmé par
oximail backup mark, ou unoximail backupplanifié), mène la cérémonie de la clé de récupération (montrée une fois, retapée, l’exercice enregistré ;oximail key escrow --guidedsur une boîte existante), crée le jeton/metrics, surveille l’IP d’envoi sur les listes de blocage et termine par une ronde d’accessibilité. L’escrow porte désormais aussi le secret d’instance, si bien qu’une boîte restaurée sur un nouveau matériel reste la même boîte. La télémétrie communautaire (ADR-153) demande d’abord, sans valeur par défaut, et une boîte sans réponse n’envoie rien ;oximail telemetry enable,disable,statusetpurgela changent ou l’inspectent (premier démarrage, télémétrie). - Configuration : les secrets SRS et TURN ont quitté le TOML pour des fichiers (
secret_key_file,turn_shared_secret_file;oximail config externalize-secretsles déplace). Chaque organisation a ses propres surcharges par/admin/v1/tenants/{id}/config, etoximail config set-overriderefuse ce que cette route refuse. Le budget sortant se règle par compte. Les six corbeilles (Drive, agenda, contacts, tâches, notes, chat) ont une rétention par organisation (configuration). - Les logos de marque des expéditeurs externes (BIMI) : affichés quand le serveur a vérifié le certificat de marque de l’expéditeur, avec
brandMarkTypequi distingue une marque enregistrée (VMC) d’une marque d’usage (CMC). UnBIMI-Selectorsigné par DKIM est honoré, etoximail bimi backfilldonne leur logo aux messages déjà en boîte (configuration). - Chat : le corps d’un message ou d’un salon est
content;encryptedContentn’est plus ni servi ni accepté. La transcription d’un message vocal est calculée une fois par le serveur (ChatMessage/transcribe,[chat] transcript_policy). Les fils se suivent explicitement et une réponse ne notifie que les suiveurs. La préférence de notification d’un salon est appliquée par le serveur, donc aussi au push d’une appli fermée. Les accusés de lecture peuvent se couper, réciproquement. Une écriture ne peut citer qu’un fichier que son auteur peut lire (chat). - Courrier et recherche : un mot se trouve par son début, et un tri par pertinence fait passer un mot présent dans le sujet ou l’expéditeur, et le courrier récent, devant les vieilles notifications qui le répètent. Le corps d’un message joint arrive dans la même réponse (
viaMessagePartId),Email/setacceptebodyStructureà la création, et un caractère de contrôle dans une adresse ou un sujet est l’erreur du client (invalidProperties), sur le courrier comme sur les contacts.oximail email normalize-received-atrépare les dates qu’un ancien import avait stockées au mauvais format (courrier). - Agenda : une seule forme de récurrence, l’objet RFC 8984 d’un profil fermé, une règle par événement ou tâche, avec les règles d’exclusion appliquées et les règles mensuelles et annuelles développées comme le dit la RFC 5545.
DTENDdevient la durée sur toutes les portes et revient inchangé en CalDAV. La disponibilité dit quand elle n’a pas pu tout voir (complete,incompleteForsurEvent/proposeTimes), et la page de réservation n’offre aucun créneau sur une telle personne. Un message iTIP entrant n’est appliqué que par quelqu’un qui a autorité sur l’événement (agenda). - Chaque type déclare ce qu’on peut y écrire : une propriété inconnue est refusée par son nom avant le gestionnaire, sur tous les types de la surface (JMAP v2). Chaque écriture enregistre son entrée de journal des changements dans sa propre transaction, si bien qu’un échec annule les deux au lieu de laisser un changement qu’aucun client de synchronisation ne verra jamais.
- Un agenda partagé ne laisse plus fuir ce que la confidentialité cache (ADR-152) : le partage réduisait déjà ce qu’un collègue reçoit d’un événement
privateet ne servait rien d’unsecret, mais la recherche regardait toujours le contenu réel : un filtre sur le titre répondait oui ou non, et une borne de temps révélait les créneauxsecret. « Ce que ce lecteur peut voir » se déclare désormais une fois et se rend deux fois, en prédicat SQL pour les surfaces qui rendent des identifiants et en réduction pour celles qui rendent des objets, liés par un test d’accord : unsecretn’apparaît dans aucun résultat, aucuntotal, aucune page ; unprivatereste visible par le temps ou le calendrier et sort du jeu dès qu’un filtre de contenu est posé ; le propriétaire ne perd rien. La même règle atteint les neuf sites de rapport CalDAV, et le journal des accès porte désormais deux nombres par lecture, combien d’événements ont été servis réduits à leur créneau et combien ont été retirés, absents plutôt qu’à zéro quand rien n’a été jugé. - Les quotas de stockage tels que livrés (ADR-151) : deux quotas par personne, courrier 50 Gio et Drive 1 Tio par défaut, aucun pour un compte partagé, une boîte système ou un compte déclaré illimité, et plus de quota de locataire. Le contrôle est l’écriture ; SMTP diffère par
452 4.2.2, JMAP répondoverQuota, IMAPNO [OVERQUOTA]; une garde d’espace disque du serveur ([storage] min_free_percent, 5 % par défaut) diffère le courrier entrant et refuse les ajouts avant que le disque soit plein (stockage). La route de téléversement du locataire, celle des pièces jointes du chat et des avatars de salon, passe enfin par la même admission. - La boîte d’une équipe s’active depuis un client :
Principal/enableMailpose les six boîtes, l’identité d’envoi, la liste de tâches, le dossier racine et le script de tri qui exigeaient un terminal, répond laquelle de quatre choses s’est vraiment passée (posée, déjà vivante, une pose interrompue complétée, ou un composant à moitié posé et rien de touché, qui est une erreur nommée et jamais un succès), sérialise les activations concurrentes, et annonce ce qu’elle a créé sur le compte de l’équipe pour que les clients connectés voient la boîte arriver. L’annuaire dit si une adresse reçoit (Principal.receivesMail, les listes de diffusion comptent comme joignables), et une équipe qui reçoit sans pouvoir répondre est un échec dedoctorqui nomme l’adresse et le verbe qui répare. - Écrire une propriété que le serveur ne connaît pas ne répond plus « enregistré » : un nom inconnu, une casse différente, un mot renommé étaient comparés à rien et acquittés. Le refus nomme désormais la propriété, distingue un nom inconnu d’un chemin qui plonge dans une propriété absente, et dit quand une propriété existe mais est calculée par le serveur ou changée par un autre geste. Le durcissement s’active type par type, l’annuaire d’abord (JMAP v2).
- Dossiers et règles de tri, quatre corrections : un compteur « nouveaux depuis la dernière visite » à côté du total de non-lus (
folder_entered_atposé à l’entrée,FolderVisit/getetmarkViewed, filtrenewSinceVisitd’Email/query, annoncé parfolderVisit), sur les dossiers système comme personnels ; deux dossiers frères ne peuvent plus porter le même nom et un nom de dossier ne porte aucun caractère réservé, garanti par une contrainte de base après réparation ; une règle peut désigner sa cible par un chemin (Archive/Crisp, annoncé parruleFolderPath) plutôt que par un nom nu que deux dossiers pouvaient porter (courrier). - La recherche exige tous les mots, et l’accent ne décide plus : une requête de plusieurs mots exige désormais tous ses mots, avec un repli sur « l’un des mots » quand cela ne trouve rien, et
résumétrouveresume;Email/querysait trier par pertinence.sendAtetscheduledSendAtn’acceptent plus que la chaîne RFC 3339, ce qui clôt une migration de fil en trois temps. Un message soumis par un compte authentifié garde cette provenance avec lui ; un import sans date de source exploitable prend l’en-têteDate:du message avant l’heure de l’import. - Chat : un salon détruit par son propriétaire part dans une corbeille que le propriétaire voit et d’où il restaure (corbeille des salons) ; qui a détruit un salon, retiré un membre, changé un rôle ou modéré un message est désormais au journal d’audit, avec l’adresse et la session d’origine ; le statut de présence gagne une note libre avec un emoji optionnel, annoncée dans la capability chat avec ses deux plafonds ; la surface E2EE
keySlotsest retirée (zéro ligne mesurée sur six instances) et un message créé avec un schéma de chiffrement autre quenoneest refusé au lieu d’être stocké en clair. - Les journaux se lisent ensemble :
oximail journal listlit le journal d’administration et le journal des accès dans une seule chronologie, avec filtres d’acteur et d’objet ;AuditEvent/verifyest plafonné àmaxEventsPerVerify(2000) et reprend parnextAfter; une borne de temps surAuditEvent/verifyet/queryest retamponnée dans la forme canonique avant d’atteindre le SQL (elle était comparée comme du texte, si bien que10:30:00Zexcluait l’instant même qu’elle nommait) ; la rétention du journal d’administration passe à 365 jours, alignée sur le journal des accès, et un effacement ne touche plus la chaîne ; les extensions journalisent par une porteext:; un locataire qui active le journal des accès choisit strict ou au mieux pour une ligne qui ne peut pas s’écrire (conformité, CLI). - L’adresse du client derrière un proxy de confiance n’est plus choisie par le client :
Forwardedse lit de droite à gauche, les adresses sont analysées ou rien, les en-têtes ne sont jamais crus sans pair TCP, et une requête dont l’adresse ne peut pas être établie est refusée plutôt que servie sous"unknown".check-configrefuse une écoute loopback derrière un proxy qu’elle ne reconnaît pas, puisque tous les visiteurs partageraient sinon un seul seau de limitation. - Exploitation :
/metricsa son propre jeton ([admin] metrics_token_file), distinct du jeton d’administration qu’une configuration Prometheus devait détenir ; les avertissements et erreurs se comptent par module ;restorerefuse une sauvegarde faite par un binaire plus récent et tout verbe qui ouvre la base refuse une base migrée par un binaire plus récent ; un espace de noms de migration inconnu est un refus au démarrage ;oximail app-password revokeferme les sessions ouvertes avec lui ; un harnais de fuzzing couvre les analyseurs de protocole du dépôt et a trouvé deux défauts du lexer Sieve dans sa première minute ;setup verifysort enfin non zéro et dit qui renouvelle le certificat ; l’assistant publie l’IPv6 du serveur (AAAA,ip6:) et ne prend plus une adresse v6 pour une v4 ; aucun verbe CLI n’exige un secret sur sa ligne de commande (exploitation). - Mesuré, puis tranché : SQLite alloue désormais chez jemalloc, dans une arène qui lui est propre (il portait 94 % du tas chez glibc) ; le planificateur de rappels d’agenda lisait les événements sous un
LIMIT 1000sans ordre et en sautait 380 sur 1 380 sur la box de production ; le plancher de rétention de 7 jours sur la corbeille et le chat disparaît (la valeur de l’administrateur s’applique, à partir de 1 jour) ; le plancher de posture établie du filtre anti-spam passe à 14 jours sur la foi d’une mesure sur 119 000 messages ; le contrôle d’usurpation de marque ne prend plus un logo pour un lien.
- Le chiffrement au repos est celui du volume, pas de l’application (ADR-148, cinq lots en neuf jours) : la base SQLCipher, les clés de blobs par compte et l’en-tête auto-descriptif des blobs ont quitté le binaire ; la base est un SQLite ordinaire, les blobs sont leur contenu nommé par son empreinte, et la protection au repos est dm-crypt/LUKS sous l’instance, mesuré par le démarrage, par
doctor at_restet par la jaugeoximail_at_rest_volume. L’assistant refuse un volume nu sauf si--accept-bare-volumeconsigne le consentement, et imprime la configuration de référence en six points.server.key, les clés de tenant, l’escrow et la rotation restent pour les secrets qu’ils enveloppent ;key purge-pendingretire désormais tous les reliquats de rotation sous un seul exercice de récupération ;blob verify --walkcontrôle le disque contre le registre ;restorerefuse un blob scellé et nomme le binaire de son époque. Le déclencheur était une mesure : la mémoire de clés verrouillée coûtait un facteur 6 à 20 sur chaque requête (chiffrement au repos). - Le relais n’est pas une archive (ADR-149) : le corps d’un message soumis par un compte relais est un fichier d’un spool dédié (
[storage] relay_spool_path, un point de montage à lui, exclu des sauvegardes), pas un blob ; il est délié dans la même écriture terminale que sa ligne de file au250du destinataire ou à l’abandon ; le rapport d’échec ne porte rien du message et n’est jamais livré dans une boîte locale ; un MX de secours garde le courrier en transit de la même façon ; sans spool, aucune soumission relais n’est acceptée, etdoctor relay_spoolmesure la séparation (relais sortant). - Le journal des accès aux données est servi (ADR-150, lots 2 à 6) : qui a lu, listé, écrit, partagé, exporté ou détruit quel objet, dans sa propre table chaînée avec sa propre rétention de 365 jours, sous la capability
accesslog, activé par locataire et fermé sur échec quand il est actif. L’amendement 1 a suivi un banc refusé (p99 +251 % surEmail/getavec un commit par appel) : le journal trace l’accès par un tiers, jamais les lectures du propriétaire.access-log list --actorrépond « qu’a fait tel collaborateur », borné par--since; le checkpoint WAL a quitté le chemin de la requête (conformité). - La chaîne du tenant : un acte du nœud lui-même (appairer une organisation, la suspendre, tourner la clé de travail, enrôler une racine) n’avait aucun domicile dans le journal d’administration ; il a désormais sa propre chaîne avec un enregistrement d’origine,
audit-log list|verify|attest, un contrôledoctorqui vérifie aussi chaque chaîne de compte, et une réécriture légitime (rédaction d’effacement, rekey de principal) est un acte de la chaîne et non une rupture. Le créateur d’un principal est enregistré. - Meet, la forme servie : un invité externe sans compte rejoint par lien (
POST /meet/guest, un identifiant TURN éphémère par invité), la salle d’attente et le rôle de modérateur existent, un participant actif peut faire venir quelqu’un dans un appel déjà commencé, un appel de groupe peut grandir au-delà du maillage direct par un relais média branché sur le seam d’extension (sans relais, le comportement d’aujourd’hui bit pour bit), le serveur répond lui-même au STUN sur un port que l’exploitant ouvre, et une réunion planifiée porte son lien dans l’invitation iTIP, là où la copie de l’invité arrivait sans (ADR-147, Meet). Un étranger à une session reçoit la même réponse qu’un identifiant inventé. - Notes, une nouvelle surface : la capture libre du workspace, pour ce qui n’est pas une tâche (si ça a un état « fait », c’est une tâche, sinon une note).
Notebookest l’unité de partage, avec un vocabulaire de droits à trois bits qui lui est propre ; uneNoteporte unbodyProseMirror canonique et unbodyTextdérivé par le serveur, servis seulement s’ils sont nommés, des étiquettes libres, des liens vers d’autres objets du workspace qui ne cassent jamais, une corbeille en deux temps et[notes] trash_retention_days. La dictée est unNote/set createavec une pièce jointe audio derrière un seam de moteur : sans moteur, la page est acceptée et répondtranscription: "failed"avec sa raison, jamais en silence.Note/transcribeajoute un enregistrement à une page existante ou relance une transcription en échec, et chaque pièce audio porte la provenance de sa propre transcription, fournisseur, hôte contacté et un palier de résidence (local,ch,eu,non_eu) sur lequel le client branche, écrite sur la tentative ; la page n’affirme pas davantage que la moins souveraine de ses pièces (ADR-144, Notes). - Invitations de réunion : le message d’annulation a la forme de l’invitation, dans la langue du destinataire et à sa pendule ;
CalendarEvent/setajoute un lien de visioconférence à une réunion qui existe déjà au lieu de répondreupdatedsans rien faire. - Boîtes et agendas partagés depuis tous les clients : une boîte partagée apparaît en IMAP sous
Other Users/<adresse>/…, un agenda partagé en lecture ne s’annonce plus modifiable à CalDAV, un message se copie d’une boîte partagée vers la sienne avec son historique, marquer un message à supprimer dans une boîte partagée exige le droit de supprimer, un partagemayWriten’implique plusmayDeletesur le Drive, et une requête qui mélange son propre compte et un compte partagé est refusée au lieu de répondre depuis le mauvais. Les mandats d’un compte gelé sont suspendus, ceux de l’opérateur restent.EventSourcepousse aussi les changements des comptes partagés. - Lot de conformité protocolaire (mesuré contre de vraies boîtes) : IMAP répond
BADà une commande hors de son état, sert lesTHREAD,SEARCH MODSEQ,STATUS SIZEetQUOTAqu’il annonce, honore QRESYNC surEXAMINE, accepte un littéral dans toute commande, refuse ce qu’il ne comprend pas, et les verbes ACL sont refusés plutôt qu’acquittés à vide quand la face partagée est éteinte ; SMTP apposeReturn-Pathet une clausefor, etMAILrefuse ce qui n’est pas un reverse-path ; unREPORTCalDAV/CardDAV que le serveur ne sait pas nommer est refusé au lieu de répondre avec toute la collection, un segment d’URL qui n’est pas un compte n’est pas un principal, et l’en-têteDAV:n’annonce plus la classe 2 ; les trames d’erreur WebSocket ont la forme de la RFC 8887 ;SearchSnippet/getcalculenotFoundquel que soit le filtre ;accountIdest requis en lecture comme en écriture ; unrequireSieve d’une extension inconnue est refusé selon la RFC 5228 (protocoles historiques). - Cloisonnement entre comptes : sept écarts mesurés sur la flotte lors d’une campagne de conformité, corrigés la même semaine ; un téléchargement de blob porte
ETagetCache-Controlpuisque son identifiant est son empreinte ; un lien de partage public ne peut plus être sans fin. - Surface d’exploitation : une clé de configuration inconnue est une erreur et un bloc répété s’imbrique (ADR-007 Am. 2) ;
doctorcharge enfin les sections d’extension que tous les autres verbes lisaient déjà ; un binaire étendu peut ajouter des verbes CLI et des contrôlesdoctorau lieu de les intercepter ; la corbeille du Drive a un réglage par locataire ([drive] trash_retention_days), un verbe et une seule sortie qui respecte les séquestres, et les quatre autres corbeilles (tâches, contacts, événements, pages) passent par elle ; la rétention des versions de fichiers est un réglage par locataire appliqué à chaud ;oximail drive sharepartage un seul dossier depuis la CLI etrights auditvoit les fichiers ; le retour arrière d’un déploiement se prouve avant le swap par le binaire cible ; les deux cents commandes d’administration ouvrent une connexion au lieu d’un pool (quatre invocations sur dix plantaient sur cinq box sur six) ; la sauvegarde et la vérification des blobs ne vident plus le cache de pages ; supprimer un lot de messages libère ses pièces jointes en secondes et non en jours ; le courrier accentué atteint un récepteur sans 8BITMIME par dégradation au lieu d’être perdu sans rebond ; une adresse se résout par un seul chemin. - Les fichiers, aux portes : un fichier tenu ouvert par un protocole qui a un « open » (un moteur SMB branché dans le même binaire) est refusé aux rédacteurs JMAP avec
forbidden, en nommant le porteur et l’âge du verrou, etFileNode/getsertlockedBy; le registre est en mémoire, dans le processus, donc un verrou meurt avec la connexion ; un fichier créé sanscontentTypereçoit le type que son nom implique, un type explicite gagne toujours (fichiers). - Sieve dit ce qu’il implémente : l’objet de capacité valait
{}; il porte désormais le nom de l’implémentation, les plafonds de taille de script et de nom et la liste des extensions depuis les constantes que le compilateur applique,nulllà où rien n’est plafonné ; unrequired’extension absente est refusé à la compilation en nommant ce qui est disponible, et les trois comparateurs peuvent être exigés ;onSuccessActivateScriptest honoré dans la transaction des écritures qu’il suit au lieu d’être ignoré pendant que la réponse disait « créé » ; activer un script qui n’existe pas ne change rien, là où cela désactivait d’abord tous les autres (Sieve). - Licence et doctrine : le serveur sera publié en fair source sous l’OxiMail License, dont chaque version repasse en AGPL quatre ans après sa parution (ADR-142, qui remplace ADR-004) ; le navigateur ne parle qu’à sa propre origine et tout appel vers un tiers passe par le serveur (ADR-143) ; un verdict anti-spam porte son axe pour qu’une tolérance de renvoi puisse re-disposer par destinataire sans mentir au scoreur (ADR-146) ; les vestiges E2EE d’ADR-020 ont quitté le schéma.
- Meet grandit : des liens d’invitation (un par réunion, rachetable N fois), la salle d’attente et le modérateur qui agit sur autrui, un
maxParticipantsappliqué, une fin de session qui ne réécrit plus l’histoire, un invité qui écrit dans le chat de l’appel, des lignes de réunion enfin conservées et effacées,Preferencesqui accepte la sectionmeetoù deux fonctions clientes écrivaient déjà, et le lien de jonction fabriqué avec le bon hôte dans les invitations sortantes (Meet). - Le temps, une seule fois : le cœur portait deux moteurs de calcul des répétitions, l’un sensible au fuseau et l’autre non, et une série hebdomadaire à 9 h traversait un changement d’heure décalée d’une heure ; il n’y en a plus qu’un. Une seule façon de lire une heure murale, avec l’écart du changement d’heure lisible dans la zone. Un horaire de travail sait dire « de 22 h à 6 h le lendemain » (
endDayOffset, ADR-139), le client demande d’abord au serveur s’il comprend la notion, et la disponibilité d’un jour se calcule sur la veille autant que sur lui-même. Le fuseau d’une personne peut être retiré, s’écrivait sous un nom que le serveur ne lisait pas, et le fuseau par défaut d’une organisation se corrige depuis un client ;doctorcalcule la prochaine bascule par fuseau utilisé et compte ce qui tombe dans l’heure qui n’existe pas ; la case « rappels d’agenda » coupe enfin quelque chose ; un incident de disponibilité laisse quelque chose à regarder. Un séminaire de trois jours n’est plus un agenda libre. - Seams d’extension (ADR-137, ADR-138) : des comptes système sans surface mail, un verbe administratif
calendar share, des collections résolubles sur le préfixeshared:, et un contributeur externe optionnel au free-busy d’un principal dont l’échec estserverFailplutôt que « libre ». - Anti-spam, les mécanismes nommés par une mesure à J+7 : un renvoi par règle ne blanchit plus le spam détecté ; le verdict du modèle n’étouffe plus les autres signaux, et un correspondant établi ne part plus en indésirable sur la seule opinion du filtre statistique ; un envoi en Cci massif hors de la liste de TLD atteint la bande suspecte ; le bouton « indésirable » du webmail entraîne enfin le filtre dans les deux sens ; un verdict perdu à la livraison n’est plus avalé ; la signature de désabonnement en un clic n’est plus un passe-droit au-dessus du seuil ; les réponses des DNSBL sont lues, pas crues ; la relation avec un expéditeur se lit dans les deux sens ; un geste qui contredit le filtre est une opinion, pas une leçon ; un statut de transaction n’est pas un nom d’expéditeur ; une usurpation de banque sans rien qui lui appartienne, quatre tromperies de lien et les liens cachés dans du HTML encodé sont vus ; un faux avis de livraison en allemand ne passe plus ; l’hameçonnage n’est plus rangé avec la publicité ; le courrier renvoyé par votre ancien fournisseur n’est plus condamné par construction ; l’alerte sur les rapports DMARC dit ce que le rapporteur a expliqué (anti-spam).
- Annuaire et équipes : une équipe peut avoir sa propre adresse (réservée à la création, plus adossée en silence au compte de son créateur) ; les collègues portent leur nom dans le carnet d’adresses ; les champs de profil ne vivent plus que sur la fiche d’annuaire, semée depuis les profils existants ; un groupe de distribution ne peut plus éclipser une adresse existante ; le départ d’un collaborateur tient en une commande ; désactiver un compte ferme enfin la porte, session IMAP ouverte comprise, et désactiver le dernier administrateur n’est plus une porte à sens unique ; le séquestre légal a sa première étape.
- Courrier et recherche : chaque message connaît sa langue, un ancien à l’ouverture sans backfill, et la langue est un critère de recherche ; « re: facture » cherche vraiment (un deux-points n’est plus un nom de champ) ; une conversation en sourdine le reste dans le temps ; la surface des quotas est une liste de vrais chiffres plutôt qu’un objet unique au plafond fictif ; un refus de quota dit lequel et de combien ; l’accusé de remise fonctionne avec un envoi annulable ; un nom d’affichage encodé à virgules n’explose plus en expéditeurs vides ; un filtre non supporté et une mauvaise valeur de filtre sont deux erreurs distinctes ; le plafond de téléversements simultanés annoncé est tenu ; un
/changesfiltré ne nomme plus des messages qui ne l’ont jamais concerné ; le push en flux ne perd plus sa fenêtre ;@here,@channelet@allpréviennent enfin quelqu’un ; une réaction ne peut plus peser un mégaoctet ; les emojis personnalisés sont bornés et peuvent être éteints par organisation ; les stickers ont leur calibre. - Drive et fichiers : les dates des documents migrés survivent ; le responsable d’un espace partagé n’en perd plus la main et sait quand il est passé outre un partage ; le premier dossier d’un espace partagé ; trouver un fichier dans un grand dossier coûte le même prix que dans un petit ; un fichier de 27 Go ne passe plus par la mémoire (ADR-145) ; un carnet ré-importé sans identifiants ne duplique plus ; « dernier échange » regarde en arrière ; le carnet d’adresses répond aux questions qui font son utilité, et ses colonnes et vues enregistrées vivent sur le compte.
- Ce qui a été retiré, ou ramené au vrai : six réglages qui annonçaient une garantie que rien ne consultait, un contrôle vert qui ne prouvait rien, trois boucles de retour publiées et mortes, un service qui annonçait un confinement qu’aucune machine n’appliquait, un client de migration qui acceptait n’importe quel certificat, un service durci qui ne pouvait pas lire sa propre clé, deux ports qui se seraient ouverts sans qu’on le demande, un diagnostic qui présentait un contrôle non exécuté comme réussi, des noms DNS et HTTPS qui pouvaient diverger, un certificat qui ignorait un nom ajouté, des pages publiques sans leurs protections de navigateur, un journal d’exploitation noyé sous 144 000 avertissements, et un journal qui enregistrait à quelle vitesse un client lisait son courrier. La clé racine en clair sur un volume nu est nommée, et sa purge redevient atteignable. Le courrier effacé quitte les fichiers de l’index de recherche, pas seulement l’index.
- CLI : les commandes d’administration démarrent deux fois plus vite ; un nouvel export écrit un fichier par message (neuf secondes là où il fallait deux heures pour cinq mille) ; la taxonomie des commandes est tranchée et gardée (
blobcomme racine unique) ; un verbe d’administration ne suit plus jamais le wildcard de livraison (unset-passwordsur une adresse inexistante avait remplacé le mot de passe du propriétaire du catch-all) ; une commande d’administration ne fabrique plus de clé racine par mégarde ; le MX de secours démarre par le même chemin que les autres ; les listes de noms DNS et HTTPS de l’assistant viennent d’une seule source. - L’observation, bornée (ADR-140) : le niveau de journalisation ne se monte que pour une durée bornée,
oximail log elevate --directives … --duration-secs NouPUT /admin/v1/logs/level, 60 à 3600 secondes, et il revient de lui-même, l’élévation et le retour étant deux événements du journal (debugétait allumé depuis avril sur la plus vieille box de production, jamais éteint) ; le projecteur de trace protocolaire capture l’échange brut d’un compte ou d’un pair, jamais tout le monde, pour 60 à 900 secondes, caviardé,0600sur le tmpfs, purgé à l’arrêt ;log tailrend le journal une ligne lisible par événement (exploitation, API d’administration). - Dit nommément, pas avalé : un contact créé avec des propriétés que le serveur ne connaît pas répondait succès et existait sans nom, il est refusé en les nommant ;
Rule/test,Rule/applyet le dry-run de la CLI lisent le verdict anti-spam stocké au lieu de « non noté » ; une tâche porte sontimeZone, si bien qu’unDUE:…Zvenu de CalDAV ne flotte plus et qu’un rappel sonne à l’instant de la tâche ; le flux temps réel perdait une fenêtre en attente quand un client se réabonnait, l’abonnement ne remplace plus que la liste des types suivis ; un import IMAP ancre sa reprise sur l’UIDVALIDITYde la source, si bien qu’une renumérotation ne saute ni ne duplique, et une source qui n’en annonce pas échoue plutôt que de reprendre sur des clés ambiguës (contacts, tâches, migration).
- Meet, première forme qui fonctionne : les appels en temps réel gagnent une surface serveur, à savoir une session ancrée sur un salon de discussion, dont la création atteint tous les membres du salon pour qu’un appelé apprenne l’appel sans type de notification dédié, plus un relais transitoire pour la poignée de main WebRTC, jamais persistée ni journalisée. La phase 1 est en pair-à-pair jusqu’à trois participants actifs, et l’adhésion est un bail de présence à expiration automatique plutôt qu’un drapeau (Meet).
Email/getgagne son arbre :bodyStructureest émis et récursif,fetchAllBodyValuesatteint enfin toutes les feuillestext/*(la partietext/calendard’une invitation comprise), et les pièces jointes portentpartId,charsetetdisposition. Les en-têtes par partie sont servis sousbodyProperties, seul chemin conforme vers les paramètres de Content-Type qui distinguent une invitation d’un.icsjoint. Changement de contrat : sans argumentfetch*BodyValues,bodyValuesrevient désormais vide comme l’exige la RFC 8621 §4.2, alors qu’il était rempli inconditionnellement (l’arbre du corps).- Chaque
/getferme son vocabulaire, et le canon est publié : un nom de propriété inconnu devient uninvalidArgumentsqui nomme les fautifs au lieu d’un mot ignoré en silence, et ce qui est sélectionnable, comme ce qui est calculé par appelant, est désormais émis en forme machine à côté des types générés (le canon de projection). - Les boîtes partagées se lisent et s’écrivent correctement : la clé de déchiffrement suit le compte effectif et non l’appelant, si bien que les corps d’une boîte partagée s’ouvrent ; et un message classé par un bénéficiaire est chiffré pour le propriétaire, ce qui referme le miroir du même défaut. La couche de clés elle-même est partie avec ADR-148 trois semaines plus tard ; la règle du compte effectif lui survit comme périmètre du registre des blobs.
Thread/getetThread/changesreviennent aux clients RFC 8621 purs, servis sous la capacitémaillà où le §3 les place ; un client ne déclarant quecore+mails’entendait répondreunknownCapabilitysur une méthode obligatoire (courrier).- Les annuaires de contacts de tenant : une organisation peut publier des jeux de contacts partagés qui atteignent les membres en fiches lisibles seulement dans leur propre carnet, avec des entrées tenues par des principaux et des groupes nommés (contacts, ADR-133).
- L’échange de clés post-quantique est réellement négocié : X25519MLKEM768 est proposé en tête, avec le X25519 classique en repli, sur 25, 465, 587, 993 et 443. La fonctionnalité était compilée depuis des mois alors que le fournisseur installé ne pouvait pas l’implémenter : chaque session retombait en silence (TLS & ACME).
- Deux ans de chiffrement amont rattrapés : SQLCipher passe de 4.5.7 à 4.14.0, SQLite de 3.45.3 à 3.51.3, et le binaire livré est contrôlé au déploiement pour ne dépendre d’aucune bibliothèque de cryptographie, TLS ou SQLite du système. Trois semaines plus tard, ADR-148 a retiré SQLCipher du binaire (début septembre, ci-dessus) ; le contrôle de dépendances lui survit.
- Les journaux de poignée de main cessent de crier au loup : les quatre écouteurs TLS séparent un pair qui a raccroché avant de négocier d’un vrai échec de négociation, chaque branche portant un champ
reasonstable. Une instance de production émettait 480 avertissements inoffensifs par jour pour une seule sonde de supervision, et un vrai échec s’y serait caché (exploitation). dkim=faildit pourquoi : le motif d’échec atteint l’en-têteAuthentication-Resultset le résultat conservé par message, si bien qu’une analyse après coup sépare une signature invalide d’un corps modifié en transit, d’une clé absente, ou d’une signature datée dans le futur, ce qui signifie que l’horloge du serveur retarde (authentification du courrier).- Exploitation :
oximail sqlroute sur la forme du statement, si bien qu’unWITH ... SELECTretourne des lignes au lieu de rapporter « 0 rows affected » ;blobs gcne collecte plus un blob non référencé plus jeune qu’une fenêtre de grâce de 24 heures (RFC 8620 §6.1) ; les instantanés locaux de retour arrière ont gagné une politique de rétention que le déploiement applique ;doctorjuge la santé de l’horloge ; et des limites seulement annoncées sont devenues des limites qu’un mécanisme applique (CLI, exploitation). - Fuseaux horaires : le fuseau par défaut d’un tenant est lisible, hérité et surveillé, et un fuseau fourni au provisioning atteint désormais le principal. Un fuseau invalide est refusé avant la première écriture au lieu d’être accepté puis ignoré.
- La fédération, première forme qui fonctionne : la cérémonie d’appairage bilatérale hors bande (empreinte sur le realm et la clé, clé de nœud par organisation), une racine d’identité portable distincte de la clé de travail jetable qui vit sur la machine (la rotation vaut révocation, par époque monotone), et le modèle de grant inter-organisation : borné au realm, écrit par le propriétaire, à expiration automatique, et qui n’élargit que l’axe d’accès. Révoquer un appairage suspend l’accès au lieu de détruire l’enregistrement ; les notices d’effacement sont estampillées sur l’ancre d’identité et échouent fermé à la livraison (ADR-124 à ADR-127).
- Les accusés de lecture, sur les deux surfaces. Le courrier gagne la surface MDN de la RFC 9007 :
MDN/sendcompose un accusé comme geste explicite de l’utilisateur,MDN/parserend enfin lisibles les accusés entrants déjà rattachés à vos messages envoyés. Les accusés de lecture du chat atteignent désormais en direct chaque membre d’un groupe ou d’un canal, et non plus le seul pair d’une conversation directe, avec un interrupteur de visibilité par canal et un plafond de taille de salon sur la diffusion en direct (chat). - API d’administration : la liste des expéditeurs de confiance d’un compte, l’ensemble que les envois sortants et les sauvetages de ham écrivent aussi, se lit et se modifie (
GET/POST/DELETE /admin/v1/accounts/{id}/trusted-senders), puisqu’une règle permanente que personne ne peut lister est invisible ; un connecteur d’annuaire externe pousse les contacts de l’organisation dans les comptes qu’il nomme (POST /admin/v1/contacts/org-sync) (API d’administration). - L’historique de versions du drive sur le fil :
FileVersion/query,getetrestore, avecmaxVersionsPerNodeannoncé et l’élagage piloté par la même constante (fichiers). - L’honnêteté de la synchronisation : un curseur
Foo/changesplus ancien que la fenêtre de rejeu de 90 jours est maintenant refusé aveccannotCalculateChanges, au lieu de s’entendre dire qu’il est à jour. C’est un seul point de passage au niveau du stockage dont tous les consommateurs héritent,sync-collectionde DAV compris./changesréduit aussi à une seule issue par identifiant, conformément à la RFC 8620 §5.2, et un lot/setvide ne saute plus sa vérification d’ifInState(JMAP Core). - Les identifiants de streaming : les flux SSE s’ouvrent avec un ticket éphémère de 60 secondes au lieu du token de session, pour qu’un identifiant valable 24 heures ne circule plus dans une URL que les proxies journalisent.
- Les formes de fil corrigées là où elles laissaient filtrer le stockage : les aperçus de liens du chat sont des objets typés et non plus un tableau d’octets bruts ; une partie
message/rfc822est annoncée comme la pièce jointe qu’elle est, au lieu de publier au premier niveau les pièces jointes du message encapsulé ; quatre internes de stockage de l’agenda ont quitté le fil. - IMAP :
FETCH RFC822,RFC822.HEADERetRFC822.TEXTne renvoyaient aucune charge utile, etRFC822marquait quand même le message\Seen. Les deux sont corrigés (protocoles historiques). - L’intégrité de la rétention et des sauvegardes : la sauvegarde par organisation n’omet plus en silence les blobs de pièces jointes ni les lignes des tables absentes d’une liste tenue à la main, et
verify-backuppeut voir la différence ; la corbeille vers laquelle balaient les messages qui expirent a enfin une politique de rétention derrière elle ; les blobs de parties de corps sont devenus le cache dérivé qu’ADR-098 décrivait depuis toujours, re-dérivé et vérifié par empreinte lors d’un échec de téléchargement (exploitation). - L’exploitabilité : onze tâches de ménage au démarrage ne se marchent plus dessus en
sqlite busyavec un tick perdu à chaque boot ;doctora cessé de présenter toute la file de remise comme en attente ; un verbespam checken lecture seule demande au filtre son opinion actuelle sur un message stocké ; les DSN et ARF entrants lèvent désormais des événements de rebond et de plainte sur le chemin d’ingestion. - Les portées des mots de passe d’application sont appliquées de bout en bout : la portée voyage avec le token et survit au renouvellement, une seule matrice de capacités décide, et l’accès aux protocoles se déduit de l’ensemble des capacités, appliqué au dispatch JMAP, à la connexion IMAP et à DAV (ADR-129).
- Anti-spam : le greylisting au moment du
RCPTa été retiré comme défense. Les botnets réessaient, les pools d’adresses des gros expéditeurs cassent le triplet, et le mécanisme taxait les expéditeurs légitimes de premier contact. L’exigence d’authentification et le pipeline scoré portent cette charge (ADR-128, anti-spam). - Installation : l’assistant a gagné un profil smarthost comme troisième entrée, consigné comme marqueur d’intention audité et non comme un rôle (premier démarrage).
- Domaines d’enveloppe : une plateforme qui envoie par le MSA peut utiliser un
MAIL FROMtechnique sur un domaine prouvé par DNS, formes VERP comprises, pendant que l’en-têteFrom:reste l’identité humaine. Le domaine accordé doit partager son domaine organisationnel avec une identité du compte : l’alignement SPF sous DMARC relaxed tient donc par construction (envois en nombre).
- Conformité : la journalisation du courrier par organisation (entrant/sortant, boîte ou archiveur externe), et l’effacement de compte reconstruit en machine à phases durable et reprenable, avec tampon de réversibilité, preuve DSAR (
oximail erasure prove) et rétention appliquée du journal d’audit. - Performance : une campagne de test de charge mesurée a environ triplé le débit de lecture (cache d’instructions préparées par connexion) et doublé l’ingestion saturée (index composite de fils) ; l’ingestion d’un message isolé a perdu son plancher de latence fixe (l’index de recherche valide au repos de la file) ; le WAL est borné et observable.
- Justesse de la remise : la visibilité de synchronisation incrémentale de l’ingestion est devenue atomique avec la ligne du message ; les règles du destinataire et l’absence s’exécutent désormais sur la remise locale (ADR-117) ; les sauts sortants font la médiation des extensions ESMTP (SMTPUTF8/8BITMIME/SIZE) au lieu de combler en silence ; DKIM sursigne From/To/Subject.
- Vague d’interopérabilité clients (vérifiée contre Apple Calendar, Thunderbird, eM Client, les invitations Outlook) : amorçage DAV à la racine, XML sûr en CDATA, ETag en empreinte de contenu, vrais filtres
calendar-query, émission des VTIMEZONE, modélisation des VALARM, annonces IMAPEXPUNGEcorrectes, et un point d’accès de configuration eM Client. - Les surcharges de configuration se listent :
GET /admin/v1/configrenvoie les surcharges en vigueur etknownKeys, l’ensemble fermé des clés que le code consomme, si bien qu’une faute de frappe ne devient pas un réglage silencieux (API d’administration). - Authentification : DPoP v2 : nonce serveur, preuves par requête, et le jeton média mono-blob.
- Relais smarthost sortant (ADR-116) : comptes de relais aux domaines prouvés par DNS, enrôlement à usage unique, quotas de destinataires par jour avec montée en charge, rétention éphémère du relais, auto-surveillance DNSBL (relais sortant).
- Lot sécurité : vérification des mots de passe d’application à travail constant, durcissement SSRF des récupérateurs de push et d’aperçus, dispatch des comptes partagés fermé par défaut, autorisation du
From:d’en-tête à la soumission, hachage au repos des tokens. - Refonte du pipeline anti-spam : époques et reconstruction du corpus Bayes, liste blanche des réponses sur enveloppe authentifiée seulement, colonne vertébrale de disposition (anti-spam).
- Drive et collaboration : drive raciné avec favoris par lecteur et vignettes serveur, comptabilité des liens de partage, chronologie de conversation, plafonds de capacité du chat et saisie limitée aux membres.
- Balayage de conformité du fil : la classe des « ignorés en silence » de
/queryéliminée (filtres, tris et arguments inconnus sont des erreurs), les capacités d’extension annoncées honnêtement dansaccountCapabilities.