Andrey Epifancev ede028346b Документация: модуль wiki и агенты модулей (#91)
Тест границы test_core_has_no_module_terms; ARCHITECTURE/CLAUDE/README; дельта-спека о хуках before_result/abort_result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 03:37:17 +04:00

62 lines
5.7 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.

## ADDED Requirements
### 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** у `AWPCA` `board_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`, подготовка снята, команда остаётся выданной