---
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).
