要約

  • RFC 5256 の並べ替えとスレッド化は再現可能な規則を持つが、結果は検索条件、選択アルゴリズム、照合規則、ヘッダー品質、メールボックス状態に依存する投影である。
  • 親子関係はMessage-IDの参照、存在しない祖先のダミー、あるいは基本件名の合流から生まれ得る。どれも執筆意図、完全な系譜、保管、配送を単独では証明しない。

画面は欠けた記録を滑らかな物語にした

監査資料に一本のメールツリーが貼られていた。最上段が指示、その下が承認、さらに下が実行報告に見えた。ところが、ツリーを作った検索は特定の日付以後に限定され、最初のメッセージの前にあった可能性のある記録はそもそも対象外だった。

THREAD は会話を発見する命令ではない。まず検索を行い、その一致集合にアルゴリズムを適用する。日付、語句、メールボックス、現在の状態が変われば、メッセージ本文を一文字も変えずに木の形が変わり得る。結果が答えるのは「この入力集合をこの規則でどう見せるか」であって、「実際の対話が完全にどう進んだか」ではない。

記録層にはメールとサーバーのメタデータがある。変換層には検索、デコード、正規化、照合、構木がある。表示層には字下げ、開閉記号、「会話」というラベルがある。Lu Heng の現実層という観点では、この三つを一枚の画面に畳み込んでも、権限まで一つにしてはならない。

クライアント、サーバー、送信者、UIは別の主体である

クライアントは検索条件、文字集合、並べ替え条件、またはスレッドアルゴリズムを選ぶ。サーバーは現在のメールボックスを読み、ヘッダーを解釈し、規定の変換を実行して、シーケンス番号またはUIDを返す。送信側ソフトウェアは Message-ID、References、In-Reply-To を生成する。最後にUIが線と階層を描く。

各主体が仕様どおり動いても、利用者の結論は誤り得る。偽の References: をサーバーが正しく処理し、クライアントが正しく描けば、誤った親子関係ほど整然と見える。逆に親が見えない場合、検索から外れたのか、保存されなかったのか、既に削除されたのかは木だけでは分からない。

ORDEREDSUBJECT の平坦さは仕様である

RFC 5256 は ORDEREDSUBJECT を “poor man's threading” と呼ぶ。基本件名を定める手順で件名を簡約し、同じ文字列を持つメッセージを集め、送信日で並べる。一番早いものが根になり、その後のメッセージはすべて根の直接の子、互いには兄弟となる。孫は存在しない。

これは壊れた返信解析ではなく、件名によるグルーピングだ。参照ヘッダーが乏しい環境では有用だが、誰が誰に返答したかは示さない。同じ基本件名の無関係なメールが一緒になり、本当の会話でも件名が変われば分かれる。

基本件名も原文そのものではない。符号化語をUTF-8へ変換し、タブ、継続、重複空白をまとめ、定義された返信接頭辞、転送の囲み、末尾記号、角括弧部分を除く。接続中と切断中で結果が食い違わないよう、実装は同じ手順を使わなければならない。これは再現性の規則であり、意味の規則ではない。重要な語が装飾と誤認されれば、不適切な照合になるとRFC自身が警告している。

REFERENCES は不完全な主張を整理する

REFERENCES は References に並んだMessage-IDを用い、条件によっては In-Reply-To の最初の有効なMessage-IDを使う。引用符の違いで同じIDが別物にならないよう正規化し、循環を作るリンクは拒否する。

しかし入力には欠損がある。有効なMessage-IDがなければ計算用の一意IDを与える。同じIDを複数メッセージが名乗れば、最も小さいシーケンス番号の最初の一通だけが保持し、後続には新しいIDを与える。参照先が集合に存在しなければ、同じ欠損を表すダミーメッセージを作る。

その後、子のないダミーは削除される。子があれば削除して子を現在の階層へ昇格させることがある。根直下で形を崩す場合は構造用ダミーを残す場合もある。切り詰められた参照列による競合では、既存リンクを保持したり、新しい末尾参照を優先して切り直したりする。

この手続きは丁寧だが、失われた事実の復元ではない。ダミーは回収されたメールではなく、昇格は中間メッセージが存在しなかった証拠でもない。計算用IDは認証済みの送信者識別子ではない。

ヘッダー系譜の後にも件名による合流がある

REFERENCES はMessage-IDによる木を作った後、根にあるスレッドの基本件名も比較する。同じ非空件名を持つ根は、非返信らしいメッセージを代表に選ぶか、新しいダミー親を置くなどの規則で合流し得る。

UI上の線だけでは、直接の参照、複数IDを経た推定、件名だけによる根の合流を区別できない。エッジごとの由来を保存しなければ、監査者はヘッダーの宣言と表示上の補完を同じ証拠として扱ってしまう。

RFCは、偽の References: が別のスレッドを誤って取り込む可能性を明記する。正規化は表記差を吸収するが、ヘッダーを書いた主体を認証せず、そこで語られた親子関係を保証しない。

日付順にも複数の時計が混じる

SORT も検索を先に行い、その後に指定されたキーを優先順で適用する。文字列は照合規則、日付とサイズは定義された昇順を使う。明示キーがすべて同値ならメールボックスのシーケンス番号が暗黙の最終キーになる。そのため REVERSE SUBJECT は SUBJECT の完全な逆順ではない。

DATE はまず Date: をUTCへ正規化する。無効な時刻帯や時刻には定められた補正が入り、解析できなければ INTERNALDATE を使う。同じ「日付順」の中に、送信者の申告時刻、仕様上の代替値、サーバーの内部日付が共存し得る。

RFC 5957 の表示名ソートも、完全な表示名を解読して使い、なければメールボックス名やホストへ戻るが、言語依存の姓を推測しない。並べ方は宣言された投影であるべきで、普遍的な人名順序を装うべきではない。

運用証跡は木の外側に置く

シーケンス番号よりUIDが適切でも、UIDVALIDITYとメールボックス文脈は欠かせない。RFC 5267 の継続更新やRFC 5182の保存検索結果は、効率的なビュー管理を実現するが、改変不能な履歴を作らない。

重要判断に使うなら、メールボックスの状態、検索条件と文字集合、アルゴリズム、照合、能力一覧と実装版、UIDVALIDITYとUID、原ヘッダー、正規化したMessage-ID、各エッジの生成規則、ダミーの生成・剪定・昇格、件名合流、同値時のキー、結果ハッシュ、描画版を別々に残すべきだ。

「この時点のRFC 5256表示でBはAの下に置かれた」は検証できる。「BはAへの返答として書かれた」には追加証拠が要る。「受信者がAを読み承認した」はさらに別の出来事だ。

便利なスレッド表示を疑う必要はない。ただし、表示が越えていない境界を組織側が勝手に越えさせてはならない。

出典