Andrey Epifancev 2c8cc61ca4 docs(openspec): архив agent-v9-hardening (#26)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 00:51:34 +04:00

5.7 KiB
Raw Blame History

Why

Самообновление агента работает с 14.10.2026 (v5 → v8 на виртуалке, живая проверка пройдена), но финальное ревью change'а agent-self-update оставило отложенные находки в запускателе run.py и Updater (aep/jira-agent#22): run.py верит update.json на слово, и после падения запускателя посреди подмены или отката может откатить здоровую версию, оставить новую версию без пробного периода или уйти в цикл «10 минут работы → SIGTERM». Полный диск роняет агента трейсбеком и запускатель — в цикл падений. Рядом лежат мелкие находки гигиены (aep/jira-agent#18) и неточность фейков Jira/хаба в тестах агента (aep/jira-agent#4, M-10): ошибку ensure_sprint (KeyError: 'fields') 13.10.2026 нашли только на живой Jira.

Решения владельца 14.10.2026 (brainstorming): чинить всё одним пакетом — агент v9 (через самообновление) и запускатель v2 (владелец переставляет вручную); фейки подтянуть к наблюдённому поведению Jira, а не отклонять.

What Changes

  • Запускатель run.py v2 (LAUNCHER_VERSION = 2):
    • сверка при старте: update.json сравнивается с sha256 файла agent.py и наличием agent.py.new; устаревший trial (агент не та версия) → rolled_back без отката; staged при уже подменённом agent.py → trial; staged без годного agent.py.new → rejected; удаление agent.py.new.tmp, agent.py.prev.tmp, update.json.tmp;
    • пробный период включается, только если sha256 agent.py равен sha256 версии в update.json;
    • после истечения пробного периода и остановки агента update.json перечитывается: ok — отката нет;
    • код выхода агента 73 («другой процесс держит журнал») — не сбой версии: без отката, перезапуск с паузой;
    • OSError при подмене — rejected «подмена не удалась», работает текущая версия; запускатель не падает.
  • Агент v9 (AGENT_VERSION = 9):
    • run при занятой блокировке журнала выходит с кодом 73 (было 1);
    • OSError при подготовке версии — временный сбой (повтор через 5 мин), не трейсбек;
    • agent_release неверного формата (версия не целое, sha256 не 64 hex-символа) игнорируется, в логе не чаще раза в час;
    • время журнала в будущем — одна строка лога вместо двух противоречивых;
    • ошибки хаба внутри refresh помечаются источником «хаб» (лог и error отчёта), FolderTransport пишет «хаб не ответил через папку…»;
    • тесты: будущее время журнала + остановка в паузе, on_sigterm запускателя, trial при перезапуске run.py;
    • фейки: project = и created >= -Nd в поиске, очистка Epic Link null, 400 на key in (...) с несуществующим ключом, долгий claim хаба.

Capabilities

New Capabilities

Modified Capabilities

  • agent: код выхода при занятом журнале; источник ошибки хаба в refresh; лог при времени журнала в будущем; самообновление — OSError и формат agent_release; запускатель — сверка состояния с файлом, повторная проверка ok, код 73, OSError при подмене, очистка временных файлов.

Non-Goals

  • код хаба не меняется: agent_release.sha256 у хаба всегда строка (release.current), формат проверяет агент;
  • самообновление run.py — по-прежнему вручную;
  • повтор подмены в запускателе после OSError (у запускателя нет таймера; лечится публикацией v+1, см. design R-2);
  • новые состояния update.json — используются существующие staged, trial, ok, rolled_back, rejected.

Impact

  • jira-hub: только openspec/specs/agent/spec.md (через этот change). Код, схема БД, API, MCP — без изменений.
  • jira-agent (aep/jira-agent#23): src/agent.py (v9), src/run.py (v2), tests/ (фейки и новые тесты), README, ARCHITECTURE.md, CLAUDE.md.
  • Выкатка, порядок важен: сначала jira-hub agent publish v9 (самообновление с v8), затем владелец вручную ставит run.py v2. Запускатель v2 с агентом v8 работает, но код 73 понимает только от v9.