feat(ai-chat)!: drop updateComment from the agent toolset

Editing an existing comment's text is irreversible (not version-tracked),
which breaks the agent's "only reversible operations" invariant. Remove the
updateComment tool that was added in the toolset-expansion change, leaving the
agent at 40 tools (comments: create/resolve only).

- Remove the updateComment tool from forUser().
- Remove updateComment from the DocmostClientLike interface.
- Reword SAFETY_FRAMEWORK: comments are create/resolve only; drop the
  comment-text-edit exception (keep the public-sharing one); keep the
  no-permanent-deletion guarantee and anti-prompt-injection rules.
- Tests: assert updateComment is NOT exposed (mirrors the deleteComment guard).
- docs(ai-agent-chat-plan): move updateComment to the "not exposed" list.
This commit is contained in:
vvzvlad
2026-06-17 06:03:19 +03:00
parent eefbf67288
commit b0997cb749
5 changed files with 15 additions and 31 deletions

View File

@@ -680,15 +680,15 @@ API AI SDK v6 + мост стрима (H3/M4/M5), снять аудит как
**Сделано.** Раньше агенту были доступны только 10 тулов (поиск, чтение страницы, грубый
CRUD страниц + create/resolve комментариев). Прокидываем в адаптер **все** оставшиеся
возможности клиента `@docmost/mcp` (`packages/mcp/src/client.ts`), КРОМЕ удаления
комментариев. Добавлены:
возможности клиента `@docmost/mcp` (`packages/mcp/src/client.ts`), КРОМЕ удаления и
редактирования комментариев. Добавлены:
- **чтение:** `getWorkspace`, `listSpaces`, `listPages`, `listSidebarPages`, `getOutline`,
`getPageJson`, `getNode`, `getTable`, `listComments`, `getComment`, `checkNewComments`,
`listShares`, `listPageHistory`, `getPageHistory`, `diffPageVersions`, `exportPageMarkdown`;
- **обратимая запись:** `editPageText`, `patchNode`, `insertNode`, `deleteNode`,
`updatePageJson`, `tableInsertRow`, `tableDeleteRow`, `tableUpdateCell`, `copyPageContent`,
`importPageMarkdown`, `sharePage`, `unsharePage`, `restorePageVersion`, `updateComment`,
`importPageMarkdown`, `sharePage`, `unsharePage`, `restorePageVersion`,
`transformPage`.
**Сознательно НЕ прокидываем:**
@@ -696,6 +696,9 @@ CRUD страниц + create/resolve комментариев). Прокидыв
- `deleteComment` — hard delete комментария, необратимо (запрошено явно: «кроме удаления
комментариев»). По той же причине у `transformPage` НЕ экспонируем опцию `deleteComments`
(захардкожен `false`).
- `updateComment` — редактирование контента комментария БЕЗ истории версий (необратимо) и
только своего. Сначала добавили по запросу «всё кроме удаления», затем убрали по
отдельному решению: необратимо и нарушает инвариант D2/D3 «агенту доступно только обратимое».
- `uploadImage` / `insertImage` / `replaceImage` — принимают **локальный путь на ФС сервера**
(`filePath`, НЕ URL). Для серверного агента это бесполезно (он не может положить файл на
хост) и потенциально опасно — по сути примитив чтения локальных файлов хоста.
@@ -709,10 +712,6 @@ filePath-тулам. Требует доработки клиента (новы
**Замечания (учесть при ревью/эксплуатации):**
- `updateComment` редактирует контент комментария БЕЗ истории версий — **необратимо**;
отступление от инварианта D2/D3 «агенту доступно только обратимое». Включено по явному
запросу (исключили лишь удаление). Серверная проверка прав остаётся: правится только свой
комментарий (`creatorId === authUser.id`).
- `sharePage` делает страницу **публично доступной**; возвращаемый `publicUrl` строится от
`apiUrl` адаптера (loopback `127.0.0.1`), поэтому для внешней ссылки нужен публичный хост
(`MCP_DOCMOST_API_URL`).