From aea8ca7236ee0ddd352cf5902ca4f28921e5c744 Mon Sep 17 00:00:00 2001 From: evgeny Date: Mon, 26 Oct 2026 14:39:21 +0100 Subject: [PATCH] Close feedback admission fix with full integration and sanitizer verification --- doc/member_merkle_audit_findings.txt | 93 ++++++++++++++++++++++++++-- doc/tasks.md | 33 +++++----- 2 files changed, 103 insertions(+), 23 deletions(-) diff --git a/doc/member_merkle_audit_findings.txt b/doc/member_merkle_audit_findings.txt index 203a81eb7..120cf8c61 100644 --- a/doc/member_merkle_audit_findings.txt +++ b/doc/member_merkle_audit_findings.txt @@ -1,9 +1,10 @@ member_sync / merkle_sync — аудит контрактов, 26.10.2026 -Текущий статус: продолжение аудита остановлено на отказе feedback/chat_sync init -после исключения автора сохранённой реакции; новый дефект описан в разделе7. -Проверка плана выявила также отложенную зависимость приглашения и её межканальное -разрешение; прежнего SQL-фильтра и обновления только изменённого автора недостаточно (раздел8). +Текущий статус: дефекты очистки MEMBERS и запуска feedback исправлены и проверены. +Исключение скрывает результаты, сохраняя историю; отложенные ключи и их межканальное +разрешение поддерживаются. Архитектурные пробелы раздела8 устранены реализацией раздела9. +Окончательный check.sh:200/200, proxy9/9,burst1/1,load8/8,exit0,186с; +ASAN/UBSan/LSan:15/15 PASS. Полный аудит остальных контрактов чата остаётся частичным. Согласованное исправление очистки реализовано и проверено, его задача закрыта. Общий набор200/200 PASS, proxy9/9,burst1/1,load8/8 PASS; ASAN/UBSan/LSan11/11 PASS с detect_leaks=1. Подробности и ограничения — раздел6. @@ -378,3 +379,87 @@ Exit0 означает подтверждённый контрпример с в feedback — chat_feedback, представление опросов — chat_poll. Независимые копии признака допуска, снятие общей проверки radio/attachments и запись индекса из post-commit callbacks не являются согласованным решением. Полная реализация и её проверка остаются отдельным этапом. + +9. Реализация feedback: активный набор, зависимости и восстановление + +Реализован выбранный пользователем контракт: неактивные реакции/ответы исчезают +из результатов, выдачи и Merkle-набора, но сохраняются в feedback_ +вместе с ver, подписью и нулевым состоянием отмены. При восстановлении допуска +сохранённое состояние заново проверяется и может распространяться новым пирам. +Wire v3/feedback v1 и формат подписанной записи не менялись; добавлен индекс (node_id,bucket). + +Проверки удостоверения сосредоточены в member_sync_author_key: ACTIVE, INACTIVE, +PENDING, INVALID, ERROR. Только ACTIVE записывает выходной ключ. Недостающий сертификат +или доверенный ключ отличается от недействительной подписи и отказа SQL/OpenSSL. +Старый verified_ed25519 по-прежнему допускает radio/attachments только при ACTIVE. +source=0/deleted=0 — необходимый фильтр, но не доказательство полного допуска. + +chat_feedback использует один fb_read_active для восстановления, хеша и страницы: +проверяются текущий допуск, подпись состояния, канонические record_key/bucket. +Неактивная/ожидающая история не включается в индекс; ошибка проверки не маскируется пустым листом. +Init строит активный индекс в одной транзакции после начального purge MEMBERS. +Входящие INACTIVE/PENDING не сохраняются и не ломают остальные корректные записи страницы. +Локальный set проверяет допуск до сравнения со старым значением, включая no-op. +chat_poll использует тот же author_key до декодирования и учёта ответа/реакции. + +При изменении удостоверения, общего Ed25519-ключа или deleted пересчитываются +feedback-листья автора и зависимых от его ключа signed_by во всех каналах. +Пересчёт входит в транзакцию изменения MEMBERS/общего ключа; ошибка откатывает оба индекса. +PENDING не блокирует корректную запись участника, даже если signer приходит позднее. +До регистрации FEEDBACK hook ничего не делает; startup rebuild затем учитывает результат purge. +Сохранённая активность автора отдельно в БД не дублируется. + +MS_APPLY_FEEDBACK переносит факт изменения удостоверения/ключа/допуска через внешнюю транзакцию. +Страница и JOIN сохраняют полную маску apply до вызова record_committed после внешнего commit. +Обычные profile/name/stream options меняют MEMBERS, но не пересчитывают feedback и не будят его сессии. +Post-commit уведомления читают адреса сообщений без живого cursor через callback. +После физического purge сохраняются feedback и барьеры ver у отмен; уведомления идут после commit. + +Сетевой сценарий выявил также зависший старый раунд после исключения пира: +пакет уже отброшен по допуску, а восстановление членства само по себе не завершает ожидание. +merkle_sync_revalidate_peers после commit/changed завершает ожидания MT_ERR_DATA, +освобождает tx/waiter/deadline и оставляет подписку FAILED. При возврате changed начинает +новый раунд BEGIN/WAKE через прежний UP-транспорт. Callback вправе отменить сессию; +обход после callback не использует старый указатель. MEMBERS/другие datasets не затрагиваются. + +Штатные регрессии: +— test_chat_feedback: исключённый другой автор, реакция/ответ/отмена, сохранность подписей/ver, + два канала, restart, запрет локального no-op/отмены, смешанная страница, физический purge, + возвращение без возрождения старой версии, неизвестный signer и его поступление только в1002. + Проверены SQL lookup/index failure, SQLite commit veto и внешние rollback/commit без ранних событий. + Подписанное обновление профиля оставляет feedback-корень/события неизменными. +— test_member_adapter/test_member_purge: дополнительная проверка ERROR и неизменности выходного + ключа при отказах двух стадий Ed25519, SHA256 и prepare/bind/step/finalize. +— test_merkle_protocol: отзыв допуска при заблокированных QUERY/ERROR, освобождение ожидания, + сохранение подписки, новый раунд после возврата, callback с удалением своей сессии. +— test_chat_poll_network: четыре настоящих ядра/UDP, A↔B↔C, исключение A, полный stop/start C, + поздний D без feedback исключённого A, возврат A, догон D и новая отмена от A по прежнему транспорту. + Проверены JSON-результаты, сохранённые версии/подписи/отмены и совпадение Merkle-корней. + +Первый расширенный сетевой запуск остановился в стенде: D открыл группу до входящего UP. +Ожидание транспорта добавлено; затем тест обнаружил и помог исправить ожидание отозванного раунда. +Первый sanitizer-прогон дал12 PASS, затем test_stream_service остановился на временном +assertion line1630 (99–150 мс); отчёта ASAN/UBSan не было. По логу устранены лишние пустые +feedback-раунды при профилях/stream options. Временные границы stream-теста не ослаблялись. +Повторный полный профиль без параллельной нагрузки проходит15/15, включая stream_service. + +Сборка обычного ядра/тестов PASS. До оптимизации отдельный check.sh дал200/200 и все +сетевые интеграции,exit0,193с: /tmp/feedback-author-fix-full-check.log. +Окончательный check.sh текущего кода:200/200 PASS,0 failed/0 skipped, proxy9/9, +burst1/1,8388608 байт, load8/8,134217728 байт,exit0,186с. +Лог /tmp/feedback-author-fix-full-final-check.log. Запущен через sudo -n unshare -nm +с собственным /run и новым lo; сеть, firewall и /run хоста не менялись. +Профильные логи /tmp/feedback-author-fix-native-final-{feedback,member,protocol,network}.log. + +ASAN/UBSan/LSan:15/15 PASS, detect_leaks=1:halt_on_error=1:abort_on_error=1, +UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1, отдельный user/network namespace. +Изолированная сборка /tmp/utun-member-purge-sanitizers; подтверждены __asan_/__ubsan_ +в core/libuasync/Opus,12 изменённых C/header-файлов побайтно совпадают с рабочим кодом. +Логи /tmp/feedback-author-fix-asan-final-results.log, -final-run.log и -final-test_*.log; +согласованность /tmp/feedback-author-fix-{asan-consistency,source-consistency}.log. +Предварительные отказы сохранены в /tmp/feedback-author-fix-network*.log и -asan-test_stream_service.log. + +Ключевые коммиты:606c32f3,5e125755,0877930e,c0095c54,23329a44; +штатные регрессии c4a6a128,9750fd22,f6a72c16,1720945d. Коммиты локальные, push не выполнялся. +Исправление закрыто. Это не завершает исходный аудит member/Merkle, db_sync и всех callers: +частичные отметки чеклиста сохранены. Native Windows/FreeBSD, GUI и Android не запускались. diff --git a/doc/tasks.md b/doc/tasks.md index 43bac65f6..e9d588f69 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -4,25 +4,20 @@ ## Текущие задачи -[ ] **feedback: сохранённая реакция исключённого автора блокирует запуск чата** — обнаружено 26.10.2026. - chat_feedback_init проверяет историю через member_sync_verified_ed25519 с deleted=0; - после штатного подписанного deleted=yes сохранённый feedback приводит к -1. - На отдельной SQLite :memory: с настоящими подписями: активный автор/restart PASS, - после исключения feedback_init=-1 и chat_sync_init=-1; собственный участник и второй канал валидны. - Подписанное восстановление ver=2 снова даёт init=0, исходная запись сохраняется; tracked allocations восстановлены. - Стенд /tmp/member-merkle-feedback-restart.c и .mk; полный лог /tmp/member-merkle-feedback-restart.log,exit1,2/2 FAIL. - Пользователь выбрал: скрывать реакции/голоса исключённого автора из результатов, - сохраняя записи, версии и отмены в БД; нужен согласованный init/apply/hash/page/подсчёт. - Проверка плана выявила: source=0/deleted=0 не гарантирует подтверждённое приглашение. - Корректное обновление принимается с отсутствующим ключом signed_by, feedback_init=-1; - добавление signer только в1002 делает неизменённого автора1001 снова проверяемым. - Стенд /tmp/member-merkle-feedback-plan-review.c, лог /tmp/member-merkle-feedback-plan-review.log,exit0: - assertions подтверждают контрпример на исходном runtime, не исправленную реализацию. - План требует отдельного статуса ожидания зависимостей и пересмотра зависимых авторов/каналов; - немедленная проверка feedback не должна блокировать корректную пачку MEMBERS до прихода signer. - Нельзя просто ослабить общий verifier текущего допуска или пропустить отказ init с неполным индексом. - Реализация не менялась; аудит остановлен по AGENTS.md:10. Прежние200/200 и sanitizer11/11 этот случай не покрывают. - Подробности: [member_merkle_audit_findings.txt](member_merkle_audit_findings.txt), разделы7–8. +[+] **feedback: исключение и отложенное удостоверение не блокируют запуск чата** — исправлено 26.10.2026. + Исключённые/ожидающие авторы скрываются из результатов, Merkle и выдачи; записи, ver и отмены сохраняются. + Единый member_sync_author_key различает ACTIVE/INACTIVE/PENDING/INVALID/ERROR; radio/attachments остаются строгими. + Изменение удостоверения/deleted/общего ключа атомарно обновляет зависимые feedback-листья во всех каналах. + Отложенный signer не блокирует MEMBERS; поступление его ключа через другой канал включает допустимую историю. + MS_APPLY_FEEDBACK переносится через внешний commit; профиль/stream options не запускают лишние раунды. + Отзыв завершает ожидание текущего раунда, сохраняя подписку; возврат запускает обмен по прежнему UP-транспорту. + Регрессии: restart, реакция/ответ/отмена, purge, два канала, межканальный ключ, mixed page, + SQL/index/commit faults и внешний rollback без событий; новый сетевой D и новые изменения вернувшегося A. + Окончательный check.sh200/200 PASS,0 failed/0 skipped; proxy9/9,burst1/1,load8/8 (134217728 байт),exit0,186с. + ASAN/UBSan/LSan15/15 PASS,detect_leaks=1; core/libuasync/Opus инструментированы согласованно. + Логи /tmp/feedback-author-fix-full-final-check.log и /tmp/feedback-author-fix-asan-final-results.log. + Исправление закрыто; полный аудит остальных контрактов остаётся частичным, push не выполнялся. + Подробности: [member_merkle_audit_findings.txt](member_merkle_audit_findings.txt), раздел9; исходные дефекты — разделы7–8. [+] **member_sync: атомарная очистка повреждённых записей с передачей ошибок** — исправлено 26.10.2026. Очистка владеет транзакцией канала от чтения до commit удаления/индекса; чужая транзакция