diff --git a/openspec/changes/bridge-hygiene/design.md b/openspec/changes/bridge-hygiene/design.md index a4df7b8..c94d5e5 100644 --- a/openspec/changes/bridge-hygiene/design.md +++ b/openspec/changes/bridge-hygiene/design.md @@ -141,3 +141,5 @@ | R-10 (design #13) | 2026-10-14 | Расхождения спеки и кода из разбора D закрываются правкой спеки, не кода | код разумнее текста спеки (спринты с доски, автообновление от `sync_run`), потребитель один | нет | | R-11 (design #21) | 2026-10-14 | Агент — версия 4, `min_agent_version` не поднимается | поведение сравнения и темпа изменилось; v3 продолжает работать | нет | | R-14 (design #22) | 2026-10-14 | В `fmt_batch` MCP строка про команду у агента без типа команды: «команда #N уже у агента и будет выполнена; остановить — `POST /commands/N/cancel` с `force: true`» | бриф Task 6 («команда #N (тип) …») противоречил тесту и спеке mcp; побеждает спека; тип доступен в JSON `still_claimed` | в тексте MCP не виден тип команды, только номер | +| R-15 (design #8) | 2026-10-14 | Спека commands приведена к коду: `null` допустим у любого необязательного параметра («не задан»; у `ensure_fields` — очистка), а не только «где параметр можно очистить» | проверка типов (R-6) не должна вводить список очищаемых параметров — агент уже трактует `null` как «не задан»; финальное ревью хаба M-2 | `null` в необязательном параметре `ensure_issue` (например, `labels`) создаст задачу без поля — как и пропуск параметра | +| R-13 (агент) | 2026-10-14 | Спека agent: ответ папки с `body: null` или без `body` — пустое тело, нечитаемый — только `body` иного типа | совместимость с прежним поведением агента; реле всегда пишет строку; финальное ревью агента M-1 | нет | diff --git a/openspec/changes/bridge-hygiene/specs/agent/spec.md b/openspec/changes/bridge-hygiene/specs/agent/spec.md index f0d3dbe..c3f93a7 100644 --- a/openspec/changes/bridge-hygiene/specs/agent/spec.md +++ b/openspec/changes/bridge-hygiene/specs/agent/spec.md @@ -67,7 +67,7 @@ README агента SHALL описывать: копирование `agent.py` 45 с) через временный файл с именем на точку и переименование, затем опрашивать `resp/.json` каждые 0,1 с. Полученный ответ агент SHALL удалить; `status` 2xx — вернуть разобранное тело, иной — выбросить `HttpError(status, body)` так же, как HTTP-клиент. Если к `deadline` ответа нет, агент SHALL удалить свой `req/.json` (если он ещё там) и -выбросить `ConnectionError`. Нечитаемый ответ — не JSON-объект, `status` не целое число или `body` не строка — SHALL +выбросить `ConnectionError`. Нечитаемый ответ — не JSON-объект, `status` не целое число или `body` не строка и не `null` (`null` и отсутствие — пустое тело) — SHALL перечитываться до 2 с, затем `ConnectionError`. Чужие файлы в `resp/` агент MUST NOT трогать. Цикл выполнения, журнал, повторы отчёта и восстановление SHALL работать без изменений. diff --git a/openspec/changes/bridge-hygiene/specs/commands/spec.md b/openspec/changes/bridge-hygiene/specs/commands/spec.md index 906b429..e203484 100644 --- a/openspec/changes/bridge-hygiene/specs/commands/spec.md +++ b/openspec/changes/bridge-hygiene/specs/commands/spec.md @@ -50,7 +50,8 @@ ### Requirement: Пакет и порядок выполнения Пакет SHALL создаваться одним вызовом с автором, заголовком и списком команд; хаб SHALL назначить `seq` по порядку списка и добавить в хвост `refresh` по всем ключам пакета (кроме пакетов, состоящих только из `refresh`). Хаб SHALL проверять -типы параметров: текстовые параметры и ключи — строки (`null` — только где параметр можно очистить), `target` команды +типы параметров: текстовые параметры и ключи — строки (`null` у необязательного параметра — «не задан»; агент +трактует его по контракту типа, для `ensure_fields` — очистка поля), `target` команды `ensure_status` — строка или список строк, `labels`, `labels_add`, `labels_remove`, `keys` — списки строк, `replace` — логическое значение; нарушение — 422 с именем параметра. Пакет с двумя и более `ensure_issue` с одинаковой `summary` (после обрезки пробелов по краям) SHALL отвергаться (422). Очередь SHALL выдавать команды в порядке