9.5 KiB
verdict, work_item, stage, author_agent, status, created_at, model_used, type, work_item_id, version
| verdict | work_item | stage | author_agent | status | created_at | model_used | type | work_item_id | version |
|---|---|---|---|---|---|---|---|---|---|
| APPROVED | ORCH-100 | review | reviewer | approved | 2026-06-10 | claude-opus-4-8 | review | ORCH-100 | 1 |
Review ORCH-100 — FND/F1b: sidecar-watchdog
Summary
Аддитивная реализация sidecar-наблюдателя в отдельном контейнере orchestrator-watchdog
(папка watchdog/, тонкий Python-3.12-stdlib-only демон). Проверено по 4 осям. Реализация
точно соответствует ТЗ (FR-1…FR-11) и ADR-001 (D1…D9): отдельный контейнер, толерантный
парсинг /metrics, debounce orch_down, read-only docker.sock (GET-only по построению),
обобщённая чистая decide, независимый Telegram-канал, структурный анти-дубль диск-алерта (D6),
трёхуровневый never-raise, kill-switch.
Корневой инвариант соблюдён: PR не трогает src/** ни одной строкой (подтверждено
git diff --stat -- 'src/**' → пусто) ⇒ STAGE_TRANSITIONS / QG_CHECKS / check_* /
machine-verdict ключи / схема БД орка — байт-в-байт прежние. Документация обновлена
исчерпывающе. 66 тестов tests/watchdog/ зелёные.
Вердикт: APPROVED. P0/P1, относящихся к этому PR, нет. Ниже — P2-замечания (не блокируют) и одна эскалация по pre-existing красному тесту вне области F1b.
Findings
P0 — Blocker
- (нет)
P1 — Must fix
- (нет)
P2 — Should fix
- Заявление «полный регресс
tests/ -qзелёный» неточно (CHANGELOG / AC-7). Полный прогонpytest tests/даёт 1 падение:tests/test_queue.py::TestRetry::test_finalize_job_requeue_then_fail. Важно: этот тест байт-в-байт идентиченorigin/main(git diff origin/main...HEAD -- tests/test_queue.py→ пусто), а PR не меняетsrc/**— падение pre-existing на main, НЕ вызвано ORCH-100 и структурно неустранимо в рамках F1b (ТЗ §2 прямо запрещает правкиsrc/**). Поэтому это не основание для REQUEST_CHANGES этого PR. Действие: скорректировать формулировку «полный tests/ зелёный» → «tests/watchdog/зелёные (66); один pre-existing красный тест на main вне области F1b» и завести отдельную баг-задачу (см. Escalation). Источник: AC-7 (03-acceptance-criteria.md), CHANGELOG-запись ORCH-100. - FR-4: host inode/CPU не реализованы как сигналы. ТЗ FR-4 упоминает «диск (% и, где
доступно, inode), память, CPU»; ADR-001 D5 (реестр сигналов) сузил host-метрики до
host_mem+ opt-inhost_disk_crit, и этот реестр реализован полностью. Host-CPU (loadavg) и inode в сигналы не превращены —watchdog/collectors/host.pyих не собирает (host-CPU/«завис» покрыт черезagent_hungиз/metrics). Это документированное сужение на стадии архитектуры (FR-4 формулирует inode как «где доступно»), не нарушение. Замечание: docstring ADR D3 дляhost.pyупоминает «CPU (loadavg)», которого в реализации нет — расхождение комментария и кода; либо реализовать host-CPU/inode-сигнал, либо снять упоминание из docstring D3. Источник:02-trz.mdFR-4,ADR-001D3/D5.
P3 — Nice-to-have
- CLAUDE.md не обновлён. Паспорт проекта не получил запись о F1b. Прецедент: парная задача
F1a (ORCH-099) также отсутствует в CLAUDE.md (grep → 0) — это семейство наблюдаемости в паспорте
не трекается, а золотой архитектурный док (
docs/architecture/README.md) покрывает F1b исчерпывающе (компонентная строка + полная секция §«Sidecar-watchdog F1b»). Опционально для единообразия с другими операционными демонами (disk_watchdog/reaper) — добавить краткую TL;DR-строку. watchdog/collectors/containers.py::DockerSockReader.list_containersне вызывается вcore.tick(используется толькоinspect(name)по спискуcfg.containers). Публичный read-метод оставлен для полноты API/тестов — безвреден; при желании отметить как explicit-API или удалить.
Документация
Обновлена исчерпывающе — golden source синхронизирован с кодом:
- ✅
docs/architecture/README.md— новая компонентная строка (Sidecar-watchdog F1b) + полная секция «## Sidecar-watchdog F1b (ORCH-100 — design)» + перекрёстная ссылка в секции F1a. - ✅
CHANGELOG.md— детальная запись F1b (стек D1 / топология D2 / decide D4 / реестр сигналов D5 / анти-дубль D6 / транспорт D7 / never-raise D8). - ✅
docs/work-items/ORCH-100/06-adr/ADR-001-sidecar-watchdog.md+ сквознойdocs/architecture/adr/adr-0033-sidecar-watchdog.md(оба с корректным frontmatter). - ✅
docs/work-items/ORCH-100/07-infra-requirements.md— разовое инфра-предусловие (сервис в compose, bot/chat watchdog,.env.watchdog, первый запуск). - ✅
.env.example— канон всехWATCHDOG_*ключей, без реальных секретов (токены пустые). - ⚠️ CLAUDE.md — не обновлён (P3, см. выше; прецедент F1a — допустимо).
- ✅ README «Известные ограничения» (ось ORCH-079): F1b — новая способность (внешний наблюдатель), ни один из 3 открытых пунктов витрины не закрывается этим PR ⇒ обновления обзорной витрины не требуется (ось удовлетворена).
Поскольку src/** НЕ изменён, P0 «src изменён, документация не обновлена» не активируется;
при этом документация всё равно обновлена сверх минимума.
Проверки инвариантов (явно)
git diff origin/main...HEAD --stat -- 'src/**'→ пусто (src нетронут; STAGE_TRANSITIONS / QG_CHECKS / check_* / схема БД — байт-в-байт).docker.sockсмонтирован:ro(compose) И код GET-only по построению (_getхардкодитGET, нет ни одного мутирующего метода) — двойная гарантия read-only (AC-6).- Нет импорта
src/**изwatchdog/**(C-1 / BR-8) — независимый Telegram-транспорт со своими токенами; падение орка не утянет алерт-канал. - never-raise: per-source (коллекторы), per-tick (
__main__+core._dispatch), per-send (notify) — все три уровня присутствуют. - kill-switch
WATCHDOG_ENABLED=false→ idle-loop (НЕ exit) — restart-policy не крутит петлю. mem_limit: 128m+mem_reservation: 32m; stdlib-only (нет requirements/pip-дерева) — тонкость C-3 соблюдена.- Багфикс-трек (ORCH-019 BR-4): задача —
feat/FND, неBug⇒ требование регресс-теста-фиксатора не применяется.
Escalation
- Pre-existing красный тест на
main:tests/test_queue.py::TestRetry::test_finalize_job_requeue_then_failпадает стабильно (3/3 изолированных прогона) и идентиченorigin/main. Он не вызван ORCH-100 и неустраним в области F1b (правкиsrc/**запрещены ТЗ §2). Однако он завалит downstream merge-gate re-test (ORCH-043 гоняетpytest tests/на догнанной ветке) и нарушает AC-7 «полный tests/ зелёный» на уровне репозитория. Рекомендация: Owner/планировщику завести отдельную баг-задачу (меткаBug, маршрут ORCH-019) на починкуtest_finalize_job_requeue_then_failвsrc/**; без неё прод-выкат ORCH-100 упрётся в merge-gate по причине, не относящейся к F1b. Это эскалация, а не finding против данного PR.