Keep the borrowed audio provider on UTUN_INSTANCE across chat service restarts. Attach and detach Android voice from the core worker and reject DSP startup after detach. Preserve TX owner epochs, pending slots and foreign-instance RX isolation. Remove the unused cross-thread online API and keep its check local to call.c. Add eight lifecycle regressions with real cores and the Android host bridge. Audit public call, DSP, clock, headless and desktop audio contracts and record the findings and validation scope. Validation: voice/desktop 38/38, four native call suites, native and both Android ABI builds, full check 204/204 plus proxy/burst/load. JVM results remain Gradle UP-TO-DATE (155 app and 15 router). No hardware runtime validation.
178 KiB
Задачи по проекту
Сюда пишется список задач с короткой аннотацией. Если задача большая и имеет ТЗ - то ТЗ оформляется отдельным файлом, а сюда помещается аннотация и ссылка на ТЗ.
Текущие задачи
[+] DM media: восстанавливать завершение TTL после SQL-отказа при EXPIRED — исправлено 26.10.2026. EXPIRED/REJECT атомарно освобождают назначение и сбрасывают текущий holder; все результаты SQL проверяются. Таймер завершает stored-назначение по сохранённому expires при offline B/потерянном EXPIRED и после restart. Для неподтверждённого STORE сохраняется повтор с ответом custody/tombstone M; квитанция B не отменяется. test_dm_media:18 отказов prepare/bind/step/finalize двух UPDATE и commit для EXPIRED/REJECT, точный rollback, повтор, дубликат и поздний STORED; реальная сеть A/B/S/M с потерянным EXPIRED, SQL-отказом, restart S, восстановлением TTL и поздними STORE/STORED; allocations0->0. Старый координатор ожидаемо FAIL новой регрессии; исходный one-shot IOERR-стенд теперь phase9 PASS. Независимое readonly чтение по точному UUID:на M custody0/tombstone1,на S holder0/stored0/expired1/released1, без ложной квитанции; прежняя доставленная квитанция сохранена. Native/санитайзеры подтверждают те же состояния. Build/DM-профиль8/8 PASS;ASAN/UBSan/LSan8/8 PASS,detect_leaks=1,core/libuasync/Opus инструментированы. Полный check.sh205/205 PASS,0 failed/0 skipped;proxy9/9,burst1/1,load8/8 (134217728байт),exit0,173с. Подробности: dm_audit_findings.txt,раздел11; /tmp/dm-expiry-fix-*.log. Общий аудит DM остаётся частичным;платформенные GUI/Android/Windows/FreeBSD не проверялись.
[+] DM: сохранять границы UTF-8 при усечении имени собеседника — исправлено 26.10.2026. Единый предел DM_PEER_NAME_MAX=63 байта; создание, загрузка, входящее автосоздание и JSON копируют только целые code points. Повреждённый суффикс отбрасывается с WARN и точным смещением. Снимок нормализует также fallback из nodes без изменения БД; обычная запись сохраняет нормализованное имя. test_dm_names:68 случаев создания/SQL/load/save/fallback/restart, ASCII и 2/3/4-байтовые границы, overlong/surrogate/>U+10FFFF/оборванные последовательности/NUL/JSON escapes; allocations0->0. Независимый Python-парсер:273 JSON-снимка,9452 строки,строгие UTF-8/JSON и предел63 PASS. Старый core ожидаемо FAIL новой регрессии; исходный пример32×«Я» теперь сохраняет62байта и валидный JSON. Сборка/DM-профиль8/8 PASS; ASAN/UBSan/LSan8/8 PASS,detect_leaks=1,core/libuasync/Opus инструментированы. После rebase на fa76447f:build/check.sh205/205 PASS,0 failed/0 skipped; proxy9/9,burst1/1,load8/8 (134217728 байт),exit0,175с;273 JSON-снимка повторно PASS. Подробности: dm_audit_findings.txt,раздел9; /tmp/dm-utf8-fix-*.log. Исправление закрыто; полный аудит DM остаётся частичным, аппаратные GUI/Android не проверялись.
[+] call_audio: сохранить регистрацию при stop/start чата и согласовать Android lifecycle — исправлено 26.10.2026. Заимствованный audio_ops хранится у UTUN_INSTANCE и переживает пересоздание call_ctx; повторный init не нужен. Идемпотентный init того же owner сохраняет эпоху/занятые TX-слоты. Init/destroy выполняются в uasync; Android worker привязывает voice до SERVICE_STARTED и снимает привязку перед destroy при stop/restart/ошибке запуска. GUI больше не читает raw instance для lazy-init; поздний start без ядра отклоняется. Восемь новых регрессий с реальными ядрами/Opus/worker PASS, allocations0->0; общий voice/desktop38/38 PASS. Диагностика/исправление: call_audit_findings.txt,разделы18–19; /tmp/call-registration-fix-{voice-tests,native-build,android-build,full-check}.log.
[+] call/JNI: удалить неиспользуемый межпоточный online-API — исправлено 26.10.2026. call_is_online обещал любой поток, но напрямую читал uasync-очереди topo_groups/group_nodes без синхронизации. Диагностика на двух настоящих ядрах: owner и post в uasync PASS; прямой worker — два поиска в чужом потоке, ожидаемый FAIL, без конкурентного удаления объектов; cleanup во всех трёх режимах allocations0->0. Внешних потребителей Android-метода нет: удалены Kotlin/JNI/C bridge и публичная декларация, проверка стала static внутри call.c и выполняется из call_start в uasync. Алгоритм проверки сохранён. Native build и Android assembleDebug для arm64-v8a/x86_64 PASS; Android/JVM170/170 PASS. Отсутствие старого API проверено в исходниках, core archive, Kotlin-классе и обеих JNI-библиотеках APK. check.sh204/204 PASS,0 failed/0 skipped;proxy9/9,burst1/1,load8/8,exit0,176с. Подробности: call_audit_findings.txt,раздел17; /tmp/call-online-thread-audit-{owner,worker,posted}.log, /tmp/call-online-fix-{validation,full-check}.log. Общий аудит call остаётся частичным; чек-лист6[V]/5[~]/10[ ] не менялся.
[+] Android CallAudioRouter: владение Bluetooth proxy при stop/restart — исправлено 26.10.2026. Поколение запроса и общий монитор start/stop/BT callbacks исключают принятие proxy старого lifecycle. Disconnect сохраняет owner до close; stop отсоединяет ссылки и закрывает через создавший adapter, поздний connected закрывает свой proxy. Диагностика содержит proxy/generation/accepted и ошибки API. Отдельный JVM-модуль компилирует production router с управляемой моделью Android API:15/15 PASS, включая64 конкурентных callback/stop и I/O start с задержанным callback; после cleanup0 proxy/callbacks. Прежний исходник:штатный контроль PASS,три ownership-сценария ожидаемо FAIL. Android clock/trace/buffer/recovery26/26,voice/desktop30/30,нативная сборка и assembleDebug для двух ABI PASS. check.sh204/204 PASS,0 failed/0 skipped;proxy9/9,burst1/1,load8/8,exit0,173с. Fixtures не входят в APK;Bluetooth/Binder/звук на устройстве не проверялись. Общий аудит call остаётся частичным. Подробности: call_audit_findings.txt,раздел15; /tmp/call-bt-fix-{gradle,negative,voice-tests,full-check}.log.
[+] Android call mute: настоящий PCM и флаг mute передаются через JNI до core — исправлено 26.10.2026. Kotlin передаёт исходный buf и snapshot muted на кадр; NativeLib/JNI/C bridge вызывают feed_pcm_muted. AEC/AGC продолжают получать микрофон, mute зануляет PCM непосредственно перед Opus; wire/DSP/desktop не менялись. Добавлен секундный mutedFrames и контекст feed-отказа. Постоянный test_android_call_mute:5/5 PASS — AEC/AGC on/off,20 кадров до mute/во время/после,PTS/эпоха и360 TX callbacks,allocations0->0; контроль раннего mute воспроизводит ненулевой сигнал. Прежнее тело bridge даёт ожидаемый FAIL с полным cleanup. Native build PASS; voice/desktop-профиль30/30 PASS; Android unit14/14 PASS; assembleDebug arm64-v8a+x86_64 PASS, JVM/JNI descriptor (J[SZJ)Z сверён. check.sh203/203 PASS,0 failed/0 skipped;proxy9/9,burst1/1,load8/8,exit0,168с. Подробности: call_audit_findings.txt,раздел14; /tmp/call-android-mute-fix-{voice-tests,voice-details,negative,android-final-build,android-unit,full-check}.log. Установка/звонок на устройстве не выполнялись; общий аудит голосового и платформенного кода остаётся частичным.
[+] call_headless: целостность PCM-кадра при переполнении TCP-очереди — исправлено 26.10.2026. Header/PCM собираются до отправки; очередь принимает целый кадр или отбрасывает его целиком. Частичная запись сохраняет хвост перед следующими кадрами. Потери учитываются отдельно для клиента/сервиса; WARN содержит причину/состояние очереди, итоговые счётчики выводятся при закрытии/destroy. Постоянный test_call_headless_queue:11/11 PASS — TCP/uasync/Opus, EAGAIN/short-write, точная ёмкость, переполнение после частичного drain, следующий кадр, destroy с очередью и недопустимый размер/NULL. Весь полученный поток сравнивается с независимым decoder, allocations0->0; старый код ожидаемо FAIL. Штатный e2e1/1 PASS; native build PASS; check.sh203/203 PASS,0 failed/0 skipped, proxy9/9,burst1/1,load8/8 (134217728 байт),exit0,188с. Полный аудит call остаётся частичным. Подробности: call_audit_findings.txt,раздел12; /tmp/call-headless-fix-{queue,e2e,full-check}.log. Аппаратный GUI/Android не проверялись.
[ ] radio_headless: проверить целостность PCM-кадра при переполнении TCP-очереди. При сравнении замечен сходный шаблон раздельной отправки header/PCM в rh_write_frame/rh_send_raw. Runtime overflow отдельно не воспроизводился; нужны диагностика и компонентная проверка до решения об исправлении. Наблюдение: call_audit_findings.txt,раздел11. Полный аудит рации не выполнен.
[+] DM media: не выдавать отказ квоты при ошибке чтения занятого места — исправлено 26.10.2026. dm_custody_store проверяет step/finalize отдельно;SQL-ошибка возвращает управление без REJECT/регистрации custody. S сохраняет назначение M и повторяет STORE;настоящий недостаток квоты выдаёт REJECT по прежнему контракту. test_dm_media дополнен Linux wrappers:4 SQL-отказа без записей/REJECT/STORED,настоящая квота с одним REJECT; реальная UDP-цепочка с prepare/step/finalize на первых3 STORE,успешный4-й STORE на том же M, restart S/M при выключенном A,точный файл на B,удаление custody/тела S,поздние control и TTL;allocations0->0. С прежним dm_media регрессия ожидаемо FAIL;исходный one-shot IOERR-стенд и вариант без fault injection PASS. Сборка/DM-профиль7/7 PASS;ASAN/UBSan/LSan7/7 PASS,detect_leaks=1,core/libuasync/Opus инструментированы. Полный check.sh203/203 PASS,0 failed/0 skipped;proxy9/9,burst1/1,load8/8 (134217728 байт),exit0,176с. Подробности полного набора и границы проверки: dm_audit_findings.txt,раздел6.
[+] DM: различать отсутствие беседы и ошибку её загрузки, сохранять seq при отказе — исправлено 26.10.2026. dm_conv_load различает FOUND/NOT_FOUND/ERROR; только успешный SELECT без строки разрешает создание. SQL/короткие ключи/X25519 возвращают ошибку без перезаписи беседы, изменения hidden или события успеха. Проверены все5 callers; приём/invite не пересоздают беседу после отказа. Ошибка сохранения области передаётся наружу. test_dm_load:79 отказных сценариев, все поля7 DM-таблиц, отсутствие SQL-записей/ложных квитанций, поколения до/после удаления, restart/продолжение seq и отдельные ошибки подготовки медиа; allocations0->0. Прежний core даёт ожидаемый FAIL новой регрессии; исходный SQLITE_DENY-стенд теперь PASS,out1/in2 сохранены. Сборка и DM-профиль7/7 PASS; ASAN/UBSan/LSan7/7 PASS,detect_leaks=1,ядро/libuasync/Opus инструментированы. Окончательный check.sh203/203 PASS,0 failed/0 skipped;proxy9/9,burst1/1,load8/8 (134217728 байт),175с. Первый прогон202/203 с отдельным отказом JOIN сохранён;задача диагностики ниже,критерии теста не менялись. Подробности полного набора и ограничения: dm_audit_findings.txt, раздел4.
[ ] test_chat_join_e2e: диагностировать раннее чтение файла приглашения — замечено 26.10.2026. Первый общий прогон исправления DM:202/203 PASS; happy A!=C завершился invalid invitation length or prefix у J, затем A/C не нашли подписанного J. Degraded/invalid-key сценарии прошли. Отдельный повтор3/3 PASS. wf(link.txt) создаёт файл до vfprintf/fclose, wait_file проверяет только access(F_OK): возможна гонка публикации. В исходном отказе нет размера/прочитанных байтов, поэтому конкретная причина пока не доказана. Повторный полный check.sh203/203 PASS;это не доказательство устранения причины исходного отказа. Добавить диагностику длины/результатов I/O и при подтверждении публиковать файл атомарно после закрытия. Критерии JOIN не ослаблять. Логи /tmp/dm-load-fix-{full-check-first,join-first,join-repeat}.log; production JOIN и штатный test_chat_join_e2e в исправлении DM не менялись.
[+] db_sync: финальная сверка принимает разные хеши при равном count — исправлено26.10.2026. db_handle_sync_done явно выставляет synced и вызывает done даже при chain_hash mismatch. Дополнительный локальный стенд подтвердил ложный done и разные корни одинаковых подписанных записей с разными неподписанными id. Для200 записей с отличием в первой sparse-поиск даёт fm148; выбранный хвост состоит из дубликатов, простой повтор не сходится. Стенд exit0, без сетевых пакетов, /tmp/db-sync-completion-design.c/.mk, лог /tmp/db-sync-completion-design.log. MESSAGES=2 подключён к общему Merkle; канонические записи/полные корни без local id и сетевого OFFSET. Собственный bulk/chain удалён; PUSH/ACK сохранены. Wire v4 со свежими round_id/accept_id обеих сторон изолирует cancel/start от старых PAGE/DONE/ERROR. RNG failure, дубликаты и CHECK/DONE revision проверены. Локальная вставка и индекс — одна короткая транзакция; страница до16 записей. Preflight16 строк проверяет подписи вне write-lock; индекс16 листьев за commit, timer1 tick между порциями. SQL/OpenSSL/NOMEM/неизвестный ключ сохраняют строки, доказанная порча удаляется; late key возобновляет обход. Deleted автора не фильтрует историю; допуск пересылающего READY-пира проверяется отдельно. Sound/sleep, callback dispatch/remove и сохранность схемы проверены. TTL ms, короткие DELETE/index commits. check.sh203/203 PASS,0 failed/0 skipped; proxy9/9,burst1/1,load8/8,STUN/stream PASS,exit0,179с. ASAN/UBSan/LSan10/10 PASS,detect_leaks=1. Крупный сценарий5000 новых записей:5002/5002,полные корни равны. После общего прогона добавлены только крупный тест и CHECK/DONE:оба PASS, последний также sanitizer PASS. Логи /tmp/history-merkle-verified-check.log, /tmp/history-merkle-asan-results.log, /tmp/history-merkle-large.log. member_merkle_audit_findings.txt, раздел13; исходный план — раздел12.
[+] db_sync: отказ проверки/битый дубликат удаляли корректную историю — исправлено26.10.2026 после rebase на03b05094. VALID/BAD_SIGNATURE/BAD_FORMAT/DEFERRED/ERROR разделены; перед DELETE проверяется сама сохранённая копия. SQL/OpenSSL/NOMEM/неизвестный ключ сохраняют данные; доказанная порча удаляется в транзакции. Recalc сохраняет pending при отказах; после COMMIT удаления сбрасываются позиции пиров и цепочка строится с0. Прежний стенд сохранения2/2 PASS; новый test_db_sync_integrity:10 введённых отказов, реальные SQL-триггеры, формат0/1/63/65/255/4001, два канала, откат удаления/COMMIT/next_id, несколько батчей, allocations восстановлены. check.sh203/203 PASS,0 failed/0 skipped; proxy9/9,burst1/1,load8/8,exit0,195с. STUN по новому запросу пользователя PASS отдельно и в общем наборе; прежний bind assert не воспроизведён, первый падающий коммит/причина не установлены. ASAN/UBSan/LSan8/8 PASS с detect_leaks=1. Логи /tmp/db-sync-full-final-check.log, /tmp/db-sync-integrity-final.log, /tmp/db-sync-asan-results.log. Подробности: member_merkle_audit_findings.txt, раздел11.
[+] db_sync: неверный SQL и неоднозначная идентичность ACK доставки — исправлено26.10.2026. ACK_PUSH содержит message_id[32]; один идемпотентный UPDATE адресует только конкретную запись. Счётчик отражает ACK, а не очередь отправки; WAS_SENT — только для локального автора. Все SQL-отказы логируются. Две записи одного автора с одним timestamp проверены отдельно и через настоящие PUSH/ACK; повтор ACK не увеличивает счётчик. Общий и sanitizer прогоны выше PASS, совместимость старого wire не нужна. Подробности: member_merkle_audit_findings.txt, раздел11.
[+] 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, раздел9; исходные дефекты — разделы7–8.
[+] member_sync: атомарная очистка повреждённых записей с передачей ошибок — исправлено 26.10.2026. Очистка владеет транзакцией канала от чтения до commit удаления/индекса; чужая транзакция отклоняется до изменений. Ошибки чтения/проверки/памяти/SQL/commit возвращаются через init/start. Недействительная подпись отделена от отсутствующей зависимости и SQL/OpenSSL-отказа, включая sc_ed25519_verify и SQL-getters ключей. Корректные данные при отказе не удаляются. Props/mute/группа меняются после commit; self-unsubscribe и повторный вход безопасны. Штатный test_member_adapter расширен test_member_purge: SQL/commit/allocator faults, 24 crypto faults, identity hash, malformed BLOB, placeholders/deferred и init/start/retry. Реальный stream_member проверяет rollback mute/READY/reader, успешное удаление, сохранение другого канала и внешнего NCD-владельца. Профиль11/11 PASS. Общий набор200/200 PASS в IPv6 namespace; proxy9/9,burst1/1,load8/8,134217728 байт PASS отдельно в root network/mount namespace. Первые отказы среды и повторные прогоны описаны в отчёте. ASAN/UBSan/LSan11/11 PASS,detect_leaks=1; lib/src/Opus инструментированы согласованно. Полный аудит остальных контрактов остаётся частичным; wire/формат БД не менялись. Подробности: member_merkle_audit_findings.txt.
[+] test_radio_mesh: учитывать дедупликацию на любом узле diamond — исправлено 26.10.2026. Проверяется ровно5 упорядоченных кадров и один FIN у B/D/C, отсутствие эха у A и дедупликация всего burst. Unix-наблюдение ждёт обработки всех отправленных RADIO-пакетов; gate воспроизводит обходную копию раньше A→B/A→D. Обычный сценарий и принудительные dupB6/dupC0,dupD6/dupC0 проходят; паузы/диагностический хвост удалены. Один прогон и16 параллельных повторов (по3 сценария) PASS, allocations0->0; сборка без wrappers также PASS. Отрицательные стенды: старое условие dupC>0 и лишняя локальная доставка ожидаемо FAIL без утечки. После rebase нативная/CMake-сборки PASS, C++ voice17/17 PASS; check.sh202/202 PASS,0 failed/0 skipped, proxy9/9,burst1/1,load8/8 (134217728 байт),exit0,176с. Production radio/uasync не менялись. Логи /tmp/radio-mesh-fix-{test,repeat-results,negative-results,voice-tests,full-check}.log; подробности: call_audit_findings.txt,раздел10. Windows/FreeBSD/GUI/Android не запускались.
[+] call_audio: изолировать pending TX-задачи разных привязок instance — исправлено 26.10.2026. Отдельная эпоха привязки ограждает pending, отправку и поздние post-time/age-drop; старые звонки того же owner освобождают свои слоты, повтор init идемпотентен. Предел8 относится к активной привязке; uasync освобождает старые embedded tasks без дополнительных owner-объектов. Добавлены INFO эпох init/destroy, TRACE отклонённой задачи и ERROR нарушения счётчика. Постоянный test_call_audio_tx:13/13 PASS, allocations0->0; прежний C++ voice-профиль4/4 PASS. Те же тесты со старым voice-архивом:7/13 PASS, шесть ожидаемых отказов; production не подменялся. Нативная/CMake-сборки PASS. Два полных check201/202: test_radio_mesh с dupC=0, одиночный повтор PASS; флак вынесен отдельно. Подробности полного прогона — раздел8 отчёта. После исправления критерия mesh и rebase полный check202/202 PASS; актуальная проверка — раздел10 отчёта. Интеграции выполнены отдельно: proxy9/9,burst1/1,load8/8 (134217728 байт) PASS. Аппаратный GUI/Android и санитайзеры не запускались; полный аудит call/ ещё не завершён. Подробности: call_audit_findings.txt,разделы6–8.
[+] call: запрещать второй исходящий вызов при незавершённом обычном звонке — исправлено 26.10.2026. call_start до session/CM/INVITE отклоняет новый ID при обычной занятости с ENDED/BUSY. Уже зарегистрированный ID, включая ENDED до очистки, отклоняется без события/изменения старого звонка. INFO содержит новый/занятый ID, peer/ch и состояние; нулевые peer/id отклоняются с ERROR. Штатный test_call_admission:547 assertions,22 BUSY,18 отказов без событий,7 сочетаний состояния/роли, CHAT/DM/другой tuple до поиска маршрута, отсутствие новых CM/INVITE/started, сохранение состояния/таймеров, двустороннее Opus RX, новый вызов при старом tombstone, продолжение PHONE_BUSY и взаимодействие с рацией. Полные join/update/tree подписи fixture через member_sync; tracked allocations0->0. Прежний диагностический стенд5/5 теперь PASS. Сборка PASS, C++ voice4/4 PASS, check.sh202/202 PASS,0 failed/0 skipped; proxy9/9,burst PASS,load8/8,134217728 байт,174с. Полный прогон в отдельном IPv6 namespace, сеть хоста сохранена. Санитайзеры/аппаратный GUI/Android не запускались. Подробности: call_audit_findings.txt,раздел5; логи /tmp/call-admission-{fix-regression,voice-tests,full-check,netns}.log. Остальной аудит src/call частичный.
[+] stream: закрывать INFO-пробу при истечении её 9-байтового запроса — исправлено и проверено 26.10.2026. expire_controls сверяет length9 и текущий probe_id; истёкший INFO закрывает flow с OVERLOAD. Лог содержит размер, возраст control и факт закрытия flow; чужой probe_id не закрывает новую попытку. test_stream_control_expiry4/4 PASS: обе media-формы, SUBSCRIBE8, до/на/после TTL и несовпадающий ID. test_stream_service проверяет оба media-режима: настоящая очередь ETCP удерживается4,2с, второй INFO истекает в control FIFO до общего deadline5с; после разблокировки ответ/повторное открытие успешны. Общее ETCP-соединение и handles публикации/подписки сохраняются; cleanup без tracked leaks. Сборка PASS. Первый check198/201: три отказа из-за отсутствующего ::1 при отключённом IPv6 окружения. В отдельном IPv6 namespace check201/201 PASS,0 failed/0 skipped; proxy9/9,burst PASS,load8/8,134217728 байт,175с. Настройки основного namespace не менялись. Логи /tmp/stream-info-expiry-fix-build.log, /tmp/stream-info-expiry-fix-unit.log, ...-integration.log, ...-ipv6-full-check.log. Подробности: stream_audit_findings.txt,разделы8–9. Аудит остальных контрактов stream частичный.
[ ] tests: явно проверять IPv6-предпосылку полного набора — замечено 26.10.2026. В основном окружении disable_ipv6=1 для all/default/lo, ::1 отсутствует; bind(::1) даёт EADDRNOTAVAIL. Из-за этого падают test_ncd_faults, test_ipv6_sockets и test_route_connectivity до проверки своей логики. Предусмотреть ясную предварительную диагностику/подготовленный отдельный namespace без изменения сети хоста. Все три проверки и полный набор201/201 проходят в таком namespace; пропуски не требуются. Подтверждение: /tmp/stream-info-expiry-host-ipv6.log и /tmp/stream-info-expiry-fix-ipv6-env.log.
[+] stream: упаковывать помещающийся Opus без обязательного резерва под видео — исправлено и проверено 26.10.2026. Без ожидающего видео используется вся ёмкость пачки, включая точное заполнение. Крупный Opus уходит отдельно; ожидающее видео получает второй слот actor без coalescing delay. Пакет, не помещающийся даже отдельно, удаляется с WARN размера/максимума/ID/PTS до блокировки следующей записи. Wire и неделимость Opus сохраняются; feed=1 подтверждает копирование в очередь, в том числе во время OPENING. test_stream_publisher включён в общий check:23 сценария PASS, полученный Opus декодируется, видео проверяется по байтам/offset, P-кадр не запускает media timer; tracked allocations восстановлены. После merge origin/master повторная сборка PASS, профиль8/8 PASS; check.sh200/200 PASS,0 failed/0 skipped. Интеграции: proxy9/9,burst PASS,load8/8 (134217728 байт), полное время175с. Логи /tmp/stream-publisher-fix-merged-build.log, /tmp/stream-publisher-fix-profile-results.log, /tmp/stream-publisher-fix-full-check.log. Полный аудит остальных контрактов stream не закрыт. Подробности: stream_audit_findings.txt, разделы6–7.
[+] stream: учитывать подписанный deleted при загрузке мембера — исправлено 26.10.2026. stream_member_load читает deleted вместе с профилем и возвращает STREAM_ERR_NOT_MEMBER до crypto, с отдельным логом причины/группы/узла. WAIT для неполного профиля и выходы при отказе сохраняются. test_stream_member включён в общий check и использует fixture test_stream_service в отдельном процессе. Проверены подписанные запрет/разрешение, неверная подпись/старая версия, source/supplier/self, закрытие handles/выдач, отсутствие новых DATA callback, Merkle-остановка publisher, другой канал с рабочей записью и чужое NCD-владение; после разрешения нужны новые handles/эпоха. Воспроизведение: /tmp/stream-audit-member-deleted.c и /tmp/stream-audit-member.mk; до исправления /tmp/stream-audit-member-deleted.log, exit=1; архитектурная копия PASS, /tmp/stream-arch-results-final.log. Штатная сборка PASS, профиль7/7 PASS, tracked allocations=0. check.sh:195/195 PASS,0 failed/0 skipped; proxy9/9,burst PASS,load8/8 (134217728 байт),167с. Логи: /tmp/stream-member-fix-build.log, /tmp/stream-member-fix-profile-results.log, /tmp/stream-member-fix-full-check.log. Полный аудит остальных контрактов stream этим не закрывается. Подробности: stream_audit_findings.txt.
[+] utun_instance: завершить аудит владения, lifecycle и reload — завершено 26.10.2026 после config_parser. Исправлены вложенные подписки, отказ конструкторов, индекс TCP-реестра, жизнь пути общего logger, selective/full reload, TCP listener teardown, освобождение очередей/подписок и SQLite BUSY. Headless start/stop освобождает контексты/клиентов/таймеры; PCM и radio hop-list читаются выровненно. Заголовок и документ полностью сверены; core-разделы service_lifecycle.md согласованы, общий [~] сохранён. Новый test_instance_contract покрывает callbacks/OOM, reload/fault/retry, duplicate servers, database/logger ownership и headless lifecycle. Сборка PASS; check.sh196/196 PASS,0 skipped,proxy9/9,burst1/1,load8/8,173с. ASAN/UBSan/LSan11/11 PASS,detect_leaks=1; ограничения partial reload и нативных платформ описаны в utun_instance_audit_findings.txt.
[+] config_parser: завершить сверку и строгий разбор значений — завершено 26.10.2026. Исправлены IPv6 /32, control /0 и порядок ip/port, числовые границы/таймеры, storage overflow, потерянные ошибки обработчиков и памяти, повторное включение proxy, HEX и диагностический dump секретов. Config updater нормализует ошибочные ранние дубли выбранными последними значениями без смены идентичности. Заголовок и документы согласованы; профиль6/6, ASAN/UBSan/LSan6/6, detect_leaks=1. Полный check.sh195/195 PASS,0 skipped,proxy9/9,burst1/1,load8/8,134217728 байт,169с. Подробности, платформенные ограничения и логи: config_parser_audit_findings.txt.
[+] chat JOIN: исправить кодек, владение попыткой и покрыть нюансы тестами — завершено 26.10.2026. Общий C-кодек для Qt/JNI/headless, отдельные request/attempt IDs, защита от старых ответов, потокобезопасный порт команд, целостный запуск и очистка до уведомления, SQL/runtime-откат. Кодек116342 случаев; отказы памяти/таймеров/NCD/send, REALITY, SQL, повторные callbacks, чужие владельцы и JOIN, детерминированная гонка stop/producer и отмена извлечённого batch — PASS. check.sh196/196, proxy9/9, burst1/1, load8/8 (134217728 байт); ASAN/UBSan/LSan6/6, detect_leaks=1. Desktop/Android APK build PASS, Qt invite/local UI2/2. JOIN wire изменён без совместимости со старыми узлами. Подробности: chat_audit_findings.txt. Коммит/push не выполнялись.
[ ] chat: продолжить аудит заголовков и документов — проверка всего каталога не завершена. Приглашения исправлены по согласованному плану: общий кодек, токены попыток, целостный запуск, SQL/runtime-границы, единое завершение и отдельный потокобезопасный порт команд GUI/JNI. Добавлены test_invite_codec и test_chat_join_faults; подробности и результаты: chat_audit_findings.txt. Остальные непроверенные пункты чек-листа сохраняются.
[+] transport_layer: завершить аудит заголовков и документов — завершено 26.10.2026. С учётом прежних этапов сверены все32 собственных заголовка и17 документов каталога плюс doc/stun_nat.md. Закрыты auto_socket/socket_monitor/SOCKS/call_ring/REALITY/STUN; исправлены владение endpoints/posts, потеря TCP banner, ошибки запуска/очистки, relay HUP/half-close и двойной STUN recheck. Обычная сборка PASS; check.sh194/194 PASS,0 skipped, proxy9/9,burst1/1,load8/8,134217728 байт,170с. Динамические IPv4/IPv6 auto_socket PASS; проверки build.sh44/44; ASAN/UBSan/LSan12/12,detect_leaks=1. Два первых отказа sanitizer-стенда вызваны отсутствием glibc FORTIFY wrappers; исправлены, повторные прогоны PASS. Нативные сборки/runtime Windows и FreeBSD не выполнялись; платформенные ветки сверены по исходникам. Подробности, ограничения и логи: transport_layer_audit_findings.txt.
[+] socket_monitor: исправить FreeBSD-разбор уведомлений адреса — исправлено 25–26.10.2026. Прежний bsd_parse_rtm безусловно писал gw[0] при NULL из RTM_NEWADDR/RTM_DELADDR. Ненужный разбор sockaddr удалён; уведомления проверяются по длине/версии и правильным native структурам ifa_msghdr/if_msghdr/if_announcemsghdr/rt_msghdr с копированием выровненного заголовка. Также исправлены исчезновение адресов, IPv6 scope, изменение endpoints внутри callbacks и pending Windows post. Linux native-fixture, init faults и ASAN/UBSan/LSan PASS; FreeBSD определения сверены с releng/14.3. Нативный runtime FreeBSD недоступен; он не подменяется Linux-тестом. Заголовок и lifecycle-контракт согласованы.
[+] packet_dump: ограничить чтение входного IPv4-пакета — исправлено 25.10.2026 по указанию пользователя.
Единый hex-цикл читает min(32, total length-IHL) байт; проверяются NULL/version/IHL/total length,
хвост после total length игнорируется. Адреса читаются побайтно; последующие IP-фрагменты
не выдаются за транспортный заголовок. Исправлены обрезание полного набора TCP-флагов и вывод нулевого порта.
Ошибки входа отражаются в строке и логируются в dump/warn, частичный первый фрагмент — dump/debug.
Прежний тест не вызывал модуль; теперь проверяет реальный форматтер: протоколы, поля, фрагменты,
77 длин захвата, невыровненный вход, сохранность входа и точный hex в2904 случаях.
Контракты .h/документа согласованы. Код235c2c4f, тестыc3fa6d4d; rebase на e035f53a без конфликтов.
Обычная сборка PASS; полный check.sh после rebase:190/190 PASS,0 skipped,
proxy9/9,burst1/1,load8/8 PASS,134217728 байт,214с. ASAN/UBSan/LSan packet_dump PASS сdetect_leaks=1;
встроенные lib/src/Opus в изолированной копии собраны с согласованными sanitizer-флагами.
Логи: /tmp/packet-dump-fix-test.log, /tmp/packet-dump-fix-full-check.log,
/tmp/packet-dump-fix-asan-build.log, /tmp/packet-dump-fix-asan-test.log.
[+] member_files: сверить контракты и исправить ошибки владения/повторов — завершено 24.10.2026. Прочитаны все6 реализаций и6 заголовков C-модуля. Исправлены удаление чужого temp, повторный запуск после раннего cancel с UAF, обрыв массовых мутаций при64 квитанциях и блокирующий open FIFO до проверки типа. Заголовки и серверная/клиентская документация согласованы. Подтверждены сохранность файлов при трёх отказах, 76 созданий/76 удалений и потеря успешного ответа без повторной мутации. Сборка PASS; профиль7/7, ASAN/UBSan/LSan4/4 PASS с detect_leaks=1. Общий GUI/avatar документ остаётся [~]. Отчёт и границы: member_files_audit_findings.txt. Логи: /tmp/member-files-audit-profile-results.log, /tmp/member-files-sanitizer-results.log. Прежний FAIL удаления чужого temp из ETCP-проверки закрыт коммитом0f42f92f; защита от возобновления после раннего cancel —20b4975d. Повторный фикс не требуется. После объединения с ETCP-диагностикой: сборка PASS, общий check.sh186/186, proxy9/9, burst1/1, load8/8 PASS,134217728 проверенных байт,162с. Сохранность target/temp подтверждена всеми тремя сценариями; test_member_files_network PASS phase21. Логи: /tmp/etcp-master-integration-build.log, /tmp/etcp-master-integration-check.log.
[+] media_async/media_delivery: завершить сверку контрактов и исправлений — завершено 24.10.2026. Проверены все11 заголовков двух каталогов по полным реализациям; исправлены alias файлов, граница voice duration, переанонс SQLite и расхождение MIME. Результаты каждого фикса приведены ниже. Устаревший _desc.txt заменён описанием текущей архитектуры; уточнены sync.md, encrypted_attachments.md и media-раздел service_lifecycle.md. Общий lifecycle за пределами media остаётся частично проверенным. Итог, границы и доказательства: media_async_audit_findings.txt.
[+] encrypted_file: одинаково проверять MIME при записи и чтении контейнера — исправлено 24.10.2026. Прежний write проверял только strlen(type)<32 и принимал пустое значение/недопустимые символы, тогда как read их отвергает. Пять реальных write/read с теми же ключом/UUID/подписанным hash: write=0, read=-1; контрольный application/octet-stream проходит полный roundtrip. Прежний chat_attachment_send также проверял только длину и мог принять такой MIME до записи ключа/запуска worker. Воспроизведение: /tmp/media-content-type-audit.c и .mk, /tmp/media-content-type-audit.log; исходники/контейнеры: /tmp/media-content-type-audit-FdtMC3/. Исходный файл не меняется. Реализован один bounded encrypted_file_validate_type для send/write/read; 1..31 байт, ASCII33..126 без двойной кавычки/обратной косой черты — действующие ограничения read. Отказ до создания ключа/файлов; формат, криптография и файловое владение сохранены. Регрессии: все256 значений байта,92 допустимых;8 ранних отказов writer/send,3 roundtrip, 7 отказов чтения аутентифицированных плохих метаданных. Проверены прежние выходы, файлы, fd/temp и отсутствие ключей/worker. ./build.sh --no-gui -j4 PASS; профиль10/10 и ASAN/UBSan/LSan4/4 PASS, detect_leaks=1. Логи: /tmp/media-mime-fix-build.log, /tmp/media-mime-fix-profile-results.log, /tmp/media-mime-sanitizer-results.log. Полный check и Windows/FreeBSD для этого фикса не запускались. Подробности: media_async_audit_findings.txt. Сверка описаний завершена.
[+] media_delivery: проверять записи SQLite перед переанонсом локальных блоков — исправлено 24.10.2026. Прежний announce_local_blocks не проверял длины media_id/block_id, диапазон chunk и полный chat_id. Реальный обработчик отправил все7 повреждённых записей: UUID длиной1/17 байт, chunk=-1/2^32, chat_id=111junk. При UUID длиной1 байт остальные15 байт сетевого поля взяты за границей BLOB; chunk=-1 превращается в4294967295, 2^32 — в0, 111junk — в группу111. Стенд использует настоящие SQLite/Ed25519; отправка перехвачена, пакеты в реальную сеть не уходят. Воспроизведение: /tmp/media-announcement-audit.c и .mk; лог: /tmp/media-announcement-audit.log. Реализованы проверки типов/точных длин UUID, chunk через int64 и канонического ненулевого decimal chat_id до копирования/кастов/отправки. Плохие строки пропускаются с WARN; prepare/bind/step/finalize проверяются. UUID копируются до вложенных SQL. Сохранены void API, поштучные анонсы и формат wire. test_media_delivery_sql: 36 случаев полей (32 отказа/4 корректных), смесь2/3 и5 SQL faults с recovery. Проверяются точные wire UUID/group/chunk, отсутствие оставшихся statements и ERROR вместо успешного лога при отказе SQL. Сборка PASS; профильные12/12 и ASAN/UBSan/LSan4/4 PASS, detect_leaks=1, все встроенные зависимости инструментированы. Логи: /tmp/media-announcement-fix-profile-results.log, /tmp/media-announcement-fix-sql-final.log, /tmp/media-announcement-sanitizer-results.log. Полный check и Windows/FreeBSD не запускались. Архитектура, границы воспроизведения и регрессии: media_async_audit_findings.txt. Последующая сверка описаний двух каталогов завершена; итог указан в начале списка.
[+] media_async voice_file: согласовать верхнюю границу длительности с метаданными — исправлено 24.10.2026. Прежняя проверка samples/channels/rate >86400 пропускала полные кадры 24ч+20..980мс, хотя attachment_validate отклоняет duration_ms >86400000. В штатном pipeline это означает лишнюю подготовку файла перед отказом публикации; дефект относится к граничным записям длиннее суток. Диагностический вызов реального voice_file_encode с остановкой на создании Opus: 60 случаев, все пять частот и 1/2 канала; 20 подтверждённых расхождений проверки. /tmp/media-voice-duration-repro.c, /tmp/media-voice-duration-repro.mk, /tmp/media-voice-duration-repro.log. Реализован общий предел миллисекунд в attachment.h; voice_file проверяет 25..4320000 полных кадров до создания encoder/открытия output. Валидатор и video completion используют тот же предел. test_attachment: 120 граничных случаев; 70 ранних отказов, прежний файл и metadata сохранены. Настоящий Opus encode/decode: 11 записей, включая 500мс с хвостом для всех пяти частот и 1/2 канала. Границы метаданных voice/video 86400000/86400001мс проверены через validate/encode/decode. ./build.sh --no-gui -j4 PASS; профильные тесты 10/10 PASS, включая DM, encrypted attachments и video. Логи: /tmp/media-voice-fix-build.log, /tmp/media-voice-fix-profile-results.log, /tmp/media-voice-fix-profile-logs/. Подробности и ограничения воспроизведения: media_async_audit_findings.txt. На этом этапе новые полный check и sanitizer-прогоны не выполнялись; последующие проверки и итог аудита указаны выше.
[+] media_async encrypted_file: не уничтожать source через alias назначения — исправлено 24.10.2026. write/read отвергают только одинаковые строки; /./ и hardlink обходят проверку одного файла. write возвращает0, заменяя исходные30 байт контейнером пустого файла; read возвращает0, заменяя входной ciphertext182 байта plaintext30 байт. Проверены реальные функции, inode и SHA256. Реализован один file_io_temp в ak_file; codec готовит закрытый проверенный temp, worker публикует его одним rename. Target не открывается с усечением; alias проверяется до work и перед publish. Durability задаётся на весь срок temp; ошибка directory sync после rename не считается откатом. Cleanup удаляет только собственные артефакты; crash recovery учитывает temp в media и decrypted. DM не вызывает codec: сохранить его контракт общих sync/publish helpers при изменениях file_io. Детали, проверка архитектуры исправления и незавершённый аудит: media_async_audit_findings.txt. Воспроизведение: /tmp/media-encrypted-alias-repro.c, /tmp/media-encrypted-alias-repro.log. Добавлены восемь alias-сценариев, 23 отказа I/O с контролем fd/temp/метаданных, отмена настоящего worker после rename до completion, startup/restart обоих деревьев. Профильные21/21 и основной make check185/185 PASS; proxy9/9, burst1/1, load8/8 PASS в отдельном network namespace,134217728 проверенных байт. ASAN/UBSan/LSan21/21 PASS, detect_leaks=1. Логи: /tmp/media-fix-full-check.log, /tmp/media-fix-network-check.log, /tmp/media-fix-sanitizer-results.log. Последующий аудит остальных контрактов media_async/media_delivery завершён; Windows/FreeBSD не проверялись.
[+] Proxy: исправить HUP/backpressure, владение и rollback — завершено 24.10.2026. Согласованный проект, причины и результаты: doc/proxy_fix_plan.txt. HUP больше не обходит read_high_water/ручную паузу; idle HUP снимается с poll, low_water восстанавливает регистрацию с новой generation, запись остаётся независимой. Общими UDP/ICMP владеет instance; TCP-модули освобождают только свои ресурсы. Proxy закрывается до групп/транспорта. Listeners/mappings обязательны, частичный запуск откатывается. Raw ICMP запускается отдельно: EPERM сохраняет клиентские REPLY и TCP/UDP; остальные ошибки запуска фатальны. UDP проверяет создание flow, таймеры и точную отправку; нулевой payload и EINTR обработаны. Поздний WINDOW завершённого sid — DEBUG drop. Неверный enabled убран из серверных тестовых конфигов. Штатный TLS shutdown проходит без EPIPE/ENOTCONN; abrupt сохраняет реальные ошибки TCP. Оба TLS-режима: 16 byte-exact загрузок. Настоящий raw ICMP и явный loopback PASS. test_proxy_lifecycle: 25/25 сценариев отказов без утечек fd/памяти; test_tcp_io: 19/19, epoll/poll HUP. Основной make check: 185/185 PASS. Общий check.sh сначала не уложился в141с, затем TUN-этапу помешал занятый другим процессом UDP15002. TUN-тесты повторены с тем же бинарником в отдельном network namespace: proxy9/9, burst1/1, load8/8 PASS, 134217728 проверенных байт. ASAN/UBSan/LSan: 16/16 и отдельный raw ICMP PASS, detect_leaks=1. Логи: /tmp/proxy-fix-full-check2.log, /tmp/proxy-fix-network-check.log, /tmp/proxy-fix-sanitizer-results.log, /tmp/proxy-fix-icmp-raw.log. Windows/FreeBSD runtime не проверялся.
[ ] ETCP: полезная утилизация нескольких каналов и доставка при зависании части линков — общая задача открыта.
Небольшой недобор до условного порога85% сохраняется как результат измерений;
сам по себе не оправдывает изменения/усложнения BBR. Далее по приоритету — STCP backpressure,
смена RTT нескольких путей/BW и повторный отказ; строгие критерии — доставка, паузы и рост очередей.
После push исследован одиночный дуплекс2Мбит/с на изолированной базе a198cfb9.
Точные7763 ACK показывают задержку обратной очереди: пример DATA15.909мс, hold0.029мс,
обратный ACK32.219мс; DOWN продолжает ждать flight7644 при цели5915байт.
Контрольный20-секундный замер1.726/1.658Мбит/с, retries=0; простой ACK-резерв/округление/уменьшение бюджета
не дают устойчивого прохождения. Предел окна DOWN сокращает фазу до6..22мс, но короткий FAIL1.656 остаётся.
Прототипы не перенесены в рабочий ETCP/BBR. Добавлены сценарий duplex-slow и UTUN_MULTIPATH_SAMPLE_MS=1000..60000
для длительных замеров; прежние пороги сохранены. Далее — причины остановки DATA в CRUISE/REFILL:
физическое окно, общий admission budget и pacer; подробные данные/команды — doc/etcp_multipath_plan.txt.
24.10.2026: исправлены RTT. min_rtt наследует метку короткого минимума, вместо омоложения кеша каждым ACK;
прежний минимум20мс заменяется после10с своего возраста (прежде15с). Метки/hold PROBE_RTT используют полные uint64 TB;
проверены 32-битная граница, нулевые младшие32бита срока, длительный idle, hold>=200мс и ACK-раунд.
Исправлено замораживание DATA-измерений при скачке RTT: RTO берёт max(DATA EWMA, timestamp-RTT своего линка).
Формула1.2RTT+1.5DATA_jitter+3мс и clamp10мс..1с сохранены; BBR обновляют только действующие DATA ACK.
Новый профиль rtt-change:20->100->20мс, проверяет обновление RTT, снятие stalled, старение/снижение minRTT и доставку.
DATA-измерения возобновились примерно за203мс, после перехода повторов нет; minRTT103.794мс, после возврата23.941мс.
До фикса стенд дал2035 повторов и остановку DATA ACK-модели; отдельная регрессия настоящего retrans-таймера также FAIL.
Пересчёт attempts-таймера вызывается и при сокращении timestamp-RTT без новых DATA/ACK: регрессия123->27мс
до фикса сохраняла96мс лишнего ожидания. Пересчёт идёт до внешнего RTT callback, который может закрыть conn/линк;
OOM таймера также безопасно закрывает conn из RX. Негативный ASAN-тест ловит UAF при обратном порядке.
BBR24/24; test_etcp_windows63 сценария в обоих режимах часов PASS; четыре ASAN/UBSan-теста и ASAN rtt-change без ошибок/утечек.
Check.sh186/186, proxy9/9, burst1/1, load8/8 PASS,134217728 проверенных байт,189с после последней правки.
Полная матрица: первые6 скоростных профилей, все9 отказов и rtt-change PASS; остался1 FAIL2Мбит/с:1.662<1.700.
Одиночный8Мбит/с7.076/7.019, агрегат8.737/8.717 из10. Далее —2Мбит/с, STCP backpressure, смена RTT нескольких путей/BW и повторный отказ.
Логи/CSV /tmp/etcp-rtt-complete-* и /tmp/etcp-rtt-close-;8652 среза проверены, отдельные332 RTT: /tmp/etcp-rtt-complete-rtt-change.csv/.html.
Детали: doc/etcp_multipath_plan.txt. Предыдущий этап — исправление BW:
24.10.2026: исправлена недооценка BW растянутыми ACK: достоверный RX clock заменяет ACK clock,
interval=max(send_us,ceil(delivereddelta_rx_us/delta_rx_bytes)); без RX-базы/прогресса max(send_us,ack_us).
Сохранены send-граница, проверка пары/переполнения/idle и логические ACK; wire/RTT/RTO/окно не менялись.
DEBUG ACK показывает исходные интервалы и выбранные часы. До фикса точная регрессия FAIL, после PASS.
test_etcp_windows: 61 сценарий с обоими режимами часов PASS; BBR 20/20, восемь ASAN/UBSan-тестов без ошибок/утечек.
Check.sh 186/186, proxy 9/9, burst 1/1, load 8/8 PASS, 134217728 проверенных байт, 201с.
Полная последовательная матрица: все 7 скоростных и 9 отказных профилей PASS; дуплексный агрегат 8.768/8.789 из10.
Три прогона рабочего кода: одиночный 8Мбит/с даёт 7.045..7.081 в обе стороны, агрегат проходит каждый раз.
Ранних ACK-пакетов 0; steady retries=0; ACK на одиночном 8Мбит/с пути 0.170..0.180Мбит/с.
Остаётся нестабильность одиночного дуплекса 2Мбит/с: один повтор дал 1.672<1.700Мбит/с.
Далее — этот недобор, STCP backpressure, отдельные проверки смены RTT/BW и повторного отказа.
Обнаруженный на этом этапе дефект возраста min_rtt исправлен и проверен следующим этапом выше.
Логи/CSV: /tmp/etcp-rx-clock-; 8372 среза проверены, HTML /tmp/etcp-rx-clock-matrix.html.
Подробности и предыдущие этапы: doc/etcp_multipath_plan.txt.
Предыдущий этап — диагностика до исправления ACK:
Продолжение 24.10.2026: диагностика срезов 100 мс (настройка 10..1000 мс), 104 поля; CSV и лог буферизуются до drain.
Видны очереди, callbacks/deferred waiter, DATA/ACK, flight/cwnd, BBR/RTT/RTO, долг/готовность pacer и канал эмулятора.
tools/etcp_diag_report.py проверяет CSV и строит автономные интерактивные графики с исходными срезами.
Дуплекс: 598 срезов; two-stuck/ASAN: 5208/5196 срезов, без ошибок sanitizer/утечек; CHECK сохраняет накопленный лог.
Итоговый check.sh 184/184, proxy 9/9, burst 1/1, load 8/8 PASS, 166 с; JS smoke-проверка графиков/фильтров PASS.
На одиночном 8 Мбит/с пути ACK занимают 0.347/0.390 Мбит/с, среднее ожидание ACK-only 230/271 мкс вместо окна 2 мс.
В срезах side=1 path=1 DATA готовы, а BBR задаёт около 6.3 Мбит/с; PROBE_RTT временно уменьшает окно до 32.9 тыс. байт.
Дедлайн обходит посторонний wake sender. Дальше разбирать абсолютные deadlines ACK; простого !timer недостаточно.
Алгоритмы протокола на этом этапе не менялись; полный дуплекс всё ещё не проходит скоростные пороги (5 нарушений, 8.513/8.337).
Логи/CSV: /tmp/etcp-duplex-diag-; просмотр: /tmp/etcp-duplex-diag-view.html; детали — doc/etcp_multipath_plan.txt.
24.10.2026: реализованы сканирование send_q с приоритетом готовых повторов и ограниченная подгрузка новых DATA.
Заблокированный пакет пропускается. История путей пакета (32 байта) исключает новый обход до перебора допустимых;
история/RR фиксируются после принятого send, удаление линка очищает слот до callbacks/повторной выдачи ID.
После 3 RTO без ACK-прогресса tx_stalled исключает путь из повторов при наличии незастрявшего UP-пути.
Все застрявшие пути допускаются, новые DATA сохраняют прежний выбор; действующий ACK отправки после флага снимает его.
Старый/чужой ACK не восстанавливает путь; reset очищает состояние. Новых очередей/таймеров/копий нет, RTO сохранён.
Windows: 51 сценарий PASS с управляемыми/реальными часами; восемь ASAN/UBSan-тестов без ошибок/утечек.
Контроль занятого на 1 мс рабочего пути: latency 377.012 вместо 736.623 мс, ready_wait 2.318 мс, профиль PASS.
Отрицательный контроль задержки готового повтора 200 мс остаётся FAIL по очереди и общей задержке.
Полная последовательная multipath-матрица: все 9 профилей отказов PASS, первые 6 скоростных профилей PASS.
Two-stuck: latency 379.997 мс при пределе 462.219 мс; ещё 3/3 повтора — 374.981..378.557 мс.
Load-drop/load-hold: паузы 39.234/39.355 мс, steady goodput 7.221/7.468 из 8 Мбит/с.
Max latency под насыщенной нагрузкой 161.287/86.306 мс записана; отдельным порогом она здесь не ограничена.
Two-stuck/load-drop также проходят ASAN/UBSan с detect_leaks=1 без ошибок/утечек.
Остаётся дуплекс: 8.412/8.435 из 10 Мбит/с, все 7 нарушений матрицы — его скоростные пороги.
Далее — дуплекс, STCP backpressure, отдельные проверки смены RTT/BW и повторного отказа.
Полный check.sh: 184/184, proxy 9/9, burst 1/1, load 8/8 PASS, 134217728 проверенных байт, 197 с со сборкой.
Длинная multipath-матрица запускается отдельно; её общий результат остаётся FAIL из-за дуплекса.
Логи: /tmp/etcp-send-scan-.log; подробности — doc/etcp_multipath_plan.txt.
Предыдущая диагностика:
24.10.2026: тесты отдельно проверяют обработку RTO (опоздание<=20мс), ожидание готового повтора (<=100мс)
и доставку сверх заданной задержки канала (<=100мс). TX учитывается после принятия send.
Быстрые профили сохраняют общий предел100мс; длинные учитывают по одному RTO отказавших путей плюс100мс.
Остальные8 профилей PASS; two-stuck нестабилен: обычный прогон дал738.317мс при пределе459.332мс,
история фрагмента324 —1->2->1->2->0. Готовый повтор не застревает: лишнее ожидание создаёт ещё один круг RTO.
Контроль с занятостью рабочего пути всего1мс воспроизводит736.623мс latency и534.548мс паузы;
точный лог показывает свободное окно рабочего пути и ожидание pacer при выборе2->1.
Контроль задержки уже готового повтора на200мс проваливает новую проверку очереди, а не маскируется бюджетом RTO.
Slow-drop/two-stuck/load-drop проходят ASAN/UBSan с detect_leaks=1 без ошибок/утечек.
Полный check.sh184/184, proxy9/9, burst1/1, load8/8 PASS,134217728 байт,161с; multipath запускается отдельно.
Перед изменением транспорта отдельно проработать выбор путей без DATA-прогресса, ограниченные пробы
и восстановление, сохраняя физический UP и защиту от поздних ACK. Ранние копии исключены; дуплекс не менялся.
Логи: /tmp/etcp-recovery-stages-.log/.csv; подробности — doc/etcp_multipath_plan.txt.
Предыдущий этап:
24.10.2026: повтор ждёт другого initialized+UP канала, даже когда прежний уже готов.
При отсутствии таких альтернатив разрешён прежний; DOWN последней альтернативы будит sender.
Новых состояний/ресурсов/таймеров нет. ACK/control и burst-FILLER не блокируются ожиданием DATA.
Регрессия до исправления воспроизводит возврат на прежний путь; после — windows44 сценария
с управляемыми/реальными часами PASS, восемь ASAN/UBSan-тестов без ошибок/утечек.
Полный check.sh184/184, proxy9/9, burst1/1, load8/8 PASS,134217728 проверенных байт,161с.
Профили отказов:7/9 PASS. load-drop/load-hold проходят каждый3/3, паузы39.796..44.982мс,
steady goodput7.189..7.476 из8Мбит/с оставшегося канала. Пороги сохранены.
Slow-drop остаётся FAIL: пауза238.569мс, latency264.727мс; two-stuck219.338/380.177мс.
В них4 нарушения порогов; доставка/порядок/ресурсы проходят. Полная скоростная матрица не повторялась.
Трейс показал ожидание первого RTO на медленном пути и повторный выбор прежнего пути под нагрузкой;
ожидание в хвосте send_q в этих опытах не объясняет основную паузу (максимум2.6/3.5мс).
Ранние копии до RTO исключены пользователем24.10.2026. При UP повтор ждёт RTO своего пути;
закрытие линка по-прежнему возвращает недоставленные DATA без ожидания RTO.
При RTT200мс RTO уже243мс без jitter: порог паузы100мс этого ожидания не учитывает.
Пороги тестов не менялись; дальше отдельно оценивать ожидание RTO, готовность повтора и доставку.
Остаются здоровье/пробы каналов, STCP backpressure и дуплекс; спекулятивных ранних копий в плане нет.
Логи: /tmp/etcp-retry-alternative-.log/.csv; диагностический observer — /tmp/etcp-recovery-probe.c/.mk.
Предыдущий контроль после исправления pacer: таймер ждёт первого разрешённого TB, а не погашения всего долга;
кредит1мс, BBR/cwnd/min_rtt, RTO и wire-формат сохранены. Нового состояния и ресурсов нет.
До исправления регрессия получает10TB вместо1TB; после него18 сочетаний долга/дроби проходят.
Проверены INT_MAX, ранний/поздний callback, ограниченный burst, OOM повторного таймера,
rate change и reset/close из настоящего uasync callback. Windows42 сценария PASS с обоими режимами часов;
восемь профильных тестов ASAN/UBSan с detect_leaks=1 без ошибок/утечек.
check.sh184/184, proxy9/9, burst1/1, load8/8 PASS (134217728 байт),162с.
Полная последовательная матрица c7a53009 с прежними порогами: FAIL,14 нарушений —
8 скоростных проверок дуплекса и6 проверок пауз/задержек slow-drop,two-stuck,load-drop/load-hold.
Equal14.438/16, bandwidth9.052/10, RTT20/200:14.299/16Мбит/с; первые6 скоростных профилей PASS.
Дуплекс8.394/8.458 из10Мбит/с остаётся FAIL. Drop-forward PASS: пауза58.001мс, задержка83.656мс.
Паузы slow-drop/two-stuck/load-drop/load-hold:239.421/201.381/213.644/208.899мс;
задержки slow-drop/two-stuck:264.044/482.693мс. Доставка, порядок и контроль ресурсов проходят.
Это один прогон; сравнение с исходными15 нарушениями не доказывает устойчивое улучшение всей матрицы.
Далее отдельно разбирать ограничения BBR/cwnd и PROBE_RTT, здоровье линков и STCP backpressure.
Результаты/план: doc/etcp_multipath_plan.txt; /tmp/etcp-pacer-ready-matrix.log/.csv,
/tmp/etcp-pacer-ready-{windows-final,real-time,full-check}.log и /tmp/etcp-pacer-ready-asan-test_.log.
Реализованы начальный pacing от 4MSS/RTT, точные DATA B/s и ограниченный кредит shaper,
разделение логического seq/payload и физических attempt_id, ACK/RTT/RTO каждого пути,
ротация повторов A→B→C→A при UP-каналах, rollback отказавшего send и запрос потерянного till.
Wire attempt_no сокращён до2 байт, общий для всех каналов одного seq; внутренний ключ — (seq<<16)|attempt_no.
DATA header7 вместо13 байт, ACK entry10 вместо16. Номер1..65535; исчерпание номера/seq меняет эпоху через REINIT.
Normalizer не менялся. Пара seq/номер не повторяется в одной эпохе; старые ACK отсекаются до разбора.
Проверка компактного формата: windows38 сценариев, session/BBR/transport/init_liveness PASS;
те же5 тестов ASAN/UBSan с detect_leaks=1 без ошибок/утечек. check.sh184/184, proxy9/9, burst1/1, load8/8 PASS.
bandwidth2+8 RTT20/20:8.715Мбит/с, retries=0, профиль PASS. Логи: /tmp/etcp-attempt16-.log/.csv.
RTO=clamp(ceil(1.2RTT+1.5jitter+3мс),10мс,1с), округление до мкс. Пределы: попытки 16384/линк,
32768/соединение, ACK 16384/линк. Без RTT начальный RTO=1с.
STARTUP завершается после целого раунда устойчивой очереди выше бюджета, без искусственного изменения BW.
BBR20/20, windows26 сценариев PASS; восемь тестов ASAN/UBSan с detect_leaks=1 PASS; основной набор183/183 PASS.
check.sh завершён успешно; дополнительные tcp_proxy_full/burst/load PASS (8 соединений,134217728 проверенных байт).
Полная штатная multipath-матрица до смены формулы RTO: FAIL, 20 нарушений. Есть недобор RTT20/200мс и bidirectional;
slow-drop даёт паузу401мс, два зависших пути676мс, DROP/HOLD под нагрузкой229–243мс.
После смены RTO один полный прогон даёт 15 нарушений: slow-drop244мс, two-stuck278мс,
load-drop/load-hold96/83мс; установившиеся интервалы исправных каналов без повторов.
windows31 (20 наборов проверки реального RTO), BBR20/20, session/transport PASS;
windows/session/transport ASAN/UBSan с detect_leaks=1 PASS. Логи: /tmp/etcp-rto-margin-.log.
Jitter-контроль RTT20/200мс: при случайной добавке 0..10/30мс новая формула даёт отдельные лишние повторы,
старая в контрольном прогоне — без повторов. При jitter30мс скорость снижена у обеих формул;
коэффициенты не объявлены оптимальными. Логи: /tmp/etcp-rto-jitter-review.log, /tmp/etcp-rto-jitter-old.log.
Последний check.sh после смены RTO: 182/183, FAIL только test_bgp_route_exchange (повтор отдельно с debug PASS).
test_encrypted_attachment в этом прогоне PASS; воспроизведённый ранее дефект media остаётся открытым.
Логи: /tmp/etcp-rto-margin-full-check.log, /tmp/etcp-rto-margin-bgp-repeat.log.
Три прогона скоростей: 8+8 RTT20/20 — 13.868..14.083Мбит/с; RTT20/200 — 13.567..13.951;
2+8+2 RTT20/80/200 — 10.566..10.749 из12; 2+8 одновременно в обе стороны — 8.080..8.379 из10 на направление.
DATA-повторов в измеряемых исправных интервалах нет. Подробные результаты: /tmp/etcp-multilink-quality-20261023.csv/.txt.
BGP-падение из-за INIT/remote_keepalive исправлено; отдельная задача ниже содержит итог проверки.
Дуплекс проверен18 последовательными опытами в /tmp/etcp-duplex-native/, исходники проекта не менялись.
ACK compression завышает BW:170502 байта приняты за186.36мс, sender sample использует150.73мс.
Нативный прототип counter/time в ACK сокращает пики очереди до23.1мс вместо52.9мс, но все скоростные пороги не проходит.
Коэффициент282/256+3мс и запас10мс при busy-флаге не дали устойчивого выигрыша, пики очереди выросли до35.5/33.7мс.
В штатном агрегате ACK занимает0.515..0.559Мбит/с на направление (5.15..5.59% полосы), большая часть — ACK-only.
Реализована только коррекция BW по точке приёма:16 байт добавляются при count>0, пустой ACK остаётся8-байтовым.
Перестановка/дубли ACK, независимые часы, простой/reset, переполнения и границы MTU/формата проверены.
Windows35 сценариев и ещё4 профильных теста PASS, те же5 тестов ASAN/UBSan без ошибок/утечек;
check.sh184/184, proxy9/9, burst1/1, load8/8 PASS (/tmp/etcp-bw-correction-full-check.log).
Отдельный дуплекс2+8 RTT20/80:8.223/8.182Мбит/с, пики очереди агрегата22.8мс, retries=0;
профиль остаётся FAIL по5 прежним порогам скорости. bandwidth2+8 RTT20/20:8.844Мбит/с, PASS.
RTT20/200,8+8:13.453Мбит/с, очередь<=24мс, retries=0, FAIL по3 прежним порогам скорости.
Логи: /tmp/etcp-bw-duplex-final.log/.csv, /tmp/etcp-bw-{bandwidth,rtt}.log/.csv, /tmp/etcp-bw-asan-.log.
Объединение ACK в пределах прежнего дедлайна2мс отложено; окно/RTT/RTO и политика ACK не менялись.
Дуплексный запас и busy-флаг не добавлялись и не считаются подтверждённым исправлением.
One-way->duplex->one-way:3/3 PASS; ASAN/UBSan не нашли ошибок/утечек, скоростной профиль остаётся FAIL.
Подробности/уточнённый план: doc/etcp_multipath_plan.txt; результаты: /tmp/etcp-duplex-native/results.json,
/tmp/etcp-duplex-native/summary.csv и ack_bandwidth.csv. Политика окна прототипов в репозиторий не переносилась.
Здоровье/пробы каналов и STCP backpressure пока не реализованы; ранние копии исключены, пороги тестов сохранены.
OOM после принятия данных исправлен аварийной сменой эпохи с сохранением физических линков.
Старый поток отбрасывается без воспроизведения; после согласования владельцы получают REINIT.
Очистка reset не выделяет память; убрана реконструкция inflight, новых OOM-очередей/таймеров нет.
Проверены отказы RX/TX, flush/waiter/session-таймеров, RNG, reset/close из callback и ноль выделений при reset.
windows31 сценарий, queue_regressions77/77 и шифрованное восстановление обеих сторон PASS;
десять тестов ASAN/UBSan с detect_leaks=1 PASS. Далее — здоровье каналов; ранние повторы исключены.
После OOM-правок полный check.sh: 181/183; FAIL BGP route exchange и encrypted attachment.
BGP отдельно с диагностикой PASS; encrypted attachment повторно FAIL из-за удаления активного temp кешем (задача ниже).
Отдельно proxy9/9, burst1/1 и load8/8 PASS (134217728 проверенных байт); /tmp/etcp-oom-reinit-proxy-check.log.
План и подробные результаты: doc/etcp_multipath_plan.txt.
Логи: /tmp/etcp-attempts-matrix.log, /tmp/etcp-attempts-asan-test_.log,
/tmp/etcp-oom-reinit-asan-test_.log, /tmp/etcp-abort-encrypted-recovery.log.
[+] Crypto: повторное освобождение ключа после отказа инициализации потоковой подписи — исправлено 24.10.2026: Оба init создают ключ и SHA-512-контекст локально, заполняя state только после полного успеха. Перед первым использованием state={0}; отказ оставляет его пустым. Повторный init активного state отклоняется без потери ресурсов и накопленного хеша. Cleanup обнуляет все поля и допускает повторы. Final проверяет capacity до финализации; недостаточный буфер позволяет повторить вызов с сохранённым хешем. Контракты и обработка ошибок отражены в .h и примере документации; формат подписи прежний. Регрессия до исправления падает на непустом state после отказа EVP_MD_CTX_new. Проверены 6 отказов init, 8 отказов final/verify, 4 сочетания повторного init, capacity0/63/64, повторная очистка/использование и совпадение с независимой one-shot подписью SHA512 сообщения. Тесты не перехватывают free. Восемь профильных тестов ASAN/UBSan с detect_leaks=1 PASS; check.sh184/184, proxy9/9, burst1/1, load8/8 PASS. Пример документации компилируется с -Werror. Логи: /tmp/sc-sign-regression-before.log, /tmp/sc-sign-fix-full-check.log, /tmp/sc-sign-fix-asan-*.log.
[+] Media: очистка кеша удаляла временный файл активной загрузки — исправлено 24.10.2026: file_io хранит общий защищённый mutex реестр владельцев temp по фактическим нормализованным путям. Владение сохраняется от создания до publish/discard, включая интервал после finish; очистка кеша проверяет владение и удаляет сироту под тем же mutex. Угадывание суффиксов не используется. Регрессии проверяют открытый/закрытый temp, барьеры создания/finish и очистку после реального BLOCK_CHUNK. Полный check.sh: 184/184, proxy9/9, burst1/1, load8/8 PASS; пять профильных тестов ASAN/UBSan PASS, test_encrypted_attachment дополнительно повторён пять раз без отказов. Логи: /tmp/media-orphan-full-check.log, /tmp/media-orphan-asan-.log, /tmp/media-orphan-repeat-.log.
[+] ETCP: входящий INIT сохранял устаревший признак обратной достижимости — исправлено 23.10.2026: Принятый INIT обновляет RX и remote_keepalive до переиспользования буфера для ответа; flag_up=0 снимает ложный UP. INIT/INIT_RESPONSE и обычный RX публикуют переходы живости с защитой от close/удаления линка из callback. При DOWN handshake продолжает ответ/keepalive; исправный второй линк сохраняет UP соединения. INIT_RESPONSE проверяет длину тела (>=64 байт без timestamp/flag_up) и node_id до изменения состояния. Раньше проверка общей длины принимала усечённое тело 61..63 байта. Новых таймеров/очередей/полей нет. test_etcp_init_liveness: 130 отказов без изменения link/conn и передачи владения pkt, 12 допустимых ответов; оба направления односторонней потери, оба порядка ключей, восстановление без смены эпохи, резервный линк, close и удаление link из INIT/keepalive callback PASS, также с обычными часами. Семь профильных тестов ASAN/UBSan с detect_leaks=1 PASS; дополненный тест удаления link повторён отдельно. BGP route exchange: 100/100 PASS (A<B:48, A>B:52; последние пять с debug). Основной набор: 184/184 PASS. Логи: /tmp/etcp-init-boundary-before.log, /tmp/etcp-init-final-{liveness,realtime,asan-liveness}.log, /tmp/etcp-init-fix-asan-test_.log, /tmp/etcp-init-bgp-stable-.log, /tmp/etcp-init-fix-full-check.log.
[+] ETCP/BBR: бюджет очереди в установившемся режиме — реализовано 23.10.2026 по выбору пользователя: В PROBE_BW окно ограничено max(4MSS, BDP + BW20мс), с насыщением арифметики и учётом ACK/PROBE_UP резервов внутри общего предела. Ограничение применяется также на fast path и до callback. 0 отключает политику. STARTUP/DRAIN не ограничены этим бюджетом; это мягкая цель модели, а не гарантия физической очереди <=20мс. До политики bandwidth давал очередь 47.1–47.9мс >40мс при корректных единицах и сложении резервов; после политики профиль проходит по скорости и очереди, equal также PASS. Разные RTT и отказы не закрыты. BBR 18/18, windows 16 сценариев PASS; BBR/windows/session/transport/STCP traffic/NCD ASAN/UBSan с detect_leaks=1: 6/6 PASS. Полный check.sh: 180/183, FAIL NAT detection/fault и encrypted_attachment; связь падений с BBR не установлена, отдельная открытая задача сохраняется. Логи: /tmp/etcp-queue-budget-fastpath.log, /tmp/etcp-queue-budget-windows.log, /tmp/etcp-queue-limited-asan-results.log, /tmp/etcp-queue-limited-asan-test_*.log, /tmp/etcp-queue-limited-full-check.log. Политика описана в etcp_bbr.h, etcp_bbr_doc.md и doc/etcp_protocol.txt.
[+] ETCP/BBR: единое окно DATA и корректное осушение PROBE_RTT — исправлено 23.10.2026: BBR использует MSS=normalizer->frag_size, а не wire-MTU/размер STCP-кадра. Начальное окно UDP/STCP равно 4MSS; MTU пересчитывается после включения нового линка в список. init_cwnd инициализируется четырьмя фрагментами. Транспорт применяет положительное окно с верхним ограничением bbr_max_cwnd, не поднимая его до 8192. INFLIGHT_LIM_MIN=8192 остаётся нижней допустимой границей настройки максимального окна; нулевое окно отклоняется с логом. PROBE_RTT осушает до max(4MSS, 0.5BDP), ждёт >=200мс и раунд ACK, затем восстанавливает предыдущее окно. Отправленные при осушении DATA помечаются app_limited. Ограничения после потерь больше не уменьшают окно ниже 4MSS. BBR 15/15, отправитель 16 сценариев; ETCP session/transport, STCP traffic и NCD PASS. Те же шесть тестов ASAN/UBSan с detect_leaks=1: 6/6 PASS, ошибок и утечек не обнаружено. Общий check.sh: 181/183, FAIL test_nat_detection_faults/test_nat_detection (contact_history/UNKNOWN); test_encrypted_attachment в этом прогоне PASS. NAT-падения и отдельный повтор отмечены следующей открытой задачей. Логи: /tmp/etcp-probe-test_.log, /tmp/etcp-probe-asan-results.log, /tmp/etcp-probe-asan-test_.log; полный прогон: /tmp/etcp-probe-full-check.log. исходные нарушения: /tmp/etcp-probe-contract-{bbr,windows}-before.log, /tmp/etcp-probe-lossfloor-before.log.
[+] ETCP/BBR: байтовые единицы, delivery clock и независимость ACK от локального DATA-pacer — исправлено 23.10.2026: Устранено повторное умножение на MSS при расчёте pacing/BDP: доставка 1MB/s давала 570240000B/s при MSS=576, теперь cruise pacing=990000B/s независимо от MSS. Q16 байт/мкс сохраняет многогигабитные оценки; выходы pacing/BDP/cwnd и рост inflight_hi насыщаются вместо переполнения. PROBE_UP растит inflight_hi на MSS за подтверждённое окно; резерв равен 2*MSS, Reno rounds считаются в пакетах. Счётчики ACK aggregation расширены до 32 бит, подтверждения свыше 64KiB больше не усекаются. Delivery sample использует снимки delivered/time/send-time пакета и max(send_elapsed, ack_elapsed); несколько ACK в одном tick больше не создают ложный пик скорости. Суммарный delivered растёт только на новые ACKed байты. ACK без DATA обходит локальный DATA-cwnd и DATA-pacer и не начисляет их нагрузку: низкая исходящая DATA-скорость получателя не тормозит обратные подтверждения. Физическая очередь канала остаётся общей для DATA/ACK. dummynet измеряет максимальное время очереди/сериализации отдельно от заданной propagation delay; multipath проверяет его предел base_RTT+20ms наряду с полезной утилизацией, FILLER/повторы не засчитываются. BBR 14/14, window/sender 14 сценариев PASS. ASAN/UBSan с detect_leaks=1: BBR/windows/calibration/session/transport/STCP/NCD 7/7; после последнего исправления переполнения BBR/windows повторены отдельно. Основная multipath-задача остаётся открытой. Общий check.sh перед последним исправлением переполнения: 181/183; падения вынесены отдельной задачей ниже. Логи: /tmp/etcp-recovery-overflow-{before,after,windows}.log, /tmp/etcp-recovery-asan-results.log, /tmp/etcp-recovery-asan-overflow-{bbr,windows}.log, /tmp/etcp-multipath-recovery-check.log.
[ ] Разобрать падения NAT detection/fault и encrypted attachment в общем прогоне — обнаружено 23.10.2026: check.sh: test_nat_detection_faults завершился assert в run_alias (ожидался inbound OPEN, получен UNKNOWN/contact_history); отдельный повтор тоже упал, уже в run_case mode=5: mapping DEPENDENT корректен, inbound UNKNOWN вместо ожидаемого. test_encrypted_attachment достиг phase=3/12001 heartbeat и упал; отдельный повтор завершился phase=10/560 heartbeat PASS. После исправления окна BBR общий прогон снова 181/183: encrypted_attachment PASS, но FAIL оба NAT-теста. test_nat_detection_faults упал в run_case mode=1 (UNKNOWN/contact_history); test_nat_detection не дождался профиля за 18с на socket=udp. Его отдельный повтор тоже упал, уже на socket=second, с той же причиной contact_history/UNKNOWN. После бюджета очереди полный check.sh: 180/183, повторились оба NAT-падения и encrypted_attachment. Связь с изменениями BBR не установлена. Разобрать фикстуры/таймеры по логам, не ослаблять ожидания. Логи: tests/logs/test_nat_detection_faults.log, tests/logs/test_encrypted_attachment.log, /tmp/etcp-recovery-nat-retry.log, /tmp/etcp-recovery-attachment-retry.log, /tmp/etcp-probe-full-check.log, /tmp/etcp-probe-nat-retry.log, /tmp/etcp-queue-limited-full-check.log.
[+] ETCP: единый установщик прямого транспорта через NCD — исправлено 22.10.2026: Удалён неиспользуемый рабочим кодом etcp_connect с EARLY/LATE, отдельными линками и таймерами; три тестовых файла переведены на NCD handles с начала подключения. Сохранены проверки независимых владельцев, отмены отложенного UP, TIMEOUT, выхода из UTUN с сохранением транспорта и shutdown с pending LEAVE. Состояние реестра, физический UP, готовность ETCP-сессии и READY группы разделены в контрактах. Начальный отправитель не создаёт преждевременный UP. Merkle-фикстура ждёт готовности обоих потоков.
[+] ETCP: индивидуальные окна DATA, ACK и корректный учёт повторов — исправлено 22.10.2026: Выбор линка проверяет место для целого DATA, ACK не блокируется DATA-cwnd; burst без места использует FILLER. WAIT_ACK занимает окно, RTO освобождает его до постановки в WAIT_SEND; поздний ACK не вычитает байты повторно. BBR получает факт ограничения окном до вычитания ACK; app_limited учитывает подготовленные данные и normalizer. Один call_soon объединяет пробуждения без таймерной задержки/рекурсии; OOM retry через 10ms, reset/close отменяет token. Невозможность запланировать отправку закрывает транспорт отложенно, сохраняя вызывающий стек. Проверяются размер max_cwnd, переполнение суммы окон; ошибки [global] теперь отклоняют конфигурацию. Новый test_etcp_windows: 12 сценариев настоящих очередей/отправителя, сверка счётчиков и внедрение отказов. STCP-тест проверяет каждый байт двустороннего 1MiB трафика при окнах 8KiB и независимых тестовых командах. ASAN/UBSan с detect_leaks=1: windows/session/transport/connect/stcp_traffic/SIGPIPE/NCD, 7/7; результаты /tmp/etcp-asan-complete-results.log, логи /tmp/etcp-asan-complete-logs/. Финальный check.sh: 182/182, TCP proxy 9/9, burst/load PASS (210s); полный лог /tmp/etcp-full-check-complete.log. Ветка fix/etcp-connect-link-windows.
[+] STCP: запись в закрытый TCP-сокет завершала библиотечный процесс SIGPIPE — исправлено 22.10.2026: В общем прогоне STCP traffic завершался сигналом 13 после передачи данных, при teardown; воспроизведено первым же повтором ASAN. Оба send-пути STCP используют socket_send с MSG_NOSIGNAL либо SO_NOSIGPIPE; обработчики сигналов процесса не меняются. Ошибка EPIPE обрабатывается штатным путём. test_stcp_sigpipe проверяет raw/buffered send в дочерних процессах с SIGPIPE=SIG_DFL. 20 повторов STCP traffic под ASAN/UBSan с detect_leaks=1 прошли без сигналов/ошибок/утечек; логи /tmp/etcp-asan-traffic-fixed-*.log, детерминированная проверка включена в общий Linux-набор.
[ ] Аудит .h ETCP/STCP: оставшиеся расхождения контрактов — проверено 22.10.2026: stcp.h: do_close уже очищает оба sc_stream и планирует free для allocated/free_on_close; комментарий утверждает обратное. Разделить контракты finish (drain/запрет новых данных/до 1с) и do_close (немедленное закрытие/потеря очередей/callback). Описать владение внешними rx_queue/tx_queue, преусловия размера frame и callback/reentrancy/lifetime. stcp_client.h: ping автоматически освобождается после завершения; NULL на ошибке запуска не вызывает ping callback. RTT пинга — uint16_t в 0.1мс, от отправки STCP handshake, без TCP/SOCKS/REALITY dial; явно описать срок out_cli/handle. inst также нужен для NTP-времени и профиля REALITY, а не только padding автономного STCP. stcp_link.h/stcp_server.h: дополнить параметры, возвраты, время жизни callbacks/inst и различие handles серверного адаптера stcp_server_listen и базового stcp_server_create (одно имя opaque-типа, разные реализации). etcp.h: ref_count удерживает объект/phase-2, но close уже освобождает normalizer и линки в phase-1; reset_done не блокирует reinit (в реализации только запись/диагностика); last_rx_id не обновляется при RX. etcp_connection_ready объявлена без реализации/вызовов; рабочая функция — etcp_conn_ready. etcp_connections.h проверен частично: у data_len исключены все 3 байта timestamp/flag, не только timestamp; send_hook уступает SOCKS UDP; etcp_send_tcp_ping при отказе запуска возвращает отрицательный код без callback. etcp_session.h и etcp_padding.h сверены с реализацией без подтверждённых смысловых расхождений. Подробности: /tmp/protocol-header-audit.txt. Продолжить протоколы перед routing/BGP; media/file_transfer отложен.
[+] Android: приём рации через SCO после отпускания PTT — исправлено 22.10.2026: Общий MediaAudioController сохраняет разговорный тракт для SCO-only выхода, даже без подписчиков микрофона. AudioTrack рации снова использует USAGE_VOICE_COMMUNICATION: Android учитывает playback как разговорную активность. Добавлены логи фактического routedDevice/mode/SCO и аппаратная проверка после закрытия последнего input. Samsung + C1 PRO: PHONE → Bluetooth → PHONE, 35с приёма без микрофона и холодный запуск SCO без PTT прошли. На Q8 прошли общий захват/переключения/сохранение playback. JVM 145/145, сборки ядра и APK успешны.
[ ] Android: просмотр трансляции через SCO без работающей рации — воспроизведено 22.10.2026: Media-выход с USAGE_MEDIA после закрытия микрофона теряет SCO: mode=0, sco=false, хотя общий контроллер продолжает владеть выходом и сам больше не закрывает разговорный тракт. AudioService учитывает VOICE_COMMUNICATION playback/record для активности MODE_IN_COMMUNICATION. Повтор: adb -s RZ8R72MG64B shell am instrument -w -e output media com.utun.chat/com.utun.chat.data.MediaAudioProbe. Радио с USAGE_VOICE_COMMUNICATION проходит ту же проверку, media-вариант её не проходит. Сохранить media-назначение/громкость обычных выходов; для SCO переключать аппаратный AudioTrack на VOICE_COMMUNICATION. При пересоздании только аудиовыхода сохранить недописанный PCM, учесть уже записанный буфер и непрерывный played; видео и его кодеки не перезапускать. Проверить оба направления смены выхода и длительный playback без микрофона.
[+] media_async: файловые примитивы и точные контракты .h — исправлено 22.10.2026: ma_copy_file проверяет существование/идентичность, сохраняет один regular-файл при ./ или hardlink; ссылки назначения отклоняются, копирование идёт через соседний temp с проверенными записью/close/publish. Общие примитивы lib/file_io используются также video, сохраняя публикацию видео только в completion. ma_uuid возвращает ошибку RNG и обнуляет выход; media_index не регистрирует блоки при отказе media/block UUID. ma_file_size и переменные вызывающего кода — int64_t; проверяются смещения, число блоков и размеры выделений. Обход передаёт ошибки, пропускает ссылки/reparse points, проверяет длину/глубину; Windows использует wide API. Контракты .h и service_lifecycle описывают синхронные отказы, лимит 16 до completion и отсутствие отката work при отмене. Неверные аргументы дают -1, closing/destroy — CANCELLED; повторный вход в destroy диагностируется и отклоняется. Новый test_media_primitives проверяет сохранность при I/O/fdopen ошибках, RNG/seek без записей блоков в БД, sparse-размеры на границах 2/4 ГиБ, ошибки обхода, ссылки/глубину и ownership задач с внедрением ошибок. Все шесть тестов media_primitives/video/media_index/attachment_send/services/dm_worker прошли ASAN/UBSan с detect_leaks=1. Общий check.sh: 176/176 и proxy/burst/load. Windows runtime/сборка не проверялись: кросс-компилятора в окружении нет. Логи: /tmp/media-primitives-full-check-final.log, /tmp/media-primitives-final.log, /tmp/media-asan-test_*.log.
[+] media_index: пути без обрезания и единая media_base — исправлено 22.10.2026: Общие location/path проверяют границу базы, компоненты и пределы UTF-8 путей (1024/512 с NUL). Путь в 550 байт полностью сохраняется, читается и удаляется. Проверки предшествуют файловой подготовке. Выдача использует UTF-8 file_io; загрузчик проверяет общую базу, stop/start сохраняет выбранную базу БД. Писатели, backfill, выдача и удаление используют один формат; контракты находятся в media_index.h.
[+] media_index_commit: атомарная регистрация и проверяемые повторы — исправлено 22.10.2026: Единый commit регистрирует весь авторский/скачанный файл через SAVEPOINT; key=NULL означает скачанный файл. Проверяются геометрия/массивы, bind/step/finalize и управление транзакцией. Ошибка второго блока откатывает оба пути регистрации; обычная ошибка сохраняет внешнюю транзакцию. SQLite может сама откатить её целиком — это обнаруживается и диагностируется. Совпадающий повтор сохраняет node_sign и timestamp; противоречащие метаданные дают ошибку без замены старых. Файловые изменения worker не входят в SQL-атомарность.
[+] Удаление канала: дождаться исходящих медиа и учесть незавершённые файлы — исправлено 22.10.2026: Канал ждёт свои video/register completions; новые исходящие задачи отклоняются до завершения удаления. Последний completion продолжает удаление. Подготовленные ожидающие отправки не становятся новыми сообщениями. Контекст остаётся у владельца во время синхронного MSG_SUBMITTED; повторный вход обработчика проверен. До worker путь учитывается в media_preparations; успешный commit снимает запись в той же транзакции. После ошибки хеширования/отмены опубликованная копия остаётся известна для очистки канала. Проверены две ожидающие задачи, повтор удаления, создание того же channel_id и удаление из обработчика события.
[+] media_index_delete_channel: ошибки и повторяемая частичная очистка — исправлено 22.10.2026: Полный снимок и проверка путей предшествуют удалению; внешняя транзакция отклоняется. Общие файлы других каналов сохраняются; ENOENT считается успехом. SQL/файловые ошибки возвращают -1, записи неочищенных путей сохраняются для повтора. Проверен отказ DELETE после unlink: повтор завершает очистку без восстановления файла. Очистка включает media_preparations; ошибки очистки и удаление метаданных канала сообщаются раздельно.
[+] media_index_init: ошибки всех индексов доходят до запуска чата — исправлено 22.10.2026: Проверяется каждый CREATE INDEX. Ошибка прерывает chat_core_init с освобождением собственных ресурсов; общая БД ядра сохраняется. Проверены запрет каждого индекса и успешный повтор старта после снятия запрета. Дополнительно исправлены дубликат start (отказ без callback) и доступ к dl после синхронного завершения QUERY. Тесты используют реальную схему БД и проверяют новый контракт владения. Итог: check.sh — 177/177, proxy/burst/load PASS, 159с. Девять тестов index_regressions/index/delivery_download/download_timeout/services/delivery_full/delivery_chat/attachment_send/video прошли ASAN/UBSan с detect_leaks=1. Windows runtime/сборка не проверялись: кросс-компилятора нет. Логи: /tmp/media-index-full-check-final.log, /tmp/media-index-final-test_media_index_regressions.log, /tmp/media-index-asan-test_*.log. Новый тест: tests/test_media_index_regressions.c.
[+] media_delivery QUERY/QUERY_RESP: проверять длины до чтения записей — исправлено 22.10.2026: Проверяются точный размер, счётчики и все записи до SQL/изменений состояния. Ответ связан с media_id, UUID попытки, группой и end-to-end отправителем router; дубликаты, истёкшие и старые ответы игнорируются. test_media_query защищает точную границу payload под ASAN и проверяет все усечения, чужие ответы, повреждение последней записи без изменения первой, отмену и повторный start того же media_id.
[+] media_delivery QUERY: устранить потерю блоков и держателей из-за разных лимитов — исправлено 22.10.2026: Одна пачка до 32 block_id — один полный ответ, до четырёх кандидатов на каждый блок (максимум 1604 байта). Нулевой результат и ошибка БД различаются. Неполная пачка не принимается; держатели других пачек и текущие CM сохраняются. QUERY имеет отдельный дедлайн и курсор источников каждого блока; чанки не продлевают поиск остальных блоков. Источники своей CHAT-группы, автор последний; HAVE_BLOCK не зависит от курсора поиска. Peer-слоты переиспользуются после освобождения; SLOT/SEARCH/RETRY различаются, OVERLOADED соблюдает retry_after. Отменяется поздний CM UP, события обрабатываются после open. Устранено двойное освобождение при отказе router. Проверены 65 блоков/260 записей, старт 4100 блоков, сборка с 13 держателями при 10 слотах, настоящий watchdog при входящих чанках, SQL-ошибка второго блока, RNG/send failures и отсутствие повторного done_cb. Сетевой integration проверяет содержимое QUERY_RESP вместо безусловного smoke PASS. Восемь тестов query/delivery_download/download_timeout/delivery_sql/delivery_integration/delivery_chat/delivery_full/services прошли ASAN/UBSan с detect_leaks=1. Итоговый check.sh: 178/178, proxy/burst/load PASS, 172с. Логи: /tmp/media-query-regressions.log, /tmp/media-query-full-check-final.log, /tmp/media-query-asan-final-test_*.log. Windows runtime/сборка не проверялись: кросс-компилятора нет. Контракты — в соответствующих .h.
[+] media_delivery QUERY_RESP: устранить неверное поле chunk — исправлено 22.10.2026: Неиспользуемые chunk/rtt удалены из нового формата QUERY_RESP. Блок однозначно задаётся block_id, а его номер загрузчик берёт из сохранённых метаданных; позиция в выборочной пачке не считается номером блока.
[+] media_delivery CHUNK: прогресс только после проверенного приёма и записи — исправлено 22.10.2026: Реальные router callbacks/SQLite, корректные подпись блока и ключ автора. CHUNK с data_len=1 без payload оставляет файл пустым, но устанавливает bytes_received=1, RECV и обновляет last_progress_tb. То же при внедрённом fwrite=0/ENOSPC. Текущий unit-тест допускает 456 байт при expected_size=100. Проверять полный payload, геометрию/непрерывность, текущего держателя и попытку до файловых операций; не считать дубли и неудачную запись прогрессом. Нужна привязка пакетов к отдельной попытке передачи блока. Стенд /tmp/media-block-audit.c; логи /tmp/media-block-audit-truncated.log, /tmp/media-block-audit-write.log. Реализованы строгие размеры/непрерывность, tuple группы/держателя/блока/UUID и отдельный temp каждой попытки. Прогресс публикуется после проверенного close. Регрессии: tests/test_media_blocks.c, включая реальные I/O-сбои.
[+] media_delivery DONE: проверка ключа и конечный результат ошибки хеша — исправлено 22.10.2026: Для настоящей Ed25519 пары с pubkey[0]=0 корректно подписанный блок отвергается: наличие ключа определяется первым байтом. При отсутствии ключа проверка заменяется сравнением wire block_sig с метаданными. Отдельно: при верной подписи блока и несовпадающем хеше файла state=DONE, validated=0/1, active=1; три проверки watchdog возвращают 0, done не вызывается. Итоговая ошибка должна завершать загрузку, а публикация назначения и регистрация допустимы только после проверенных чтения/записи/close/SHA256. Обязателен ключ ровно 32 байта; проверяется подпись метаданных по фактическим байтам и ожидаемый размер. Сборка идёт в собственный temp, SHA-256 проверяется всегда, затем publish и регистрация SQLite. Ошибка до publish сохраняет старое назначение; ошибка SQLite сохраняет подготовленный опубликованный файл. Регрессии с настоящим pubkey[0]=00, неверной подписью/хешем, сбоями I/O/rename/SQLite: tests/test_media_blocks.c.
[+] media_delivery progress_cb: отмена освобождает dl внутри обработчика DONE — исправлено 22.10.2026: progress_cb вызывает media_download_cancel, md_dl_finish освобождает dl; media_download_handle_done затем вызывает md_dl_send_have_block с освобождённым указателем. ASAN heap-use-after-free, чтение 8 байт. Обработчик явно удерживает контекст. Terminal снимает загрузку с индекса и отменяет её timers/CM/waiters; освобождение и done выполняются после выхода последнего удерживающего обработчика, ровно один раз. После progress проверяется terminal: отменённая загрузка не продолжает финализацию. Один перенос callback в конец функции/отложенный финализатор не заменяет владение. Relay-получатели отдельно удерживают файл блока. Проверить также отмену с повторным start того же media_id, отмену на последнем progress и поздние пакеты. Лог /tmp/media-block-audit-cancel-asan.log; стенд вне репозитория /tmp/media-block-audit.c. Реализовано явное удержание контекста обработчиком; отдельные ссылки producer/выдач удерживают файл блока. Единый TX pump готовых/растущих источников соблюдает backpressure для DATA и DONE; remote CANCEL привязан к UUID. Проверены отмена/повторный start из последнего progress и старые relay-читатели при успехе/отмене новой загрузки. Полный ./check.sh: 179/179, proxy/burst/load PASS (/tmp/media-block-full-check-final.log). Десять целевых наборов ASAN+UBSan с detect_leaks=1: PASS (/tmp/media-block-asan-test_*.log). Windows runtime/сборка не проверялись. Синхронные проверка и сборка блоков остаются в uasync.
[+] media_delivery: исправить репликацию суперузлов — исправлено 22.10.2026. Воспроизведения прежней реализации: SUPER_REPL с num_entries=1 и одним заголовком: ASAN use-after-poison при чтении id в media_delivery.c:622. ACK от известного пира в другой router-группе без ожидающей пачки: inflight 0→255, tx_cursor=77, запускается timer. HELLO двух пустых узлов: после 20 доставок остаётся следующий HELLO, обмен сам не завершается. Для 9 записей sender ставит 4 одинаковые пачки первых 4 записей. По таймауту 20000→40000 при inflight=4 отправляет 0 повторов, хотя timer снова вооружён. На потерю ACK эта схема не восстанавливается. При id=4294967297 первая запись остаётся 64-битной, но seq максимума пачки усечён до 4. Ошибка INSERT второй строки оставляет первую применённой, сохраняет RX cursor=2 и отправляет ACK=2: теряются данные. Группа из тела HELLO переопределяет router-группу (111→333); ответ включает записи групп 111 и 222. Старая пачка уменьшает сохранённый RX cursor 2→1. После supernode stop/start чужие записи удалены, но cursor=2 сохранён и рекламируется в HELLO. Принятая запись не будит выдачу третьему готовому супер-пиру. Уточнение прежней записи: смешения направлений курсоров в БД нет — md_ss_set вызывается только при приёме REPL; ACK обновляет peer_last_recv_id в памяти. Исправлять нужно подтверждение ожидающей пачки и жизненный цикл курсоров. Стенд вне репозитория /tmp/media-super-audit.c; обычные логи /tmp/media-super-audit-{ack,hello,pages,timeout,wide,sql,group,purge,replay,forward}.log. ASAN: /tmp/media-super-audit-truncated-asan.log, exit=1 ожидаем из-за подтверждённой ошибки, не успешный regression. Реализованы receiver-driven SYNC_REQ/SYNC_RESP и CHANGED вместо HELLO/ACK/inflight: одна страница с UUID на (group,peer). Группа/источник только из router, актуальные подписанные роли обоих участников; CM владеет прямым/непрямым путём. Страницы до 32 строк, little endian, 64-битные ID; high-water из sqlite_sequence, сохранённая эпоха каталога. Весь RX packet и курсор фиксируются собственной транзакцией после полной проверки, включая ошибки commit/rollback SQLite. Идемпотентный максимум (status,timestamp) выдаёт новый локальный ID только при изменении; собственные блоки сеются из media_files. Таймаут повторяет прежний запрос, CHANGED/dirty и периодическая сверка не теряют обновление около последней страницы. Репликация соблюдает backpressure; ограниченный слот ответа и watchdog восстанавливаются после reset router send_q. Потеря роли/удаление канала очищают строки вместе с RX-курсорами только своей группы; обычный stop сохраняет БД. test_media_replication: 10000 строк, id>2^32, усечения/дубли/чужие ответы, SQL read/write/commit faults, потеря запросов/ответов/CHANGED, DOWN/UP, новая эпоха, две группы, смена роли, три узла, заполнение/reset очередей. SQL-тест использует настоящую схему; сетевые full/chat/integration — CHAT-группы и подписанные роли member_sync. Финальный ./check.sh: 180/180, proxy 9/9, burst/load PASS (/tmp/media-repl-full-check-final.log). 11 целевых наборов ASAN+UBSan с detect_leaks=1: PASS (/tmp/media-repl-asan-final-test_*.log). Контракты обновлены в media_delivery.h/media_delivery_proto.h, sync.md и doc/service_lifecycle.md. Windows не проверялся.
[+] test_stream_service: убрать зависимость bootstrap-проверки от гонки TCP-handshake — исправлено 22.10.2026: Падение на строке 409: REINIT=0 при probes=1/subflows=1/failures=0 и доставленной первой пачке. Встречный TCP-линк успевает сообщить peer_reset_id до ETCP CONFIRM: начальная эпоха уже известна, поэтому etcp_session_receive не вызывает REINIT. При другом порядке событий REINIT=1 и тест проходит. Холодная подписка проверяет одну пробу/выдачу и доставку без ошибок, число начальных REINIT диагностическое. Отдельная автоматическая подписка удерживает INFO_RESP, выполняет настоящий REINIT и продолжает ту же пробу. Проверяются новые epoch/nonce, отсутствие лишних проб/CLOSED и пустой локальный буфер перед получением DATA. Ручные проверки старых ответов и исходного deadline сохранены; ожидания привязаны к поколениям и событиям. Добавлен --bootstrap-only: 8 повторов с ускоренными и 2 с обычными часами прошли. Полный test_stream_service прошёл ASAN/UBSan с detect_leaks=1; check.sh — 175/175 и proxy/burst/load. Изолированная потеря pending-пробы вызвала ожидаемый отказ новой автоматической проверки; мутация убрана. Логи: /tmp/stream-service-original-failure.log, /tmp/stream-bootstrap-repeat-*.log, /tmp/stream-service-asan-final.log, /tmp/stream-bootstrap-mutant.log, /tmp/stream-bootstrap-full-check-final.log.
[+] video: сохранность файлов, JPEG и подготовка MP4 — исправлено 22.10.2026: Одинаковые файлы/алиасы и недопустимые пути отклоняются без изменения исходника. JPEG и MP4 пишутся в эксклюзивный временный файл; запись, drain, trailer и close проверяются. Только успешный completion публикует результат; отмена до callback сохраняет старое назначение. Превью получает задержанные B-кадры. MOV/H.264/AAC проходит remux в MP4; остальные профили перекодируются с audio FIFO, сохранением временного смещения и хвоста ресемплера. Атомарный global slot удерживается до completion, ошибки имеют точную фазу и контекст в логе. Контракты описаны в src/video/video.h и doc/service_lifecycle.md. test_video проверяет реальные кадры/сигнал, 1080p→720p, PCM/MP3/AAC, resample 12345→12000 Гц, файловые ошибки, отмену, повтор из callback и конкурентные start; test_video_no_ffmpeg — стабы. Оба теста, test_services и test_attachment_send прошли ASAN/UBSan с detect_leaks=1. Отдельная конфигурация всего ядра/тестов без FFmpeg собрана, оба video-теста прошли. Логи: /tmp/video-asan-final.log, /tmp/video-services-asan.log, /tmp/video-attachment-send-asan.log, /tmp/video-without-ffmpeg-build-final.log; общий прогон: /tmp/video-full-check-final.log.
[+] tcp_io: владение connect-таймером и повторный FIN — 21.10.2026: Замена таймаута сохраняет старый таймер при ошибке создания нового; <=0 отменяет таймер. Возвращаемые ошибки и диапазон INT_MAX/10 проверяются API и TCP-прокси; connect/error/destroy отменяют таймер. FIN различает fin_pending и fin_local, ошибка shutdown идёт в on_error без ложного on_fin_sent. Уточнены отложенное освобождение, синхронные callbacks очередей и платформенный выбор IPv6/маршрута. Проверено: 15 сценариев test_tcp_io, test_tcp_io_flush, test_proxy_regressions и test_socks_http_proxy (16 загрузок с побайтной сверкой). test_tcp_io и flush также прошли ASAN с detect_leaks=1 без ошибок. Логи: /tmp/tcp-io-fix-unit.log, /tmp/tcp-io-fix-asan-unit.log, /tmp/tcp-io-fix-asan-flush.log, /tmp/tcp-io-fix-proxy-regressions.log, /tmp/tcp-io-fix-socks-http.log.
[ ] Desktop publisher: проверить восстановление после недопустимого FPS в Xvfb-тесте — 20.10.2026: Широкий screenAndWindowCapture прошёл закрытие управления с active=1 и продолжением публикации, затем не получил видео revision>=3 после запроса fps=61 и возврата engine.config().video.fps к 15. Перед этим применены VP9/rotation=90; worker продолжает кодировать generation=4. Причина и связь с UI-изменениями не установлены; отдельная проверка закрытия управления PASS. Лог /tmp/desktop-stream-controls-xvfb.log, тест tools/chatgui/tests/test_stream_publish.cpp.
[ ] Проверить одновременную собственную и удалённую трансляции в multiview — 20.10.2026: Собственный preview и удалённые readers по отдельности проверены; их совместный живой сценарий в одном канале не проверялся. На desktop/Android проверить переход в управление своей публикацией и возврат, fullscreen/Back/Esc, сохранение удалённых readers и общего звука, отсутствие местного звука и остановку собственной публикации.
[ ] Multiview desktop: terminal CLOSED оставляет аудиовход и timer — проверка 20.10.2026: fail(reason, false) ставит complete=true/failed=false, но tick снимает audio только по ended/failed. После STREAM_CLOSE_GROUP воспроизведено complete=1, failed=0, attached=1, timer=1. При valid=0 каталог сохраняет плитки, поэтому состояние живёт до ручного закрытия окна. Отделить завершение от разрешения retry и освобождать output при любом terminal CLOSED. Временный regression-проверочный стенд и лог: /tmp/multiview-review/test_stream_view.cpp, /tmp/multiview-review/lifecycle.log. Исходники реализации при проверке не менялись.
[ ] Проверить ожидание запросов ключей в test_encrypted_attachment — 21.10.2026: До rebase исправлений control_server: check.sh вне sandbox 165/166; отдельный повтор также phase=5/heartbeats=12001, ожидание двух pending incoming-запросов после перезапуска автора. Логи: /tmp/control-server-full-check.log, /tmp/control-server-attachment-recheck.log; артефакты общего прогона: /tmp/utun_encrypted_attachment_6JMO0c. Код вложений в этой работе не менялся.
[ ] Разобрать нестабильную загрузку storage-узлов в test_media_delivery_chat — 19.10.2026: В том же общем прогоне storage st1/st2 не собрали файл, n2 исчерпал попытки блока 0 (15/19 внутренних проверок). Отдельный повтор прошёл 19/19. Причина не установлена; сравнить маршруты и готовность storage под общей нагрузкой. Логи: tests/logs/test_media_delivery_chat.log, /tmp/phone-busy-media-recheck.log. Повторилось 21.10 при аудите ID сервисов: 164/165, те же 15/19 внутренних проверок. Отдельный запуск и 16 параллельных повторов прошли. Причина остаётся открытой; тест теперь сохраняет подробный media/router лог и БД при отказе в /tmp/utun_mdc_*/. Логи /tmp/service-ids-full-check.log, /tmp/service-ids-media-chat-debug.log, /tmp/service-ids-media-chat-stress/.
[ ] Разобрать нестабильное ожидание ACK в test_local_transport — 19.10.2026: Общий check.sh: 161/162, chat_adapter упал на строке 173 при ожидании LOCAL_DELIVERY_FORBIDDEN для request=508. В логе получатель дважды отклонил приглашение и отправил ACK; отправитель до проверки получил только late ACK request=507. Отдельный повтор прошёл. Причина не установлена; проверить доставку UDP и шаги ускоренных часов под параллельной нагрузкой. Логи: /tmp/config-name-local-transport-failure.log, /tmp/config-name-local-transport-retry.log. Ещё один общий прогон 19.10: 161/162, chat_adapter упал на строке 145 при ожидании доставки request=501. Получатель принял приглашение и дважды отправил ACK; до проверки в логе отправителя нет приёма этого ACK. Отдельный повтор прошёл. Логи: /tmp/utun-stream-preview-local-transport-failure.log, /tmp/utun-stream-preview-local-transport-retry.log.
[x] Разобрать нестабильную проверку аудиопауз desktop-трансляции — исправлено 25.10.2026: test_stream_view::realH264RenderingAndClose нестабильно получает silenceGaps=3–4 вместо 2. Зафиксированы pcm_short с got=96/480 и 288/480; видео продолжало выводиться. Сбой повторялся с общей нагрузкой и после её завершения; изолированные повторы проходили. Проверить актуальные PCM workers/часы под нагрузкой; единичный PASS не подтверждает устранение. Повтор 25.10 при проверке восстановления потоков: silenceGaps=3 вместо 2, got=384/480; stream-перезапросов/GAP в этом локальном воспроизведении не было. Проверка шла рядом с полным C-прогоном. Новый лог: /tmp/utun2-key-qt-tests-verified.log; отдельный повтор: /tmp/utun2-key-qt-isolated.log. Диагностика 25.10 в utun2: изолированный сбой воспроизведён до искусственного stall видеодекодера. В момент провала got=96/480 (8мс тишины), PCM_before=96, tempo=1000, worker_age=239мкс; последний Opus feed был 104585мкс назад. Следующие 100мс аудио уже опубликованы 10771мкс назад, но ещё не поданы в decoder. Источник выдаёт 100мс аудио с фактическими интервалами 95–106мс. Старт с KEY оставляет 33мс аудио до головы; DSP имеет initial_latency=30мс, предзаполнения нет. PCM_target=250мс ограничивает дальнейшую подготовку, но не задаёт минимальный запас перед стартом/возобновлением. reserve включает 200мс очереди устройства и опубликованные, ещё не декодированные пакеты; minimum=233мс при guard=250мс лишь отключает ускорение, не восстанавливает недостающий запас. Это реальная нехватка PCM на границе пакетной подачи и асинхронной подготовки, а не ложный silenceGaps или доказательство блокировки аудио видео-декодером. Проверка после фиксированных 400мс зависит от фазы таймеров. Добавлены снимки PCM/темпа/guard/времени callback и отдельные эпизоды underrun; UTUN_TEST_AUDIO_DIAG=1 включает замеры публикации/кодирования источника и тишины тестового устройства. Воспроизведение: /tmp/utun2-audio-diag-repro.log, /tmp/utun2-audio-episodes-repro.log (повтор 2 из 5). Отдельный TRACE-прогон video-stall прошёл: 500мс задержки видео, 63352 ненулевых sample, новых пауз нет. Лог /tmp/utun2-audio-causal-trace.log; это подтверждает отдельность audio worker, но не устраняет PCM starvation. Исправление: общий PCM consumer при старте/underrun ждёт уже заданные 250мс готового PCM. Накопление сохраняет decoder и PTS; desktop/Android держат темп 1x до возобновления. EOF снимает ожидание порога, ограничение pull по PTS не считается нехваткой PCM. Счётчик preparedFrames публикуется после готового SPSC-слота, чтобы порог не учитывал ещё недоступный PCM. Детерминированная регрессия без таймеров падает до фикса и проходит после: 33мс после KEY, пачки по 100мс с джиттером 95–106мс + 20мс до feed, 767 полных callback без провала после старта. Отдельно проверены 600мс паузы, дробное поступление, возобновление/PTS, ограничение PTS и короткий EOF 20мс. Старые проверки точной длительности/темпа, stereo, конкурентного producer/consumer и позднего аудио проходят. GUI test_stream_view прошёл 8 повторов подряд; итоговый desktop stream-набор 4/4, Android stream unit tests 55/55, APK и основная C-сборка успешны; часы и Android bridge также проверены. Логи: /tmp/utun2-audio-regression-before.log, /tmp/utun2-audio-recovery-test-after.log, /tmp/utun2-audio-fix-view-repeat.log, /tmp/utun2-audio-fix-stream-tests.log, /tmp/utun2-audio-fix-android.log. Логи: /tmp/stream-zoom-full-view-audio-gap.log, /tmp/stream-zoom-full-view.log, /tmp/multiview-review/desktop-review.log, /tmp/multiview-review/audio-original.log.
[ ] Устранить коллизию порта при перезапуске узла в test_dm_e2e — 16.10.2026: Общий check.sh при проверке Windows-курсора: 155/156, test_dm_e2e упал в phase=9 на создании B2. Повторный bind 127.0.0.1:33843 вернул Address already in use; отдельный повтор теста проходит. Проверить владение/резервирование порта между остановкой B и созданием B2 при параллельном прогоне. Логи: /tmp/win-stream-cursor-dm-e2e-failure.log, /tmp/win-stream-cursor-dm-e2e-retry.log.
[ ] Проверить Windows-трансляцию на исходной машине после исправлений playback/stop — 16.10.2026: Цикл ожидания позднего аудио исправлен; join и закрытие микрофона выполняются асинхронно, QVideoFrame::toImage() вынесен в долгоживущий image worker. Linux/Xvfb-регрессии проходят. Осталась свежая трансляция Windows → Samsung и stop после пересборки Windows: исходный Qt backend ещё не проверен. На RYS HFR USB2.0 Camera проверить сообщение об отсутствии PCM, отзывчивость при завершении WASAPI, отказ/согласие на CPU после отказа NVENC. Причина frames=0 микрофона пока не установлена; подробный AudioDiag реализован только для Linux. libx265 3440×1440 на исходном CPU выдаёт около 2–3fps. Логи: 4.log, /tmp/stream-viewer-new-run.log, /tmp/late-audio-test.log, /tmp/stream-persistent-image-xvfb.log, /tmp/stream-audio-stop-full-check.log.
[ ] Проверить появление значка свежей трансляции на SM после сна через colo2 — 16.10.2026: Пробуждение и перезапуск SM во время сна уже проверены на обновлённом colo2: новый линк снимает прежний таймер, Merkle завершается без ожидания полного сна 120с. Осталась визуальная проверка значка новой desktop-трансляции после возврата SM в foreground; в прежнем прогоне активных источников не было (count=0). Логи: /tmp/stream-wake-live-{sm,colo2}-*.log.
[ ] Проверить остаточные паузы видеозвонка на актуальном playout — 15.10.2026: После исправления TX flush живой звонок 12694689407894286842 дал SM 29.87fps без drops, desktop 29.91fps/3 late drops за последние 20с; отдельные промежутки SM доходили до 63.8мс. В старой трассе краткие invalid audio clock сбрасывали якорь, точная причина invalid не была видна. После переработки playout/ACK и чтения аудиочасов 19–20.10 повторить оба направления на устройствах, сопоставить gap_pts_us/gap_rx_us/gap_dispatch_us и причины недоступности часов, если паузы сохраняются. Текущий контракт и результаты поздних проверок: doc/call_video.txt.
[ ] Доступность разговорного динамика в UI звонка — при подключённой проводной гарнитуре Samsung убирает EARPIECE из Telecom endpoints, но кнопка остаётся доступной по наличию физического встроенного устройства. Нажатие создаёт отложенный запрос, который исполняется после отключения гарнитуры. Согласовать UI с доступными endpoints. Также выбор проводной гарнитуры в CallScreen сейчас запрашивает BLUETOOTH_CONNECT при отсутствии этого разрешения; проверку разрешения нужно привязать к выбранному типу гарнитуры.
[ ] Ручная приёмка видеозвонков Android и ChatGUI после последних исправлений — 14–20.10.2026: Сигналинг, CAPS, реальные codecs/камера/render и A/V подключены; живые звонки уже проводились. Осталась полная проверка после изменений Full HD/50–60fps, HEVC High tier, Surface ACK и фоновых codec probes: Windows ↔ Samsung/Q8, камеры и оба направления, первый и повторный звонок, смена камеры/разрешения/кодека/битрейта, A/V, завершение и освобождение Surface/видеопорта. Аппаратные probes не заменяют эту проверку. Архитектура, контракты и выполненные проверки: doc/call_video.txt, doc/chat_call_arch.md.
[ ] Тесты: нестабильное завершение test_stcp_traffic — 14.10.2026: В полном прогоне после NCD CLOSE server получил 1029466/1048576 bytes (done=0), client — 1048576 (done=1). Упала проверка test_stcp_traffic.c:216; отдельный повтор прошёл. Причина не установлена, сетевой код в задаче zoom не менялся. Проверить завершение двусторонней передачи относительно закрытия handle; первичный лог сохранён: /tmp/stream-zoom-stcp-first.log.
[ ] Тесты: диагностировать нестабильную проверку TX snapshot в test_android_stream — 14.10.2026: В полном прогоне один раз упала строка 177: snapshot успешен и 0 < video_bytes < 500000 после test_clock_run_for(ua, 1000). Сам publisher обновляет snapshot таймером 1000; текущий CHECK не выводит result/sample_us/video_bytes. Отдельный повтор и следующий полный прогон прошли. Добавить значения и проверить ожидание конкретного снимка; причина не установлена, Kotlin-аудиовывод этот C-тест не вызывает. Логи прогонов: /tmp/stream-audio-check-host.log, /tmp/stream-audio-native-retry.log, /tmp/stream-audio-check-final.log.
[ ] Общий AGC: клиппинг после резкого роста сигнала при max_gain=45dB —
на SM при проверке CAMCORDER с настройками рации rise=6/release=30 наблюдались
4581 обрезанный отсчёт за интервал около 1s. Это общий алгоритм radio/stream,
плавное снижение gain может не успеть за скачком входа. Проверить ограничение пиков
без щелчков и ухудшения адаптации. Лог: /tmp/stream-camcorder-sm-live.log.
[ ] Desktop: выход после SIGTERM оставляет GUI после остановки ядра — 13.10.2026:
при обновлении live-плеера старый vibechat завершил ядро/worker, но процесс остался
в QCoreApplication::exec с работающим audio output. В логах также DM SELECT после
уничтожения SQLite (bad parameter or other API misuse). Проверить отмену Quit
в MainWindow::closeEvent (всегда ignore), порядок уведомлений и отключение GUI от БД.
Снимок: /tmp/stream-desktop-shutdown-backtrace.log, лог vibechat 13:04:09.
[ ] Стриминг SM → colo2 → desktop: восстановление частично остановившихся субпотоков —
13.10.2026: помощь подключилась за ~8 с, все 8 субпотоков через colo2 приняты с общего индекса 5844.
Позже шесть субпотоков перестали продвигаться около seq=111625; четыре restart не восстановили
просмотр, desktop завершился по таймауту в 11:10:48 (colo2: 12:10:48). На SM публикация продолжилась,
colo2 снял свою подписку через 3 с. В том же интервале сервер видит RX timeout/переподключения TCP к SM;
первопричина остановки выдач пока не установлена: stream на colo2 наследовал error, детальных логов не было.
Повторить с заранее включённой диагностикой stream/etcp на SM и colo2, проверить upstream handles,
аренды, позиции и повторное согласование. Логи: /tmp/stream-live-gui-final.log,
/tmp/stream-live-colo2-final.log, /tmp/stream-live-sm-final.log.
Повтор 13.10 со stereo: до 15:20 desktop показывал ~30fps, затем video/audio очереди опустели;
decodeFps упал до 7–18 и viewer завершился по таймауту в 15:21:13 после пяти restart.
SM при этом сохранял ~30fps без dropped. Новые логи: /tmp/stream-stereo-desktop-delivery-stall.log,
/tmp/stream-stereo-colo2-delivery-stall.log, /tmp/stream-stereo-sm-delivery-stall.log.
[ ] Android: отмена асинхронного запуска до готовности ядра — при проверке
мониторинга 12.10.2026 обнаружено: NativeLib.stop() пропускает native stop,
если isReady()==false, а instance_lite_stop() возвращается при g_inst==NULL.
Поэтому запрос stop до завершения конструктора может не отменить запускаемый
поток. Согласовать отмену с состоянием потока и единым сигналом завершения;
проверить stop до SERVICE_STARTED, отказ конструктора и последующий start.
[ ] Android: повторные отказы persisted node snapshots — замечено 12.10.2026
на устройстве D2AR10P3600820 при проверке live media. В сохранённой БД ряд узлов
регулярно получает invalid persisted snapshot в topo_node_sqlite_snapshot_load,
затем NCD сообщает node not found; повторные попытки засоряют лог.
Лог: /tmp/stream-av-device-initial.log. Причина пока не установлена: текущий
текст объединяет отказ deserialize, несовпадение ID и отказ verify. Разделить
диагностику этих ветвей и проверить повторные попытки загрузки отвергнутого снимка.
Существующую БД устройства при проверке стриминга не очищали.
[ ] STUN IPv6 — отдельный этап: IPv6 endpoint/config/DNS и XOR-MAPPED, scope/netif, тесты IPv6/NAT66. IPv4-оценки не переносить на IPv6 или TCP.
[ ] check.sh: изоляция сетевых integration-тестов — после основного набора автоматически запускает check-proxy/burst/load при доступном sudo. Скрипты меняют rp_filter, таблицу 100 и iptables главного namespace; cleanup выставляет rp_filter=1 вместо сохранённого значения. Перенести тесты в отдельный namespace и проверять неизменность родительской сети, как в tests/stream_netns.
[ ] Стриминг: оставшиеся длительные и масштабные сетевые проверки — 10–12.10.2026: Реализация ядра, публикации, приёма и автоматического выбора поставщиков завершена; контракт — doc/stream.txt. Есть 16-процессный namespace-стенд с NAT/reverse и выбором UDP/TCP: tests/stream_netns/README.md. Осталось подтвердить покрытие длительной нагрузки, смены адресов/мультилинка, одновременной перестройки нескольких ретрансляторов, нескольких автоматических источников/групп и mobile standby на устройстве (doc/stream.txt, раздел 16). Сохранённые проверки отдельных этапов не закрывают всю матрицу.
[+] Member files: исчерпание кеша результатов массовых изменений — исправлено 24.10.2026. Воспроизведено test_member_files_browser::recursiveDeletion(server-busy): из 76 объектов удаляются 64, следующая команда получает MF_BUSY, остаются 12. storage.c: STORE_RECEIPTS=64, RECEIPT_TB=1200000 (120 секунд). Лимит общий для успешных COMMIT/MKDIR/RENAME/REMOVE; затрагивает также рекурсивное копирование. Сохранены64 квитанции/120с без досрочного вытеснения. BUSY.cursor сообщает ближайшее освобождение, клиент этих мутаций ждёт отменяемый таймер с прежним ID/параметрами и общим сроком120с без продления. Новая сетевая регрессия через настоящий клиентский API:76 созданий, потеря успешного ответа, затем76 удалений; QUOTA подтверждает76 и0 каталогов без дубликатов. Обычный и sanitizer-прогоны PASS. Старый Qt-stub вызывает storage напрямую и по-прежнему видит допустимый сырой MF_BUSY; он не проверяет новый клиентский retry. Подробности: member_files_audit_findings.txt.
[ ] Desktop: провалы вероятности VAD при компрессии — диагностика 09.10.2026: Воспроизведение пользователя: длительная гласная, затем временная нечувствительность; ближе к концу лога несколько повторов. Новый лог 14:32:14–14:34:38: на 14:34:07–18 и 14:34:20–38 все 556 окон с RMS > -30dBFS имеют p < 0.5; PCM непрерывен, errors=0, RX-gate не мешает, clips=5 не растёт. Сигнал не исчезает, порог остаётся 0.5. --probe-stream: C-обёртка + реальный AGC + две Silero на одинаковом PCM, отличие — один reset состояния второй модели. Синтезированный flite ah растянут до 24.576с: без AGC/клиппинга p первой секунды следующей речи 0.027 против 0.674 после reset. При AGC 1dB (clips=0) — 0.012 против 0.662. Влияние истории модели подтверждено, провал на десятки секунд целиком не воспроизведён. Лог стенда: /tmp/vad-vowel-context.log; запуск: test_silero_vad lib/silero_vad.onnx --probe-stream /tmp/vad-vowel-context48.pcm 993. Вход стенда: mono s16le/48кГц, reset_window — индекс окна 512/16кГц; режим проверяет без AGC, 1dB и 15dB. Автоматические сбросы в рабочем VAD не добавлялись; test_silero_vad PASS. Уточнение: низкая вероятность держится десятки секунд, затем распознавание восстанавливается; краткий клиппинг это не объясняет. Локальный лог 14:00:10–14:00:58: 15 сбросов AEC при пропусках референса, 16 clipped samples в VAD; vad DEBUG не был включён. Добавлены секундные уровни raw/clean/reference и причина bypass/reset AEC; отдельное предупреждение о клиппинге VAD. Секундный отчёт захвата работает также без PCM: возраст кадра, очередь, максимальная задержка и предупреждение о простое. TRACE каждого окна содержит DC, число нулей и gain вместе с вероятностью/уровнем/паузой между окнами; видны сбросы и RX-gate. В локальном build/vibechat.cfg включены vad=trace, aec/radio/call=debug, general=info; после диагностики вернуть обычные уровни. Стенд --probe повторяет одинаковый PCM без reset: AGC 15/30dB после паузы обрезает пики (468/5625 samples на чистой записи). Полного провала всей фразы почти до нуля стенд не воспроизвёл; нужен повтор живой речи с новыми логами для связи с AEC/AGC. Алгоритмы обработки сигнала пока не менялись; исправление причины выбирается по результатам повтора.
[ ] Linux headless CMake: актуализировать зависимости общего ядра — 07.10.2026: чистая сборка tools/chatgui-android/build_headless останавливается на lib/speex_aec.c: speex/speex_echo.h не найден. utun_setup_sources включает этот исходник, но UTUN_INCLUDE_DIRS не содержит lib/speexdsp/include. Проверить полный состав Speex/voice зависимостей отдельного каркаса; основная Autotools C-сборка и Android NDK-сборка проходят.
[ ] Завершить проверку реакций и голосов на SM — 07.10.2026: Исправления подписей корней и их сохранения реализованы, проверены тестами; local и копия SM проверены. Последующие APK уже устанавливались на SM, поэтому прежнее ожидание подключения ADB неактуально. Осталась явная проверка реакции/голоса на устройстве с текущей БД и сборкой. Разовый скрипт и резервная копия подписей: /home/user/utun2-backups/root-certificates-20261007.
[ ] rlottie: разбор предупреждений GCC 15 в импортированных исходниках — 05.10.2026:
при сборке tools/chatgui/rlottie_src GCC сообщает -Wuninitialized в
VArenaAlloc::reset(): fFirstBlock/fFirstSize/fFirstHeapAllocationSize читаются
после явного вызова деструктора. Проверить сохранение значений до разрушения
и повторный reset с реальными выделениями. Также проверить -Wfree-nonheap-object
в vcow_ptr: статическая модель default_s сохраняет базовую ссылку.
Лог: /tmp/utun-rlottie-vendor-build.log. Сборка библиотеки и подключение её
экспортированного CMake-пакета к ChatGUI на Linux прошли; Windows ещё не проверен.
[ ] ChatGUI Windows: подтверждение обновления runtime компилятора — 05.10.2026:
cc-probe.log: cc1 запускается из корня, но в tools/chatgui/build завершается
с 0xC0000139; локальные DLL GCC/math/runtime отличаются от UCRT64.
Перед обеими точками сборки добавлено обновление существующих копий этих DLL;
раскладка FFmpeg использует для них UCRT64. Проверены обновление, повторный вызов,
сохранение кодеков и ошибки. Требуется Windows-прогон check_cc.bat: cc1 после
обновления, повтор команды Ninja и сборка Opus должны завершиться с кодом 0.
[ ] ChatGUI Windows: обновление остальных DLL приложения после обновления MSYS2 — 05–06.10.2026: Пропуск раскладки при наличии основного комплекта уже убран: зависимости проверяются на каждой сборке, Qt DLL/плагины и собственный комплект FFmpeg копируются заново; runtime GCC обновляется отдельно. Осталось определить обновление прочих уже существующих транзитивных DLL: рекурсивный проход по-прежнему копирует только отсутствующие файлы. Сохранить приоритет собственной сборки FFmpeg и проверить запуск приложения после обновления MSYS2.
[ ] Android: время жизни config provider — 03.10.2026: utun_bridge_init()
передаёт адрес локального utun_config_provider_t в utun_config_set_provider(),
который хранит указатель. После возврата из init он недействителен; перед
использованием cfg_get_* обеспечить постоянное хранение provider.
[ ] Общий лимит check.sh после clean — 01.10.2026: расчёт по времени предыдущего
прогона дал 205с вместе с полной сборкой и оборвал проверку после успешных тестов
до test_uasync_socket_race. Повторный запуск на готовой сборке с большим лимитом
прошёл за 206с, включая proxy/burst/load. Разделить бюджет сборки и запуска тестов
либо учитывать clean при расчёте.
[ ] Повторно проверить паузы desktop-аудио при звонке с SM — 01.10.2026: В звонках 939a3ea36f3eeac3/b2a423ed2d36ed83 частота callback падала до 4–40/с, входящий PCM продолжал приходить, очередь росла до нескольких секунд без dropped. Диагностика backend, интервалов callback и capture/playback уже добавлена; позднее менялись аудиовывод и его буферы. Нужен повтор на текущей сборке с CALL_STATS и временными метриками, чтобы проверить сохранение исходного сбоя. Сетевую задержку оценивать отдельно: в одном из прежних звонков DIRECT RTT был 2–3мс.
[ ] Измерить оставшуюся задержку запуска аудио SM после исправлений — 01.10.2026: В исходном звонке 2b9ad4e21a54d8ba первый capture приходил через 1140мс от startAudio; router.start=781мс, startRecording → первый кадр=328мс, AudioTrack.play=327мс. Независимый запуск capture/playback, отмена частичного старта и подробные замеры уже реализованы; позднее добавлен выбор AAudio/AudioTrack. Осталось измерить текущую сборку на SM: callbackMs/btProfileMs/applyMs/refreshMs, первый AudioRecord.read и первая запись playback, начальное накопление очереди. Старые длительности не считать характеристиками текущей реализации.
[ ] Гонка invite-файла в test_chat_join_e2e — wait_file() проверяет только
существование файла, а wf() создаёт его до записи. Читатель иногда получает
пустую ссылку и ошибку префикса utun://. Публиковать готовый файл атомарно.
[+] Linux ONNX Runtime: повторная регистрация схем при запуске теста — проверено 21.10.2026:
Причина в системной сборке 1.23.2+dfsg-6ubuntu1: Runtime вручную регистрирует схемы,
затем динамическая libonnx.so.1 повторяет регистрацию в OpSchemaRegistry::map().
Подтверждено GDB (/tmp/silero-schema-gdb.log) и исходниками обеих библиотек.
Текущая Linux x64 CMake-сборка переключена на официальный Runtime 1.23.2.
Архив onnxruntime-linux-x64-1.23.2.tgz распакован в .cache/onnxruntime/;
SHA-256: 1fa4dcaef22f6f7d5cd81b28c2800414350c10116f5fdd46a2160082551c5f9b.
Для существующего include onnxruntime/onnxruntime_c_api.h создана ссылка
.cache/onnxruntime/include/onnxruntime → ../onnxruntime-linux-x64-1.23.2/include.
В CMake явно заданы абсолютные пути: ONNXRUNTIME_INCLUDE_DIR=<repo>/.cache/onnxruntime/include,
ONNXRUNTIME_LIB=<repo>/.cache/onnxruntime/onnxruntime-linux-x64-1.23.2/lib/libonnxruntime.so.
Выбор сохраняется в tools/chatgui/build/CMakeCache.txt; после удаления cache его нужно повторить.
ldd подтверждает официальный Runtime без отдельной libonnx; весь test_silero_vad проходит без Schema error.
Лог проверки: /tmp/silero-runtime-test.log, полный вывод — tools/chatgui/build/Testing/Temporary/LastTest.log.
[ ] debug_parse_config: формат и индексы категорий — parser ожидает :, документация
описывает =; преобразование битовой маски осталось после перехода enum на индексы.
Разбор.
[ ] Повторно проверить crypto-шум при автоподключении в сценарии A–C–B: В старом test_dm_e2e попытка прямого A↔B через topo_group_connect давала packet undecryptable примерно раз в секунду. Наблюдение относилось к прежним настройкам приёма и архитектуре подключений; устранение не подтверждено. Воспроизвести на текущих NCD/ETCP и установить точную причину по логам до изменения политики подключения. Отсутствие [client] само по себе не считать основанием запрета: CHAT использует собственных NCD-владельцев.
[ ] lwip/proxy: утечка pcb в FIN_WAIT_2 — tcp_shutdown(pcb,0,1) (half-close по FIN от
exit) не ставит TF_RXCLOSED, поэтому таймаут FIN_WAIT_2 в tcp_slowtmr не срабатывает:
если браузер никогда не пришлёт FIN, pcb навсегда остаётся в FIN_WAIT_2 (утечка, не crash).
Двойной free по TIME_WAIT уже закрыт (detach по локальному закрытию + guard abort).
Открытые флаки
[ ] test_etcp_transport: таймаут восстановления REALITY-сессии — 18.10.2026:
в общем ./check.sh сценарий reality=1 simultaneous=0 restart=0 завершился
Session recovery timed out: phase=1 stream=15 control=6. Перед таймаутом —
record socket read failed: err=104, клиент ждал server-handshake.
Отдельный повтор того же бинарника прошёл. Причина нестабильности пока не установлена;
изменения Android JNI/UI транспортные исходники не затрагивали.
[ ] test_etcp_reconnect — флаки под параллельной нагрузкой make check -j4:
phase 4 (reconnect после server restart) таймаутит (sent=480 recv=0), при одиночном
запуске стабильно TEST PASSED. Наш код (chat_join/chat_sync) его не трогает.