train_utility/.agents/PROJECT_ISSUES.md

8.3 KiB
Raw Blame History

Исправленные проблемы проекта YOLO Train WebUI

Дата исправления и повторной проверки: 2026-07-18

Итог

Все 10 дефектов аудита от 2026-07-17 исправлены. WebUI снова проходит синтаксическую проверку, серверный обработчик события начала обучения не зависает, WebSocket-сообщения отправляются в event loop ASGI-сервера, а успешное завершение, отмена и ошибка представлены отдельными состояниями.

Регрессионный набор расширен с 37 до 49 тестов.

ID Приоритет Статус Исправление
BUG-001 Критический Исправлено Закрыт try/catch, удалено повторное объявление configForm, добавлен node --check в тесты
BUG-002 Критический Исправлено Status broadcast вынесен за пределы threading.Lock; добавлен тест на отсутствие deadlock
SEC-001 Критический при сетевой публикации Исправлено Compose публикует loopback, URL запрещены, пути ограничены доверенными корнями, restricted checkpoint loading включён
BUG-003 Высокий Исправлено Все WebSocket send выполняются в ASGI loop через run_coroutine_threadsafe; ошибки логируются, сломанные сокеты удаляются
BUG-004 Высокий Исправлено Введены состояния succeeded, cancelled, failed; ошибка после stop больше не маскируется как отмена
DOC-001 Высокий Исправлено README полностью обновлён для WebUI, актуальных CLI-команд, Docker и модели безопасности
BUG-005 Средний Исправлено Провалидированные классы всегда записываются в итоговый YAML и имеют приоритет над случайным корневым YAML
BUG-006 Средний Исправлено Числа разбираются с проверкой Number.isNaN; нули сохраняются при чтении и восстановлении формы
BUG-007 Средний Исправлено Серии графика добавляются динамически и выравниваются по эпохам, включая новые ключи метрик
BUILD-001 Средний Исправлено Docker устанавливает frozen-набор из uv.lock; версия uv также зафиксирована

Жизненный цикл и WebSocket

  • Событие started меняет состояние под lock, но отправляет статус только после освобождения lock.
  • Event loop запоминается при подключении WebSocket. Вызовы из фонового потока передаются в него через asyncio.run_coroutine_threadsafe().
  • Отправки сериализуются asyncio.Lock, поэтому сообщения одного запуска сохраняют порядок. Ошибка доставки попадает в журнал, а нерабочий клиент удаляется.
  • Финальная классификация учитывает return code, stop-флаг, последнее структурированное событие и факт принудительной остановки.
  • Штатная кооперативная остановка даёт cancelled; ненулевой код после stop без подтверждённой отмены даёт failed.

Безопасность

  • docker-compose.yml публикует 127.0.0.1:8000:8000.
  • Dataset, model и project не принимают URL.
  • Локальные пути ограничены datasets, models и runs; дополнительные доверенные корни задаются переменными YOLO_WEBUI_DATA_ROOTS, YOLO_WEBUI_MODEL_ROOTS, YOLO_WEBUI_RUN_ROOTS.
  • Проверка использует разрешённые абсолютные пути после resolve(), поэтому symlink/.. не позволяют выйти из доверенного корня.
  • Имена профилей валидируются на сервере, а last_run нельзя перезаписать через публичный endpoint профилей.
  • ULTRALYTICS_SAFE_LOAD=1 включён и в Python-процессе, и в Docker-образе.
  • Для намеренной удалённой публикации по-прежнему нужен аутентифицирующий reverse proxy; это явно указано в README.

Frontend

  • app.js снова является валидным JavaScript.
  • workers=0, patience=0 и close_mosaic=0 проходят полный цикл form → JSON → localStorage → form без замены default-значениями.
  • График создаёт dataset при первом ключе метрики и добавляет новые серии в следующих эпохах. Пропущенные значения дополняются null, поэтому точки не сдвигаются.
  • UI и CSS отдельно отображают succeeded, cancelled и failed; старый finished оставлен только как frontend-совместимость.

Датасеты, Docker и документация

  • Результат read_classes() безусловно становится dataset_data["names"], сохраняя при этом остальные ключи выбранного YAML (kpt_shape, flip_idx и другие).
  • Docker копирует pyproject.toml вместе с uv.lock и выполняет uv sync --locked --no-dev; обход lock-файла удалён.
  • README описывает uv run yolo-train-webui, uv run -m yolo_webui, Compose, структуру датасетов, MLflow и ограничения доверенных путей.

Добавленные регрессионные проверки

Тесты теперь покрывают:

  1. синтаксис browser JavaScript;
  2. сохранение допустимых нулей и динамические серии Chart.js в Node smoke-test;
  3. отсутствие deadlock на событии started;
  4. доставку сообщения из background thread в loop WebSocket-сервера;
  5. различие succeeded / cancelled / failed;
  6. запрет URL и выходов за разрешённые корни;
  7. защиту зарезервированного профиля last_run;
  8. приоритет явно указанного classes.txt над корневым YAML.

Выполненные проверки

uv run pytest -q                         -> 49 passed, 1 warning
uv run python -m compileall -q src tests -> успешно
node --check src/yolo_webui/static/app.js -> успешно
node tests/frontend_smoke.js             -> успешно
uv lock --check                          -> успешно
docker compose config                    -> успешно, host_ip=127.0.0.1
git diff --check                         -> успешно

Полная сборка Docker-образа локально не запускалась: Docker daemon недоступен. Конфигурация Compose проверена отдельно, а соответствие lock-файла — через uv lock --check.

Оставшееся предупреждение pytest относится к deprecated-связке fastapi.testclient/starlette.testclient с httpx; оно не связано с исправленными дефектами и не ломает тесты.