From 0804d8cc9c204d6004478e65dee0ecdd9da31ac0 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 3 Nov 2026 23:23:19 +0100 Subject: [PATCH] Record history isolation and separate MEMBERS bootstrap work --- doc/group_isolation_plan.txt | 36 ++++++++++++++++++++++++++++++++++++ doc/tasks.md | 9 +++++++++ 2 files changed, 45 insertions(+) diff --git a/doc/group_isolation_plan.txt b/doc/group_isolation_plan.txt index 4534da26f..647bd7069 100644 --- a/doc/group_isolation_plan.txt +++ b/doc/group_isolation_plan.txt @@ -3,6 +3,7 @@ Статус: этап 1 реализован; доработаны CONN_MGR, MEMBER_FILES, GROUP_AVATAR, ADMIN_KEY, RADIO_CALL, routed JOIN, CHAT NAT_DETECTION, MULTICAST_REPORT и ATTACHMENT_KEYS из этапа 2, RADIO/BROADCAST/MULTICAST из этапа 3. +Из этапа 3 также закрыты текущий допуск DB_SYNC PUSH/ACK, MESSAGES и SOUND_SETTING. Из этапа 4 доработаны FILE_TRANSFER, прямой DM, mailbox/custody и попарная доставка личных файлов. Полная матрица ещё не закрыта. Граница отмены дисковых операций согласована с пользователем и реализована (раздел 5). @@ -135,6 +136,23 @@ MEMBERS/Merkle может требоваться до admitted=1 для полу наличие строки, placeholder или tombstone нельзя молча объявить достаточным правом: каждый разрешённый bootstrap/recovery случай должен иметь отдельный тест. +Последовательность следующей доработки MEMBERS: + - Отделить обычный допуск от первого получения состава после JOIN_READY и восстановления + состава при неполной цепочке подписантов. Проверить каждую причину admitted=0 отдельно. + - Сейчас JOIN_INFO_RESP сохраняет запись connection-узла, JOIN_READY завершает локальный + attempt, а свою запись новичок получает только последующим MEMBERS. Поэтому требование + admitted(self)=1 на всём MEMBERS создаёт взаимную блокировку при законном вступлении. + Нужен ограниченный контекст этого обмена (peer/key, channel, attempt, deadline), + существующий до завершения получения состава и отзываемый при cancel/stop/delete. + - Это разрешение относится только к модели MEMBERS. Общий ETCP, любая строка peers, + placeholder, tombstone и старый READY сами по себе не являются основанием восстановления. + Для повторного восстановления после restart отдельно определить проверяемое основание, + не превращая историческую подпись в бессрочный доступ удалённого участника. + - Проверить raw GROUP_INVITE отдельно: действующий INFO_REQ передаёт только group_id, + без invite-ключа, и выдаёт описание канала любому ETCP-пиру. Не считать его уже + ограниченным правилами CHAT_SYNC JOIN_INFO_REQ; унифицировать с актуальным входом JOIN + либо явно ограничить назначение этого старого API и добавить отрицательные тесты. + Для DM/CALL/DEVGROUP/FILE_TRANSFER разделять право пользоваться маршрутом группы и право на личную беседу, вызов или объект. Сохранить проверки адресата и E2E, снимка устройств/эпохи и истории. Смена общей группы для маршрута не должна менять @@ -590,3 +608,21 @@ FILE_TRANSFER и прямого DM. Для реализации mailbox/custody - Это не закрывает общую задачу изоляции всех CHAT-протоколов: STREAM, CALL/DEVGROUP, sync/BGP/bootstrap и полная матрица подмены источника остаются отдельной границей проверки. UTUN не изменён. MEMBER_FILES по-прежнему принадлежит конкретной группе. + +03.11.2026: текущий допуск истории и её настроек. + - До исправления новый сетевой сценарий дал 69 PASS / 9 FAIL: отозванный пир при старом + READY изменял подписанную историю PUSH, отмечал доставку ACK, менял SOUND_SETTING, + создавал MESSAGES-сессию и запускал отложенную отправку. Лог /tmp/chat-sync-isolation-before.log. + - DB_SYNC использует общую проверку текущего допуска self/peer в живой CHAT-группе, + точного ключа ETCP и живого соединения. READY/готовность индекса остаются дополнительными + условиями истории. SOUND_SETTING разрешён допущенному пиру до готовности истории, + а постороннему не создаёт даже состояние SI_PEER. + - Модель MESSAGES проверяет эту же политику до создания сессии, входящей обработки, + фоновой работы и выдачи подготовленного пакета в ETCP. Существующий Merkle waiter + сохранён; диагностика различает отказ модели и потерю транспорта, указывает dataset/type. + - test_chat_group_isolation:84/84, /tmp/chat-sync-isolation-final.log. Проверены отзыв peer/self, + прежний READY, source=1, deleted=1, несовпадение ключа, stopping, повторный допуск, + отложенная работа и уже подготовленный пакет; соседняя история/настройки A продолжают + работать на том же ETCP. test_db_sync_integrity PASS, /tmp/chat-sync-integrity.log. + - MEMBERS/bootstrap пока не изменены: их исключение не переносится на историю/настройки. + Следующая граница описана в 2.4. Транзит BGP-доставки и UTUN не изменены. diff --git a/doc/tasks.md b/doc/tasks.md index 533d2f1da..2543a5cf2 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -63,6 +63,15 @@ Уточнена граница BGP-доставки: права конечного API проверяет конечный получатель; транзитный SVC_ROUTE не проверяет состав группы/предметные права на каждом переходе. Проверка служебных BGP-команд, меняющих локальную топологию принимающего соседа, сохраняется. + Закрыты текущий допуск DB_SYNC PUSH/ACK, модели MESSAGES и SOUND_SETTING: старый READY, + placeholder/tombstone и несовпадающий ключ не дают доступа. История требует допуска self/peer; + SOUND_SETTING допустим до готовности истории, но только от допущенного пира своей группы. + Новый сетевой сценарий до исправления:69 PASS/9 FAIL; после доработки CHAT isolation84/84. + Проверены обе границы отложенной выдачи Merkle, отзыв self/peer, stopping и работа соседней A. + Логи /tmp/chat-sync-isolation-before.log, /tmp/chat-sync-isolation-final.log; db_sync_integrity PASS. + Для MEMBERS осталось разделить обычный обмен, первое получение состава после JOIN_READY + и восстановление после restart; простой admitted=1 блокирует законное вступление, любая + строка peers даёт слишком широкий доступ. Конкретная следующая граница — п.2.4 плана. Подмена источника, raw JOIN/invite, STREAM/CALL/DEVGROUP, sync/BGP/bootstrap и оставшиеся сервисы ещё не закрыты общей гарантией; точная граница проверок — раздел 5 плана. План исправления и критерии по четырём этапам: [group_isolation_plan.txt](group_isolation_plan.txt).