Andrey Epifancev 06ef35a013 OpenSpec: change fact-status-removal (#104)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:37:54 +04:00

96 lines
12 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.

## MODIFIED Requirements
### Requirement: Инструменты
| Инструмент | Параметры | Результат |
|---|---|---|
| `projects` | — | таблица: метка, название, доска, тип доски («неизвестен», пока агент не определил), число своих задач; в привязанной сессии текущий проект отмечен |
| `project_create` | `label`, `name`, `board_id` (необязательно) | `POST /projects` с автором `claude`: проект, id пакета обновления и фрагмент `.mcp.json` для репозитория проекта (см. ниже); 409/422 — текст ошибки |
| `issues` | фильтры как у `GET /issues` (кроме `project` — его задаёт привязка), `limit` (по умолчанию 50) | таблица: ключ, тема (до 80 символов), статус, срок, исполнитель, спринт |
| `issue` | `key` | поля, связи (обе стороны, с типом и направлением), заметки, последние команды, комментарии: «комментарии (N):» и 5 последних (номер «#<comment_id>», автор, время, текст до 300 символов с «…»), «ещё M», если их больше 5; без комментариев — «комментариев нет»; у комментария со ссылками на вложения — строка «файлы: #<id> <имя>, …»; затем вложения (см. «Вложения в MCP») |
| `comment` | `key`, `comment_id` (номер из ответа `issue`, «#» в начале допускается) | один комментарий целиком по `GET /issues/{key}`: строка «<key> #<id> <автор>, создан <created>» (и «, изменён <updated>», если `updated` есть и отличается от `created`), под ней полный текст с переносами строк; нет такого номера — «у <key> нет комментария #<id>»; есть ссылки на вложения — после текста строка «вложения:» и по строке на каждое: «#<id> <имя> (<размер>)» |
| `attachment` | `key`, `attachment` (номер вложения «#<id>» или «<id>», иначе — точное имя файла), `wait_seconds` (по умолчанию 120, не больше 600) | скачивает вложение и отдаёт путь к локальной копии (см. «Вложения в MCP») |
| `notes_set` | `key`, подмножество полей заметок | обновлённые заметки |
| `batch_create` | `title`, `commands` (список объектов по контракту `commands`; у `ensure_attachment` вместо `file` можно `path`) | `id`, `estimate_seconds`, число команд; 422 — текст ошибки валидации |
| `batch_status` | `id` | статусы команд, ошибки, оценка остатка |
| `batch_wait` | `id`, `timeout_minutes` (≤ 60) | как `batch_status`, возвращается по завершении или по таймауту |
| `batches` | `limit` | последние пакеты со статусом |
| `command_retry` | `id` | новый пакет |
| `batch_cancel` | `id` | вид пакета; для команд пакета, уже взятых агентом, — строка «команда #N уже у агента и будет выполнена; остановить — `POST /commands/N/cancel` с `force: true`» |
| `refresh` | `keys` или `full`, `wait` (bool) | без `wait` — строка с id поставленного пакета; с `wait` — итог пакета, как у `batch_wait` |
| `agent_status` | — | онлайн/офлайн, версия, текущая команда, довыданные команды (id, тип, число выдач), 429 за сутки, версия настроек; публикация агента («публикация: v<N> от <дата>» или «публикации нет»), состояние обновления («обновление: <state> v<from> → v<to>»), запускатель («запускатель: v<N>», «без запускателя» или, пока `agent_reported = false`, «запускатель: неизвестно (агент ещё не выходил на связь после перезапуска хаба)»), `update_hint`, если он есть |
| `sync_log` | `limit` | последние `sync_run` |
| `settings_get`, `settings_set` | ключ, значение | текущее значение / новая `settings_version` |
Разрез по проекту и поведение без привязки — требование «Привязка сессии к проекту».
Описание инструмента `batch_create` SHALL перечислять параметры каждого типа команды (обязательные, необязательные в
`[ ]`, формат значения) и собираться из описания параметров в коде хаба (см. `commands`), а не вручную.
`ensure_attachment` в `batch_create` SHALL принимать вместо `file` параметр `path` — абсолютный путь к локальному файлу на
машине MCP-сервера. До постановки пакета MCP SHALL прочитать файл, загрузить его `POST /files` и заменить `path` на
`file`; `filename` по умолчанию — имя файла из `path`. Нет файла, нет прав, не файл, больше 10 МБ — ответ инструмента
с причиной и путём, пакет не ставится. Передан и `path`, и `file` — ответ «у ensure_attachment либо path, либо file».
Описание инструмента `batch_create` SHALL сообщать, что метку проекта сессии хаб дописывает в `ensure_issue` сам, метки
других проектов запрещены, а команды над задачами вне проекта отклоняются; `board_id` для `ensure_sprint` выставляет хаб.
Ответ `project_create` SHALL содержать фрагмент `.mcp.json`
`{"mcpServers": {"sdlc-jira": {"command": "uv", "args": ["run", "--project", "<корень хаба>", "sdlc-hub", "mcp", "jira",
"--project", "<метка>"]}}}`, где корень хаба — корень репозитория, из которого загружен пакет текущего процесса MCP
(вычисляется от расположения пакета, без зашитого пути), и указание: положить файл в корень репозитория проекта (слить
с имеющимся `.mcp.json`) и переподключить MCP (`/mcp` → reconnect, одобрить сервер проекта).
Автор команд из MCP SHALL быть `claude`; из API без автора — `api`.
#### Scenario: Пакет из чата
- **WHEN** `batch_create {title: "1538 в спринт 2", commands: [ensure_fields{…}, ensure_link{…}, ensure_sprint{…}]}`
- **THEN** пакет создан с четырьмя командами (три + `refresh`), ответ содержит оценку в минутах
#### Scenario: Проект из чата
- **WHEN** сессия без привязки, `project_create {label: "STOCKS_DRRK", name: "Запасы ДРРК", board_id: 5120}`
- **THEN** проект создан, ответ содержит id пакета обновления и фрагмент `.mcp.json` с `"--project", "STOCKS_DRRK"`
#### Scenario: Ошибка с файлом из чата
- **WHEN** `batch_create {title: "Ошибка ОСВ 60", commands: [ensure_issue{temp_key: new:1, issue_type: bug, …},
ensure_attachment{key: new:1, path: "/Users/…/ОСВ сч. 60 за 2 кв. 2026.xlsx"}]}`
- **THEN** файл загружен в хаб; пакет создан с `ensure_attachment {key: new:1, file: <sha>, filename: "ОСВ сч. 60 за 2 кв.
2026.xlsx"}` и хвостовым `refresh`
#### Scenario: Файла нет
- **WHEN** тот же вызов, файла по `path` нет
- **THEN** ответ «файл не найден: <path>», пакет не создан, в хаб ничего не загружено
#### Scenario: Ожидание результата
- **WHEN** `batch_wait {id, timeout_minutes: 10}` и пакет завершился через 6 минут
- **THEN** ответ через 6 минут со статусами всех команд
#### Scenario: Статус агента с довыдачей
- **WHEN** агент на связи, команда 40 выдана дважды и ещё без отчёта
- **THEN** ответ `agent_status` содержит «агент онлайн» и строку о команде 40 с числом выдач 2
#### Scenario: Отмена пакета с командой у агента
- **WHEN** `batch_cancel {id: 9}`, команда 30 пакета в `claimed`
- **THEN** ответ содержит вид пакета и строку «команда #30 уже у агента и будет выполнена; остановить — …»
#### Scenario: Статус агента после отката
- **WHEN** опубликована v7, агент v6 под запускателем v1 прислал `update_state = rolled_back` для v7
- **THEN** ответ `agent_status` содержит «публикация: v7 от …», «обновление: rolled_back v6 → v7», «запускатель: v1» и
«откат с v7 на v6: …»
#### Scenario: Статус агента сразу после перезапуска хаба
- **WHEN** хаб перезапущен, агент ещё не прислал `claim`
- **THEN** ответ `agent_status` содержит «запускатель: неизвестно (агент ещё не выходил на связь после перезапуска
хаба)» и не содержит «без запускателя» и «агент запущен без run.py»
#### Scenario: Задача с семью комментариями
- **WHEN** `issue {key: "AURORA-9001"}`, у задачи 7 комментариев, у самого нового текст 500 символов
- **THEN** ответ содержит «комментарии (7):», 5 последних комментариев с номерами «#<comment_id>» (самый новый — первым, обрезан до 300 символов с «…») и «ещё 2»
#### Scenario: Комментарий целиком
- **WHEN** у задачи `AURORA-9001` комментарий `#101` длиной 800 символов с переносами строк, вызван `comment {key: "AURORA-9001", comment_id: "101"}`
- **THEN** ответ — «AURORA-9001 #101 <автор>, создан <created>» и полный текст комментария без обрезки, переносы строк сохранены
#### Scenario: Нет такого комментария
- **WHEN** `comment {key: "AURORA-9001", comment_id: "999"}`, у задачи нет комментария 999
- **THEN** ответ «у AURORA-9001 нет комментария #999»