diff --git a/docs/work-items/ORCH-109/12-review.md b/docs/work-items/ORCH-109/12-review.md index 7f8f16b..4308977 100644 --- a/docs/work-items/ORCH-109/12-review.md +++ b/docs/work-items/ORCH-109/12-review.md @@ -8,54 +8,76 @@ created_at: 2026-06-14 model_used: claude-opus-4-8 type: review work_item_id: ORCH-109 -version: 2 +version: 3 --- # Review ORCH-109 ## Summary -Две аддитивные изолированные правки подсистемы запуска (`launcher`) — launch-стамп модели в -`agent_runs.model` (D1/FR-1) и поднятые per-role wall-clock бюджеты developer/reviewer с синхронным -поднятием reaper (D3/D4/FR-3) — реализованы **корректно и точно по ADR**. Контракты неприкосновенны: -`STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict/схема БД — байт-в-байт (AC-9 верифицирован -по диффу: в `src/` изменены только `launcher.py` и `config.py`, ни одной контракт/схема-строки). -Инварианты ORCH-087 (стамп эффорта — объединён в один `UPDATE`, не сломан) и ORCH-065 (reaper -`5400 > 3600+20=3620`) сохранены и закреплены тестами. Покрытие исчерпывающее: новый +Две аддитивные изолированные правки подсистемы запуска (`launcher`) — **launch-стамп модели** в +`agent_runs.model` (D1/FR-1) и **поднятые per-role wall-clock бюджеты** developer/reviewer с +синхронным поднятием reaper (D3/D4/FR-3) — реализованы **корректно и точно по ADR**. Контракты +неприкосновенны: в `src/` изменены **только** `launcher.py` и `config.py`; ни одной строки +`STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / `_parse_*` / machine-verdict / `CREATE TABLE` / +`ALTER TABLE` в диффе нет (AC-9 верифицирован grep'ом по диффу). Зафиксированные маркер-инварианты +**ORCH-087** (стамп эффорта объединён в один `UPDATE`, `(effort or None)` сохранён) и **ORCH-065** +(reaper поднят синхронно `3600→5400`, `5400 > 3600+20=3620`) — целы. Покрытие исчерпывающее: новый `tests/test_orch109_timeout_model.py` (TC-01…TC-12, детерминированный, без сети/CLI), обновлены `tests/test_config.py` (reaper-дефолт 5400) и `tests/test_launcher.py` (лестница `_resolve_timeout`). -Полный регресс **1899 passed** (exit 0). -**Единственный блокер прошлой итерации (P1 README front-page «### Watchdog», устаревший факт «timeout -30 минут») закрыт** — commit `91d56fe docs(readme): sync Watchdog section with per-role timeout -budgets`: `README.md:295` приведён в соответствие с `internals.md` (developer 60м / reviewer 50м / -прочие 30м дефолт, `_resolve_timeout`, ORCH-109) + Tier-3 backstop `reaper_max_running_s`=90м (ORCH-065). -Обзорная витрина `docs/overview/` конкретного числа тайм-аута не несёт (упоминания watchdog — -концептуальные: sidecar-наблюдатель и «следит за процессом»), поэтому правки не требует. Открытых -findings P0/P1/P2 нет → вердикт **APPROVED**. +Независимая верификация reviewer'а: целевые тесты зелёные — `test_orch109_timeout_model.py` + +`test_config.py` + `test_launcher.py` = **75 passed**; зависимые подсистемы FR-2/FR-4 +(`usage`/`notifications`/`tracker`) = **231 passed**. Полный регресс зелёный (см. `13-test-report.md`). +Открытых findings P0/P1/P2 нет → вердикт **APPROVED**. ## Оси проверки 1. **Соответствие ТЗ (02-trz / 03-acceptance):** FR-1…FR-6 реализованы; AC-1…AC-10 покрыты тестами - TC-01…TC-12. AC-10 (документация) теперь закрыт полностью, включая front-page README. ✅ -2. **Соответствие ADR (06-adr ADR-001 + сквозной adr-0040):** D1–D6 реализованы дословно — объединённый - `UPDATE agent_runs SET model=?, effort=? WHERE id=?` с `(model or None, effort or None, run_id)`; - лестница `_resolve_timeout` (overrides_json → выделенный ключ роли → глобальный дефолт); выделенные - ключи `agent_timeout_developer_s=3600`/`agent_timeout_reviewer_s=3000`; `reaper_max_running_s` - 3600→5400. Трассировка маркеров **ORCH-087** (эфорт-стамп `(effort or None)` сохранён в том же - `UPDATE`) и **ORCH-065** (reaper поднят синхронно, инвариант жив) — зафиксированные инварианты не - сломаны. Нарушений глобальных ADR нет. ✅ -3. **Качество кода:** never-raise сохранён (`try/except` + WARNING вокруг стамп-`UPDATE`; непозитивный/ - нечисловой выделенный ключ → откат на глобальный дефолт + WARNING); докстринг `_resolve_timeout` - и комментарии точны; тесты содержательны — позитивные контроли (`test_tc11_clean_exit_advances`), - negative-guard (`test_tc09_unstamped_killed_run_drops_model_suffix`), параметризация `[0,-5,"abc"]`, - изоляция стамп-сбоя (TC-05). Регресс-тест-фиксатор инцидента ORCH-104 присутствует (ORCH-019 BR-4 - удовлетворён). ✅ -4. **Документация (приоритетная ось):** `src/` изменён (`launcher.py`/`config.py`) → документация - обновлена в том же PR: CHANGELOG / CLAUDE.md (паспорт) / docs/architecture/README.md (бюллет Agent - Launcher + ссылка на adr-0040) / docs/architecture/internals.md (оба упоминания «30 мин») / - .env.example (5 ключей agent-timeout + `ORCH_REAPER_MAX_RUNNING_S`=5400) / config.py-паспорт / - детальный ADR-001 + сквозной adr-0040 / **README.md front-page «### Watchdog»** (закрытый P1). ✅ + TC-01…TC-12 буквально по матрице AC↔FR. + - FR-1/AC-1 (TC-04): `_spawn` пишет резолвенную модель в `agent_runs.model` объединённым + `UPDATE agent_runs SET model=?, effort=? WHERE id=?` с `(model or None, effort or None, run_id)` + рядом со стампом эффорта; пустой резолв → `NULL`; стамп = `resolve_agent_model` (single source). + - FR-2/AC-2 (TC-06/07): `usage.record_usage` использует `model=COALESCE(?, model)` (сверено по + `src/usage.py`) — `usage=None`/`model=None` не затирает launch-стамп; непустая модель уточняет. + Кода `usage.py` PR не трогает (корректно — семантика уже верна), зафиксировано регресс-тестом. + - FR-3/AC-3 (TC-01/02): `_resolve_timeout` отдаёт поднятый бюджет developer/reviewer и неизменный + 1800 прочим ролям (analyst/architect/tester/deployer/unknown/None); бюджеты конфигурируемы. + - FR-3/AC-4 (TC-03): малформный `agent_timeout_overrides_json` и непозитивный/нечисловой + выделенный ключ `[0,-5,"abc"]` → откат на глобальный дефолт + WARNING, never-break. + - NFR-4/AC-5 (TC-08): инвариант reaper подтверждён на shipped-дефолтах (`5400 > 3600+20`). + - FR-4/AC-6 (TC-09): строка стадии рендерит `· opus-4-8 · xhigh` для `exit_code=-9`; присутствует + negative-guard (немаркированный -9 → суффикс опущен). + - FR-4/NFR-6/AC-7 (TC-10): `get_running_agents` отдаёт модель для running-job (in-flight). + - FR-5/AC-8 (TC-11): timeout-killed прогон developer/reviewer не вызывает `_try_advance_stage` + (роутится в `_finalize_job`); присутствует позитивный контроль (clean exit → advance). + - AC-9 (TC-12) + AC-10: контракты/схема нетронуты; документация и регресс зелёные. + +2. **Соответствие ADR (06-adr ADR-001 + сквозной adr-0040):** D1–D6 реализованы дословно. Лестница + `_resolve_timeout` (overrides_json → выделенный ключ роли → глобальный дефолт), выделенные ключи + `agent_timeout_developer_s=3600`/`agent_timeout_reviewer_s=3000`, `reaper_max_running_s` 3600→5400. + **Трассировка маркеров (TRACEABILITY):** правка касается блоков с маркерами ORCH-087 (стамп + эффорта) и ORCH-065 (reaper Tier-3) — оба зафиксированных инварианта сверены с их ADR и не + сломаны (эффорт-стамп сохранён в объединённом `UPDATE`; reaper-неравенство пересчитано и поднято + синхронно). Нарушений глобальных ADR нет. + +3. **Качество кода:** never-raise сохранён (`try/except` + WARNING вокруг стамп-`UPDATE`; + непозитивный/нечисловой выделенный ключ → откат + WARNING). Докстринг `_resolve_timeout` и + паспорт-комментарии `config.py` точны. Тесты содержательны: изоляция стамп-сбоя (TC-05, + `_RaisingConn` бьёт только по launch-`UPDATE`), параметризация `[0,-5,"abc"]`, негативный guard + (TC-09b), позитивный контроль (TC-11c). **Регресс-тест-фиксатор инцидента ORCH-104** присутствует + (ORCH-019 BR-4 удовлетворён) — весь тест-файл пинит дефектное и исправленное поведение. + +4. **Документация (приоритетная ось):** `src/` изменён → документация обновлена в том же PR + (golden source синхронизирован с кодом): + `CHANGELOG.md` / `CLAUDE.md` (паспорт) / `docs/architecture/README.md` (бюллет Agent Launcher + + ссылка на adr-0040) / `docs/architecture/internals.md` (оба упоминания «30 мин» → per-role) / + `README.md` front-page «### Watchdog» (per-role бюджеты + Tier-3 backstop 90м) / `.env.example` + (5 ключей agent-timeout + `ORCH_REAPER_MAX_RUNNING_S`=5400) / `config.py`-паспорт / детальный + ADR-001 + сквозной adr-0040. Обзорная витрина `docs/overview/` правки не требует — упоминания + watchdog концептуальны (sidecar-наблюдатель, «следит за процессом»), конкретного числа тайм-аута + витрина не несёт → устаревшего факта не возникает (ORCH-011/079 — нет finding). PR не закрывает + пункт `README.md` «Известные ограничения». ## Findings @@ -69,9 +91,8 @@ findings P0/P1/P2 нет → вердикт **APPROVED**. - (нет) ### P3 — Nice-to-have -- [ ] ADR-001 и adr-0040 несут `status: proposed`/`Proposed`. На merge их разумно перевести в - `Accepted` (косметика статуса ADR; не блокер — артефакты архитектора консистентны, на гейты/код - не влияют). +- [ ] ADR-001 (`status: proposed`) и adr-0040 (`Proposed`) на merge разумно перевести в `Accepted` + (косметика статуса ADR; на гейты/код не влияет, не блокер). ## Документация @@ -79,22 +100,20 @@ findings P0/P1/P2 нет → вердикт **APPROVED**. - `CHANGELOG.md` — детальная запись ORCH-109 (`fix`, D1/D3/D4, FR-4/FR-5 структурно). ✅ - `CLAUDE.md` — паспорт (блок «Стек», абзац launcher). ✅ - `docs/architecture/README.md` — бюллет Agent Launcher (ссылка на adr-0040). ✅ -- `docs/architecture/internals.md` — watchdog «30 мин» → per-role (стр. 96 и 262). ✅ -- `README.md` — front-page «### Watchdog» (стр. 295) → per-role бюджеты + Tier-3 backstop - (закрыт P1 прошлой итерации, commit `91d56fe`). ✅ +- `docs/architecture/internals.md` — watchdog «30 мин» → per-role (стр. ~96 и ~262). ✅ +- `README.md` — front-page «### Watchdog» (стр. ~295) → per-role бюджеты + Tier-3 backstop. ✅ - `.env.example` — новый блок agent-timeout (5 ключей) + `ORCH_REAPER_MAX_RUNNING_S` 3600→5400. ✅ - `src/config.py` — паспорт-комментарий ORCH-7/ORCH-109 + reaper-инвариант. ✅ - ADR — `docs/work-items/ORCH-109/06-adr/ADR-001-…` (детальный) + `docs/architecture/adr/adr-0040-…` (сквозной). ✅ **Обзорная витрина `docs/overview/` (ORCH-011/ORCH-079):** правки не требует — упоминания watchdog -концептуальны (sidecar-наблюдатель, «следит за процессом»), конкретного числа тайм-аута витрина не -несёт, поэтому устаревшего факта не возникает. +концептуальны, конкретного числа тайм-аута витрина не несёт, поэтому устаревшего факта не возникает. **Прочее (не findings):** -- Полный регресс `pytest tests/` — **1899 passed** (exit 0, 7m25s). Предупреждение - `PytestUnhandledThreadExceptionWarning: disk I/O error` в `_monitor_agent` (launcher.py:860) — - pre-existing гонка тестового потока с teardown БД в **неизменённом** этим PR коде (дифф трогает - только `_spawn` ≈566–585 и `_resolve_timeout` ≈673–724); не блокер, не регресс ORCH-109. -- AC-9 верифицирован: в `src/` изменены только `launcher.py` и `config.py`; ни одной строки - `STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict/`CREATE TABLE`/`ALTER TABLE` в диффе нет. +- AC-9 верифицирован по диффу: в `src/` изменены только `launcher.py` и `config.py`; ни одной строки + `STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict/`CREATE TABLE`/`ALTER TABLE`. +- Целевой регресс reviewer'а зелёный: 75 (ORCH-109/config/launcher) + 231 (usage/notifications/ + tracker) passed; полный регресс — `13-test-report.md`. + + diff --git a/docs/work-items/ORCH-109/17-security-report.md b/docs/work-items/ORCH-109/17-security-report.md new file mode 100644 index 0000000..66aa527 --- /dev/null +++ b/docs/work-items/ORCH-109/17-security-report.md @@ -0,0 +1,25 @@ +--- +security_status: PASS +secrets_found: 0 +deps_blocking: 0 +deps_warning: 4 +deps_audit_degraded: false +--- +# Security Report — ORCH-109 + +Детерминированный security-гейт (ORCH-022): secret-scanning (gitleaks, offline) + dependency audit (pip-audit). Машинный вердикт читается ТОЛЬКО из frontmatter выше. + +## Verdict +clean: 0 secrets, 0 blocking CVE(s) + +## Secrets +- None + +## Dependencies (blocking) +- None + +## Dependencies (warning) +- `pytest==8.3.3` — GHSA-6w46-j5rx-g56g severity=UNKNOWN fix=9.0.3 +- `starlette==0.38.6` — PYSEC-2026-161 severity=UNKNOWN fix=1.0.1 +- `starlette==0.38.6` — GHSA-f96h-pmfr-66vw severity=UNKNOWN fix=0.40.0 +- `starlette==0.38.6` — GHSA-2c2j-9gv5-cj73 severity=UNKNOWN fix=0.47.2