role-edit · diff

git:20260901.7502a05 to git:20260908.2565dd2

87 added, 48 removed. Audit A to A.

---
name: role-edit
description: Типизированно изменить права существующей роли 1С по логическому адресу, сохранив RLS, шаблоны и остальные права.
- argument-hint: <sourceSet> <metadataPath> <operations>
+ argument-hint: <at> <operations>
allowed-tools:
- Read
- Glob
---
# /unica:role-edit — точечное редактирование прав роли
## MCP routing
- - Preferred path: use MCP `unica` tool `unica.role.edit`.
- - Выбирайте роль только через `sourceSet + metadataPath` вида `Role.<Имя>`.
- Физический `Rights.xml` — внутренняя деталь разрешителя.
- - Передавайте непустой упорядоченный массив `operations`; сейчас его закрытый
- вариант — `setRight` с `objectName`, `right` и булевым `value`.
- - Вызов по умолчанию строит preview. Передавайте `dryRun: false` только когда
- пользователь явно попросил применить изменение.
- - Читайте `metadataPath`, `changed`, `effects` по `operationIndex`,
- `validation` и `diagnostics` из `structuredContent.data`. `stdout`, diff и
- физический путь не являются контрактом результата.
- - Не передавайте снятые top-level поля `RightsPath`, `Path`, `ObjectName`,
- `Name` и `Value`; schema и parser обязаны их отклонить.
- - `sourceSet` — имя набора исходников из `v8project.yaml`, а не константа.
- Получите его через `unica.view {}`; `"main"` ниже — только пример.
+ - Preferred path: use MCP `unica` tool `unica.apply` с операцией `right.set`.
+ - Роль называет адрес: `args.at` вида `<набор>:Role.<Имя>`. Физический
+ `Rights.xml` — внутренняя деталь; наружу путь отдаёт только аварийный
+ `unica.resolve`, и в обычном ходе работы он не нужен.
+ - Имя набора даёт `unica.view {}`, адрес роли по имени —
+ `unica.search {corpus: "names", kind: "Role"}`. `"main"` ниже только пример.
+ - Всегда сначала `dryRun: true`. Применяй `dryRun: false` только когда
+ пользователь явно попросил внести именно эту правку, и только с `ifRev` из
+ предпросмотра.
+ - Читай из ответа `changed`, `effects` по порядку операций и диагностики.
+ Физический путь и diff контрактом результата не являются.
- ## Вызов
+ ## Операция `right.set`
+ `args.values` принимает `object`, `right` и хотя бы одно из `value` и `rls`:
+
+ | Поле | Что задаёт |
+ |---|---|
+ | `object` | Объект метаданных, например `Catalog.Демо` |
+ | `right` | Имя права, например `Delete` |
+ | `value` | Булево значение права |
+ | `rls` | Условие ограничения записей |
+
+ Операции выполняются по порядку и публикуются одной транзакцией: либо все,
+ либо ни одной. Повтор эквивалентной операции даёт `changed: false` без записи.
+
+ **Объект, ещё не перечисленный в роли, добавляется сам.** Прежний писатель
+ отказывал `object_not_listed` и требовал сперва внести объект Конфигуратором;
+ канонический `right.set` заводит объектный блок вместе с правом.
+
+ Платформа хранит объектное право только со значением, отличным от умолчания
+ роли `setForNewObjects`. Поэтому `right.set` со значением умолчания (обычно
+ `false`) удаляет элемент права вместе с его RLS, а опустевший объектный блок —
+ целиком; если право уже отсутствует, это законный no-op.
+
+ Зависимости прав платформы писатель не моделирует: «ввод по строке» требует
+ «просмотра», и состояние, нарушающее матрицу зависимостей, платформа молча
+ дополнит при импорте. Следи за парными правами сам.
+
+ Для `DataProcessor.*` значение `Use=false` применяет правило платформы:
+ удаляется весь объектный блок вместе с зависимым правом `View`. На другие виды
+ объектов и права это не обобщается.
+
+ ## MCP examples
+
+ ### Предпросмотр
+
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
- "name": "unica.role.edit",
+ "name": "unica.apply",
"arguments": {
- "sourceSet": "main",
- "metadataPath": "Role.Демо",
- "operations": [
+ "at": "main:Role.Демо",
+ "ops": [
{
- "op": "setRight",
- "objectName": "Catalog.Демо",
- "right": "Delete",
- "value": false
+ "op": "right.set",
+ "args": {
+ "at": "main:Role.Демо",
+ "values": {
+ "object": "Catalog.Демо",
+ "right": "Delete",
+ "value": false
+ }
+ }
}
],
"dryRun": true
}
}
}
```
- Операции выполняются последовательно и публикуются одной транзакцией. Writer
- проверяет право для вида `objectName` до изменения XML, сохраняет RLS,
- templates, глобальные флаги, остальные объектные блоки и права. Повтор
- эквивалентной операции даёт `changed: false` без записи.
-
- Платформа хранит объектное право только со значением, отличным от умолчания
- роли `setForNewObjects`. Поэтому `setRight` со значением умолчания (обычно
- `false`) удаляет элемент права вместе с его RLS, а опустевший объектный блок —
- целиком; если право уже отсутствует или объект не перечислен в роли, это
- законный no-op. Право со значением, отличным от умолчания, записывается явно.
-
- Ограничения, о которых стоит помнить:
-
- - Writer не создаёт отсутствующий блок `object`: выдать роли право на объект,
- который в `Rights.xml` ещё не настроен, нельзя — вызов отвечает
- `object_not_listed`. Сначала перечислите объект в роли Конфигуратором или
- `unica.role.compile`.
- - Writer не моделирует зависимости прав платформы (например, «ввод по строке»
- требует «просмотра»). Состояние, нарушающее матрицу зависимостей, платформа
- молча дополнит при импорте — следите за парными правами сами.
+ ### Право с ограничением записей
- Для `DataProcessor.*` операция `Use=false` применяет правило платформы:
- удаляется весь объектный блок вместе с содержащимся в нём зависимым правом
- `View`. Это не обобщается на другие виды объектов или права. Неподдерживаемое
- сочетание завершается диагностикой без частичной мутации.
+ ```json
+ {
+ "jsonrpc": "2.0",
+ "method": "tools/call",
+ "params": {
+ "name": "unica.apply",
+ "arguments": {
+ "at": "main:Role.Демо",
+ "ops": [
+ {
+ "op": "right.set",
+ "args": {
+ "at": "main:Role.Демо",
+ "values": {
+ "object": "Document.Заказ",
+ "right": "Read",
+ "value": true,
+ "rls": "ГДЕ Автор = &Пользователь"
+ }
+ }
+ }
+ ],
+ "dryRun": false,
+ "ifRev": "<rev из предпросмотра>"
+ }
+ }
+ }
+ ```