Files
utun2/doc/tasks.md
T

786 lines
104 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задачи по проекту
Сюда пишется список задач с короткой аннотацией. Если задача большая и имеет ТЗ - то ТЗ оформляется отдельным файлом, а сюда помещается аннотация и ссылка на ТЗ.
## Текущие задачи
[ ] **Proxy: проверить ошибки teardown и убрать неверный ключ в тестовых конфигах** — обнаружено при аудите документации 24.10.2026.
Проект исправлений и проверка владения/rollback/half-close: [doc/proxy_fix_plan.txt](proxy_fix_plan.txt).
Уточнение 24.10.2026: существующие proxy/socket debug включены через gdb без правок исходников.
Подтверждён обход backpressure при HUP: tcp_io error_cb снимает read_waiter и принудительно читает,
очередь выросла до53 блоков при high_water=4. Нужны ограниченное чтение и ожидание low_water без HUP busy loop.
strace четырёх HTTPS-потоков: после EOF назначения приходит TLS-запись24 байта от клиента;
send принимает её, затем SO_ERROR=EPIPE или shutdown=ENOTCONN. Повторный shutdown не обнаружен.
Не подавлять эти ошибки; отдельно проверить корректный TLS shutdown тестового сервера и abrupt close.
Доказательства: /tmp/proxy-design-debug.log, /tmp/proxy-design-lifecycle.log,
/tmp/proxy-design-close.744427 и /tmp/proxy-design-close-summary.txt. Исходники пока не изменены.
Девять профильных тестов PASS, но в test_socks_http_proxy после ответов встречаются EPIPE (32)
в tcp_io error_cb и ENOTCONN (107) при shutdown write; причина и корректность cleanup отдельно не установлены.
Побайтовая проверка всех 16 загрузок проходит. Начать с информативного лога FIN/close/socket events
(proxy/socket), сопоставить обе половины и очереди; поведение по одному PASS не считать проверенным.
test_udp_proxy, test_icmp_proxy и test_socks_http_proxy также используют [tcp_proxy_server] enabled=yes:
парсер логирует Unknown option, но включает сервер при обработке любого параметра этой секции.
В тестах использовать поддержанный параметр, например connect_timeout=2000, либо отдельно согласовать API конфига.
ICMP здесь проверен через fallback без raw socket (нет прав); реальный raw ping не подтверждён.
Логи: /tmp/proxy-doc-audit-network-logs/test_socks_http_proxy.log, test_udp_proxy.log и test_icmp_proxy.log в том же каталоге.
[ ] **ETCP: полезная утилизация нескольких каналов и доставка при зависании части линков** — общая задача открыта.
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 от 4*MSS/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.2*RTT+1.5*jitter+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](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(4*MSS, BDP + BW*20мс), с насыщением арифметики и учётом 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 равно 4*MSS;
MTU пересчитывается после включения нового линка в список. init_cwnd инициализируется четырьмя фрагментами.
Транспорт применяет положительное окно с верхним ограничением bbr_max_cwnd, не поднимая его до 8192.
INFLIGHT_LIM_MIN=8192 остаётся нижней допустимой границей настройки максимального окна; нулевое окно отклоняется с логом.
PROBE_RTT осушает до max(4*MSS, 0.5*BDP), ждёт >=200мс и раунд ACK, затем восстанавливает предыдущее окно.
Отправленные при осушении DATA помечаются app_limited. Ограничения после потерь больше не уменьшают окно ниже 4*MSS.
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.
[ ] **Разобрать нестабильную проверку аудиопауз desktop-трансляции** — 17–20.10.2026:
test_stream_view::realH264RenderingAndClose нестабильно получает silenceGaps=3–4 вместо 2.
Зафиксированы pcm_short с got=96/480 и 288/480; видео продолжало выводиться.
Сбой повторялся с общей нагрузкой и после её завершения; изолированные повторы проходили.
Проверить актуальные PCM workers/часы под нагрузкой; единичный PASS не подтверждает устранение.
Логи: /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: исчерпание кеша результатов массовых изменений** — 10.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; затрагивает также рекурсивное копирование.
Нужен отдельный этап управления временем жизни receipts с сохранением идемпотентности повторных запросов;
простое вытеснение старых записей нарушает гарантию повторного ответа. После исправления изменить регрессию
на успешное удаление более 64 объектов и проверить повторные запросы/потерю ответа.
[ ] **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](https://github.com/microsoft/onnxruntime/releases/tag/v1.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 на индексы.
[Разбор](etcp_full_suite_findings.md).
[ ] **Повторно проверить 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) его не трогает.