Кратко

  • IMAP определяет \Seen как «сообщение прочитано», но сервер наблюдает изменяемое состояние ящика: BODY[...] может выставить флаг неявно, BODY.PEEK[...] получает содержимое без этого, а авторизованный клиент способен добавить или убрать его.
  • Вывод о чтении человеком требует связать субъект, клиент, поколение ящика, UID, команду, флаги до и после, ответ сервера и событие показа. Один бит не доказывает внимание, понимание, согласие или ответ.

Человеческий глагол внутри машины состояний

Mark Crispin создал IMAP, чтобы письма оставались на сервере и были доступны разным клиентам из разных мест. Мемориальная запись Stanford сообщает, что он изобрёл протокол, работая системным программистом в 1977–1988 годах. Профиль IETF перечисляет 25 RFC, включая RFC 3501 — многолетнюю основу IMAP4rev1. Unicode Consortium помнит своего давнего участника как специалиста по электронной почте и отца IMAP.

RFC 3501 прямо описывает \Seen: сообщение прочитано. RFC 9051 сохраняет эту семантику в IMAP4rev2. Общее слово делает состояние совместимым между клиентами, но спецификации различают человека — user — и программу — client. Сервер видит команды, выдачу данных и атрибуты, а не взгляд или понимание.

Надёжное утверждение уже: в данный момент ящик содержит стандартный флаг прочитанного. Чтобы говорить о человеке, надо установить происхождение бита.

FETCH пишет состояние, PEEK не делает этого неявно

Если клиент запрашивает часть тела через BODY[...], RFC 3501 и RFC 9051 требуют неявно выставить \Seen. При изменении сервер сообщает новые flags. Получение данных одновременно становится записью метаданных.

BODY.PEEK[...] получает ту же часть без неявной установки. Значит, тело может быть выдано с изменением или без него; STORE может выставить Seen без получения тела; последующая операция может удалить флаг после выдачи.

Эти варианты нужны для предпросмотра, очереди «прочитать позже» и синхронизации. Они же показывают, что бит не является датчиком человека. Индексатор, фильтр, кэш или генератор превью может получить содержимое — это допустимый сценарий, а не утверждение о конкретном продукте. И наоборот, клиент может показать данные PEEK и сохранить состояние «не прочитано». Доказательство сервера заканчивается командой и её эффектом.

Сообщение может попасть в ящик уже Seen

APPEND принимает начальные флаги; обе RFC приводят примеры добавления с \Seen. Тогда бит описывает состояние при помещении, а не чтение новой копии человеком после сохранения.

STORE может добавить или снять флаг. «Пометить всё прочитанным» не требует показывать тела, а «пометить непрочитанным» стирает бит и после внимательного чтения. В делегированном ящике или при нескольких клиентах наблюдаемое состояние мог создать другой уполномоченный субъект.

Поэтому «не прочитано» не равно «никто не читал». Оно лишь означает отсутствие \Seen сейчас. Текущее значение может скрывать получение тела, ручной откат, гонку синхронизации или начальное состояние APPEND.

Права меняют сохраняемый след

RFC 4314 выделяет право s для изменения \Seen. FETCH, который обычно выставил бы флаг, не должен делать этого, если у текущего пользователя нет s. STORE проверяет то же право.

Две личности могут получить одно тело и оставить разные следы: одна сессия запишет бит, другой помешает политика. Отсутствие флага может свидетельствовать о границе полномочий, а не об отсутствии показа.

Модели общих и персональных флагов также различаются. Полный вопрос звучит так: чьё это состояние, в какой модели ящика и по какому праву записано? Личный ящик, общая поддержка и делегированный ящик руководителя не дают одинакового человеческого доказательства из-за одинакового имени.

Порядок изменений не раскрывает человеческую причину

RFC 7162 добавляет CONDSTORE и QRESYNC. Номера модификации помогают обнаружить новое состояние, обновить кэш и связать STORE с UNCHANGEDSINCE. Устаревшая запись может завершиться конфликтом вместо тихой перезаписи.

Но MODSEQ — квитанция порядка, не свидетельство. Он сам не различает неявный FETCH, STORE, другой клиент или внешний агент и не показывает экран или внимание. RFC 8621 переносит идею в JMAP как ключ $seen, который уполномоченный пользователь добавляет и удаляет. Согласованная синхронизация доказывает репликацию состояния, а не расширяет его наблюдение.

Составлять чтение из отдельных квитанций

Защищаемая запись хранит аутентифицированного субъекта, делегирование, экземпляр клиента и сессию. UIDVALIDITY и UID связывают поколение ящика с сообщением. Затем фиксируются причина — BODY FETCH, PEEK, STORE, APPEND, синхронизация или внешний агент, — запрошенная часть, flags до и после, ответ, время и доступный MODSEQ.

Показ интерфейса — отдельное событие, подтверждение человека — ещё одно. Запись «тело получено; Seen выставлен неявно; показ неизвестен; подтверждения нет» менее удобна, чем «прочитано», но не выдумывает свидетеля.

Crispin сделал состояние ящика совместимым. Задача последующих систем — не заставлять его свидетельствовать за человека, которого протокол не наблюдал.

Источники