В справочнике операции при каждом исключённом виде стояла причина: «порядок
разделителей задаёт порядок параметров сеанса», «порядок в панели», «порядок
мультиязычных строк». Позицию вставки выбирает проект, а не модель, — в инструкции
навыка этому места нет. К тому же документальное основание есть только у
CommonAttribute (исключение самого стандарта), остальные три — наш вывод из замеров,
и подавать его как факт тем более не следовало. Осталось перечисление видов.
Заодно сняты два утверждения, которые предыдущая правка сделала ложными: «взаимный
порядок групп видов навыки не меняют вовсе» в гайде и та же фраза в докстрингах обоих
портов — рядом с реализацией, которая ровно это и делает. Формулировка про четыре вида
в гайде уточнена: не сортируются их ИМЕНА, положение самой группы канонично всегда.
Обоснования остаются в docs/v8-project-guide.md, где решение принимает человек.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
Настройка newObjectPosition не чинит накопленное, а собранная навыками конфигурация
могла держать группы видов не в каноне — первая же выгрузка платформы давала диф.
Теперь вызов без значения приводит в порядок и сами группы. Вызов с явным видом этого
не делает: назвали вид — операция остаётся точечной и трогает только имена внутри него.
Приём тот же, что уже работал для имён: переставляется содержимое существующих узлов, а
не сами узлы, поэтому отступы и структура файла не меняются, а диф остаётся перестановкой
строк. Отличие в том, что меняется и имя тега: в py это присваивание el.tag, в PS имя
элемента неизменяемо, поэтому узел заменяется через ReplaceChild — он сохраняет
окружающие пробельные узлы на месте (тот же приём, что в meta-edit.ps1).
Проверки: порты дают байт-в-байт одинаковый файл; повторный прогон пишет Modified: 0 и
не меняет ни байта; на боевой выгрузке УТ (13 979 строк) команда сообщает Modified: 0 —
там уже канон, и Bot остался между DefinedType и CommonCommand. Раундтрип через
платформу 8.3.24: отсортированная конфигурация вернулась побайтово той же, то есть наш
канон совпадает с платформенным и сортировка не создаёт работы следующей выгрузке.
Правило видов с осмысленным порядком продолжает действовать для ИМЁН: в раундтрипе языки
остались как были. Положение самой группы оно не регулирует — это порядок платформы.
Три прежних кейса фиксировали поведение «группы не трогаем» и переписаны по факту.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
Правило «Subsystem не упорядочиваем» распространено на четыре вида и вынесено в
семью is_order_sensitive_type / Test-OrderSensitiveType: раньше литерал "Subsystem"
был размазан по четырём точкам — регистрация в Register-InChildObjects,
add-childObject, заимствование в расширение и сортировка.
CommonAttribute — исключение самого стандарта #std467: у общих реквизитов-разделителей
порядок в дереве задаёт порядок установки параметров сеанса
(https://github.com/1C-Company/v8-code-style/issues/78). Единственный из четырёх, где
сортировка ломает поведение, а не только диф.
CommandGroup и Language добавлены по замерам. В ACC 15 живых групп команд из 39 не
перечислены ни в одном GroupsOrder — как и подсистемы, они падают на порядок дерева.
Порядок языков задаёт порядок <v8:item> в мультиязычных строках по всей выгрузке.
Прежний вывод «сортировать их безопасно» опирался на стендовый прогон, где не было
ни подсистем (а значит и CommandInterface.xml), ни второго языка у объектов: ломаться
там было нечему, и отсутствие изменений ничего не доказывало.
PaletteColor сортируется — это переменные цветов.
Второе послабление стандарта (объекты «Удалить*» можно держать в конце ветки) не
реализуем: типовые им не пользуются — в ACC 360 таких объектов из 373 стоят по
алфавиту, а сортировка стандарту не противоречит. Оговорено в гайде.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
Резолвер настройки искал файл от каталога конфигурации и лишь потом от cwd —
единственное место в репозитории с таким отсчётом. Остальные ищут от рабочего
каталога: support-guard (18 навыков) с фолбэком на каталог конфигурации, группа
db-* (5 навыков) вообще без фолбэка, потому что каталога конфигурации у них нет.
Обоснование прежнего порядка («cwd почти всегда чужой проект») опиралось на нашу
стендовую раскладку — вызов из репозитория навыков по выгрузке в cfsrc. У
пользователя cwd и есть каталог проекта с .v8-project.json, а скрипт навыка
зовётся по абсолютному пути и cwd не меняет, так что оба порядка эквивалентны.
Кейс cfe-borrow/newobjectposition-byname клал настройку внутрь каталога расширения
и тем закреплял несуществующую раскладку — конфиг проекта лежит в корне проекта,
расширение внутри него. Поправлен на реальную.
Из гайда убран абзац, объяснявший особый порядок: объяснять больше нечего.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
Навыки-создатели дописывали новый объект в конец группы своего вида, а стандарт
требует порядка по имени (АПК:1108). Замеры на 8 боевых выгрузках: 103 385 объектов
лежат по алфавиту, нарушают его ровно дописки в хвост. Стенд подтвердил, что
беспорядок вечен: платформа нормализует порядок ВИДОВ (возвращает канонический),
но порядок имён внутри вида не трогает.
Настройка newObjectPosition в .v8-project.json (end по умолчанию | byName) —
решение проекта, а не вызова: читают её meta-compile, role-compile, xdto-compile,
cfe-borrow и cf-edit add-childObject. Компаратор при этом константа, моделирующая
дерево Конфигуратора: ключ «ранг+символ» без культурных таблиц, одинаковый в обоих
портах на любой ОС. На корпусе он даёт 4 нарушения на 125 088 пар против 2866 у
ordinal-сравнения, которым cf-edit и cfe-borrow сортировали до сих пор.
Subsystem не упорядочивается автоматически нигде: пока подсистемы не перечислены
в <SubsystemsOrder>, порядок дерева задаёт порядок разделов в панели, а платформа
этот список сама не заводит.
Настройка не чинит накопленное, поэтому cf-edit получил операцию sort-childObjects
(вся конфигурация или названные виды). Она переставляет значения узлов, а не узлы,
поэтому диф — чистая перестановка строк. Имя вида принимается в любом регистре,
во множественном числе и по-русски; неизвестный вид — отказ со списком допустимых.
Попутно:
- PS-порты создателей переведены с DOM-сериализации на текстовую вставку: на
выгрузке не в каноне Конфигуратора они переписывали заголовок без просьбы;
- PS-сторона семьи detect_xml_style/finalize_xml_bytes закрыта в cf-edit и
cfe-borrow — правка чужого файла наследует его BOM/EOL/заголовок;
- xdto-compile присоединён к семье Register-InChildObjects вместо инлайн-копии;
- закрыт ложный успех в py subsystem-compile: <ChildObjects /> с пробелом ET
разбирает, а текстовые ветки не находили — файл писался без вставки;
- cfe-borrow py не импортировал json, из-за чего резолвер молча возвращал end;
- cf-edit add-childObject ставил объект в конец блока, за пределы своей группы,
когда видов старше в файле не было.
Проверки: 906/906 на PowerShell и 903/906 на Python, 10 гардов, верификация
эталонов платформой без падений, раундтрип отсортированной конфигурации на
8.3.24 и 8.3.27, сортировка боевой выгрузки ACC (1,4 МБ) и расширения из корпуса.
Задачу принёс PR #85; часть кода взята оттуда.
Co-Authored-By: Sergei Pleshanov <72200277+Abacadabras@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
В SKILL.md место только тому, как навык применять. Оговорка о том, что форма
адреса не описана в известной документации и проверена на стенде, — это история
работы, модели она ничего не даёт. Осталось применимое: вид адреса, порт по
умолчанию и то, что недоступный сервер отвечает тем же сообщением, что и
отсутствие реквизитов.
В справочнике проекта оговорка тоже переписана на факты: требование совпадения
версий сервера и платформы вместо рассказа о том, где мы это выясняли.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Установлен crserver 8.3.23, поднят на порту 1542 — сетевое хранилище перестало
быть непроверенным местом. Адрес tcp://<хост>[:<порт>]/<имя>, порт по умолчанию
1542; хранилище создаётся сервером по требованию. Весь цикл, файл списка
объектов и администрирование работают так же, как на файловом, и одинаково в
обоих портах. Отдельного поведения у сетевого хранилища не обнаружено.
Нашлась двусмысленность: недоступный сервер даёт «Соединение с хранилищем
конфигурации не установлено» — ровно то же сообщение, что и отсутствие
реквизитов. Прежняя подсказка «добавьте repository в реестр» в сетевом случае
уводила не туда. Теперь db-repo различает по схеме адреса и советует проверить
сервер и порт, а подсказка db-load-xml и db-load-git называет обе причины.
Документация больше не оговаривается «не проверено»: форма адреса подтверждена
на стенде.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Форма tcp://srv01/MyApp пришла из примера в ишью #77, а мы повторили её в
справочнике реестра и в db-list как факт. Прицельный поиск показал, что в
доступной документации её нет: глава 7.4.15 описывает только каталог хранилища,
а в обоих «Приложение 4» (8.3.24 и 8.3.27) не встречаются ни crserver, ни
tcp:// — совпадения по слову «хранилище» относятся к лицензированию.
Теперь сказано «каталог хранилища или адрес сервера хранилища» и добавлена
оговорка: путь передаётся платформе как есть, конкретный синтаксис в известной
нам документации не описан, на серверном хранилище навык не проверялся.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Проверка навыка субагентом на сквозном сценарии вскрыла фактическую ошибку
в инструкции: реквизиты и табличные части перечислялись наравне с формами как
захватываемые объекты. Платформа их объектами не считает — список объектов
получается пустым, причём без секции «отсутствующие в конфигурации». Правишь
реквизит, табличную часть, измерение, ресурс или модуль — захватывай владельца;
формы, макеты и команды захватываются отдельно.
Сообщение «объект не найден» имеет три разные причины: опечатка, отставание
базы от хранилища и попытка захватить то, что объектом не является. Теперь
перечислены все три.
В цикл добавлен нулевой шаг — получение актуального состояния перед началом
работы: правки должны опираться на актуальные версии в том числе тех объектов,
которые не меняются, но используются. Загрузка и обновление БД слиты в один
шаг через -UpdateDB, поэтому цикл не удлинился.
Захват корня конфигурации с -WithChildren отклоняется: это захват всей
конфигурации, а выглядит как захват корня. Для всей конфигурации есть
однозначная форма — вызов без -Objects.
Текстовый отчёт печатается, а не только сохраняется в файл.
Схема repository и extensions[] описана в docs/v8-project-guide.md,
цикл под хранилищем — в docs/db-guide.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ограничение «только файловые базы» — свойство обвязки навыков, а не утилиты:
ibcmd умеет клиент-серверные базы, но подключается к СУБД напрямую и требует
реквизитов, которых навыки не запрашивают. Плюс добавлен headless-сценарий для
Linux/macOS с примером v8path.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Список пишется одной строкой через запятую — так же, как -Objects/-Files;
отмечено ограничение: значение с запятой внутри не поддерживается.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Разбор escape hatch для вызывающего: два параметра по движкам, ключи
v8args/ibcmdargs в реестре проекта, что отклоняется и почему,
маскирование секретов и известные пределы разбора (/Psecret, /@).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Приводим авторский контент (.ps1/.psm1/.py/.mjs/.md/.json, пин .bsl)
к единому LF и закрепляем политикой в .gitattributes. Инструмент правки
всегда пишет LF, поэтому единый LF убирает EOL-шум в диффах, ложные
срабатывания blame и налог на ручную синхронизацию CRLF-файлов.
BOM на .ps1 сохранён (git с eol=lf меняет только CR<->LF, BOM не трогает).
Данные 1С (*.xml) и бинарники под нормализацию не берём.
Гейт: PS-порт 459/459, Python-порт 459/459, web-test E2E 22/22 (с пересборкой стенда).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- .v8-project.example.json в корне как шаблон (без секретов, коммитится; точное
имя .v8-project.json остаётся в .gitignore). Версия платформы и configSrc=src\cf
под рекомендуемую структуру.
- v8-project-guide: раздел «Рекомендуемая структура проекта» (src/cf, src/cfe/<Имя>,
src/epf/<Имя>, src/erf/<Имя>), упоминание шаблона, configSrc-примеры → src\cf,
нейтральный раздел про выбор движка 1cv8/ibcmd.
- db-guide: нейтральный раздел «Движок: 1cv8 или ibcmd» (по умолчанию конфигуратор;
ibcmd — на усмотрение пользователя через -V8Path в задаче или файл ibcmd.exe в v8path).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- plugin.json: убран ключ hooks → плагин больше НЕ подключает хуки
автоматически. Базовая защита поддержки (§1B в навыках) остаётся
on-by-default; хуки — опциональный слой поверх (перехват правок мимо
навыков + суфлёр), включается вручную.
- hooks/README.md: помечено «экспериментально, по умолчанию выключено»;
раздел установки переписан под ручное включение.
- docs/v8-project-guide.md: добавлен флаг skillSuggester (глоб. + по базе)
и секция про опциональные хуки.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Пилот энфорсмента issue #23: перед записью навыки-мутаторы проверяют
состояние поддержки (Ext/ParentConfigurations.bin) и блокируют опасную
правочку. Триггер — наличие bin (конфиг на поддержке); реакция из
.v8-project.json editingAllowedCheck (deny|warn|off, по умолчанию deny).
Assert-EditAllowed (нативная копия в каждом навыке, оба порта):
walk-up резолвит uuid цели (объект / владелец / корень — по пути) и
корень конфигурации, затем G-vs-f1 и консервативная свёртка min(f1).
Два режима: require-editable (f1≥1, G≠1) для правок/добавлений;
require-removed (f1=2) для удаления.
- meta-edit (v1.7): editable на редактируемом объекте;
- meta-compile (v1.13): editable на корне (добавление нового объекта);
- meta-remove (v1.2): removed на удаляемом объекте.
Диагностика через [Console]::Error.WriteLine + exit 1 (не Write-Error:
под ErrorActionPreference=Stop тот бросает и был бы проглочен catch'ем).
Тесты: малая on-support фикстура с рукотворным bin (root/Locked f1=0,
Removed f1=2); guard-deny кейсы (expectError) — оба рантайма зелёные,
старые кейсы не сломаны (конфиги без bin → allow). Поле editingAllowedCheck
задокументировано в docs/v8-project-guide.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Consolidate project config documentation into a single guide covering all
fields (v8path, databases, webPath, ffmpegPath, tts, webUrl), with "who fills"
column and resolution algorithm. Replace duplicated format sections in
db-guide.md and web-guide.md with links to the new guide.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>