diff --git a/README.md b/README.md index 03e5d97..28c2c8e 100644 --- a/README.md +++ b/README.md @@ -111,13 +111,14 @@ uv run jira-hub agent publish ../jira-agent/src/agent.py `agent_status` (MCP) покажет «обновление: ok v<старая> → v<новая>». Если новая версия упала или не вышла на связь, запускатель вернёт прежнюю — `agent_status` покажет «откат с v …»; исправление публикуется следующим номером. Снять публикацию нельзя: откат «назад» — тот же старый код с новым номером. + Если записать публикацию не удалось (диск полон, нет прав), команда печатает «не удалось записать публикацию: …» и выходит с кодом 1; опубликованной остаётся прежняя версия, временных файлов в `release/` нет. Манифест, который хаб -не может разобрать (`version` не целое, `sha256` не 64 hex-символа), означает «публикации нет» — одно предупреждение в +не может разобрать (`version` не целое, `sha256` не 64 символа `[0-9a-f]`), означает «публикации нет» — одно предупреждение в логе хаба на каждую новую ошибку. Состояние обновления и версию запускателя агент сообщает в каждом `claim`, хаб держит их в памяти: сразу после -перезапуска хаба, пока агент не вышел на связь (до 30 с), `agent_status` пишет «запускатель: неизвестно (агент ещё не +перезапуска хаба, пока агент не вышел на связь (до первого `claim` агента, обычно до 30 с), `agent_status` пишет «запускатель: неизвестно (агент ещё не выходил на связь после перезапуска хаба)», а подсказки «агент запущен без run.py» нет. ## HTTP API diff --git a/openspec/changes/hub-hygiene-d/design.md b/openspec/changes/hub-hygiene-d/design.md index c51c498..719e6eb 100644 --- a/openspec/changes/hub-hygiene-d/design.md +++ b/openspec/changes/hub-hygiene-d/design.md @@ -88,8 +88,8 @@ ## Risks / Trade-offs - [`agent.py.prev` в `release/`] лишний файл живёт только между переименованием и записью манифеста; при падении - процесса посреди — остаётся; следующая публикация его перезапишет. → не влияет на `load` (читается только `agent.py`). -- [«неизвестно» до первого claim] до 30 с после перезапуска хаба статус неполный. → честнее ложного «без запускателя». + процесса посреди — остаётся; следующая публикация его перезапишет. → при падении процесса между переименованием и записью `agent.py` нет вовсе, и `GET /agent/release` отдаёт 404 до следующей публикации (как и прежде при падении между записью agent.py и манифеста). +- [«неизвестно» до первого claim] до первого `claim` агента (обычно до 30 с) после перезапуска хаба статус неполный. → честнее ложного «без запускателя». - [`PUT /settings` отдаёт больше полей] клиенты, ожидавшие ровно `{settings_version}`, получают надмножество. → поле на месте. - [Конфликт с #29] текстовый в `tests/test_api.py` (одна строка у #29). → кто сливается вторым, разрешает. @@ -110,4 +110,5 @@ | R-10 (design #2) | 2026-10-15 | `secure_dir` при публикации вызывается внутри `try` | его `OSError` тоже должен стать `PublishError`, а не трейсбеком | трейсбек в CLI | | R-11 (design #7) | 2026-10-15 | У `release.hint(..., reported=True)` значение по умолчанию | не переписывать старые вызовы и тесты | забытый вызов без признака даёт прежнее поведение | | R-12 (design #5) | 2026-10-15 | Запоминание последнего текста ошибки манифеста (`_warned`) под `threading.Lock` | `current` вызывается из потоков HTTP-сервера | двойное предупреждение при гонке | -| R-13 (design #14) | 2026-10-15 | Первый абзац `CLAUDE.md` («текущий change — …») не менять | его правит параллельная ветка #29 (`feat/29-web-app-followups`), конфликт гарантирован; строка перепишется при архивации | до архивации `CLAUDE.md` в ветке называет чужой change | +| R-13 (design #14) | 2026-10-15 | Первый абзац `CLAUDE.md` («текущий change — …») не менять | его правит параллельная ветка #29 (`feat/29-web-app-followups`), конфликт гарантирован; строка перепишется при архивации | до архивации `CLAUDE.md` в ветке называет чужой change. Итог: после слияния #29 первый абзац `CLAUDE.md` в main общий («активные change — `openspec/changes/` (кроме `archive/`)»), поэтому при архивации его переписывать не нужно | +| R-14 (merge) | 2026-10-15 | main не сливается в ветку; конфликт `pyproject.toml` (блок `[tool.uv]` из #29 против `filterwarnings`) разрешается при merge PR: оставить обе секции | инструкция «не мержить»; конфликт тривиален, пробное слияние даёт 317 passed | PR показывает конфликт до ручного разрешения |