# MUC: протокол и восстановление 0.8.0
Реализация сопоставлена с предоставленной Prosody `cafd74b9c5ea`, прежде всего
`plugins/muc` и `mod_muc_mam.lua`. Известные встроенные возможности перенесены
в Rust; произвольный Lua-код и community-модули Prosody не исполняются.
Неизвестный явно включённый MUC-модуль отклоняется при запуске, а не молча
игнорируется. Список `modules_disabled` применяется с учётом общих и host-настроек,
в том числе для `muc_vcard` и `muc_occupant_id`.
## Что сохраняется
MUC теперь записывает единый журнал компонента `rust_muc_checkpoint`:
конфигурацию комнат, affiliations, текущие nick и роли участников, безопасные
поля presence и ограниченную историю обсуждения. Это относится к persistent
и временным комнатам и работает без MAM. Журнал содержит согласованное поколение
состояния; запись через временный файл, синхронизацию и rename предшествует
возврату результата операции и публикации соответствующих MUC-ответов.
При ошибке сохранения изменение состояния комнаты откатывается в памяти.
Сохранение выполняется при изменениях членства, конфигурации, affiliations,
ролей и истории, а также при штатной остановке. Поэтому восстановление больше
не зависит только от SIGTERM: после SIGKILL используется последнее успешно
зафиксированное поколение. Heartbeat обновляет отметки живых участников даже
в тихой комнате. Неудачный heartbeat фиксируется в журнале сервера; состояние,
которое не удалось сохранить, нельзя считать защищённым от следующего сбоя.
Обычная история без MAM сохраняет порядок, время сообщений и ограничения
`maxstanzas`, `maxchars`, `seconds`, `since`; subject хранится отдельно в
конфигурации комнаты. MAM остаётся самостоятельным архивом и не превращается
в часть одной транзакции со всеми внешними эффектами. Presence-события MAM
и groupchat-запросы остаются раздельными.
## Возвращение участников
Без сохранённой SM-сессии после запуска членство становится ожидающей записью, а не активным
адресатом маршрутизации. Автоматический MUC-вход возможен после новой
аутентификации, bind того же полного JID и общей available presence. Bare JID
или чужой resource не заменяют эту проверку. Обычный явный вход с MUC ``
тоже доступен; актуальные ограничения комнаты проверяются повторно.
Срок ожидания задаёт `muc_recovery_grace_period` в секундах: по умолчанию `300`,
диапазон `1..604800` (значения ограничиваются этими пределами). Живое членство
получает свежую отметку при фиксации и heartbeat. Уже ожидающая запись имеет
фиксированный срок: запросы, неудачные попытки и повторные перезапуски его
не продлевают. Неактивированные временные комнаты удаляются после истечения
срока.
Смена пароля, affiliations или иной конфигурации отменяет старые ожидающие
разрешения. Подтверждённые изменения роли, явный выход и удаление комнаты
попадают в журнал до ответа, поэтому следующая авария не должна возвращать
предыдущую роль или прежний nick. Успешное восстановление создаёт текущее
членство: при следующей аварии восстанавливается его последняя сохранённая
версия, а не навсегда погашенная старая запись.
В checkpoint presence входят только `show`, `status`, `priority`.
MUC-пароли и произвольные расширения presence туда не копируются. При живом
обмене обычные caps, avatar и idle сохраняются; присланные клиентом MUC identity,
occupant-id и hats фильтруются. Пароль комнаты остаётся в её конфигурации.
Если имеется действующая приватная SM-запись Rust, логическая сессия продолжает
членство без транспорта. При запуске повторно проверяются наличие и состояние
аккаунта и текущие ограничения комнаты. Маршрутизация восстанавливается до
приёма клиентов: сообщения для ещё не подключившегося участника попадают в его
сохранённую SM-очередь. Синтетические join presence и история повторно не
отправляются. Доставка по сети требует новой TLS/SASL-аутентификации и корректного
SM-токена того же владельца; native MUC-файлы сами по себе этого не разрешают.
## Native-файлы и переход между серверами
Native config, persistent index и `state/.dat` читаются и экспортируются
для совместимости с Prosody. При работе Rust источником согласованного
восстановления служит его журнал, а native-файлы являются экспортом после commit.
Устаревший экспорт после сбоя не должен возвращать предыдущее членство.
Native state без подтверждающих Rust-метаданных сам по себе не разрешает
автоматический вход.
Редактирование native-конфигурации администратором обнаруживается по отпечатку:
старые разрешения восстановления и история, привязанная к прежней политике,
отбрасываются; удаление ранее экспортированной конфигурации отменяет её
восстановление. Это не универсальное слияние параллельных записей двух серверов.
Для отката на Prosody остановите Rust и сохраните резервную копию всего
`data_path`. Начиная с0.8.3 перед сменой writer выполните новым binary
`rust-xmpp storage-checkpoint CONFIG`: он фиксирует MAM redo и SM JSON exports.
Это не перенос Rust SM-сессий в Prosody и не универсальная конверсия MUC journal.
Подробности — [DURABLE-MESSAGE-IO.md](DURABLE-MESSAGE-IO.md). Prosody использует native-экспорт и не читает Rust-журнал. Перед
возвратом с Prosody на Rust согласуйте данные и устраните устаревший
`rust_muc_checkpoint` в остановленном экземпляре: иначе неизменившиеся native
файлы могут быть приняты за экспорт предыдущего поколения Rust. Удаление
журнала означает отказ от его crash recovery, включая историю временных комнат.
Не запускайте оба сервера с общей записываемой директорией.
## Поддерживаемые политики
- Доступны hats из affiliation data, язык комнаты, роли presence broadcast,
политики PM и модераторских PM, формы конфигурации и offline affiliation presence.
- `muc_vcard` и `muc_occupant_id` управляют соответствующими возможностями.
MAM учитывает `muc_log_all_rooms`, `muc_log_presences`, `muc_log_include_total`.
- `restrict_room_creation`: `false` разрешает создание по умолчанию, `true`
ограничивает его настроенными администраторами, `"local"` — локальными
зарегистрированными пользователями и администраторами. `muc_max_rooms`
ограничивает число комнат; существующее членство не требует повторного
разрешения на создание.
- Регистрация учитывает `allow_unaffiliated_register`,
`enforce_registered_nickname`, `muc_registration_include_form`.
Срок tombstone задаёт `muc_tombstone_expiry` (по умолчанию 31 день).
- Администраторам компонента доступны ad-hoc команды
`http://prosody.im/protocol/muc#destroy` и
`http://prosody.im/protocol/muc#set-affiliation`. Полномочия проверяются
на каждом шаге; изменения проходят обычный механизм фиксации MUC.
Presence probe не создаёт участника и возвращает сведения только допущенному
участнику. Новый вход без MUC `` отклоняется; неизвестные типы presence
не превращаются во вход. Presence errors исключают соответствующую сессию;
message errors делают это для native-набора ошибок доставки. Последняя сессия
получает статус `333`; остальные ошибки приватного сообщения могут быть
переданы адресату. Сообщение с `subject` и `body` либо `thread` остаётся обычным
сообщением и не меняет тему комнаты.
## Границы и проверка
Старые TCP/TLS-сокеты после остановки процесса не существуют. Восстановление
членства MUC и XEP-0198 resume — отдельные механизмы. В 0.8.0 Hub сохраняет resumable
SM-сессии, счётчики и очередь неподтверждённых stanza. Resume проходит на новом
защищённом аутентифицированном транспорте, включая legacy SASL и SASL2;
успешный SM resume восстанавливает MUC без дополнительной available presence.
Входящая stanza учитывается в handled-счётчике после обработки. Heartbeat и
штатная остановка сохраняют снимок; offline deadline не продлевается простыми
проверками или повторными запусками.
SM-снимок приватный: предел 256 MiB суммарно, 8 MiB и 4096 stanza на сессию.
Он не является native-форматом Prosody. Нельзя обещать сохранение сокета или
ровно одну доставку при неопределённом результате сетевой отправки.
Буфер истории ограничен `max_history_messages` (по умолчанию 100, предел 4096),
состояние комнаты — 4096 ресурсами. Большие необязательные поля presence
исключаются из checkpoint; отдельные сообщения истории больше 16 KiB не
восстанавливаются. Общий checkpoint компонента ограничен 16 MiB: превышение
лимита приводит к ошибке записи, а не к успешному подтверждению несохранённого
изменения. Долговечность предполагает исправный диск и файловую систему,
соблюдающую синхронизацию записи.
Команды и результаты проверки версии 0.8.0 публикуются в
[VALIDATION-0.8.0.md](VALIDATION-0.8.0.md). Полный прогон завершён успешно. Общие границы совместимости:
[COMPATIBILITY.md](COMPATIBILITY.md).