diff --git a/docs/work-items/ORCH-104/12-review.md b/docs/work-items/ORCH-104/12-review.md new file mode 100644 index 0000000..f165c7a --- /dev/null +++ b/docs/work-items/ORCH-104/12-review.md @@ -0,0 +1,134 @@ +--- +verdict: REQUEST_CHANGES +work_item: ORCH-104 +stage: review +author_agent: reviewer +status: changes-requested +created_at: 2026-06-12 +model_used: claude-opus-4-8 +type: review +work_item_id: ORCH-104 +version: 1 +--- + +# Review ORCH-104 — Установочный скрипт для Lite + +> Машинный вердикт читается ТОЛЬКО из `verdict:` во frontmatter. +> `REQUEST_CHANGES` → откат на `development`. + +## Summary + +PR в текущем виде **не содержит главного артефакта ТЗ**: `scripts/install_lite.py` существует +только как **untracked-файл** в worktree (`git status` → `?? scripts/install_lite.py`; `git +ls-files` его не знает; diff `origin/main...HEAD` — только docs + tests). При этом +`tests/test_install_lite_script.py` (735 строк, 50 тестов) **закоммичен** и жёстко ассертит +наличие скрипта → на свежем чекауте ветки CI (`.gitea/workflows/ci.yml` → `pytest tests/`) +красный. Дополнительно: даже при наличии скрипта локальный прогон даёт **47 passed / 2 failed / +1 вечно висящий**: tc19 и tc20 (needle-скан сырого исходника ловит докстринг и текст инструкции +оператору), tc17_health_fail (константный фейк `time.monotonic` → недостижимый дедлайн — +busy-loop, прогон не завершается). Doc-sync (FR-11/AC-12: LITE_SETUP.md, CLAUDE.md, CHANGELOG.md, +`test_lite_setup_doc.py`, витрина `docs/overview/`) не выполнен. + +Положительное: архитектурный пакет качественный — ADR-001 (D1–D15) разрешает все OQ-1…OQ-7 ТЗ, +сквозной `adr-0040` заведён; тест-набор содержательный (структурные анти-дрейф + юнит чистых +функций + фейки side-effects, зеркало `test_bootstrap_script.py`); вставка в +`docs/architecture/README.md` чисто аддитивна (чужие маркеры `ORCH-NNN` не тронуты — ось +трассировки чиста); сам скрипт статически соответствует ADR (кирпичи `gen_secrets.py`/ +`onboard_project.py` строго субпроцессом, `getpass`, `chmod 0o600`, `--force`-гейтинг, +webhook Plane — manual-step, никаких delete-операций). После фиксации скрипта в коммите и +исправления findings пакет близок к готовности. + +## Оси проверки + +| Ось | Статус | +|-----|--------| +| Соответствие ТЗ | ❌ FR-1…FR-10 не входят в PR (скрипт не закоммичен); FR-11 не выполнен | +| Соответствие ADR | ✅ содержимое скрипта/тестов следует ADR-001 D1–D15; ❌ D13/D14 (doc-sync) не исполнены | +| Качество кода | ❌ 2 падающих теста (tc19, tc20) + 1 вечно висящий (tc17) при локальном прогоне | +| Документация | ❌ LITE_SETUP.md / CLAUDE.md / CHANGELOG.md / `test_lite_setup_doc.py` / `docs/overview/` — ноль упоминаний ORCH-104/install_lite | +| Трассировка (TRACEABILITY) | ✅ diff аддитивен, чужие маркированные инварианты не правились | +| Инварианты (INV-1, AC-9) | ✅ `src/**` / `STAGE_TRANSITIONS` / `QG_CHECKS` / схема БД — байт-в-байт | + +## Findings + +### P0 — Blocker + +- [ ] **Главный артефакт ТЗ не в PR: `scripts/install_lite.py` не закоммичен** (ТЗ §2/§3 + FR-1…FR-10; AC-1…AC-11). Файл есть в worktree (1064 строки, статически соответствует + ADR-001), но untracked — ни в одном коммите ветки, в diff `origin/main...HEAD` отсутствует. + С точки зрения PR установщик не реализован. **Прямое следствие — красный CI:** закоммиченный + `tests/test_install_lite_script.py` ассертит `SCRIPT.is_file()` (стр. 68: + `"scripts/install_lite.py отсутствует (FR-1)"`) и грузит модуль по файлу — на свежем чекауте + ветки все ~50 тестов упадут; `ci.yml` гоняет `pytest tests/`. **Фикс:** `git add + scripts/install_lite.py` + коммит в эту же ветку (после исправления P1-1/P1-2 ниже). + +- [ ] **FR-11 / AC-12 (doc-sync) не реализованы** — невыполненное требование ТЗ; буквально + срабатывает FAIL-условие AC-12 «установщик добавлен, но LITE_SETUP.md/CLAUDE.md о нём молчат» + (правило агентов №2/№6, ADR-001 D13/D14). Не обновлены в PR: + - `docs/deployment/LITE_SETUP.md` — нет callout-указателя «рекомендованный путь — + `install_lite.py`» (ADR D14; 13 `## N.`-заголовков при этом сохранить байт-в-байт); + - `tests/test_lite_setup_doc.py` — нет ассерта ссылки на установщик (ADR D13); + - `CLAUDE.md` — раздел тиража (Lite) без упоминания установщика; + - `CHANGELOG.md` — без записи ORCH-104. + +### P1 — Must fix + +- [ ] **2 структурных теста падают на «тексте о запретах», а не на нарушениях** (верифицировано + прогоном: 47 passed / 2 failed). Оба — один класс дефекта: needle-скан сырым `n in src` по + всему исходнику без tokenize-исключения комментариев/докстрингов/инструкций: + - `test_tc19_has_no_delete_or_force_operations` — `AssertionError: … ['down -v', + 'force-push']`: модульный докстринг `install_lite.py` (стр. 27–28) перечисляет запрещённые + операции текстом («…никаких rm/down -v/…/force-push…»). Реальных операций в коде нет. + - `test_tc20_carries_no_own_status_canon` — needle `To Analyse`: стр. 928 скрипта — текст + инструкции оператору в manual-step webhook («Финальная проверка webhook — на smoke §11 + (задача в „To Analyse“)»). Это не форк канона 22 статусов (статус не создаётся), а + человекочитаемая подсказка (зеркало LITE_SETUP §11). + + **Фикс (одно из):** (а) сканировать с tokenize-исключением комментариев/докстрингов — паттерн + `find_violations` из `test_no_host_hardcodes.py` уже импортирован тестом (single source of + truth); для tc20 — сузить критерий до признака форка канона (напр., ≥N имён статусов или + создание статусов API-вызовом); (б) перефразировать докстринг (стр. 27–28) и инструкцию + (стр. 928 — сослаться на LITE_SETUP §11 без буквального имени статуса). Тесты обязаны быть + зелёными в том виде, в котором закоммичены вместе со скриптом. Ссылка: AC-7, AC-10, INV-3, + ADR D13. + +- [ ] **`test_tc17_health_fail_raises_install_error` виснет навечно** (верифицировано verbose- + прогоном: последний стартовавший тест — ровно он, 48/51 пройдено, прогон убит по таймауту + 240 с; fail-fast прогон первых тестов — 0.6 с). Механизм: тест фейкует `mod.time` константой + `monotonic → 1e9`, `sleep → no-op`; + `step_health` (скрипт, стр. 941–946) крутит `while time.monotonic() < deadline` с + `deadline = monotonic() + 60` — дедлайн недостижим, `_http` → 503 вечно ⇒ бесконечный + busy-loop. После коммита скрипта CI будет висеть, а не падать. **Фикс:** тикающий фейк + monotonic (счётчик/генератор, +N на вызов) либо инжектируемый дедлайн/лимит попыток в + `step_health`/`_wait_health`. Заодно: `test_tc17_main_verify_reports_fail_as_exit_error` не + фейкует время вовсе → ~3 мин реального поллинга (3 пути × 60 с × `sleep(3)`) — ускорить тем + же способом. Ссылка: AC-11, NFR-7 («детерминированный, без сети»), ADR D13. + +- [ ] **Витрина `docs/overview/` не обновлена** (ORCH-011, расширение оси обзорных доков + ORCH-079 → finding ≥ P1). `docs/overview/presentation.md` слайд 17 «Lite-установка скриптами» + (стр. 159: «Маршрут — пошаговый runbook LITE_SETUP.md…») и `business.md` (стр. 92) описывают + именно меняемую функциональность — способ установки Lite. ADR-001 D14 сам фиксирует: «витрина + Lite-install — затронута…; финальные правки — на стадии development». Не сделано. **Фикс:** + обновить слайд 17/связанные упоминания (рекомендованный путь — установщик, runbook — фолбэк) + в том же PR; сверить с `tests/test_system_docs.py`. + +### P2 — Should fix + +- [ ] `docs/architecture/README.md`: добавленный блок озаглавлен «**Установщик Lite (ORCH-104 — + design)**» — пометка «design» была честной на стадии architecture, но в PR с реализацией + вводит в заблуждение (читается как «ещё не реализовано»). Снять/актуализировать пометку в том + же PR (ось документации, golden source). + +## Документация + +**Статус: НЕ обновлена — одна из причин `REQUEST_CHANGES`.** + +- Обновлено в PR: `docs/architecture/README.md` (блок Type A, аддитивно), сквозной + `docs/architecture/adr/adr-0040-lite-installer-canon.md`, work-item ADR + аналитический пакет + (01–04, 10) — корректные frontmatter-схемы 52c. +- Требуется обновить в том же PR (см. P0-2 / P1-3): `docs/deployment/LITE_SETUP.md` (callout на + установщик), `CLAUDE.md` (раздел Lite-тиража), `CHANGELOG.md` (запись ORCH-104), + `tests/test_lite_setup_doc.py` (ассерт ссылки), `docs/overview/presentation.md` (слайд 17) / + `business.md` (упоминание маршрута Lite), плюс снять пометку «design» в + `docs/architecture/README.md` (P2). +- `07-infra-requirements.md` / `08-data-requirements.md` — N/A обоснованно (ADR D15, ТЗ §5).