Andrey Epifancev 94a7b20b27 docs(openspec): архив bridge-core, спеки ядра моста в openspec/specs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:48:52 +04:00

5.9 KiB
Raw Blame History

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 = «обновите агента», команды выдаются по-прежнему