Files
orchestrator/docs/work-items/ORCH-044/02-trz.md
claude-bot e71a44f84f
All checks were successful
CI / test (push) Successful in 13s
analyst(ET): auto-commit from analyst run_id=157
2026-06-06 07:43:48 +00:00

12 KiB
Raw Blame History

02 — Техническое задание (ТЗ)

Work Item: ORCH-044 Основано на: 01-brd.md

Примечание: ТЗ фиксирует что должно измениться и наблюдаемое поведение. Выбор конкретной реализации (например, формат проверки .credentials.json vs парсинг маркера в логе) — за архитектором (стадия architecture, ADR). Где описаны варианты — это границы допустимого решения, а не предписание.

1. Задействованные модули src/

Модуль Текущее место Изменение
src/preflight.py _run_version, _compute, check Добавить дешёвую token-free проверку авторизации (P1)
src/config.py блок ORCH-41 effort (стр. 98108), новый блок настроек preflight-auth Настройки auth-проверки; решение по effort-дефолтам (P2)
src/agents/launcher.py _spawn (effort_flag, стр. 290292, 303311), _monitor_agent (стр. 460615), _finalize_job (стр. 630667) Решение по --effort (P2); детекция пустого лога / отсутствия result-JSON (P3)
src/queue_worker.py _drain_once claim-gating (стр. 158165) Учесть новый auth-fail preflight в гейтинге клейма (P1) — при необходимости
src/db.py mark_job Использование существующего перевода job → failed (P3); новых колонок не требуется

Новых файлов модулей не предполагается обязательно; допускается выделение хелпера (например, _check_auth() в preflight.py) — на усмотрение архитектора.

2. Требования по проблемам

P1 — Preflight ловит авторизацию (token-free)

  • TR-1.1. Preflight ДОЛЖЕН, помимо os.path.exists(bin) и claude --version, выполнять дешёвую проверку авторизации без обращения к API модели и без prompt-ping.
  • TR-1.2. Допустимые подходы (выбор — за архитектором, ADR):
    • (a) Проверка существования и читаемости файла учётных данных ~/.claude/.credentials.json (HOME агента — /home/slin, см. launcher env, стр. 326) и валидности OAuth-токена по дате истечения внутри (claudeAiOauth.expiresAt, epoch ms) — expiresAt <= now ⇒ протух ⇒ fail;
    • (b) Парсинг реального run-вывода на маркер Not logged in (и подобные) с переводом job в провал и размыканием/учётом circuit breaker.
    • Подход (a) предпочтителен как проактивный (ловит ДО клейма); (b) — как защитная сетка постфактум. Допускается комбинация.
  • TR-1.3. Путь к файлу учётных данных ДОЛЖЕН резолвиться согласованно с тем HOME, под которым launcher реально спавнит claude (/home/slin), а не из окружения процесса оркестратора (аналогично тому, как _claude_bin() следует за реально исполняемым путём).
  • TR-1.4. Результат auth-проверки кешируется тем же механизмом, что и version-check (preflight_cache_ttl), чтобы не читать файл на каждый тик воркера.
  • TR-1.5. При auth=fail: check() возвращает (False, reason) с информативным reason (например, claude not logged in: credentials missing / OAuth token expired at <iso>). Job НЕ клеймится (поведение _drain_once уже корректно при ok=False).
  • TR-1.6. Граница ответственности: preflight остаётся локальным (BR-1). Сетевая валидация токена у провайдера — вне объёма.
  • TR-1.7. Поведение при «всё хорошо» не меняется: залогинен + валидный токен ⇒ ok=True.

P2 — Решение по --effort

  • TR-2.1. Провести расследование (стадия architecture/development): причина пустого stdout при --effort + --print --output-format json в CLI 2.1.142 — несовместимость с json-форматом, иной синтаксис флага, или баг CLI. Зафиксировать вывод в ADR/10-tech-risks.md.
  • TR-2.2. По итогам выбрать ровно один исход и привести к нему код+доки+дефолты:
    • Вариант A (вернуть effort): найден корректный способ (например, иной синтаксис или несовместимость только с конкретным output-format) — --effort снова формируется в _spawn корректно; прод-хотфикс ORCH_AGENT_EFFORT_*="" снимается; добавить регресс-тест, что вывод не пустой.
    • Вариант B (unsupported): effort несовместим — убрать --effort из активного пути запуска (_spawn не формирует effort_flag), убрать/нейтрализовать дефолты effort в config.py, обновить ORCH-41-доки (INFRA.md, internals.md) пометив фичу как unsupported на данной версии CLI. resolve_agent_effort либо удаляется, либо документированно оставляется заглушкой (решение — ADR).
  • TR-2.3. Независимо от A/B: не должно остаться «мёртвого» флага, который тихо гасит вывод. После задачи запуск с дефолтной конфигурацией прода ДОЛЖЕН давать непустой result-JSON.
  • TR-2.4. Изменение дефолтов/удаление флага не должно ломать resolve_agent_model (модель — независимая фича ORCH-41) и существующие тесты test_resolve_agent_effort.py (их допустимо обновить под новый контракт).

