feat(#370): агент пинит версию страницы ДО и ПОСЛЕ раунда правок (не только финальный чекпоинт) #579

Open
opened 2026-07-12 20:20:12 +03:00 by agent_vscode · 0 comments
Collaborator

Проблема / Цель

Инструмент save_page_version (агентская версия kind='agent', доставлен в #565 (feat(#370 Stage A): MCP save_page_version — агентские версии страниц)) сейчас описан и прописан в промптах только как финальный чекпоинт: «вызови, когда закончил проход редактирования». Две пишущие-контент роли (researcher, call-summarizer) вызывают его один раз в конце. Пред-редакторное состояние страницы намеренно не фиксируется — если раунд правок агента портит/перезаписывает контент, у самого агента нет чистой точки восстановления «до».

Цель: требовать от агентов, которые правят контент страницы, пинить версию и перед началом раунда правок (страховочная точка «до»), и после его завершения (результат «после») — обрамляя каждый раунд восстановимыми чекпоинтами. Правило прописать и в промптах пишущих ролей, и в центральном описании инструмента (чтобы оно действовало для любого редактирующего агента, включая встроенного in-app ассистента).

Контекст и исследование

  • Инструмент и серверный жизненный цикл уже поставлены (#370 Stage A / #565, смерджено в develop @ e074b101). Сервер выводит kind из подписанного actor; контент, идентичный последней версии → promote/no-op; пустая страница → {saved:false, skipped:true, reason:'empty'}. Инструмент идемпотентно-безопасен: лишний вызов не дублирует версию.
  • Формулировка «только финал» живёт ровно в 6 местах (исчерпывающий grep save_page_version/savePageVersion, вне node_modules/build):
    1. packages/mcp/src/tool-specs.ts — поле savePageVersion.description (~строки 751–761): «…Call it when you have FINISHED a coherent editing pass (not after every small edit)…».
    2. packages/mcp/src/server-instructions.ts — строка HISTORY (строка 47): «…Pin the page's CURRENT content … when you finish a coherent editing pass -> savePageVersion …».
    3. agent-roles-catalog/bundles/assistants/en.yamlresearcher, пункт чек-листа (~строка 349): «Once the report is complete, call save_page_version to pin the finished document…».
    4. agent-roles-catalog/bundles/assistants/en.yamlcall-summarizer (~строка 448): «Pin the result. Once the notes are complete on the page, call save_page_version…».
    5. agent-roles-catalog/bundles/assistants/ru.yamlresearcher (~строка 348): текст уже на английском (байт-в-байт как п.3) — переписывать эту английскую строку.
    6. agent-roles-catalog/bundles/assistants/ru.yamlcall-summarizer (~строка 447): «Зафиксируй результат. Когда конспект готов на странице, вызови save_page_version…».
  • Редакторские роли (structural-editor/line-editor/fact-checker/proofreader/narrator) — comment-only («You don't edit the text directly»), страницу не правят → инструмент им не даётся, НЕ трогаем.
  • Профиль ролей (важно для формулировок):
    • researcher — рабочий цикл (en.yaml:119–128) многократно «сливает» найденное в документ (flush-проходы); финальный пин в чек-листе (en.yaml:349–351).
    • call-summarizerautoStart: true, launchMessage «Take the current page into work — it contains the call transcript» (en.yaml:462): стартует на НЕ пустой странице (сырая расшифровка), перезаписывая её конспектом.

Известный техдолг, на который дизайн наступает (обязательно учесть)

  • Лок content-hashes.json на develop уже устарел. Stage A (#565) поднял researcher 9→10 и call-summarizer 1→2 и изменил их контент, но не обновил agent-roles-catalog/scripts/content-hashes.json (лок всё ещё пишет 9/1). Следствия:
    • node agent-roles-catalog/scripts/check.mjs на чистом develop уже падает (EXIT 1, «content changed and version bumped to 10/2; record it by running --update-hashes»). Это не дефект окружения кодера — это предсуществующее состояние.
    • Условие гварда «версия поднята выше лока» уже удовлетворено Stage-A-бампом (10 > 9). Поэтому если просто переписать контент, оставить версии 10/2 и прогнать --update-hashes, гвард пропустит без нового бампа. А gate распространения if (currentVersion <= source.version) skip в apps/server/src/core/ai-chat/roles/ai-agent-roles.service.ts:488 тогда не отдаст переписанный контент воркспейсам, уже синхронизированным на v10/v2 → тихий дрейф. Поэтому в этом изменении версии обязаны быть подняты явно (см. Дизайн).
  • check.mjs не подключён к CI. agent-roles-catalog не входит в pnpm-workspace (pnpm-workspace.yaml = только apps/*, packages/*), собственный package.json; pnpm -r test его не трогает; grep по .github/, turbo.json, .husky/ — ноль вызовов check.mjs. То есть бамп версии и рефреш лока — дисциплина, а не CI-гейт. Кодер обязан прогнать проверку локально (см. Критерии приёмки); рекомендуемое усиление — вынести в отдельный follow-up (см. «Отказы и наблюдаемость»).

Дизайн

Единое правило поведения — обрамлять раунд правок версией, с одинаковым триггером на всех 6 поверхностях.

Триггер и семантика (общая формулировка для всех мест)

  • ДО раунда: «Перед тем как начать раунд правок, который дополняет или переписывает существующий контент страницы, сначала вызови save_page_version, чтобы зафиксировать текущее состояние как точку восстановления. Если контент уже совпадает с последней сохранённой версией или страница пуста — вызов безопасно no-op/skip (версию не дублирует, «стоимости» нет), поэтому вызывать безопасно всегда.»
  • ПОСЛЕ раунда: «Когда раунд завершён — снова вызови save_page_version, чтобы запинить результат.»
  • Единый триггер (одинаковыми словами и в центральном описании, и в промптах — иначе поверхности разъедутся): «before overwriting existing content that isn't already captured in the latest saved version». Не смешивать с «content you did/didn't author» — дедуп в инструменте идёт по контенту последней версии (любого actor), не по авторству.

Карваут для удаляющих правок (безопасность, обязательно — иначе NEW-1)

Централизация «пинить перед правкой существующего контента» ломает редактирующие-на-удаление правки. Сценарий: пользователь говорит in-app ассистенту «убери отсюда API-ключ / вычисти PII / удали конфиденциальный раздел». Слепое пред-пиннинг сохранит удаляемый секрет в восстановимую, расшаренную по правам агентскую версию — вычистка ничего не вычистит. Поэтому формулировка обязана содержать исключение:

«Не делай пред-сейв, если цель правки — удалить чувствительный/конфиденциальный контент (пиннинг сохранил бы то, что ты убираешь, в восстановимой истории). Пред-сейв — только для правок, которые дополняют или пересматривают контент.»

Определение «раунда» (обязательно — иначе NEW-2)

Пред-сейв на no-op безвреден, но пост-сейв изменённого раунда — это реальная новая версия, поэтому гранулярность «раунда» перестаёт быть бесплатной. Без чёткого определения researcher с его flush-циклом (en.yaml:119–128) при трактовке «flush ≈ раунд» наплодит 20–30 агентских версий на отчёт и утопит осмысленный финальный чекпоинт. Зафиксировать в промпте researcher конкретно:

«Раунд = первичный черновик и каждый последующий крупный проход-ревизия (цикл блока Revision), НЕ каждый flush/мелкая правка. Один пред-сейв + один пост-сейв на крупный проход, а не на микроправку.»

Что делает каждая поверхность

  • tool-specs.ts savePageVersion.description + server-instructions.ts HISTORY — переписать на условную формулировку (триггер + карваут-на-удаление + «до и после»), сохранив описание no-op/skip-семантики. Держать прозу простым английским + только зарегистрированные имена инструментов — иначе reverse-drift-гвард #494 (packages/mcp/test/unit/tool-inventory.test.mjs:145, гоняется в CI) покраснеет на любом camelCase-токене, которого нет в реестре или в PROSE_NON_TOOL_TERMS.
  • researcher (en.yaml + английская строка в ru.yaml) — правило «до/после» + определение «раунда» (крупный проход, не flush).
  • call-summarizer (en.yaml + ru.yaml) — правило «до/после». Здесь пред-сейв осмыслен и желателен: он пинит сырую расшифровку как точку восстановления перед перезаписью её конспектом (V1 = расшифровка, V2 = конспект). Это фича, а не дефект: версия — это снимок, а не заявка на авторство; kind='agent' от подписанного actor консистентен модели #370.
  • index.yaml — поднять researcher 10→11, call-summarizer 2→3 (числа явные, т.к. гвард из-за устаревшего лока их не заставит — см. техдолг).
  • content-hashes.json — обновить через node scripts/check.mjs --update-hashes (заодно чинит устаревший Stage-A-лок).

Что НЕ вводим

Новый механизм синхронизации 6 текстов — не вводим: это разные формулировки под разные аудитории (схема инструмента / серверные инструкции / персона роли), не производный mirror; единый триггер держим вручную. Никакого нового кода/примитивов — сам save_page_version уже есть.

Границы scope

  • Только 6 текстовых мест + index.yaml (бамп 10→11 / 2→3) + content-hashes.json (рефреш).
  • Редакторские (comment-only) роли — не трогаем.
  • Билд-артефакты packages/mcp/build/*не коммитим: не трекаются git (git ls-files packages/mcp/build = 0; .gitignore игнорит packages/mcp/build/; CI пересобирает pnpm --filter @docmost/mcp build). Сгенерированный registry-stamp.generated.ts тоже gitignored и пересобирается — коммитить нечего.
  • Подключение check.mjs к CI — вне scope этого PR (см. follow-up ниже), чтобы PR остался про формулировки.

Критерии приёмки

  1. node agent-roles-catalog/scripts/check.mjs печатает OK (версии researcher=11 и call-summarizer=3 в index.yaml; content-hashes.json обновлён и закоммичен).
  2. grep по researcher и call-summarizer в обоих en.yaml и ru.yaml показывает и инструкцию «пинить ДО начала раунда» (с карваутом-на-удаление), и «пинить ПОСЛЕ»; в промпте researcher присутствует явное определение «раунда» (крупный проход, не flush).
  3. savePageVersion.description (tool-specs.ts) и строка HISTORY (server-instructions.ts) содержат условное «пинить ДО начала правок существующего контента И ПОСЛЕ», включая исключение для удаляющих правок; ни один новый camelCase-токен не добавлен в HISTORY-прозу.
  4. В packages/mcp: tsc — 0 ошибок; юнит-набор зелёный (tool-specs.test.mjs, tool-inventory.test.mjs вкл. #494-гвард, save-page-version.test.mjs).
  5. Серверные спеки зелёные: shared-tool-specs.contract.spec.ts (динамически сверяет expose-описание с spec.description), ai-agent-roles-catalog.provider.spec.ts (синтетические фикстуры, реальные номера версий не хардкодит).

Отказы и наблюдаемость

  • Новых путей отказа в рантайме нет: оба вызова идемпотентны (skip на пустой, promote/no-op на идентичной), инструмент уже возвращает структурированный результат. Видимость оператора не меняется.
  • Безопасность fail-safe: карваут-на-удаление (см. Дизайн) — единственный контроль, где «слепое поведение» опасно; дефолт — не создавать восстановимую копию удаляемого секрета.
  • Дисциплинарный риск (не рантайм): check.mjs не в CI → забытый бамп/устаревший лок дрейфит молча и блокирует распространение переписанного контента (см. техдолг). Митигируется явными числами версий в этом ишью + Критерием 1. Рекомендуемый follow-up (отдельный PR): добавить в CI шаг node agent-roles-catalog/scripts/check.mjs, чтобы гвард стал реальным гейтом.

Совместимость и миграции

  • Изменение дефолтной инструкции: правка server-instructions.ts действует на всех агентов с deferred-инструментом savePageVersion, включая встроенного in-app ассистента под любой персоной — теперь их условно (только когда реально правят существующий контент) направляют пинить «до». Осознанно, по решению человека (Вариант B). Условная формулировка гарантирует, что comment-only роли, которые текст не правят, правилом не задеты.
  • Бамп версий ролей — сигнал потребителям каталога об обновлении (штатный механизм). Поведение самих страниц не меняется. Миграций БД нет.

Решённые развилки

  • Охват: «роли + центральное описание» (Вариант B) — решил человек в сессии. Альтернатива «только промпты ролей» отклонена, чтобы правило было единым для всех редактирующих агентов, а не только для двух пишущих ролей.
  • Оставить ли «до», раз в solo-потоке это часто no-op: оставляем (явное требование человека «до и после»); переформулировано честно как дешёвая страховка, срабатывающая осмысленно ровно на непинённом пред-редакторном контенте — дизайн (после adversarial-разбора).
  • Пиннинг сырой расшифровки у call-summarizer (kind=agent): признан фичей (точка отката к пред-редакторному состоянию), не дефектом — дизайн.
  • Карваут для удаляющих правок: добавлен как fail-safe безопасности — дизайн (adversarial re-attack, NEW-1).

Связи

  • Мета: #370 ([feature][history][share] Версии страниц: ручной Save + idle-flush …) — общий дизайн трёх уровней намеренности.
  • Базовый инструмент: #565 (feat(#370 Stage A): MCP save_page_version — агентские версии страниц).
## Проблема / Цель Инструмент `save_page_version` (агентская версия `kind='agent'`, доставлен в **#565 (feat(#370 Stage A): MCP save_page_version — агентские версии страниц)**) сейчас описан и прописан в промптах **только как финальный чекпоинт**: «вызови, когда закончил проход редактирования». Две пишущие-контент роли (`researcher`, `call-summarizer`) вызывают его один раз в конце. Пред-редакторное состояние страницы намеренно не фиксируется — если раунд правок агента портит/перезаписывает контент, у самого агента нет чистой точки восстановления «до». **Цель:** требовать от агентов, которые правят контент страницы, пинить версию и **перед** началом раунда правок (страховочная точка «до»), и **после** его завершения (результат «после») — обрамляя каждый раунд восстановимыми чекпоинтами. Правило прописать и в промптах пишущих ролей, и в центральном описании инструмента (чтобы оно действовало для любого редактирующего агента, включая встроенного in-app ассистента). ## Контекст и исследование - **Инструмент и серверный жизненный цикл уже поставлены** (#370 Stage A / #565, смерджено в `develop @ e074b101`). Сервер выводит `kind` из подписанного actor; контент, идентичный последней версии → promote/no-op; пустая страница → `{saved:false, skipped:true, reason:'empty'}`. Инструмент **идемпотентно-безопасен**: лишний вызов не дублирует версию. - **Формулировка «только финал» живёт ровно в 6 местах** (исчерпывающий grep `save_page_version`/`savePageVersion`, вне `node_modules`/`build`): 1. `packages/mcp/src/tool-specs.ts` — поле `savePageVersion.description` (~строки 751–761): «…Call it when you have FINISHED a coherent editing pass (not after every small edit)…». 2. `packages/mcp/src/server-instructions.ts` — строка `HISTORY` (строка 47): «…Pin the page's CURRENT content … when you finish a coherent editing pass -> savePageVersion …». 3. `agent-roles-catalog/bundles/assistants/en.yaml` — `researcher`, пункт чек-листа (~строка 349): «Once the report is complete, call save_page_version to pin the finished document…». 4. `agent-roles-catalog/bundles/assistants/en.yaml` — `call-summarizer` (~строка 448): «**Pin the result.** Once the notes are complete on the page, call save_page_version…». 5. `agent-roles-catalog/bundles/assistants/ru.yaml` — `researcher` (~строка 348): **текст уже на английском** (байт-в-байт как п.3) — переписывать эту английскую строку. 6. `agent-roles-catalog/bundles/assistants/ru.yaml` — `call-summarizer` (~строка 447): «**Зафиксируй результат.** Когда конспект готов на странице, вызови save_page_version…». - **Редакторские роли** (`structural-editor`/`line-editor`/`fact-checker`/`proofreader`/`narrator`) — comment-only («You don't edit the text directly»), страницу не правят → инструмент им не даётся, **НЕ трогаем**. - **Профиль ролей** (важно для формулировок): - `researcher` — рабочий цикл (`en.yaml:119–128`) многократно «сливает» найденное в документ (flush-проходы); финальный пин в чек-листе (`en.yaml:349–351`). - `call-summarizer` — `autoStart: true`, launchMessage «Take the current page into work — it contains the call transcript» (`en.yaml:462`): **стартует на НЕ пустой странице** (сырая расшифровка), перезаписывая её конспектом. ### Известный техдолг, на который дизайн наступает (обязательно учесть) - **Лок `content-hashes.json` на `develop` уже устарел.** Stage A (#565) поднял `researcher` 9→10 и `call-summarizer` 1→2 и изменил их контент, но **не** обновил `agent-roles-catalog/scripts/content-hashes.json` (лок всё ещё пишет 9/1). Следствия: - `node agent-roles-catalog/scripts/check.mjs` на чистом `develop` **уже падает** (EXIT 1, «content changed and version bumped to 10/2; record it by running --update-hashes»). Это не дефект окружения кодера — это предсуществующее состояние. - Условие гварда «версия поднята выше лока» уже удовлетворено Stage-A-бампом (10 > 9). Поэтому если просто переписать контент, оставить версии 10/2 и прогнать `--update-hashes`, гвард **пропустит** без нового бампа. А gate распространения `if (currentVersion <= source.version) skip` в `apps/server/src/core/ai-chat/roles/ai-agent-roles.service.ts:488` тогда **не отдаст** переписанный контент воркспейсам, уже синхронизированным на v10/v2 → тихий дрейф. Поэтому в этом изменении версии **обязаны** быть подняты явно (см. Дизайн). - **`check.mjs` не подключён к CI.** `agent-roles-catalog` не входит в pnpm-workspace (`pnpm-workspace.yaml` = только `apps/*`, `packages/*`), собственный `package.json`; `pnpm -r test` его не трогает; grep по `.github/`, `turbo.json`, `.husky/` — ноль вызовов `check.mjs`. То есть бамп версии и рефреш лока — **дисциплина, а не CI-гейт**. Кодер обязан прогнать проверку локально (см. Критерии приёмки); рекомендуемое усиление — вынести в отдельный follow-up (см. «Отказы и наблюдаемость»). ## Дизайн Единое правило поведения — **обрамлять раунд правок версией**, с одинаковым триггером на всех 6 поверхностях. ### Триггер и семантика (общая формулировка для всех мест) - **ДО раунда:** «Перед тем как начать раунд правок, который **дополняет или переписывает** существующий контент страницы, сначала вызови `save_page_version`, чтобы зафиксировать текущее состояние как точку восстановления. Если контент уже совпадает с последней сохранённой версией или страница пуста — вызов безопасно no-op/skip (версию не дублирует, «стоимости» нет), поэтому вызывать безопасно всегда.» - **ПОСЛЕ раунда:** «Когда раунд завершён — снова вызови `save_page_version`, чтобы запинить результат.» - **Единый триггер** (одинаковыми словами и в центральном описании, и в промптах — иначе поверхности разъедутся): _«before overwriting existing content that isn't already captured in the latest saved version»_. Не смешивать с «content you did/didn't author» — дедуп в инструменте идёт по контенту последней версии (любого actor), не по авторству. ### Карваут для удаляющих правок (безопасность, обязательно — иначе NEW-1) Централизация «пинить перед правкой существующего контента» ломает **редактирующие-на-удаление** правки. Сценарий: пользователь говорит in-app ассистенту «убери отсюда API-ключ / вычисти PII / удали конфиденциальный раздел». Слепое пред-пиннинг **сохранит удаляемый секрет** в восстановимую, расшаренную по правам агентскую версию — вычистка ничего не вычистит. Поэтому формулировка обязана содержать исключение: > «Не делай пред-сейв, если **цель** правки — **удалить** чувствительный/конфиденциальный контент (пиннинг сохранил бы то, что ты убираешь, в восстановимой истории). Пред-сейв — только для правок, которые **дополняют или пересматривают** контент.» ### Определение «раунда» (обязательно — иначе NEW-2) Пред-сейв на no-op безвреден, но **пост-сейв изменённого раунда — это реальная новая версия**, поэтому гранулярность «раунда» перестаёт быть бесплатной. Без чёткого определения `researcher` с его flush-циклом (`en.yaml:119–128`) при трактовке «flush ≈ раунд» наплодит 20–30 агентских версий на отчёт и утопит осмысленный финальный чекпоинт. Зафиксировать в промпте `researcher` конкретно: > «**Раунд** = первичный черновик и каждый последующий **крупный проход-ревизия** (цикл блока Revision), **НЕ** каждый flush/мелкая правка. Один пред-сейв + один пост-сейв на крупный проход, а не на микроправку.» ### Что делает каждая поверхность - **`tool-specs.ts` `savePageVersion.description` + `server-instructions.ts` HISTORY** — переписать на условную формулировку (триггер + карваут-на-удаление + «до и после»), сохранив описание no-op/skip-семантики. **Держать прозу простым английским + только зарегистрированные имена инструментов** — иначе reverse-drift-гвард #494 (`packages/mcp/test/unit/tool-inventory.test.mjs:145`, гоняется в CI) покраснеет на любом camelCase-токене, которого нет в реестре или в `PROSE_NON_TOOL_TERMS`. - **`researcher`** (en.yaml + английская строка в ru.yaml) — правило «до/после» + определение «раунда» (крупный проход, не flush). - **`call-summarizer`** (en.yaml + ru.yaml) — правило «до/после». Здесь пред-сейв **осмыслен и желателен**: он пинит сырую расшифровку как точку восстановления перед перезаписью её конспектом (V1 = расшифровка, V2 = конспект). Это фича, а не дефект: версия — это снимок, а не заявка на авторство; `kind='agent'` от подписанного actor консистентен модели #370. - **`index.yaml`** — поднять `researcher` **10→11**, `call-summarizer` **2→3** (числа явные, т.к. гвард из-за устаревшего лока их не заставит — см. техдолг). - **`content-hashes.json`** — обновить через `node scripts/check.mjs --update-hashes` (заодно чинит устаревший Stage-A-лок). ### Что НЕ вводим Новый механизм синхронизации 6 текстов — **не вводим**: это разные формулировки под разные аудитории (схема инструмента / серверные инструкции / персона роли), не производный mirror; единый триггер держим вручную. Никакого нового кода/примитивов — сам `save_page_version` уже есть. ## Границы scope - Только 6 текстовых мест + `index.yaml` (бамп 10→11 / 2→3) + `content-hashes.json` (рефреш). - Редакторские (comment-only) роли — не трогаем. - Билд-артефакты `packages/mcp/build/*` — **не коммитим**: не трекаются git (`git ls-files packages/mcp/build` = 0; `.gitignore` игнорит `packages/mcp/build/`; CI пересобирает `pnpm --filter @docmost/mcp build`). Сгенерированный `registry-stamp.generated.ts` тоже gitignored и пересобирается — коммитить нечего. - Подключение `check.mjs` к CI — **вне scope этого PR** (см. follow-up ниже), чтобы PR остался про формулировки. ## Критерии приёмки 1. `node agent-roles-catalog/scripts/check.mjs` печатает **OK** (версии `researcher`=11 и `call-summarizer`=3 в `index.yaml`; `content-hashes.json` обновлён и закоммичен). 2. grep по `researcher` и `call-summarizer` в **обоих** `en.yaml` и `ru.yaml` показывает и инструкцию «пинить ДО начала раунда» (с карваутом-на-удаление), и «пинить ПОСЛЕ»; в промпте `researcher` присутствует явное определение «раунда» (крупный проход, не flush). 3. `savePageVersion.description` (`tool-specs.ts`) и строка `HISTORY` (`server-instructions.ts`) содержат условное «пинить ДО начала правок существующего контента И ПОСЛЕ», включая исключение для удаляющих правок; ни один новый camelCase-токен не добавлен в HISTORY-прозу. 4. В `packages/mcp`: `tsc` — 0 ошибок; юнит-набор зелёный (`tool-specs.test.mjs`, `tool-inventory.test.mjs` вкл. #494-гвард, `save-page-version.test.mjs`). 5. Серверные спеки зелёные: `shared-tool-specs.contract.spec.ts` (динамически сверяет expose-описание с `spec.description`), `ai-agent-roles-catalog.provider.spec.ts` (синтетические фикстуры, реальные номера версий не хардкодит). ## Отказы и наблюдаемость - **Новых путей отказа в рантайме нет:** оба вызова идемпотентны (skip на пустой, promote/no-op на идентичной), инструмент уже возвращает структурированный результат. Видимость оператора не меняется. - **Безопасность fail-safe:** карваут-на-удаление (см. Дизайн) — единственный контроль, где «слепое поведение» опасно; дефолт — **не** создавать восстановимую копию удаляемого секрета. - **Дисциплинарный риск (не рантайм):** `check.mjs` не в CI → забытый бамп/устаревший лок дрейфит молча и блокирует распространение переписанного контента (см. техдолг). Митигируется явными числами версий в этом ишью + Критерием 1. **Рекомендуемый follow-up (отдельный PR):** добавить в CI шаг `node agent-roles-catalog/scripts/check.mjs`, чтобы гвард стал реальным гейтом. ## Совместимость и миграции - **Изменение дефолтной инструкции:** правка `server-instructions.ts` действует на **всех** агентов с deferred-инструментом `savePageVersion`, включая встроенного in-app ассистента под любой персоной — теперь их условно (только когда реально правят существующий контент) направляют пинить «до». Осознанно, по решению человека (Вариант B). Условная формулировка гарантирует, что comment-only роли, которые текст не правят, правилом не задеты. - Бамп версий ролей — сигнал потребителям каталога об обновлении (штатный механизм). Поведение самих страниц не меняется. Миграций БД нет. ## Решённые развилки - **Охват:** «роли + центральное описание» (Вариант B) — **решил человек** в сессии. Альтернатива «только промпты ролей» отклонена, чтобы правило было единым для всех редактирующих агентов, а не только для двух пишущих ролей. - **Оставить ли «до», раз в solo-потоке это часто no-op:** оставляем (явное требование человека «до и после»); переформулировано честно как дешёвая страховка, срабатывающая осмысленно ровно на непинённом пред-редакторном контенте — **дизайн** (после adversarial-разбора). - **Пиннинг сырой расшифровки у `call-summarizer` (kind=agent):** признан фичей (точка отката к пред-редакторному состоянию), не дефектом — **дизайн**. - **Карваут для удаляющих правок:** добавлен как fail-safe безопасности — **дизайн** (adversarial re-attack, NEW-1). ## Связи - Мета: **#370 ([feature][history][share] Версии страниц: ручной Save + idle-flush …)** — общий дизайн трёх уровней намеренности. - Базовый инструмент: **#565 (feat(#370 Stage A): MCP save_page_version — агентские версии страниц)**.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#579