# Архитектура Агент — один файл `src/agent.py` (Python 3.9, только стандартная библиотека). Тесты в `tests/` работают на фейках Jira и хаба. Спека: `../jira-hub/openspec/changes/bridge-core/`, план агента: `docs/superpowers/plans/2026-10-11-bridge-core-agent.md` (план хаба: `../jira-hub/docs/superpowers/plans/2026-10-11-bridge-core-hub.md`). ## Разделы файла `src/agent.py` | Раздел | Классы и функции | Ответственность | Что использует | |---|---|---|---| | Настройки | `load_config` | читает `agent.json`, проверяет обязательные поля | — | | HTTP | `Http`, `HttpError`, `JiraClient`, `HubClient` | запросы; `JiraClient` считает вызовы, повторяет 429/503 по `Retry-After` (до 5 запросов, не более 4 ожиданий), хранит время последнего вызова | `urllib` | | Папка | `FolderTransport` | транспорт `folder:` к хабу через общую папку: `req/.json` → реле хаба → `resp/.json`; ошибки как у `Http`; `HubClient` делегирует ему `call` (спека `jira-hub/openspec/changes/folder-transport/`) | `os`, `uuid` | | Журнал | `Journal`, `_parse_at` | дозапись `journal.jsonl`: `started` → `finished` → `acked`; восстановление; `prune` (из CLI — под блокировкой журнала) | файловая система | | Исполнитель | `Executor` и `do_<тип>` | по одному методу на тип команды: читает Jira, пишет только разницу; `refresh` читает и отправляет состояние в хаб | `JiraClient`, `HubClient` (только `refresh`), настройки хаба | | Цикл | `Runner` | claim, пауза до команды, журнал, выполнение, отчёт до подтверждения, восстановление при старте | `HubClient`, `JiraClient`, `Journal`, `Executor` | | CLI | `cmd_run`, `cmd_check`, `cmd_prune`, `main` | команды `run`, `check`, `prune` (`run` и `prune` берут `acquire_lock` на `<журнал>.lock`); обработка сигналов | `Runner`, `Journal` | ## Границы - Пароль и токен Jira — только в `agent.json`. В хаб, журнал и логи не попадают. - Политика темпа не хранится в агенте: зазоры (`pacing`) и `pause_seconds` приходят от хаба. Агент досыпает паузу до зазора от последнего вызова Jira (`JiraClient.last_call_at`). - Одна команда в полёте: цикл берёт следующую только после выполнения и подтверждения отчёта. - Отчёт до подтверждения: `send_result` повторяет каждые 10 с; 404/409/422 от хаба считаются закрытием. - Журнал пишется трижды на команду вокруг выполнения: `started` — после паузы, перед первым обращением к Jira; `finished` — после результата; `acked` — после подтверждения хаба. Восстановление опирается только на этот порядок. - Каждый обработчик `Executor` возвращает `status`/`result`/`error` и счётчики. Исключение, которое не обработано в обработчике, `Runner.execute` превращает в `failed` и не роняет цикл. - Тесты не ходят во внешние сервисы; фейки — `tests/fake_jira.py` и `tests/fake_hub.py`. ## Открытые вопросы - HTTPS хаба с корпоративным CA: `HubClient` не принимает `ca_bundle`/`verify_ssl` (ограничение README, пункт 2). - Спринт задач закрытых спринтов: `sprint = null` (рулинг R-6).