8.4 KiB
modules Specification
Purpose
Устройство хаба из ядра и подключаемых модулей (первый — jira): что принадлежит ядру, как модуль подключается описанием, проверка пересечений при старте и единая схема базы.
Requirements
Requirement: Ядро и модули хаба
Хаб SHALL состоять из ядра и подключаемых модулей. Ядро SHALL владеть базой и миграциями, настройками хаба, проектами
(метка, название), хранилищем файлов, реле общей папки, релизом агента, очередью пакетов команд, HTTP-сервером с
авторизацией, раздачей веб-приложения и общим слоем MCP. Модуль SHALL подключаться к ядру описанием: таблицы, типы команд
и их обработчики в очереди, маршруты HTTP, ключи настроек, фоновые работы, инструменты MCP, подкоманды CLI. Первый модуль —
jira (зеркало задач, журнал изменений, вложения, команды Jira). Ядро MUST NOT импортировать модули, кроме списка
подключённых модулей и истории миграций схемы.
При старте хаб SHALL проверять, что типы команд, ключи настроек и маршруты (метод и шаблон адреса) ядра и модулей не пересекаются; пересечение — ошибка старта с указанием конфликта.
Схема базы SHALL оставаться одной, с одной версией setting.schema_version на весь хаб; таблицы модуля входят в неё.
Scenario: Конфликт типов команд
- WHEN два подключённых модуля объявляют тип команды
refresh - THEN хаб не стартует, ошибка называет тип и оба модуля
Scenario: Поведение без изменений
- WHEN хаб после перестройки стартует на базе v6 с агентом v14
- THEN схема остаётся v6, копия базы не создаётся; адреса API, веба, ответы и инструменты MCP — прежние; агент берёт команды и отчитывается как раньше
Requirement: Агенты модулей
У каждого подключённого модуля, объявляющего типы команд, SHALL быть свой агент; имя агента — имя модуля (jira —
jira-agent, wiki — eva-agent). Агент SHALL определяться по токену: setting.tokens = {client, agents: {<модуль>: <токен>}}, недостающий токен агента хаб создаёт при старте. Хаб SHALL для каждого агента отдельно:
- выдавать в
claimтолько команды типов его модуля, с одной командой в полёте на агента (агенты работают параллельно); - хранить строку
agent_status(ключ — имя агента); - держать опубликованный релиз
release/<модуль>/и состояние самообновления; - отдавать в
GET /agent/settingsключи ядра и ключи для агента только своего модуля; - пускать на маршруты модуля со scope
agentтолько агента этого модуля (токен другого агента — 401).
Миграция v7 SHALL сохранить прежний агентский токен как токен агента jira, перенести строку agent_status в агента
jira и прежнюю публикацию release/agent.py в release/jira/. jira-agent v14 SHALL работать без обновления.
Scenario: jira-agent после выкатки
- WHEN хаб v6 с агентским токеном T и публикацией v14 обновлён до v7, jira-agent v14 шлёт
claimс токеном T - THEN 200; ответ содержит
agent_release {version: 14, …};GET /agentпоказывает агентаjiraс версией 14
Scenario: Агенты не берут чужие команды
- WHEN в очереди пакет 1 с
ensure_issueи пакет 2 сwiki_sync, обаqueued; агентwikiшлётclaim - THEN выдан
wiki_sync; следующийclaimагентаjiraполучаетensure_issue, хотяwiki_syncещёclaimed
Scenario: Чужой маршрут агента
- WHEN токеном агента
wikiвызванPOST /agent/state - THEN 401, зеркало не меняется
Scenario: Настройки только своего модуля
- WHEN токеном агента
wikiвызванGET /agent/settings - THEN в ответе есть
wiki_pacingиsettings_version, ключей jira (project_key,transitions_map) нет
Requirement: Поля проекта от модулей
Проект ядра SHALL состоять из label, name, created_at; остальные поля проекта SHALL объявлять модули: имя, тип,
проверку, изменяемость после создания, подпись и подсказку. Модуль SHALL сам хранить свои поля и отдавать их значения
(включая вычисляемые) для списка проектов. При старте хаб SHALL отвергать два модуля с одним именем поля или поле
модуля с именем поля ядра — ошибка старта с именем поля и модулей. В ядре SHALL NOT оставаться знания о полях модулей
(доска, число задач, корень вики).
Scenario: Конфликт полей
- WHEN два модуля объявляют поле проекта
root - THEN хаб не стартует, ошибка называет поле и оба модуля
Scenario: Поля jira прежние
- WHEN после миграции v7 вызван
GET /projects - THEN у
AWPCAboard_id = 4216,board_type = scrum,issues_count— как до миграции
Requirement: Подготовка отчёта команды модулем
Контракт CommandHooks SHALL содержать два необязательных хука. before_result(conn, cmd, status, result, files_dir)
SHALL вызываться ядром при отчёте по выданной команде до транзакции отчёта, чтобы модуль готовил тяжёлую работу (перевод,
запись файлов) вне блокировки базы; ValueError из него SHALL отдаваться как ошибка сервера, а не как неверный статус
отчёта. abort_result(conn, cmd) SHALL вызываться, когда отчёт не дошёл до after_result (ранний выход, исключение), и
снимать подготовку before_result. Модуль без этих хуков SHALL работать как прежде.
Scenario: Подготовка до транзакции
- WHEN агент шлёт отчёт
doneпо команде типа модуля сbefore_result - THEN
before_resultвызван доBEGIN IMMEDIATE, после фиксации транзакции —after_result
Scenario: Отчёт прерван
- WHEN
before_resultвыполнен, а транзакция отчёта завершилась исключением - THEN вызван
abort_result, подготовка снята, команда остаётся выданной