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

76 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# hub-api Specification
## Purpose
TBD - created by archiving change bridge-core. Update Purpose after archive.
## Requirements
### Requirement: Процесс и доступ
`jira-hub serve` SHALL запускать один процесс: HTTP на `0.0.0.0:<port>` (по умолчанию 8790), база и настройки в
`~/.local/share/jira-hub/` (переопределяется `JIRA_HUB_HOME`). Все маршруты SHALL требовать `Authorization: Bearer <token>`:
агентский токен открывает только `/agent/*`, клиентский — всё остальное. Ответы — JSON, ошибки — `{error, detail}` с
кодами 400/401/404/409/422.
#### Scenario: Чужой токен
- **WHEN** агентским токеном вызван `GET /issues`
- **THEN** 401
### Requirement: Маршруты агента
Хаб SHALL предоставлять агенту следующие маршруты (все под агентским токеном):
- `POST /agent/claim` `{agent_version, settings_version, last_jira_call_at}` — долгий запрос до 30 с; ответ `{command:
{id, type, params, pause_seconds}, settings_version}` или `{command: null, settings_version}`; обновляет `agent_status`.
- `GET /agent/settings` — настройки для агента (без токенов).
- `GET /agent/commands/{id}` — команда по id (для восстановления из журнала).
- `POST /agent/commands/{id}/result` `{status, result, error, jira_calls, rate_limited}` — идемпотентно: повторный
отчёт по команде в терминальном статусе отвечает 200 без изменений.
- `POST /agent/state` `{command_id, issues: [...], links: [...], neighbor_keys: [...], page, last_page}` — загрузка состояния
пачками; `neighbor_keys` — ключи вне базовой JQL, дочитанные по связям; хаб обновляет зеркало и `sync_run`.
- `GET /agent/known-keys` — ключи зеркала (для определения соседей).
#### Scenario: Выдача с подстановкой ключа
- **WHEN** следующая команда ссылается на `new:60`, а `ensure_issue` для `new:60` завершилась с `AURORA-1590`
- **THEN** `claim` отдаёт команду с `AURORA-1590` в параметрах
#### Scenario: Повторный отчёт
- **WHEN** агент дважды прислал `result` для команды 15
- **THEN** второй ответ 200, статус и результат не изменились
### Requirement: Маршруты интерфейсов
Хаб SHALL предоставлять интерфейсам (MCP, позже просмотрщик) следующие маршруты под клиентским токеном:
- `GET /issues` с фильтрами `sprint`, `assignee`, `work_kind`, `fact_status`, `status`, `label`, `epic`, `neighbor`,
`q` (подстрока темы), `limit`/`offset` — компактные карточки (ключ, тема, статус, приоритет, срок, исполнитель, спринт,
эпик, заметки кратко).
- `GET /issues/{key}` — задача целиком: поля, связи в обе стороны, заметки, последние 10 команд по ней.
- `PUT /issues/{key}/note` — заметки (частичное обновление, `updated_by` из тела).
- `POST /batches` `{title, author, commands: [...]}` → `{id, estimate_seconds}`; 422 при неизвестном типе, неверных
параметрах, временном ключе без `ensure_issue`.
- `GET /batches?limit=`, `GET /batches/{id}` (с командами), `POST /batches/{id}/cancel`.
- `POST /commands/{id}/retry` — новая команда с теми же параметрами в новом пакете «Повтор команды N».
- `POST /commands/{id}/cancel` — только для `queued`; для `claimed` — 409, если не передан `force: true`.
- `POST /refresh` `{keys | jql | full: true}` → пакет из одного `refresh`.
- `GET /agent`, `GET /sync-runs?limit=`, `GET /settings`, `PUT /settings` (частично; поднимает `settings_version`).
#### Scenario: Фильтр по спринту
- **WHEN** `GET /issues?sprint=Спринт 2`
- **THEN** только задачи с таким `sprint`, отсортированы по сроку, затем по ключу
#### Scenario: Отмена взятой команды
- **WHEN** `POST /commands/15/cancel` без `force`, команда `claimed`
- **THEN** 409 с `claimed_at`; с `force: true` — `cancelled`, следующий отчёт агента по ней принимается, но статус не меняется
### Requirement: Резервные копии
Перед выдачей первой команды пакета, содержащего записи в Jira, хаб SHALL скопировать файл базы в `backups/<дата-время>-<batch>.sqlite`
и хранить последние `backup_keep` копий.
#### Scenario: Ротация
- **WHEN** копий больше `backup_keep`
- **THEN** самые старые удаляются до `backup_keep`
### Requirement: Автообновление зеркала
Если `auto_refresh_minutes > 0`, агент на связи и очередь пуста дольше этого интервала, хаб SHALL поставить пакет
«Автообновление» из `refresh {jql: base_jql}`.
#### Scenario: Очередь занята
- **WHEN** интервал прошёл, но в очереди есть `queued` команды
- **THEN** автообновление не ставится до опустошения очереди