52 lines
4.5 KiB
Markdown
52 lines
4.5 KiB
Markdown
## ADDED Requirements
|
||
|
||
### Requirement: Форма тела запроса
|
||
На тело неверной формы хаб SHALL отвечать 422, а не 500. В `POST /agent/state` поле `issues` SHALL быть списком,
|
||
каждый его элемент — объектом с непустым строковым `key`. Иначе 422 `bad_state` с номером элемента, и пачка не
|
||
применяется. В `POST /wiki/sync` поле `project` в теле, если задано, SHALL быть строкой. Иначе 422 `bad_request`
|
||
«project — строка».
|
||
|
||
#### Scenario: Элемент состояния не объект
|
||
- **WHEN** агент шлёт `POST /agent/state {issues: ["A-1"]}`
|
||
- **THEN** 422 `bad_state` «issues[0] — объект задачи с key», зеркало не изменилось
|
||
|
||
#### Scenario: Проект вики не строкой
|
||
- **WHEN** `POST /wiki/sync {project: 5}`
|
||
- **THEN** 422 `bad_request` «project — строка», пакет не создан
|
||
|
||
### Requirement: Ошибка доступа к файлу хранилища
|
||
Если файл хранилища вложений не читается (`PermissionError`, `IsADirectoryError` или другая ошибка ОС), хаб SHALL
|
||
обрабатывать его как отсутствующий: при `claim` `ensure_attachment` получает `size = null`, `GET /files/<sha>` и
|
||
скачивание вложения отвечают 404, как для удалённого файла. В лог хаба SHALL писаться предупреждение с путём и
|
||
ошибкой. `FileNotFoundError` в лог не пишется.
|
||
|
||
#### Scenario: Нет прав на файл
|
||
- **WHEN** у файла `files/<sha>` сняты права на чтение, агент берёт `ensure_attachment` с этим `file`
|
||
- **THEN** `claim` отвечает 200, у команды `size = null`; в логе — предупреждение с путём
|
||
|
||
### Requirement: Пустой SDLC_HUB_HOME
|
||
Переменная `SDLC_HUB_HOME`, заданная пустой строкой, SHALL трактоваться как незаданная: каталог данных —
|
||
`~/.local/share/sdlc-hub/`, проверка прежнего каталога выполняется. Хаб MUST NOT писать данные в рабочий каталог
|
||
процесса из-за пустой переменной.
|
||
|
||
#### Scenario: Пустая переменная
|
||
- **WHEN** `SDLC_HUB_HOME= sdlc-hub tokens`
|
||
- **THEN** база открыта из `~/.local/share/sdlc-hub/hub.sqlite`; в рабочем каталоге не появился `hub.sqlite`
|
||
|
||
### Requirement: Восстановление прерванной публикации агента
|
||
Перед публикацией версии агента модуля хаб SHALL приводить `release/<модуль>/` к опубликованному состоянию по
|
||
`manifest.json`. Если `agent.py.prev` есть, а `agent.py` нет или не совпадает по sha256 с манифестом, тогда как
|
||
`agent.py.prev` совпадает, `agent.py.prev` SHALL возвращаться на место `agent.py`. Если `agent.py` совпадает с
|
||
манифестом, оставшийся `agent.py.prev` удаляется. В других сочетаниях файлы не трогаются, в лог пишется
|
||
предупреждение. Годный `agent.py.prev`, совпадающий с манифестом, MUST NOT перезаписываться другим содержимым.
|
||
|
||
#### Scenario: Сбой между переименованием и записью
|
||
- **WHEN** опубликована v5, прошлая публикация упала после переименования: `agent.py` нет, `agent.py.prev` — v5,
|
||
манифест — v5; новая публикация v6 снова падает при записи
|
||
- **THEN** в `release/jira/` — `agent.py` v5 и манифест v5, опубликованной остаётся v5
|
||
|
||
#### Scenario: Сбой поверх неудачного возврата
|
||
- **WHEN** `agent.py` — недописанный v6, `agent.py.prev` — v5, манифест — v5; запущена публикация v6
|
||
- **THEN** перед записью `agent.py` восстановлен из `.prev` (v5); при сбое записи опубликованной остаётся v5, а `.prev`
|
||
не затёрт недописанным файлом
|