5.9 KiB
agent Specification
Purpose
TBD - created by archiving change bridge-core. Update Purpose after archive.
Requirements
Requirement: Состав и настройки агента
Агент SHALL состоять из одного файла agent.py (Python ≥ 3.9, только стандартная библиотека) и файла agent.json:
hub_url, hub_token, jira.base_url, jira.auth (basic с user/password или bearer с token), verify_ssl,
ca_bundle, timeout, poll_seconds. Всё остальное (id полей, типы, карта переходов, типы связей, доска, темп) агент
SHALL получать от хаба при старте и при изменении settings_version. Учётные данные Jira MUST NOT отправляться в хаб
и MUST NOT попадать в журнал и логи.
Scenario: Проверка без записи
- WHEN
python3 agent.py check - THEN агент печатает доступность хаба (версия настроек) и Jira (
GET /myself), в Jira ничего не пишет
Requirement: Цикл выполнения
Агент SHALL работать одним процессом: claim к хабу (долгий запрос) → при получении команды: досыпать до
pause_seconds от последнего вызова Jira → запись «started» в журнал → выполнение по контракту commands → запись
«finished» с результатом → отчёт хабу, повторяемый до подтверждения. Одна команда в полёте. При изменении
settings_version в ответе claim агент SHALL перечитать настройки до выполнения команды.
Scenario: Остановка между командами
- WHEN получен Ctrl-C во время выполнения команды
- THEN текущая команда доделывается и отчёт отправляется, затем процесс завершается
Requirement: Журнал на диске и восстановление
Агент SHALL вести journal.jsonl (только дозапись) рядом с собой: строки started {command_id, at}, finished {command_id, status, result, error, jira_calls, rate_limited}, acked {command_id}. При старте агент SHALL: отправить хабу все
finished без acked; для started без finished — выполнить команду заново по правилу «проверь, потом сделай»
(запросив её параметры у хаба по id). Команда python3 agent.py prune SHALL удалять из журнала записи с acked старше
30 дней.
Scenario: Падение после ответа Jira
- WHEN агент упал между
POST /issueи записьюfinished, затем перезапущен - THEN агент находит в журнале
startedбезfinished, запрашивает команду у хаба, находит созданную задачу поиском дубля и отчитываетсяdoneс её ключом; второй задачи нет
Requirement: Ограничение темпа и 429
Агент SHALL помнить время последнего вызова Jira (любого) и не начинать команду раньше pause_seconds после него.
На HTTP 429 и 503 агент SHALL ждать Retry-After (иначе 60 с × номер попытки) и повторять тот же запрос до 5 раз,
считая попытки в rate_limited; после 5 неудач — failed. Пауза между записями внутри одной команды — по зазору типа команды.
Scenario: 429 с Retry-After
- WHEN Jira ответила 429 с
Retry-After: 90 - THEN агент ждёт 90 с, повторяет тот же запрос; в отчёте
rate_limited = 1
Requirement: Чтение состояния
refresh SHALL выполняться запросом search (jql, fields = поля зеркала включая issuelinks и спринт,
maxResults = 100, постранично) и отправляться хабу пачками по 100 задач со связями; ключи из issuelinks, которых нет
в выборке и в зеркале хаба (хаб сообщает список известных), агент SHALL дочитать одним search по key in (...)
и отправить с признаком neighbor.
Scenario: Полная синхронизация
- WHEN
refresh {jql: "project = AURORA AND labels = AWPCA"}при 180 задачах - THEN 2 вызова
search+ 1 на соседей;sync_run.issues_count = 180 + соседи
Requirement: Доставка и запуск
README агента SHALL описывать: копирование agent.py и agent.example.json через общую папку, заполнение agent.json,
check, запуск в терминале и через nohup с логом, опциональный launchd-plist, prune. Версия агента SHALL быть в
константе файла и в каждом отчёте; хаб предупреждает в agent_status, если версия ниже минимальной из настроек.
Scenario: Устаревший агент
- WHEN агент версии 1 выходит на связь, а в настройках
min_agent_version = 2 - THEN
agent_status.warning= «обновите агента», команды выдаются по-прежнему