COMPAX І MATRIX
Одна відмінність
і що з неї випливає
Matrix — зрілий федеративний месенджер, і більшість того, що пишуть, порівнюючи ці два, пишуть люди, які не користувалися жодною з цих баз коду. Те, що нижче, прочитано в обох.
Виміряно 27 серпня 2026 року. Synapse: 246 976 рядків Python — 71 349 лише у сховищі. Continuwuity, друга реалізація тієї самої мережі, 95 220 рядків Rust. Цей сервер: 17 041 рядок. Обидві сторони рухаються, і половина того, що нижче, — про сьогодні, а не про природу речей; місця, які про природу речей, позначені.
РОЗХОДЖЕННЯ
Хто вирішує,
що таке кімната
- Кімната — це DAG подій, кожна з яких несе власний ланцюг авторизації.
- Коли сервери не згодні, це залагоджує state resolution v2.
- Звідси групи стану, передні й задні краї, викиди, backfill — і 71 349 рядків лише в шарі сховища.
- Commit приймається локально навіть тоді, коли мережа розпадається, а зливається потім.
- Сервер — це служба доставки. Один порядок, який тримає дім кімнати.
- Порівняй епоху, додай під тим самим замком. Немає чому розходитися.
- Тож немає ні DAG, ні state resolution, ні backfill.
- А commit потребує подорожі додому й назад і на перегонах отримує
409.
Обмін чесний в обидва боки, і MLS не лишає тут вибору: застосування commit знищує секрети попередньої епохи. Немає куди відкочуватися.
ТВЕРДЖЕННЯ, ЯКЕ ВАРТО СФОРМУЛЮВАТИ ТОЧНО
«Їхній сервер читає твої повідомлення»
хибне в обидва боки
У зашифрованій кімнаті Matrix тіло повідомлення — це шифротекст, і сервер його не читає: Megolm, точно так само, як тут MLS. Те, що правда, вужче — і для більшості людей гірше.
- Шифрування — це перемикач на кімнаті. У публічних кімнатах його зазвичай немає, і там усе можна прочитати.
- Стан кімнати не шифрується ніколи: назва, тема, аватар, членство, запрошення, power levels — відкритим текстом навіть у зашифрованій кімнаті.
- Це не недогляд. Сервер застосовує до подій правила авторизації, отже мусить уміти їх прочитати.
- Хто з ким у кімнаті, хто кого запросив і коли — їхньому серверу видно завжди.
- Тут це живе в дереві MLS. Сервер бачить
group_idі епоху. - І наслідок, який легко проґавити: серверний пошук у зашифрованих кімнатах у них не працює взагалі. Element шукає локально — тож у пошуку це відстає від Element, а не від Matrix.
КУДИ КОЖЕН КЛАДЕ ЗУСИЛЛЯ
Куди йдуть зусилля
- Пережити розпад мережі, бо DAG потім зливається.
- Дванадцять версій кімнати випущено і змігровано на живій мережі.
- Масштаб, доведений у полі: stream writers, карти інстансів, реплікація Redis.
- Модерація вглиб — адмінський API, ACL кімнати, карантин медіа, процес MSC.
- Сторонні реалізації перевіряються як чорні скриньки через Complement.
- Відновлення після втрати всіх пристроїв — через серверну резервну копію ключів.
- Назовні є
group_idі епоха, і саме цього потребує впорядкування. - Особу видає не сервер: кореневий ключ підписує атестацію пристрою, і кожен перевіряє її локально.
- Порядок коштує один рядок — compare-and-set, виміряно 239 дописів на секунду в кімнаті.
- Push не несе нічого. Їхній несе
room_id, тож кімната однаково доходить до постачальника пушів. - Дзвінок успадковує свою кімнату: ключ медіа походить із секрету епохи, тож вилучення учасника побічно вилучає його і з медіа.
- Боти — це листки дерева, а не гак через сервер: немає місця, де відкритий текст лежав би заради бота.
- Скаргу можна довести: доказ повідомлення показує авторство. Megolm — груповий ключ і не доводить нічого.
- Гроші, які група тримає разом, чого в Matrix немає взагалі.
НАСЛІДКИ
Чого кожен протокол
не може
Це не табло. Кожен рядок — ціна вибору, що стоїть над ним, і в обох стовпцях є речі, яких відповідна сторона воліла б не мати.
Matrix
Compax
Тіла повідомлень у зашифрованій кімнаті
Шифротекст. Megolm — сервер їх не читає.
Шифротекст. MLS — те саме.
Чи ввімкнене шифрування
Перемикач на кімнату, m.room.encryption. Публічні зазвичай без нього, і там сервер читає все.
Це не перемикач. Немає незашифрованої кімнати, у якій можна опинитися.
Стан кімнати — назва, тема, членство, запрошення, power levels
Відкритим текстом, завжди, навіть у зашифрованій кімнаті. Це не недогляд: сервер застосовує правила авторизації, отже мусить їх читати.
У дереві MLS. Сервер бачить group_id і епоху.
Хто з ким у кімнаті
Серверу видно, завжди.
Не видно. Саме це, а не текст повідомлень, і є справжня відмінність.
Серверний пошук у зашифрованій кімнаті
Не працює взагалі — у зашифрованої події немає content.body, який можна проіндексувати. Element шукає локально.
Теж не працює, і з тієї самої причини. Вихід той самий, який обрав Element: індекс у клієнті.
Commit, прийнятий під час розпаду мережі
Так. Подія приймається локально, а потім її зливає state resolution.
Неможливо. Застосування commit знищує секрети попередньої епохи — два commit в одній епосі це два несумісні стани ключів.
Історія після втрати всіх пристроїв
Серверна резервна копія ключів під ключем відновлення — теж наскрізна.
Зникає. Обгортка, яку відкривала б сама лише фраза, була б постійним доступом, якого ніхто не міг би відкликати; від неї відмовилися свідомо.
Правила кімнати, які дотримує сервер
Так — power levels, і сервер відхиляє подію, яка їх порушує.
Ні. Політика працює в тіні: рахує розбіжності й не відхиляє нічого, бо відхилений чинний commit не псує групу MLS, а завершує її.
Попередній перегляд посилань, модерація за вмістом, push із текстом
Можливо всюди, де кімната не зашифрована.
Неможливо. Це не «поки що ні» — це те, чим сплачено за все інше.
Гроші, які тримає група
Не частина протоколу.
П’ять мереж, ключ кожного підписанта на його власному пристрої, і платіж приходить повідомленням.
І ДЕ ВОНИ СХОДЯТЬСЯ
Однаково з обох боків
Postgres для того, що має лишитися, і Redis для того, що має бути швидким. Відра токенів на дію. Історія на другому пристрої — у них резервна копія ключів, тут запечатані вікна й передача через QR. Наростаюче очікування при повторі до мертвого вузла. Пакування багатьох записів в один запит. Оголошення версії через HTTP. Блокування постачальника. Відсіювання дублікатів на прийомі. Вкладення поза журналом подій. Prometheus і правила тривог. І жодного серверного пошуку в зашифрованій кімнаті — з жодного боку.
ДАЛІ
Питання,
які виникають першими
Шістнадцять із них, з прямими відповідями — включно з тими двома, де відповідь не з приємних.