8.4 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-109 | analysis | analyst | ready-for-review | 2026-06-14 | claude-opus-4-8 |
03 — Критерии приёмки (Acceptance Criteria): ORCH-109 — timeout budgets + launch-time model telemetry
Work Item: ORCH-109 · Repo: orchestrator · Стадия: analysis
Формат: каждый критерий имеет PASS (что должно быть истинно для приёмки) и FAIL (что считается провалом). Reviewer/tester проверяет их буквально по файлам репозитория и тестам.
AC-1 — Модель стампится в agent_runs.model в момент launch
Условие: запуск любого агента через launcher._spawn записывает резолвенную модель в
agent_runs.model строки прогона ДО завершения процесса.
- PASS: после стампа на launch (
UPDATE agent_runs SET model=…/объединённый с effort)SELECT model FROM agent_runs WHERE id=<run_id>возвращаетresolve_agent_model(agent)(непустую модель для текущей конфигурации —claude-opus-4-8); при пустом резолве —NULL. Запись происходит рядом со стампом эффорта (launcher._spawn). - FAIL: модель пишется только в
usage.record_usage(постфактум); строка прогона имеетmodel IS NULLдо завершения; стамп не изолирован и роняет launch при ошибке БД.
AC-2 — Постфактум-enrich не затирает launch-стамп при оборванном JSON
Условие: usage.record_usage с отсутствующей/None-моделью не обнуляет launch-стампнутую модель.
- PASS:
record_usage(run_id, None)иrecord_usage(run_id, {... "model": None})для строки с launch-стампнутой моделью →modelостаётся прежним непустым (семантикаCOALESCE(?, model));record_usage(run_id, {... "model": "claude-opus-4-8"})→ модель проставлена/уточнена. - FAIL: оборванный/малформный JSON приводит к
model = NULL; enrich затирает корректный launch-стамп.
AC-3 — Тайм-аут developer/reviewer поднят и конфигурируем без влияния на прочие роли
Условие: launcher._resolve_timeout(agent) возвращает поднятый бюджет для developer/reviewer
и неизменный глобальный дефолт для остальных.
- PASS: при сконфигурированном override
_resolve_timeout("developer")и_resolve_timeout("reviewer")возвращают поднятые значения;_resolve_timeout("analyst"),("architect"),("tester"),("deployer")возвращаютsettings.agent_timeout_seconds(1800 по умолчанию). Конфигурация описана вconfig.pyи.env.example. - FAIL: изменён бюджет роли вне
{developer, reviewer}; значение захардкожено; бюджет не настраивается через config.
AC-4 — Малформный timeout-конфиг → безопасный откат (never-break)
Условие: невалидный/малформный конфиг тайм-аутов не роняет прогон и не ломает старт.
- PASS: при малформном
agent_timeout_overrides_json(или невалидном выделенном ключе)_resolve_timeout(...)возвращает глобальный дефолт + пишет WARNING; процесс не падает. - FAIL: исключение пробрасывается; прогон/старт падает на плохом env.
AC-5 — Reaper-инвариант сохранён
Условие: reaper_max_running_s > max(резолвенный тайм-аут любого агента) + agent_kill_grace_seconds.
- PASS: с применённой конфигурацией бюджетов sanity-тест подтверждает неравенство для всех ролей
(
developer/reviewerвключительно); при необходимостиreaper_max_running_sподнят синхронно. - FAIL: поднятый бюджет
developer/reviewer+ grace ≥reaper_max_running_s→ job-reaper может реапнуть здоровый долгий прогон.
AC-6 — Строка стадии трекера показывает модель+эффорт при timeout/kill
Условие: для прогона с exit_code = -9 (timeout-kill) с launch-стампнутыми model+effort строка
стадии рендерит оба значения.
- PASS:
notifications-рендер строки стадии (_stage_line) для такогоagent_runs-ряда содержит· <short_model> · <effort>(например· opus-4-8 · xhigh); модель неnull/пустая. - FAIL: при
exit_code=-9строка показывает стоимость без модели (суффикс модели опущен), т.к.model IS NULL.
AC-7 — In-flight видимость модели в /metrics и /queue
Условие: db.get_running_agents отдаёт модель для running job'а (до завершения прогона).
- PASS: для running-job с launch-стампнутой моделью
get_running_agents()[i]["model"]непуст;GET /metricsagents[].modelнепуст для активного агента. - FAIL:
modelостаётсяnullдля running-job до завершения прогона.
AC-8 — Timeout-killed прогон не продвигает стадию (анти-salvage)
Условие: прогон developer/reviewer с exit_code != 0 (timeout-kill) не вызывает переход
development → review / review → testing.
- PASS: регресс-тест подтверждает, что прогон с
exit_code = -9не продвигает стадию автоматически (следует retry/fail-пути; advance — только при чистом exit + зелёный exit-гейт). Salvage-режим отсутствует. - FAIL: убитый по тайм-ауту прогон «протекает» в следующую стадию без явного решения; либо введён неявный auto-salvage.
AC-9 — Неприкосновенность контрактов и схемы
Условие: задача не трогает машину стадий, гейты и схему БД.
- PASS: диффы НЕ содержат изменений
STAGE_TRANSITIONS, реестраQG_CHECKS,check_*/_parse_*, machine-verdict ключей,CREATE TABLE/ALTER TABLE.agent_runs.modelиспользуется как есть. - FAIL: любое из перечисленного изменено.
AC-10 — Документация и регресс
Условие: конфиг задокументирован, полный регресс зелёный.
- PASS: комментарий-паспорт в
config.py(блок ORCH-7) и.env.exampleописывают бюджетыdeveloper/reviewer;CHANGELOG.md/CLAUDE.md/docs/architecture/README.mdобновлены в том же PR;pytest tests/ -qзелёный; новые тесты ORCH-109 проходят. - FAIL: конфиг не задокументирован; документация рассинхронизирована с кодом; регресс красный.
Сводная матрица AC ↔ FR/BR
| AC | Покрывает |
|---|---|
| AC-1 | BR-1 / FR-1 |
| AC-2 | BR-2 / FR-2 |
| AC-3 | BR-3 / FR-3 |
| AC-4 | BR-3 / FR-3 / NFR-2 |
| AC-5 | NFR-4 / FR-3 |
| AC-6 | BR-4 / FR-4 |
| AC-7 | BR-4 / FR-4 / NFR-6 |
| AC-8 | BR-5 / FR-5 |
| AC-9 | NFR-1 / NFR-3 / FR-5 |
| AC-10 | BR-6 / FR-6 / NFR-1 |