diff --git a/doc/chat_audit_findings.txt b/doc/chat_audit_findings.txt index 0e31b8d7..9cad027c 100644 --- a/doc/chat_audit_findings.txt +++ b/doc/chat_audit_findings.txt @@ -14,6 +14,7 @@ Chat: исправление приглашений и проверка конт После rebase на bc623f23 используется общее исправление отмены из origin;итоговый контракт — в разделе rebase ниже. Продолжение26.10.2026 от1899b7f8:начата сверка chat_attachment;подтверждён отказ сохранения ключа до worker при непроверенном SQL bind. Новый результат и граница остановки — в конце отчёта. +По согласованному плану этот дефект исправлен;итоговые контракты и проверки — в разделе исправления chat_attachment ниже. Реализация @@ -399,3 +400,82 @@ savepoint;ошибку откатывать,логировать стадию/к Изменены только комментарии/документация/задача;runtime,wire и штатные тесты не менялись. Новый fullcheck и sanitizers не запускались. По AGENTS.md:10 аудит остановлен на подтверждённом дефекте;задача открыта в doc/tasks.md. Исправление runtime и push не выполнялись. + +Исправление chat_attachment — 26.10.2026, runtime549cc202..71dfc9d7 + +По согласованному пользователем плану добавлена одна локальная операция ak_store_preparation. +send проверяет аргументы/состояние и отвергает внешнюю транзакцию до подготовки задачи. +Операция выполняет собственный BEGIN IMMEDIATE,INSERT всех полей авторской подготовки, +проверяет prepare,восемь bind,step,одну изменённую строку,finalize и COMMIT. +Только после commit выводится подтверждение и source передаётся media_async. +На отказе statement освобождается,собственная транзакция откатывается,ключ в памяти очищается; +возврат-1 не запускает worker и не выдаёт MSG_SUBMITTED,source остаётся вызывающему. +Схема получателя сохраняет допустимый NULL-ключ. Общие ak_step/входящий протокол не менялись. + +После commit задача считается принятой:send возвращает0,в том числе если media_async_submit +синхронно вызвал done с ошибкой. К job после submit не обращаемся. Source удаляет задача, +ненулевой request получает один MSG_SUBMITTED;внешний attachment_publish не дублирует результат. +Речь о собственной подготовленной копии frontend;пользовательский оригинал он сохраняет. +Политика SQLite остаётся WAL/synchronous=NORMAL,поэтому обещается завершённый commit перед worker, +а не сохранность после отключения питания. Wire/ключи/формат контейнера не менялись. + +Отказ rollback с оставшейся открытой транзакцией вызывает chat_attachment_quiesce и +utun_instance_stop без уничтожения ядра из callback. Desktop и обе Android poll-петли, +включая restart,теперь учитывают instance->running. Владелец освобождает core/uasync после poll. +Текущий poll может исполнить остальные callbacks:это штатная граница stop,не немедленное +прерывание диспетчера. В fault-логе db_sync дополнительно отклоняет BEGIN до выхода владельца; +новых workers/событий отправки нет,закрытие SQLite откатывает невидимую reader строку. + +Новый постоянный Linux test_chat_attachment использует настоящие core/chat_service/SQLite/ +OpenSSL/media_async. Точечные wrappers проверяют13 отказов:BEGIN,prepare,8 bind,step,finalize,commit. +После каждого source/прежние строки/количество файлов сохранены,нет worker и события, +autocommit восстановлен;каждый повтор действительно шифрует и публикует сообщение. +Отдельное readonly-соединение перед самым submit сравнивает ключ/UUID/автора/метаданные/пути +побайтно,проверяет завершённый commit;после отправки проверяется связь с message_id. +Дополнительные контроли:реальный commit hook veto,INSERT RAISE(ABORT)/RAISE(IGNORE),сохранность +внешней транзакции,inline-ошибка submit,сохранение опубликованного ключа после restart, +неудачный rollback из posted callback и освобождение владельцем. Баланс u_malloc восстановлен. +Qt test_utun_node проверяет stop ядра через настоящего desktop-владельца; +Android host-профиль проверяет его до/после restart и порядок voice→core→uasync. + +Проверки окончательного runtime + +Native build PASS. Полный check.sh209/209 PASS,0 failed/0 skipped;proxy9/9,burst1/1, +load8/8,134217728 проверенных байт,exit0,174с. Лог /tmp/attachment-key-fix-full-check.log, +логи тестов /tmp/attachment-key-fix-full-netns-logs. Полный прогон выполнен под sudo в +отдельном network namespace с включённым IPv6 loopback,настройки хоста не менялись. +Первый host-прогон206/209:только ncd_faults/ipv6_sockets/route_connectivity отказали на +bind(::1),поскольку net.ipv6.conf.lo.disable_ipv6=1. Это сохранено в +/tmp/attachment-key-fix-full-check-host.log и /tmp/attachment-key-fix-full-logs. +Первый запуск runner также упёрся в tests/logs,принадлежащий nobody;использован штатный +TEST_LOG_DIR в /tmp,права/содержимое прежнего каталога не менялись. + +ASAN/UBSan/LSan8/8 PASS,detect_leaks=1,halt_on_error=1:chat_attachment,attachment_send, +encrypted_attachment,encrypted_file,services,chat_admin,instance_contract,media_primitives. +Копия /tmp/utun-attachment-key-sanitizers согласована с рабочими исходниками; +Opus sanitizer flags добавлены только в этой копии и применены через build.sh. +Core/libuasync/Opus инструментированы ASAN/UBSan. Сводка /tmp/attachment-key-fix-asan-results.log, +полные логи /tmp/attachment-key-fix-asan-logs;сборки /tmp/attachment-key-fix-asan-{build,tests-build}.log. + +Desktop vibechat и тестовые цели CMake PASS,Android assembleDebug --offline PASS,без установки. +Окончательный Qt/Android host-профиль7/7 PASS;/tmp/attachment-key-fix-frontend-results.log, +/tmp/attachment-key-fix-desktop-final-build.log,/tmp/attachment-key-fix-android-final-build.log. +Два первоначальных дефекта новых фикстур исправлены:Qt вызывал finalize до join потока, +Android ожидал detach у штатного joinable worker. В финальных тестах используются stop/join +и наблюдение уничтожения uasync. Начальные логи сохранены в /tmp/attachment-key-fix-desktop-initial.log +и /tmp/attachment-key-fix-android-host-initial.log. Runtime владельцев ради обхода тестов не усложнялся. + +Исходный локальный стенд с обновлённым ожидаемым отказом теперь exit0,defects0,bind_hits1, +allocations0->0:source22 байта сохранён,новых строк/worker/событий нет,два контроля публикуются. +Логи /tmp/attachment-key-fix-original-build.log и /tmp/attachment-key-fix-original.log. +Отрицательный контроль:тот же стенд и текущая libutun с отдельным объектом chat_attachment.c +из d877e888,подставленным перед архивом. Первый положительный контроль проходит,затем старый +send после bind-отказа пишет «key saved» и принимает worker;проверка возврата-1 ожидаемо +завершается SIGABRT/exit134. Это отказ assert контракта,не memory fault. Перед запуском задан +ulimit -c0;отдельный core для контроля не извлекался. +Логи /tmp/attachment-key-fix-negative-build.log и /tmp/attachment-key-fix-negative.log. +Рабочая копия не откатывалась;прежний исходный лог аудита /tmp/chat-attachment-audit.log сохранён. + +Задача сохранения ключа закрыта. Заголовок и encrypted_attachments.md уточнены; +их отметки[~] в чеклисте сохранены:полный аудит остальных операций attachment/chat не выполнен. +Windows/FreeBSD build/runtime не проверялись. git diff --check PASS. Коммиты локальные,push не выполнялся. diff --git a/doc/service_lifecycle.md b/doc/service_lifecycle.md index 721a5c8b..4706d9e8 100644 --- a/doc/service_lifecycle.md +++ b/doc/service_lifecycle.md @@ -31,8 +31,14 @@ Desktop подтверждает start только после готовнос Повторный start работающего сервиса и повторный stop допустимы. Ошибка старта UTUN/чата откатывает созданные им ресурсы; ошибка core start оставляет подготовленные ресурсы для retry/destroy. `utun_instance_init()` сохраняет ранее запущенные сервисы -при отказе последующего. `utun_instance_stop()` останавливает цикл +при отказе последующего. `utun_instance_stop()` снимает `running` и будит цикл приложения; освобождение ядра выполняет `utun_instance_destroy()`. +Desktop и Android проверяют `instance->running` вместе со своим флагом остановки, +включая Android-цикл после restart. Запрос из callback завершает цикл после возврата +из текущего poll; уже начатая обработка остальных callbacks этого poll не прерывается. +Владелец затем снимает media-привязки, уничтожает ядро и освобождает uasync. +Это используется также при отказе rollback авторской подготовки вложения, если SQL-транзакция +осталась открыта: модуль вложений предварительно прекращает приём и снимает свой таймер/router. Create уже подготавливает listeners, топологию/SQLite, router/proxy и мониторинг; core/UTUN/chat запускаются отдельно. `create_from_str` использует временный файл diff --git a/doc/tasks.md b/doc/tasks.md index 64f32616..a958c923 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -4,16 +4,21 @@ ## Текущие задачи -[ ] **chat_attachment: проверять сохранение ключа до передачи source и запуска worker** — подтверждено26.10.2026. - send не проверяет bind ключа;при SQLITE_NOMEM INSERT сохраняет key=NULL,но пишет «key saved», - возвращает0 и запускает настоящий crypto worker. Контейнер создан,source удалён;публикация затем - правильно блокируется chat_attachment_bind и выдаёт один MSG_SUBMITTED/failure. - Локальный стенд с настоящими core/chat_service/SQLite/workers:контроли до/после PASS, - при точечном отказе key bytes0/autocommit1,defects1,bind_hits1,allocations0->0,ожидаемый exit1. - Требуется проверенный SQL commit до worker,rollback/сохранение source при отказе и регрессии SQL/fault/retry. - Логи /tmp/chat-attachment-audit-build.log и /tmp/chat-attachment-audit.log;стенд /tmp/chat-attachment-audit.c/.mk. - Подробности: [chat_audit_findings.txt](chat_audit_findings.txt),продолжение chat_attachment. - chat_attachment.h/encrypted_attachments.md остаются [~];по AGENTS.md аудит остановлен,runtime не менялся. +[+] **chat_attachment: проверять сохранение ключа до передачи source и запуска worker** — исправлено26.10.2026. + Авторская подготовка фиксируется собственной BEGIN IMMEDIATE/COMMIT до передачи source и запуска worker. + Проверяются prepare/восемь bind/step/одна строка/finalize/commit;отказ откатывается,source остаётся caller. + Внешняя транзакция запрещена;после commit синхронный отказ worker даёт один MSG_SUBMITTED при возврате0. + Неуспешный rollback с открытой транзакцией снимает модуль и запрашивает stop;desktop/Android,включая restart, + выходят после poll и освобождают ядро вне callback. Политика WAL/NORMAL и wire не менялись. + test_chat_attachment:13 SQL-отказов,реальный commit veto,INSERT ABORT/IGNORE,внешняя транзакция, + точный ключ/метаданные через readonly SQLite до worker,настоящие повторы,inline-отказ,restart и rollback fault. + Native build/check.sh209/209 PASS,0 skipped,proxy9/9,burst1/1,load8/8 (134217728байт),174с; + полный check выполнен в частном netns с IPv6 loopback — на хосте IPv6 lo отключён. + ASAN/UBSan/LSan8/8 PASS,detect_leaks=1;core/libuasync/Opus инструментированы согласованно. + Desktop/APK build PASS;Qt/Android host7/7 PASS. Исходный стенд теперь defects0,allocations0->0; + отдельный старый объект из d877e888 ожидаемо нарушает новую проверку,без отката рабочей копии. + Подробности: [chat_audit_findings.txt](chat_audit_findings.txt),исправление chat_attachment;/tmp/attachment-key-fix-*.log. + Полный аудит chat_attachment/chat остаётся [~];прочие операции SQL и платформы Windows/FreeBSD не закрыты. [+] **member_files: безопасное завершение completion при stop из uasync batch** — исправлено26.10.2026. После rebase на bc623f23 сохранена общая отмена из93ec1222:task удаляется и освобождается