ADR-0013: Единая модель команд для CLI и MCP
Статус: Принято — 2026-09-24. Владелец поручил включить в архитектуру использование доверенных установленных расширений через CLI и агентами. Принятие закрепляет описанное решение; готовый адаптер MCP и новые результаты проверок не заявляются.
English | Русский
Контекст и задача
Заголовок раздела «Контекст и задача»Rukh — встраиваемое ядро именованного CLI с доверенными устанавливаемыми расширениями. Одна установленная возможность должна служить человеку и агенту без второй реализации команды, отдельного сервера и другой модели доступа. Небольшой команде достаточно локальной конфигурации; службы организации для входа и проверки прав остаются дополнительными интеграциями.
Текст CLI, завершение процесса и типизированный исход команды недостаточны как общий программный результат. Агенту также нужны объявленные входные данные, предсказуемые результаты, явные требования к взаимодействию и безопасная обработка устаревшего инструмента. Список инструментов не выдаёт права исполнения и не закрепляет изменяемую реализацию. Решение уточняет ADR-0002, 0003, 0006, 0007 и 0010; полномочия задачи, обеспечение ограничений и последствия определяются ADR-0014–0016.
Критерии выбора
Заголовок раздела «Критерии выбора»- Одна идентичность команды, объявление, проверка смысла входных данных и путь исполнения для CLI и MCP.
- Формирование инструментов из проверенных установленных и активных расширений; публикацией и доступом управляет владелец.
- Без обязательного сервера, учётной записи, службы базы данных, планировщика агента или поставщика модели.
- Получение списка не исполняет код, не готовит среду, не запрашивает контекстную справку и не начинает вход.
- Ограниченные результаты, текущие права и отсутствие скрытого перенаправления или повторения действий.
Рассмотренные варианты
Заголовок раздела «Рассмотренные варианты»| Вариант | Преимущество | Ограничение |
|---|---|---|
| Агент запускает произвольный текст CLI | Подходит многим программам | Теряются типизированные контракты; фактическим инструментом становится доступ к оболочке |
| Каждое расширение содержит собственный MCP-сервер | Полная самостоятельность интеграции | Повторяются обнаружение, учётные данные, политика, версии и надзор |
| Единая допущенная модель команд отображается в CLI и MCP | Общие контракты и простой локальный вариант | Нужны явные правила результатов, публикации и адаптера |
Решение
Заголовок раздела «Решение»Источником остаётся установленная модель команд. CLI и MCP — её доверенные представления, входящие в одно ядро вызовов. MCP является выбираемым владельцем средством именованного приложения, а не другим видом расширения или способом регистрации привилегированного кода из расширения.
Принятая схема показывает одну реализацию команды с двумя путями входа.
Объявление и совместимость
Заголовок раздела «Объявление и совместимость»rukh.extension/2 из ADR-0006 сохраняет идентичность команды и грамматику входных данных версии 1 и добавляет следующие поля. Описание версии 1 остаётся пригодным для поддерживаемого варианта CLI. Программный контракт ему не приписывается: издатель выпускает версию 2 либо владелец объявляет отдельную доверенную встроенную обёртку. Старый проверяющий компонент отклоняет версию 2 как неподдерживаемую вместо игнорирования новых требований.
| Поле | Смысл |
|---|---|
commands[].execute.result | kind: text или kind: structured; для структурированного результата обязательна schema, определённая ниже. Поле обязательно для команды, пригодной к программному вызову |
commands[].machine | eligible, interaction (none, optional, required) и requiredFeatures с точными идентификаторами и версиями зарегистрированных возможностей; отсутствие равнозначно eligible: false |
| Требования исполнения | Существующие запросы действий и ресурсов, а также обязательные контракты задачи, последствий и ограниченного исполнения из ADR-0014–0016. Объявления запрашивают поддержку и доступ, но не предоставляют их |
Базовый программный вызов требует объявленных входных данных, поддерживаемого управляемого варианта исполнения, времени жизни foreground и согласованной возможности command-result/1. Группа не становится инструментом. Прямые альтернативные имена сохраняют одну каноническую команду и не создают дополнительные инструменты. Программы с прямой передачей аргументов остаются доступны через CLI, но автоматически не публикуются как инструменты оболочки или произвольного argv. Встроенной обёртке владельца нужны собственный типизированный контракт, реальные гарантии и проверки прав; переименование непрозрачной программы не ограничивает её действия.
В CLI существующий лексический разбор формирует типизированные значения. В MCP свойства объекта — стабильные ID параметров, а не имена флагов или строки позиций. Адаптер отклоняет неизвестные свойства и неподходящие типы JSON, отмечает явно переданные ID, применяет объявленные значения по умолчанию и нормализацию точных чисел, затем использует ту же проверку смысла данных. Он не собирает команду оболочки, не преобразует значения в argv и не разбирает их повторно. null не означает отсутствие; границы целых, конечные binary64, точные десятичные строки, порядок списков и Unicode подчиняются ADR-0006. Схемы входа формируются в JSON Schema 2020-12 с закрытым корневым объектом. Проверка ядра обязательна и после проверки на стороне клиента.
Ограниченный результат команды
Заголовок раздела «Ограниченный результат команды»command-result/1 дополняет отчёт управляемого исполнения полем commandResult. Оно содержит ровно {kind: text, text} либо {kind: structured, data} согласно объявлению результата. Поле обязательно при succeeded, необязательно при command_failed и проверяется при каждом наличии. В describe его нет: контракт структурированной справки остаётся отдельным. Неверный или отсутствующий обязательный результат означает execution_failed, если ранее не принята отмена. Отчёт, выход процесса и очистка по-прежнему должны согласоваться; получение верных данных ещё не означает окончательного успеха.
Схема результата использует ограниченное подмножество JSON Schema 2020-12: type — одно из object, array, string, boolean, integer, number, null; объекты имеют явные properties, необязательное required и additionalProperties: false; массивы — одну схему items и конечное maxItems. Разрешены применимые minimum, maximum, minLength, maxLength, minItems, enum, title, description. Ссылки, сетевое разрешение, рекурсивные схемы, регулярные выражения, код, приведение типов, значения по умолчанию и композиция схем в схемах издателя запрещены. Неизвестные ключевые слова отклоняют описание. Каждая схема явно задаёт один type; поля ограничений допустимы только для него. required содержит уникальные объявленные свойства, enum — непустой уникальный набор значений того же типа, удовлетворяющих остальным ограничениям; счётчики длины и количества — неотрицательные целые, нижняя граница не больше верхней. Числа и Unicode подчиняются ADR-0006. Общие пределы данных действуют и там, где для скаляра не задан меньший предел.
Выбраны следующие пока не измеренные значения: 64 КиБ на схему результата, 128 КиБ UTF-8 на commandResult, глубина 16 и 2 048 членов объектов и элементов массивов суммарно для схемы или результата, 100 мс фактического времени проверки результата. Меньшие пределы владельца и исполнителя сохраняются; полное сообщение IPC должно помещаться в ограничения ADR-0003. Превышение даёт ошибку, а не усечённый успешный результат. Проверка ограничена независимо от обработчиков издателя, поскольку они при ней не вызываются.
Отчёт о завершении и результат команды проверяются при получении, до фиксации окончательного исхода вызова. Проверенные данные публикуются или используются вызывающей стороной только после обязательного завершения. Ни stdout, ни stderr не распознаются как JSON и не превращаются в этот результат. Потоки байтов CLI сохраняют прежнее поведение. Базовый MCP даёт вызову закрытый stdin и не предоставляет терминал; stdout/stderr отдельно вычитываются в ограниченную диагностику под управлением владельца, никогда не попадают в MCP stdout и автоматически не возвращаются в контекст агента. После исчерпания места диагностики вычитывание продолжается, потери учитываются. Для программной совместимости команда, которой нужен конвейерный ввод, должна предоставить объявленный параметр или допущенную операцию над ресурсом.
Публикация владельцем и текущий допуск
Заголовок раздела «Публикация владельцем и текущий допуск»Инструмент существует, только если его выпуск доверенный, установленный, активный и совместимый, объявление допускает программное использование, а утверждённый профиль разрешает публикацию. Для встроенных команд действуют равнозначные объявления и проверки. Пригодность не означает установку, публикацию, видимость или право исполнения.
Базовый профиль владельца выбирает явные идентичности команд или утверждённые наборы пакетов, допустимые шаблоны задач, пределы ресурсов и профиль исполнения из ADR-0015. Метаданные обычного расширения не могут публиковать управление ядром. Управление входом, изменение доверия и источников, установка, выдача задач, управление делегированием, подтверждениями и правами исключены из общих агентных шаблонов; публикация встроенной административной операции требует отдельного полномочия и явного профиля. Обычная задача не может расширить себя через такие операции.
Описания инструментов и аннотации MCP — ограниченные сведения издателя, а не инструкции для приложения, доказательство безопасности действий или разрешение. Rukh не обещает, что агент проигнорирует вредоносный текст. Обязательные ограничения независимо выводятся из доверенных правил владельца и допущенных реализаций операций. Права проверяются при каждом вызове и защищаемой операции, даже если инструмент только что был показан. Недоступная обязательная проверка видимости возвращает явную ошибку списка, а не успешный пустой или частичный список, скрывающий сбой. Статические описания не включают секретные настройки профиля или данные другого участника.
Адаптер привязывает taskAuthorityRef, субъекта и действующего участника через доверенный контекст приложения по ADR-0014. Утверждения об идентичности и новые права из аргументов инструмента или clientInfo не принимаются. Локальная точка stdio имеет одну неизменяемую утверждённую привязку запуска и шаблон задачи; смена конфигурации её не подменяет. Удалённая точка проверяет полномочие запроса. Выбор ссылки на существующую задачу не даёт права выдать новую. У агентного приложения вне Rukh могут быть другие инструменты; ограничения Rukh не распространяются на эти независимые пути.
Совместная публикация и устаревшие имена
Заголовок раздела «Совместная публикация и устаревшие имена»ADR-0007 публикует одну activeProfileRevision, связывающую конфигурацию и commandGeneration. Теперь до той же фиксации кандидат проверяет маршруты CLI и допустимое представление MCP. Представление можно вычислять и хранить по этой ревизии; отдельного изменяемого указателя активной версии у него нет. Изменение только политики публикует новый профиль и повторно проверяет инструменты. Текущая видимость для субъекта вычисляется поверх представления, а не сохраняется в нём как разрешение.
Имя MCP имеет вид slug__fingerprint: понятная часть из [a-z0-9_-] длиной не более 48 символов и полный отпечаток SHA-256 из 64 шестнадцатеричных символов нижнего регистра. Отпечаток вычисляется от канонического по RFC 8785 JSON-массива ["rukh.mcp-tool/1", endpointNamespace, activeProfileRevision, canonicalCommandIdentity]. Владелец назначает стабильное пространство имён точки подключения; профиль уже связывает точный выпуск или сборку, описание, вариант исполнения, размещение команд и утверждённые настройки представления. Имя укладывается в предел MCP 128 символов. Отображаемое название остаётся понятным. Совпавшие имена или противоречивые привязки отклоняют публикацию; суффикс по порядку установки запрещён. Это осторожное правило меняет имена при любой ревизии профиля, в том числе при изменении только политики.
tools/call разрешает точное имя в текущем представлении и закрепляет профиль, выпуск и объявление через существующую операцию захвата и удержания ссылок. Неизвестные, устаревшие и сейчас невидимые имена получают одинаковый безопасный ответ о неизвестном инструменте без раскрытия скрытых сведений. Удалённое имя никогда не вызывает новый выпуск по похожему префиксу. Уже допущенные вызовы сохраняют закреплённый выпуск, а дальнейшие действия проходят ADR-0012. Актуальное имя не доказывает право его использовать.
Начальный контракт адаптера — MCP 2026-07-28. Список не зависит от истории соединения: адаптер использует текущий профиль и видимость, разрешённую запросу, а не замороженный набор для сеанса. Порядок имён определён однозначно; используются только статические метаданные. Ограниченные и защищённые от подмены указатели страниц связывают ревизию профиля, контекст видимости и позицию; изменение привязки делает указатель недействительным и требует нового списка. Базовая страница содержит не более 32 инструментов и 1 МиБ закодированных данных. Описание одного инструмента обязано помещаться в страницу. Инструменты MCP.
Для базового обнаружения и списков используются ttlMs: 0 и cacheScope: private. Подписанные клиенты могут получать извещения об изменении публикации, но доставка извещения и свежесть сохранённого списка не участвуют в выдаче прав. listChanged объявляется только при реализованном пути подписки. Хранение результатов MCP.
Приложение MCP, результаты и остановка
Заголовок раздела «Приложение MCP, результаты и остановка»Локальный вариант — выбранный владельцем режим именованного CLI через stdio. Ему не нужны сетевой приёмник, постоянная служба, вход, служба базы данных или отдельные серверы расширений. Внешний протокол использует правила сообщений MCP; внутренний канал дочернего процесса сохраняет закрытый канал и аутентификацию ADR-0003. Напрямую эти каналы не соединяются. Протокольный stdout принадлежит только приложению. Сообщения запуска, диагностика и вывод дочерних процессов не могут его повредить. MCP stdio.
HTTP-адаптер необязателен и должен реализовать выбранные контракты MCP для авторизации, происхождения и проверки запросов. Он проверяет каждый запрос, получает привязки участника, субъекта и задачи через доверенные интеграции и не пересылает входящий bearer-токен в код расширения или нижележащие службы. Включение локального MCP не включает HTTP. Интеграции OIDC/OAuth и собственные привязки организации остаются ответственностью ADR-0005/0011. Авторизация MCP.
Выбранная версия MCP использует явные версию и контекст каждого запроса и server/discover, а не неявный протокольный сеанс. Поддержка прежней версии требует отдельно проверенного сопоставления адаптера; менять права и смысл вызова Rukh оно не может. Вызов инструмента возвращает resultType: complete только после окончательного завершения. Сформированная outputSchema задаёт закрытый объект ядра: invocationId, outcome, необязательные reason, проверенный commandResult и безопасные ссылки на последствия по ADR-0016. Сформированная схема описывает оболочку commandResult ({kind: text, text} либо {kind: structured, data}); объявленная издателем схема структурированного результата применяется к полю data. Оболочка обязательна при успехе. Тот же объект сериализуется в текстовый блок для клиентов, читающих текст. Данные издателя не могут задать или заменить исход и идентичность, принадлежащие ядру.
| Наблюдение | Поведение на границе MCP |
|---|---|
| Неверное протокольное сообщение или неизвестный/устаревший инструмент | Стандартная ошибка протокола JSON-RPC; команда не передаётся |
| Известная команда не прошла проверку данных, поддержки или текущих прав | Завершённый результат инструмента с isError: true, rejected и безопасной диагностикой; код расширения не запускается |
Окончательный succeeded | Завершённый результат с isError: false и проверенными данными |
command_failed или execution_failed | Завершённый результат с isError: true; исход и неопределённость сохраняются, автоматический повтор не предлагается |
| Внутренний срок или отмена владельца при ещё действующем канале ответа | Завершённый результат ошибки с cancelled и стабильной причиной; ложного успеха нет |
| Отмена клиента принята до окончательной фиксации | Остановка по ADR-0004, сохранение внутреннего окончательного исхода; после принятия транспортной отмены ответ инструмента не отправляется |
Извещение отмены stdio относится только к ожидающему запросу этого клиента. Разрыв потока HTTP-запроса отменяет его вызов; полная потеря локального транспорта закрывает области исполнения приложения. Неизвестные ID отмены не влияют на других клиентов. Сохраняется первая принятая причина и существующий невозобновляемый срок остановки. Зафиксированный результат не изменяется из-за потери доставки; такая потеря не доказывает откат. ID запросов связывают сообщения, но не являются ID действий. Отмена MCP.
Базовый вариант неинтерактивен: обязательные диалоги и представления делают команду недоступной через этот адаптер; необязательное взаимодействие получает обычный результат недоступности операции. Терминал не открывается, ответ не придумывается. Продолжение многоэтапных запросов через input_required, requestState, inputResponses в этом профиле не поддерживается; неожиданные данные продолжения отклоняются до передачи команды. Для поддержки нужен явный контракт продолжения, сохраняющий один вызов и идентичность действия. Новый ID запроса никогда не разрешает повторить последствия. Обязательное подтверждение человека поступает по доверенному пути ADR-0016, а не как ответ агента на собственный вопрос.
Приложение использует конечные пределы параллелизма и удерживаемых вызовов ADR-0010 без неявной очереди исполнения. Дополнительные выбранные, но не измеренные транспортные значения: 1 МиБ на входящее сообщение, 2 МиБ на закодированный ответ, 32 исходящих сообщения или 4 МиБ очереди, 2 секунды на частичное чтение от первого байта или заблокированную запись от её начала без продления при продвижении, 30 секунд на обнаружение или список. Внешний разбор также отклоняет неверный UTF-8, повторяющиеся ключи, недопустимый Unicode и числа; до передачи данных он ограничивает структуру глубиной 32 и 4 096 членами/элементами. Входные данные вызова сохраняют меньшие пределы ADR-0006. Владелец может ужесточить совместимые ограничения. Каждый вызов имеет конечный срок из утверждённого шаблона задачи; сообщения о ходе работы его не продлевают. Перегрузка не может блокировать приём отмены и управление жизненным циклом; если управление невозможно, транспорт закрывается, а принадлежащие приложению вызовы завершаются.
Принятая последовательность разделяет публикацию списка, окончательный допуск и завершение.
Последствия
Заголовок раздела «Последствия»- Команды реализуют одну возможность и могут публиковать её через оба интерфейса без дополнительных серверов.
- Существующие расширения CLI сохраняются; программная публикация требует осознанного версионного объявления и профиля владельца.
- Имена с отпечатком и осторожные правила хранения списка уменьшают стабильность контекста модели, обеспечивая явное отклонение устаревшей привязки.
- Текстовый результат подходит простым расширениям. Структурированные данные улучшают совместимость, не превращая терминальный текст в протокол.
- Локальное исполнение с доверием к программе и более строгие профили ограничения различаются. Аннотации MCP и успешный разбор не доказывают изоляцию, безопасность смысла действий или намерение человека.
- Решение не вводит планировщик, среду модели, удалённый шлюз, службу фоновых заданий, sampling, произвольные MCP Apps или контроль движения данных.
Подтверждение
Заголовок раздела «Подтверждение»Владелец принял архитектурное направление 2026-09-24. Следующие проверки остаются невыполненными требованиями к реализации:
- Одно расширение получает равнозначные входные данные и идентичность из CLI/MCP, включая пропуски, значения по умолчанию, явные ID, списки, Unicode и точные числа. Прямая передача аргументов, неизвестные поля и неподдерживаемые требования не обходят допуск.
- Список не запускает код и не готовит среду. Правила публикации и задачи действуют для встроенных команд и расширений; описания, имена клиентов и аннотации инструментов не дают прав.
- CLI и MCP публикуются одной операцией профиля. Параллельные обновления, изменения политики, страницы, устаревшие имена и видимость не перенаправляют вызов и не раскрывают список другого участника.
- Нарушение схемы результата, пределов размера или проверки, шумные потоки и неподдерживаемое взаимодействие сохраняют определённые исходы и не повреждают MCP stdout. Текст и структурированные данные соблюдают одинаковое окончательное завершение.
- Параллельные запросы, отмена, потеря приложения или ответа и сроки сохраняют один исход, ограниченную очистку и гарантии последствий ADR-0016 без повторов. Строгие профили отклоняют недоступные ограничения.
- Показать локальный CLI со статическим каталогом без корпоративных служб. Отдельно проверить каждую поддерживаемую версию протокола и дополнительный HTTP-адаптер, включая привязку вызывающего, предназначение токена и отсутствие его сквозной передачи.
Прежние эталонные проверки ADR-0002/0003 не покрывают эту возможность и промышленный адаптер MCP. Отрисованные диаграммы и корректная документация не доказывают соответствие продукта.
- ADR-0002: Взаимодействие ядра и расширений, ADR-0003: IPC процессов.
- ADR-0006: Описание расширений, ADR-0007: Загрузка и обновление, ADR-0010: Сборка CLI.
- ADR-0014: Полномочия задачи и делегирование, ADR-0015: Ограничение исполнения, ADR-0016: Фиксация действий и проверка результата.
- RFC 8785: JSON Canonicalization Scheme.