Перейти к содержимому

Конвенции справочника

Общие понятия, на которые ссылаются страницы методов. Здесь — канон; на страницах методов даются только ссылки сюда.

Уровни доступа (middleware)

Каждый эндпоинт защищён одним или несколькими middleware (server/auth/middleware.js). В блоке инвентаря страницы метода поле Auth показывает их как есть из кода.

MiddlewareСмысл
optionalAuthАноним (гость) и авторизованный допускаются. Гостю PG отдаёт только его guest-данные.
requireAuthТолько авторизованный пользователь (есть сессия-cookie или валидный токен).
requireProjectAccessЗагружает проект и проверяет доступ читателя; уровень (read/write) кладёт в req.projectAccess. Точную запись (owner/spaceman/org_admin) досматривает PG-функция.
requireSiteAdminТолько site-admin с активной TOTP-сессией. Токену недоступно ни на одном scope.

Внутри write-хендлеров часто есть дополнительная проверка: для guest-спейса — заголовок X-Guest-Projects (claim на конкретный проект), для владельческих проектов — req.projectAccess === 'write'. Точные правила ролей — в матрице RP (источник истины разрешений) и в секции «Для человека» каждого метода.

Scope токена (агентный доступ)

Агент ходит под токеном владельца — с теми же правами, что у него в UI.

ScopeЧто можно
readТолько GET.
read_writeGET + мутации (POST/PUT/PATCH/DELETE), в пределах роли владельца.

Никакому токену на любом scope недоступны site-admin-операции (by design). Часть org-admin write-операций в v1 закрыта на уровне agent-gate (server/auth/agentGate.js). Детали — в путеводителе для агента.

Формат ответа для агента

  • Cookie-клиент (браузер) всегда получает JSON.
  • Токен с Accept: text/markdown (или ?format=md) получает Markdown-зеркало ресурса (server/agent/negotiate.js). У ресурсов есть ETag; повтор с If-None-Match304 (экономия токенов).
  • Блок ## Actions в Markdown-ответе перечисляет только действия, доступные данному токену (его scope и роль владельца) — см. server/agent/affordances.js.

Агентные конвенции записи

Эти правила касаются только запросов под токеном (Bearer). Cookie-клиент (браузер) ими не затронут: у фронта свои подтверждения и оптимистичная блокировка. Реестр операций и их риск — server/auth/opRegistry.js.

Ось риска (risk)

Каждая write-операция помечена риском. Метка видна в блоке ## Actions Markdown-ответа (см. server/agent/affordances.js):

РискЧто этоПримеры
SAFEОбычная запись/обновление/восстановлениеcreate/update/upsert, restore из корзины или версии, set-context, cancel-job
DESTRUCTIVEОбратимое удаление/снятие/отзывsoft-delete в корзину, remove участника, revoke, удаление ребра
IRREVERSIBLEНеобратимое уничтожение/сбросpermanent-delete из корзины, reset спейса к исходному
COSTLY_LLMЗапускает платную LLM-генерациюgenerate/regenerate графа, doc-content generate/inline-edit, suggest-prompt

Confirm-гейт (409)

Операции с риском IRREVERSIBLE или COSTLY_LLM требуют от токена явного подтверждения: пришлите {"confirm": true} в теле. Без него — 409 (RFC 9457 application/problem+json) с полями op и risk. Принимается только литеральное булево true собственным свойством тела (не строка "true", не 1). Гейт стоит выше роутеров, поэтому SSE-генератор (COSTLY_LLM) получает 409 до открытия text/event-stream — ответ приходит обычным JSON (server/auth/confirmGate.js).

Оптимистичная блокировка (If-Match412)

Опционально: перед PUT /api/projects/{id}, PUT /api/collections/{id} или PATCH …/doc-content/{node} можно прислать If-Match: "<ETag>" (ETag берётся из предыдущего чтения ресурса). Если ресурс изменился параллельно — 412 (precondition_failed), перечитайте и повторите. Заголовок опциональный: без него поведение прежнее. Маркер версии — updated_at ресурса; граф проекта не двигает updated_atIf-Match защищает метаданные (заголовок/промпт/спейс, поля коллекции, содержимое блока), не топологию графа (server/agent/ifMatch.js).

Асинхронный режим долгих генераций (?mode=async202 + poll)

Долгие генерации по умолчанию стримят SSE. Токен может вместо этого запросить фоновую постановку: добавьте ?mode=async к запросу генерации — вместо SSE придёт 202 {job_id, poll}. Дальше опрашивайте статус по poll-URL (GET …/jobs/{jobId}); статусы pending → running → succeeded|failed|canceled. Отменить — POST …/jobs/{jobId}/cancel (best-effort: генератор без канала прерывания может доработать, результат сохранится). Poll-ответ leak-безопасен: он не отдаёт actor_snapshot, request_body, token_id — только статус, прогресс и время. Задача принадлежит своему ресурсу (IDOR-защита по resource_type + resource_id). Async-режим доступен только токену; cookie-клиент всегда получает SSE. Инфраструктура — server/services/jobRunner.js, таблица generation_job.

Экспонирующие операции — только через человека (403)

Шеринг (/share), перенос проекта (/transfer, /transfer-owner) и публичность коллекции (is_public) недоступны токену на любом scope — они делают ресурс видимым за пределами текущих прав и требуют одобрения человека. Токену такой запрос отвечает 403 (для is_public — жёсткий 400/403). Это не confirm-гейт: агент не может подтвердить сам, канала внешнего одобрения пока нет (server/auth/opRegistry.jsWRITE_DENY_HUMAN_APPROVAL).

display label ≠ system key

Видимая надпись (заголовок H1, текст кнопки) — это отображение; слаг id:, имя PG-функции, ключ в коде — это системные ключи. Переименование надписи не меняет системный ключ, и наоборот. Слаги страниц — системные ключи: они постоянны, на них ссылаются снаружи.

Роли

Шесть ролей системы: guest, employee, spaceman (менеджер спейса), supervisor (наблюдатель, read-only), org_admin, site_admin. Подробно — roles.


Витрина продукта · Версия для агента (raw markdown) →