7.0 KiB
Raw Blame History

MODIFIED Requirements

Requirement: Цикл выполнения

Агент SHALL работать одним процессом: claim к хабу (долгий запрос) → при получении команды: досыпать до pause_seconds от последнего вызова Jira → запись «started» в журнал → выполнение по контракту commands → запись «finished» с результатом → отчёт хабу, повторяемый до подтверждения. Одна команда в полёте: новый claim агент SHALL отправлять, только когда у него нет выданной, но не завершённой и не отчитанной команды (на этом хаб строит повторную выдачу, см. commands). При изменении settings_version в ответе claim агент SHALL перечитать настройки до выполнения команды.

Факты о Jira: после первой загрузки настроек и до первого claim агент SHALL вызвать GET /myself и GET /issueLinkType и передавать в каждом claim jira_user (name из /myself) и symmetric_link_types (имена типов с inward == outward). Если вызов не удался, агент SHALL продолжить работу без этого поля и повторять сбор перед claim не чаще раза в 10 минут, пока не получит значение.

Scenario: Остановка между командами

  • WHEN получен Ctrl-C во время выполнения команды
  • THEN текущая команда доделывается и отчёт отправляется, затем процесс завершается

Scenario: Факты о Jira в claim

  • WHEN агент стартовал, /myself вернул name = "bridge-user", в /issueLinkType у «ASUPR_Связанные» inward == outward
  • THEN каждый claim содержит jira_user = "bridge-user" и symmetric_link_types, включающий «ASUPR_Связанные»

Scenario: Jira недоступна при старте

  • WHEN /myself при старте отвечает ошибкой соединения
  • THEN агент работает, claim без jira_user; через 10 минут агент повторяет /myself

Requirement: Журнал на диске и восстановление

Агент SHALL вести journal.jsonl (только дозапись) рядом с собой: строки claimed {command_id, at} (сразу после получения команды, до паузы), started {command_id, at}, finished {command_id, status, result, error, jira_calls, rate_limited, at}, acked {command_id, at}. При старте агент SHALL: отправить хабу все finished без acked; для claimed/started без finished — запросить команду у хаба по id и, если она в хабе всё ещё claimed, выполнить её заново по правилу «проверь, потом сделай» с паузой pause_seconds из ответа хаба, не записывая claimed повторно. Команда python3 agent.py prune SHALL удалять из журнала записи с acked старше 30 дней.

Scenario: Падение после ответа Jira

  • WHEN агент упал между POST /issue и записью finished, затем перезапущен
  • THEN агент находит в журнале started без finished, запрашивает команду у хаба, находит созданную задачу поиском дубля и отчитывается done с её ключом; второй задачи нет

Scenario: Восстановление без лишней записи

  • WHEN в журнале claimed 40 без finished, хаб отдаёт команду 40 в claimed с pause_seconds = 30
  • THEN в журнал дописываются started 40, finished 40, acked 40; второй строки claimed 40 нет; перед выполнением агент выдерживает 30 с от последнего вызова Jira

Requirement: Ограничение темпа и 429

Агент SHALL помнить время последнего вызова Jira (любого) и не начинать команду раньше pause_seconds после него. При старте агент SHALL принять за время последнего вызова Jira самое позднее at в журнале (если оно не в будущем); при пустом журнале паузы перед первой командой нет. На 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

Scenario: Перезапуск не сбивает темп

  • WHEN последняя запись журнала finished сделана 10 с назад, агент перезапущен и получил команду с pause_seconds = 30
  • THEN агент ждёт около 20 с перед первым вызовом Jira по команде

Requirement: Доставка и запуск

README агента SHALL описывать: копирование agent.py и agent.example.json через общую папку, заполнение agent.json (включая выбор транспорта в hub_url), check, запуск в терминале и через nohup с логом, опциональный launchd-plist, prune. Версия агента SHALL быть в константе файла (3 — с фактами о Jira в claim и восстановлением темпа) и в каждом отчёте; хаб предупреждает в agent_status, если версия ниже минимальной из настроек.

Scenario: Устаревший агент

  • WHEN агент версии 1 выходит на связь, а в настройках min_agent_version = 2
  • THEN agent_status.warning = «обновите агента», команды выдаются по-прежнему