P3 — Пустой лог / нет result-JSON ⇒ провал

  • TR-3.1. В _monitor_agent/_finalize_job: при exit_code == 0 ДОЛЖНА выполняться проверка валидности результата перед тем как считать job успешным:
    • run-лог непустой (размер > 0 и/или содержит непустой текст), И
    • из него извлекается валидный result-JSON (тот же контракт, что использует usage._extract_last_json_object / parse_usage_from_log).
  • TR-3.2. Если результат невалиден (пустой лог ИЛИ нет валидного JSON) при exit_code==0, job ДОЛЖЕН трактоваться как провал:
    • НЕ переводиться в done;
    • попасть в путь ретрая/провала (attempts < max_attempts ⇒ requeue, иначе failed), аналогично permanent-ветке _finalize_permanent, с информативным error (например, empty run log / no result JSON (run_id=...));
    • сгенерировать алерт (Telegram), как прочие провалы;
    • НЕ выполнять авто-advance стадии (_try_advance_stage) и НЕ постить «успешный» status-коммент.
  • TR-3.3. Классификация такого провала: по умолчанию — permanent (это не 429/overload). Если в логе присутствует transient-маркер (через error_classifier) — допускается transient-путь. Auth-провал (Not logged in) — на усмотрение архитектора: может маршрутизироваться как сигнал брейкеру (P1/TR-1.2b).
  • TR-3.4. Никогда не оставлять job в running навечно из-за пустого результата: либо done (валидно), либо failed/queued(retry). (Watchdog ORCH-7 продолжает закрывать случай таймаута; здесь закрывается случай «быстрая смерть с exit 0».)
  • TR-3.5. Защитность: вся проверка обёрнута так, что её собственная ошибка не роняет монитор (как и прочий код _monitor_agent); при сомнении — fail-safe в сторону провала job.

3. Изменения API

Нет новых/изменённых HTTP-endpoint'ов. Допускается обогащение поля preflight_reason в /queue (через существующий worker.status() / QueueWorker.last_preflight_reason) более информативным auth-сообщением — без изменения схемы ответа.

4. Изменения схемы БД

Нет. Используются существующие колонки jobs (status, error, attempts, max_attempts, transient_attempts) и agent_runs. Новых таблиц/колонок не требуется.

5. Требования к новым QG checks

Новых Quality Gate проверок не требуется — изменения в слое запуска/preflight, не в гейтах стадий. Реестр QG_CHECKS не меняется.

6. Конфигурация (env / config.py)

  • Возможные новые настройки preflight-auth (имена — на усмотрение архитектора), например:
    • ORCH_PREFLIGHT_CHECK_AUTH (bool, default true) — включение auth-проверки;
    • путь к credentials, если не выводится из HOME автоматически.
  • Решение по effort-дефолтам (agent_effort_*) согласно TR-2.2 (нейтрализовать при варианте B).
  • Все новые настройки документируются в config.py docstring и в INFRA.md (env-карта).

7. Артефакты pipeline (обязательны к созданию/обновлению)

  • 06-adr/ADR-NNN-*.md — решение по подходу preflight-auth (a/b/комбо) и по effort (A/B).
  • 10-tech-risks.md — риск ложноположительной auth-проверки, риск регрессии effort, риск fail-safe-провала на легитимных пустых выводах.
  • 12-review.md, 13-test-report.md — по стадиям.
  • Обновить docs/operations/INFRA.md и docs/architecture/internals.md (effort-секции), CHANGELOG.md. Документация = golden source (правило агентов №2).

8. Ограничения и запреты

  • Prompt-ping в preflight (жжёт rate limit) — запрещено (BR-1, комментарий в preflight.py).
  • Сетевые вызовы к API модели в preflight.
  • Оставлять job в running без таймаута при пустом результате.
  • --no-verify/обход хуков без одобрения Owner.
  • ⚠️ Self-hosting: не ронять прод-контейнер orchestrator; проверка изменений — через staging (8501) перед прод-деплоем (см. CLAUDE.md, INFRA.md).