Résumé

  • RFC 3503 a placé le mot-clé partagé $MDNSent dans la boîte IMAP afin que plusieurs agents de messagerie puissent respecter une seule décision et éviter les notifications de disposition répétées.
  • Ce mot-clé ne racontait pas nécessairement un envoi passé : refus de l’utilisateur, copie de message envoyé, message inachevé ou traitement automatique sans notification pouvaient tous conduire au même ordre de ne plus envoyer.

Une boîte IMAP rend les messages communs, pas la mémoire privée des logiciels qui les consultent. Un agent installé au bureau pouvait se souvenir localement d’avoir traité une demande de notification. Le portable ouvert le soir ne possédait pas ce souvenir. L’accès partagé créait donc un problème classique de coordination : chaque client voyait le même objet, mais aucun ne savait avec certitude ce que l’autre avait décidé.

RFC 3503, publié en mars 2003, a répondu avec une économie remarquable. Il n’a ajouté ni commande ni réponse au protocole IMAP. Il a défini un mot-clé de boîte aux lettres, $MDNSent, et une conduite commune. Le serveur conservait un état visible de tous les agents ; les agents s’engageaient à s’arrêter lorsqu’ils le rencontraient.

Le nom semble déclaratif : « MDN envoyé ». Les règles lui donnent pourtant un sens de contrôle. Après le traitement automatique d’un message, le client devait poser le mot-clé que la notification ait effectivement été envoyée ou non. Lorsque l’utilisateur interdisait l’envoi, le logiciel pouvait poser le même mot-clé afin qu’un autre logiciel ne repose pas la question. Une copie enregistrée dans le dossier des messages envoyés le recevait également. Une version inachevée sauvegardée dans une boîte le recevait aussi.

Ces origines n’ont pas le même passé. Elles produisent la même obligation future. $MDNSent signifiait donc surtout : « aucun agent conforme ne doit désormais produire de MDN pour cette occurrence stockée ». Il ne certifiait ni la construction d’un rapport, ni son dépôt auprès d’un serveur de soumission, ni son acheminement, ni sa réception.

La première vérification portait sur la capacité de conservation. À l’ouverture de la boîte, le client examinait PERMANENTFLAGS. Le serveur devait accepter soit le mot-clé spécial, soit des mots-clés arbitraires. Cette annonce n’était pas une promesse absolue. Même après avoir annoncé des mots-clés arbitraires, un serveur pouvait répondre NO à STORE, par exemple lorsque la limite propre à la boîte était atteinte.

RFC 3503 recommandait alors de ne pas envoyer la notification. Le choix mérite d’être lu attentivement. Envoyer immédiatement aurait pu satisfaire une intention locale, mais aurait laissé la boîte sans mémoire durable. Un second agent aurait pu répéter l’opération. La spécification préférait donc une notification manquante à une répétition incontrôlée. Elle ne promettait pas l’exécution exactement une fois ; elle fermait une porte lorsque la preuve nécessaire à la coordination ne pouvait pas être écrite.

Les indicateurs IMAP existants ne pouvaient pas remplacer ce mécanisme. \Recent était expressément exclu : avec plusieurs connexions sélectionnant simultanément la même boîte, le protocole ne disait pas laquelle verrait le message comme récent. Une observation distribuée de manière indéterminée ne peut pas attribuer une tâche commune. \Seen pouvait contribuer à une décision négative, mais avait déjà une autre signification. \Draft indiquait un message incomplet et interdisait séparément la notification. Dès que $MDNSent était présent, tous les autres drapeaux devenaient sans effet pour cette décision précise.

Le mot-clé était monotone. Une fois posé, un client ne devait jamais l’enlever. Ce choix limitait les transitions concurrentes. Il interdisait aussi de lire le bit comme un journal : aucun auteur, aucun instant, aucune raison et aucun résultat de transport n’étaient conservés. Le bit disait quoi faire ensuite, pas ce qui s’était exactement produit auparavant.

Le déplacement d’un message risquait d’effacer cette mémoire. Un client devait vérifier qu’un COPY conservait $MDNSent. Pour une copie entre serveurs réalisée par APPEND, il devait fournir correctement le mot-clé. Sinon, la destination recevait le contenu sans l’interdiction associée et un nouveau client pouvait prendre l’absence pour une autorisation.

L’interaction avec les listes de contrôle d’accès rendait la séparation des pouvoirs visible. Un serveur conforme à l’extension ACL devait encore vérifier le droit de copier le message. Mais, si la copie était autorisée, il était recommandé de préserver $MDNSent même lorsque le client ne possédait pas le droit général d’écrire les drapeaux. L’autorité de déplacer l’objet et celle de modifier librement ses attributs restaient différentes ; la propriété de coordination suivait la copie.

Les variantes de casse ne créaient pas plusieurs mondes. $MdnSENt, $MdnSENT et $mdnsent devaient être identiques. Cette règle évitait qu’un client cherche un état que l’autre avait écrit sous une graphie différente. La robustesse se jouait jusque dans la représentation.

Le rapport MDN lui-même appartient à une autre couche. RFC 2298 avait défini le format initial ; RFC 3798 l’a révisé ; RFC 8098 est devenu l’Internet Standard STD 85. Les termes de disposition n’autorisent pas les raccourcis. displayed indique que l’agent a affiché le message à quelqu’un qui consultait la boîte, sans garantie de lecture ni de compréhension. processed peut décrire une règle sans personne. deleted n’établit ni absence de consultation, ni irréversibilité.

Le standard moderne rappelle aussi les limites de confidentialité et d’intégrité. Le consentement de l’utilisateur compte, la valeur par défaut devrait être l’absence d’envoi, certaines différences d’adresse imposent une confirmation, et un MDN peut être forgé, perdu ou détourné pour amplifier du courrier. Il ne fournit pas de non-répudiation et ne garantit pas qu’un message a été vu ou non.

RFC 5788 a ensuite enregistré $MDNSent comme mot-clé partagé. Sa description élimine l’ambiguïté : il spécifie qu’un MDN ne doit pas être envoyé pour le message annoté. C’est la définition d’une interdiction commune, pas celle d’un reçu d’exécution.

Avec JMAP, RFC 9007 a rapproché l’action et son état. Une requête MDN/send doit être liée à la mise à jour $mdnsent; le serveur refuse une opération qui ne produirait pas cette mise à jour et peut répondre mdnAlreadySent. Cette jointure réduit un intervalle de défaillance dans le modèle JMAP. Elle ne transforme toujours pas l’affichage en lecture, ni l’envoi en livraison finale.

Pour interpréter correctement les traces, il faut donc conserver plusieurs reçus. PERMANENTFLAGS prouve une capacité annoncée. STORE OK prouve une mutation acceptée dans un contexte de boîte. $MDNSent prouve un état de suppression partagé. La création du rapport, sa soumission, son transport et sa remise produisent d’autres preuves. La disposition contenue dans le rapport est une assertion typée. L’attention et la compréhension humaines restent au-delà.

L’histoire est modeste mais fondamentale. L’Internet n’a pas besoin que chaque registre commun devienne une vérité générale. Ici, l’invariant minimal était d’empêcher plusieurs clients de répéter une action. Le mot-clé remplissait cette fonction précisément parce qu’il n’essayait pas de certifier le monde entier.

La faute commence lorsque le nom symbolique absorbe toutes les couches : drapeau présent devient notification envoyée, notification envoyée devient notification livrée, displayed devient lu, puis lu devient compris ou accepté. RFC 3503 n’autorise aucune de ces promotions. Il fournit un ordre d’arrêt partagé, et rien de plus.

Sources