Commit Graph

1214 Commits

Author SHA1 Message Date
Nick Shirokov 0dc014dc47 fix(cfe-borrow): не затирать существующий Module.bsl при повторном заимствовании формы
Повторный borrow формы записывал пустой Module.bsl безусловно → терялся
пользовательский код, добавленный в модуль формы (аналог IngvarConsulting/unica#4,
воспроизведено: 150→3 байта). Теперь пустой модуль создаётся только если файла ещё
нет; существующий сохраняется ("Preserved existing Module.bsl"). Дополняет
идемпотентность re-borrow (форма-обёртка/uuid уже были закрыты в v1.5).

Тест form-bindings усилен: между первым и вторым заимствованием в модуль пишется
код (writeFile), idempotent:true теперь проверяет его сохранность побайтно.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:57:41 +03:00
Nick Shirokov 36c2fd9233 feat(form-validate,cfe-borrow): проверка висячих привязок + идемпотентность re-borrow + добор по Field
Три доработки по форме, полезные модели, использующей навыки.

form-validate v1.7→v1.8 (5a): Check 5 генерализован с одного <DataPath> на все
8 тегов-привязок (DataPath/TitleDataPath/FooterDataPath/HeaderDataPath/
MultipleValue*DataPath/RowPicture*). Висячая привязка (корень не в <Attributes>)
теперь ловится при validate, а не всплывает на дорогом db-load. Skip-правила
(companion-элементы, базовые элементы id<1000000 в BaseForm, opaque-формы)
сохранены без изменений. Заодно фикс бага Check 12 в py-порте
(type_invalid → type_error_count, краш на невалидном cfg:-типе в config-контексте).

cfe-borrow v1.4→v1.5:
- #4: borrow_form переиспользует uuid обёртки Forms/<Name>.xml, если файл уже
  существует, вместо генерации нового → повторное заимствование формы
  байт-идемпотентно (агент может ретраить без дрейфа identity).
- #1: collect для -BorrowMainAttribute дополнен сканом <Field>Объект.X</Field>
  (поля фильтров/условного оформления/динсписков) — набор заимствованных
  реквизитов теперь совпадает с Конфигуратором (добавился УдалитьЮрФизЛицо).

Тесты: form-validate/dangling-binding (фикстура broken-dangling-binding,
expectError+stdoutContains); cfe-borrow/form-bindings + idempotent:true.
Регресс 6/6 cfe-borrow + 11/11 form-validate на обоих рантаймах, E2E-load OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:38:39 +03:00
Nick Shirokov 4767800fce fix(cfe-borrow): корректное заимствование формы — все привязки данных + идемпотентность
При заимствовании управляемой формы в расширение скрипт генерировал Form.xml,
который платформа отвергала при загрузке («Неверный путь к данным»), а повторное
заимствование портило объект. Три бага (подтверждены E2E-загрузкой в базу):

1. Висячие привязки. Stripping вырезал только DataPath/TitleDataPath/RowPictureDataPath,
   но не FooterDataPath/HeaderDataPath/MultipleValue*DataPath. Поле с множественным
   выбором (МеткиОбъекта) оставляло висячую привязку на незаимствованный реквизит.
   Введён единый список binding-тегов (выведен по дампам acc/erp/unf, сверен с
   form-compile) + helper Strip-FormBindings/strip_form_bindings; сборщик путей для
   -BorrowMainAttribute расширен на тот же список.
2. Повторное заимствование дублировало реквизиты (нет дедупа против ChildObjects).
3. Повторный enrich дописывал свойства объекта (DescriptionLength и т.п.) внутрь
   каждого <Attribute> (глобальная замена по </ExtendedConfigurationObject>).
   Фикс: guard + якорь к Properties объекта (count=1).

Попутно исправлен PS↔PY паритет form-borrow: PY энтити-кодировал кириллицу в
атрибутах самозакрытых элементов (decode_numeric_entities), порядок extraProps
в PS приведён к PY ([ordered]@{}).

Регресс-кейс tests/skills/cases/cfe-borrow/form-bindings.json (form-compile →
двойной borrow → snapshot/normalizeUuids). Регресс 6/6 PS+PY, cfe-validate OK,
E2E-загрузка в базу успешна на обоих рантаймах.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 22:54:13 +03:00
Nick Shirokov c172cf142a docs(v8-project): пример .v8-project.example.json + рекомендуемая структура src/ + ibcmd
- .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>
2026-06-22 20:19:39 +03:00
Nick Shirokov 684bbb5036 test(skills): platform-epf — канонический DSL form-compile (чинит PY-прогон)
Шаг form-compile в platform-epf был написан в «вольном» диалекте: атрибуты и
команды с ключом `id` вместо `name`, кнопка как `{id,type:'button',action}`.
PS-порт это молча глотал (пустые имена / skip с warning), PY-порт падал
(`KeyError: 'name'`). Переписано канонически (как cases/form-compile/commands.json
и build-epf): `name` у атрибутов/команд, кнопка `{button, command}` внутри cmdBar.
Зелено на обоих рантаймах и движках (PY-матрица platform/* → 7/7).

Это была опечатка теста, не баг навыка. Робастность form-compile на некорректном
входе (чистая ошибка вместо raw-traceback в PY / тихого пустого имени в PS) —
отдельная необязательная тема.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:53:37 +03:00
Nick Shirokov d0469c6080 merge: фикс PY-quoting в db-create (1cv8 строка соединения) 2026-06-22 18:11:47 +03:00
Nick Shirokov 32bf72bba9 fix(db-create): PY — убрать встроенные кавычки в строке соединения 1cv8
subprocess.run([exe]+args) на Windows сам экранирует кавычки внутри одного
аргумента, поэтому f'File="{path}"' / f'Srvr="..";Ref=".."' приходили в 1С
покорёженными → CREATEINFOBASE падал «Неверные параметры соединения» (exit 1).
Без встроенных кавычек subprocess сам квотит токен с пробелами, а argv-парсер 1С
снимает внешние кавычки. Предсуществующий баг (на dev), всплыл на --runtime python
движковой матрицы. PS-порт корректен (зелёный прогон) — в нём только бамп версии
для синхронности портов. v1.3 → v1.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:11:02 +03:00
Nick Shirokov 55e7d82210 merge: поддержка ibcmd в db-*/epf-*/erf- (опт-ин по имени exe) + движковая матрица в регресс-тестах 2026-06-22 16:13:11 +03:00
Nick Shirokov ceacaa3509 test(skills): движковая матрица 1cv8/ibcmd в интеграционных тестах
Раннер: контекст платформы дорезолвит ibcmd.exe рядом с 1cv8.exe;
тест объявляет `engines: ['1cv8','ibcmd']` → одни и те же шаги прогоняются
на каждом движке ({v8path} подставляется в нужный exe), результаты помечаются
суффиксом [1cv8]/[ibcmd]. ibcmd-проход авто-skip, если ibcmd.exe нет.
Дефолт engines=['1cv8'] — прочие тесты не меняются.

Новые типы шагов: editFile (подстановочная замена) и assertContains
(проверка подстроки) — для round-trip проверок.

platform-config и platform-epf переведены в матрицу. Новый platform-partial:
частичная выгрузка/загрузка объекта с round-trip маркера на обоих движках.

README: раздел про интеграционные тесты, матрицу и типы шагов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 16:04:16 +03:00
Nick Shirokov 89496f535d docs(db,epf,erf): ibcmd — опт-ин, убрать дубль автоопределения платформы
По итогам обсуждения: ibcmd оставляем на усмотрение опытных пользователей,
не светим в основном потоке инструкций.

- Убраны развёрнутые врезки «Если -V8Path указывает на ibcmd.exe — …»
  во всех SKILL.md. Упоминание остаётся только в описании параметра
  -V8Path (1cv8.exe / ibcmd.exe); ограничения и так enforced скриптом
  (чистая ошибка на серверной базе / -Format Plain / -AllExtensions).
- Заменена неактуальная и дублирующая строка автоопределения платформы
  («Get-ChildItem … Sort -Desc | Select -First 1») — скрипт сам резолвит
  платформу (реестр → числовая сортировка → Program Files [+ x86]),
  модели не нужно дублировать ручной поиск.

Только SKILL.md, скрипты и версии не затронуты. EOL/BOM сохранён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 13:08:43 +03:00
Nick Shirokov 5bd6ba30cd fix(db,epf): изолированный --data на каждую ibcmd-операцию
ibcmd без --data использует общий каталог автономного сервера в
%LOCALAPPDATA%\standalone-server: он копит реестр/локи, и зависший
процесс (например, ушедший в консольный интерактив при нехватке кред)
держит его лок, блокируя ВСЕ последующие ibcmd-операции «Рабочий каталог
заблокирован процессом N».

Теперь каждая ibcmd-операция получает свой одноразовый --data=<temp> и
удаляет его после: зависший/параллельный вызов лочит только свой каталог,
не накапливается реестр («уже зарегистрирована»). База (--db-path) и
чужой автономный сервер на дефолтном каталоге не затрагиваются.

Реализация: ps1 — --data=$tempDir (создаётся до try, finally чистит на
exit); py — свой ib_data через tempfile.mkdtemp + atexit-очистка (надёжно
на любом sys.exit); stub-db-create — свой ib_data + явная очистка.

Проверено: A/B через навык с живым холдером — операция с общим --data
падает «заблокирован процессом N», навык (свой --data) проходит; очистка
temp-каталогов подтверждена (оба порта); 1cv8-ветки не затронуты.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:01:03 +03:00
Nick Shirokov 8fb3e9421d feat(db-dump-xml,db-load-xml): -AllExtensions через ibcmd
Закрыт последний частичный пробел расширений: -AllExtensions под ibcmd
больше не ошибка, а реальные подкоманды:
- db-dump-xml -AllExtensions → ibcmd infobase config export all-extensions <dir>
- db-load-xml -AllExtensions → ibcmd infobase config import all-extensions <dir>
  (+ цепочка config apply --force при -UpdateDB)

1cv8-ветки без изменений. Версии: db-dump-xml 1.3→1.4, db-load-xml 1.7→1.8.

E2E: база с двумя расширениями → export all-extensions (Ext1/Ext2) →
import all-extensions обратно, оба порта; 1cv8-регресс (-AllExtensions
-Mode Full) цел.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 17:17:15 +03:00
Nick Shirokov 3f5065221e feat(epf-build,epf-dump): полная сборка/разборка EPF·ERF через ibcmd
Если -V8Path указывает на ibcmd.exe — обработки/отчёты собираются и
разбираются автономным сервером (offline, без запуска платформы), иначе
как прежде через 1cv8 DESIGNER.

- epf-build → ibcmd infobase config import <src-dir> --out=<epf> --db-path
- epf-dump  → ibcmd infobase config export --file=<epf> <dir> --db-path
- stub-db-create: при ibcmd создаёт stub-базу ОДНИМ вызовом
  ibcmd infobase create --db-path --create-database [--import=cfg --apply
  --force] вместо трёх стартов 1cv8 (CREATEINFOBASE/Load/Update). --force
  обязателен: иначе apply уходит в интерактивный [y/n] и отменяется.

Только файловые базы (серверные/-Format Plain под ibcmd → чистая ошибка).
1cv8-ветки без изменений. Версии: epf-build/epf-dump 1.1→1.2,
stub-db-create 1.0→1.1.

E2E: dump (.epf→XML), build без ref-типов, build СО ссылочными типами
через auto-stub на ibcmd (валидность подтверждена обратной разборкой),
1cv8-регресс — всё зелёное; оба порта.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 17:09:23 +03:00
Nick Shirokov 27b9d539e0 feat(db): ibcmd для частичной выгрузки/загрузки из исходников
Закрыты частичные режимы, ранее дававшие «use 1cv8»:
- db-dump-xml Mode=Partial → ibcmd config export objects <имена>
  --out=<dir> (выгрузка указанных объектов конфигурации);
- db-load-xml Mode=Partial / -Files / -ListFile → ibcmd config import
  files <отн.пути> --base-dir=<ConfigDir> (--base-dir обязателен);
- db-load-git → добавлена ibcmd-поддержка (раньше отсутствовала):
  config import files <изменённые из git> --base-dir=<ConfigDir>,
  с цепочкой config apply --force при -UpdateDB; DryRun не трогает движок.

Несовместимое под ibcmd по-прежнему даёт чистую ошибку: -Format Plain,
-AllExtensions, db-dump-xml Mode UpdateInfo. 1cv8-ветки без изменений.
Версии: db-dump-xml 1.2→1.3, db-load-xml 1.6→1.7, db-load-git 1.5→1.6.

E2E: export objects (только указанные объекты), import files round-trip
(+apply), db-load-git staged→import files+apply, DryRun, error-кейсы,
1cv8-регресс Partial — всё зелёное.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 16:33:07 +03:00
Nick Shirokov 4102b7005a feat(db): тиражирование ibcmd на create/cf/update/xml (по имени exe в -V8Path)
Распространение пилота dt-пары на остальные применимые навыки. Если
-V8Path указывает на ibcmd.exe — операция идёт через автономный сервер
(offline, без запуска платформы), иначе как прежде через 1cv8 DESIGNER.

Маппинг (только файловые базы --db-path):
- db-create  → infobase create --create-database [--restore=dt|--load=cf --apply]
- db-dump-cf → infobase config save
- db-load-cf → infobase config load
- db-update  → infobase config apply --force (--force обязателен: без него
  ibcmd уходит в интерактивный [y/n] и в неинтерактиве отменяет, exit 102)
- db-dump-xml→ infobase config export (иерархический, Mode Full/Changes)
- db-load-xml→ infobase config import (+цепочка config apply при -UpdateDB)

Несовместимое под ibcmd даёт понятную ошибку с указанием на 1cv8:
серверные базы, -AllExtensions, -Format Plain, Mode Partial/UpdateInfo,
Files/ListFile. 1cv8-ветки без изменений. Версии 1.1→1.2 (xml-load 1.5→1.6).

E2E цепочка через ibcmd: create→dump-cf→load-cf→update→dump-xml→
load-xml+UpdateDB — всё exit 0; 1cv8-регресс (create/load-cf/update) цел.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 15:37:19 +03:00
Nick Shirokov 11bab7669d feat(db-dump-dt,db-load-dt): пилот ibcmd (движок по имени exe в -V8Path)
Если -V8Path указывает на ibcmd.exe — операция выполняется через утилиту
автономного сервера (offline, без запуска платформы), иначе как прежде
через 1cv8 DESIGNER. Выбор движка неявный (sniff имени exe), без новых
параметров; в реестре .v8-project.json пользователь прописывает v8path
= путь к ibcmd.exe.

Пилот на dt-паре:
- dump:    ibcmd infobase dump --db-path=<base> [--user][--password] <dt>
- restore: ibcmd infobase restore --db-path=<base> [--create-database
  если нет 1Cv8.1CD] [--user][--password] <dt>
Только файловые базы (серверные под ibcmd → понятная ошибка: нужны креды
СУБД, которых нет в реестре). Вывод ibcmd (UTF-8) захватывается из
stdout/stderr (нет /Out-файла). 1cv8-ветка без изменений. Версия 1.1→1.2.

E2E: dump 115281б, restore round-trip (свежий каталог +--create-database,
overwrite существующей без флага), 1cv8-регресс, server+ibcmd→ошибка.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 15:18:41 +03:00
Nick Shirokov 3d36c20269 fix(epf-build,epf-dump,web-publish): надёжный резолв пути к платформе 1С
Распространение фикса резолва (см. предыдущий коммит по db-*) на
оставшиеся навыки с тем же дублированным блоком:
- epf-build, epf-dump (ps1+py): резолв 1cv8.exe — реестр .v8-project.json
  → числовая сортировка версий → glob Program Files [+ (x86)] с заметкой.
- web-publish (ps1+py): резолв bin-каталога (для wsap24.dll) — те же
  приоритеты; v8path из реестра уже есть нужный bin-каталог.

Чинит лексикографический выбор версии и узкую область поиска; py
деградирует без падения вне Windows. Версии: epf-* 1.0→1.1,
web-publish 1.2→1.3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
w-2026-06-21
2026-06-21 14:35:48 +03:00
Nick Shirokov e507e6bfba fix(db): надёжный резолв 1cv8.exe во всех навыках группы
Новая лестница приоритетов поиска платформы (ps1 + py, 18 файлов):
1) -V8Path; 2) v8path из .v8-project.json (скрипт сам ищет файл вверх от
cwd — пин-версия соблюдается даже без -V8Path); 3) glob по Program Files
[+ (x86)] с ЧИСЛОВОЙ сортировкой версий и заметкой «Auto-selected
platform X.Y.Z: <путь>».

Исправляет: лексикографический выбор версии (8.3.9 вместо 8.3.27);
тихий выбор максимальной версии (риск подъёма формата базы) — теперь
реестр в приоритете; узкую область поиска (добавлен x86). Python-порт
деградирует без падения вне Windows (glob пуст → чистый exit, не
трейсбэк). Версии: cf-семейство 1.0→1.1, load-xml/load-git 1.4→1.5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 14:23:51 +03:00
Nick Shirokov 293e8e7a55 chore(db): убрать boilerplate-разделы из SKILL.md группы
Удалены не несущие нагрузки разделы «Коды возврата» (универсальные 0/1)
и generic «прочитай лог / покажи результат». Сохранены только смысловые
следующие шаги (предложить db-update, регистрация в реестре, занятость
базы, предупреждения, Partial-режим). Правки только в SKILL.md, EOL/CRLF
сохранён, версии скриптов не затронуты.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:57:48 +03:00
Nick Shirokov 6787e97a72 feat(db-load-dt): загрузка ИБ из DT-файла (RestoreIB), opt-in
Новый навык пакетной загрузки всей информационной базы из .dt через
конфигуратор /RestoreIB (с опц. -JobsCount, -UnlockCode/UC). Операция
необратима (полная перезапись базы) → disable-model-invocation: true,
плюс инструкция: сначала предложить db-dump-dt как точку отката, затем
подтверждение. db-update после не нужен. PS1 + py-порт.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:57:48 +03:00
Nick Shirokov 5ad2e4b5fe feat(db-dump-dt): выгрузка ИБ в DT-файл (DumpIB)
Новый навык пакетной выгрузки всей информационной базы (конфигурация +
данные) в .dt через конфигуратор /DumpIB. Авто-режим разрешён (бэкап).
PS1 + py-порт в стиле db-dump-cf.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:57:35 +03:00
Nick Shirokov b9c7af02de fix(meta-edit): убрать лишний -Path в авто-вызове валидаторов (py-порт)
argparse-конструкция add_argument("-XPath", "-Path") объявляет два АЛИАСА
одного аргумента, а py-порты edit-навыков понимали её как «передать оба
флага» и звали валидатор как `-XPath -Path <путь>`. argparse трактовал
`-Path` как опцию, а не значение → "error: expected one argument", и
авто-валидация тихо падала (exit code не пробрасывается, правка проходила).

Убран лишний -Path в 5 py-местах:
- meta-edit.py, cf-edit.py, subsystem-edit.py, interface-edit.py (авто-вызов)
- meta-validate.py (рекурсивный batch-вызов, строка 34 — тоже был сломан)

ps1-порты корректны (один флаг), не трогались. Версии подняты парно
(ps1+py) для синхронности. Проверка «скрипт не найден → skip» уже была.

Проверено: одиночная валидация, batch-режим, сквозной meta-edit→валидация.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 11:55:42 +03:00
Nick Shirokov 58ea52cb63 merge: хуки support-guard + суфлёр (опт-ин) в support-state-format
Консолидация: §1B (в навыках) + §1A/суфлёр (хуки, экспериментальные, опт-ин).
2026-06-21 11:22:14 +03:00
Nick Shirokov 6e458bf0b8 chore(hooks): сделать хуки опт-ин (экспериментально) + доки
- 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>
2026-06-20 20:40:46 +03:00
Nick Shirokov 63fd91c3ca fix(role-compile): выровнять версию py-порта (1.6→1.7) с ps
Дуал-порт версии разъехались ранее (ps бампнули, py — нет); выравниваю.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 20:29:41 +03:00
Nick Shirokov a991458ef2 feat(mutators): предметная диагностика support-guard (§1B) по причине отказа
Синхронизация §1B с улучшенным текстом хука (ветка feat/support-guard-hooks):
вместо общего списка всех вариантов — текст под конкретную причину
(capability-off / locked / not-removed) с подставленным реальным путём и
точными командами support-edit. Понятно модели вне контекста.

- Все 16 навыков-мутаторов (оба рантайма): Assert-EditAllowed /
  assert_edit_allowed строят сообщение по $code/code причины отказа.
- Терминология «редактирование» (как у платформы 1С).
- Версии заголовков подняты в обоих рантаймах.
- EOL/BOM каждого файла сохранены; deny-тесты 16/16 на PS и PY.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 20:18:21 +03:00
Nick Shirokov 4ec2420af6 feat(hooks): суфлёр различает чтение/правку + убран триггер на поиск
- Подсказка зависит от действия: Read → info-навык (понять структуру),
  Edit|Write|MultiEdit → мутатор (meta-edit/form-edit/…). Throttle теперь
  по (сессия, группа, действие) — отдельно read- и write-подсказка.
- Убран триггер на Grep|Glob (группа search): *-info помогают ПОНЯТЬ
  найденный объект, а не НАЙТИ по содержимому → подсказка вводила в
  заблуждение. Суфлёр только на файловых инструментах.
- cfe-подсказка ведёт и на cf-info (читает свойства/состав расширения),
  и на cfe-diff (специфика); правка — cfe-borrow/cfe-patch-method.
- README обновлён.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:54:06 +03:00
Nick Shirokov ba0880a5c5 style(hooks): «правка» → «редактирование» в текстах гарда и README
Единообразие с термином платформы 1С («редактирование объекта
метаданных запрещено»).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:39:00 +03:00
Nick Shirokov 378b19b59f refactor(hooks): предметная диагностика гарда по причине + README для читателя
- support-guard: вместо общего списка всех вариантов — текст под конкретную
  причину отказа (decideSupport.code: capability-off | locked | not-removed),
  с подставленным реальным путём и точными командами support-edit. Понятно
  модели вне контекста: что за состояние и что именно сделать.
- support-state: decideSupport возвращает code (дискриминатор причины).
- README: переписан для читателя — убраны отсылки к внутренней реализации
  (§-нумерация, декодер, разбор common/); назначение, установка, настройка
  (.v8-project.json), что делать при отказе, проверка.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:36:55 +03:00
Nick Shirokov ebd620d262 feat(hooks): §1A гард поддержки + суфлёр навыков (node-хуки Claude Code)
Харнес-слой поверх пола §1B: ловит правки мимо навыков-мутаторов.

- support-guard.mjs (PreToolUse Edit|Write|MultiEdit) — §1A: блокирует
  сырую правку объекта поставщика «на замке» / read-only конфы; реакция
  deny|warn|off из .v8-project.json editingAllowedCheck, идентично §1B.
- skill-suggester.mjs (PostToolUse Read|Grep|Glob|Edit|Write|MultiEdit) —
  ненавязчивая подсказка профильного навыка, throttle 1×/сессия/группа,
  не блокирует; флаг skillSuggester (on|off).
- common/: support-state.mjs (порт декодера bin 1:1 из Assert-EditAllowed),
  project.mjs (реакция из .v8-project.json), object-class.mjs (карта
  путь→навык с различением cf/cfe и mxl/скд по нюху корня).
- test/run.mjs: 38 standalone-тестов на корпусе cfsrc + синтетике.
- plugin.json: hooks → ./hooks/hooks.json (авто-загрузка в плагине).

§1C (грубый Bash-гейт) отброшен — дублирует §1B, формат bin заморожен.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:39:05 +03:00
Nick Shirokov 07ea676326 feat(db-load-xml,db-load-git): исключать файлы состояния поддержки из частичной загрузки
Партиал-загрузка ParentConfigurations.bin платформой не принимается
(мутный отказ «редактирование объекта метаданных запрещено», пустое имя
= корень; смена поддержки требует полной загрузки). Чтобы не падать
невнятно, оба навыка теперь исключают служебные файлы поддержки из
partial-списка с явной подсказкой.

- db-load-xml (Mode Partial): фильтрует -Files и -ListFile — убирает
  ParentConfigurations.bin и ConfigDumpInfo.xml, грузит остальное;
  если после фильтра пусто — подсказка использовать -Mode Full.
- db-load-git: ParentConfigurations.bin из git-diff отбрасывается явно
  (раньше — неявно, через несуществующий производный xml) и о смене
  поддержки печатается предупреждение; ConfigDumpInfo.xml как и прежде
  пропускается.

Не блокируем быструю частичную загрузку объектов (bin всё равно partial
не применяется — ничего «быстрого» не теряем); смену поддержки честно
направляем на полную загрузку. Оба порта, v1.3→v1.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 17:10:02 +03:00
Nick Shirokov de04a8dc7a feat(support-edit): навык переключения состояния поддержки + ссылка из диагностики гарда
Замыкает петлю issue #23: после отказа support-guard модель может
легитимно включить редактирование. support-edit правит правила поддержки
в Ext/ParentConfigurations.bin выгрузки (только XML; в ИБ — полной загрузкой):
  -Path <путь> -Set editable|off-support|locked   (пообъектно или корень)
  -Path <путь> -Capability on|off                  (возможность изменения)
Path-based, симметрично гарду — модель берёт путь прямо из отказа.

Реализация: regex-замена in-place по разобранному формату bin (round-trip
байт-в-байт; парсер подтверждён consumed=100% на корпусе acc/erp/K=7).
При выключенной возможности (G=1) пообъектный -Set отказывает с подсказкой
«сначала -Capability on» (явные шаги). Включение возможности ставит всё на
замок (вендорские флаги «не редактировать» в выгрузке недоступны — массовой
разблокировки нет; non-goal). Оба порта дают байт-в-байт идентичный bin.

Диагностика support-guard (32 файла, 16 мутаторов × 2 порта) теперь печатает
готовую команду support-edit под конкретный отказ.

Тесты: фикстуры g0/g1 + кейсы set-editable/off-support/предусловие/capability
со снапшотами bin; зелёные на PowerShell и Python. Все 16 мутаторов +
support-edit зелёные на обоих рантаймах.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 16:45:43 +03:00
Nick Shirokov acbd6be46c test(support-guard): committed deny-тесты на 13 навыков-мутаторов + фикс help-add
Регрессионная защита гарда: по одному expectError-кейсу guard-deny на
каждый из 13 размноженных мутаторов (раньше committed-тесты были только
у 3 пилотных). Ловит случайное удаление/поломку guard-вызова в будущем.

Фикстуры on-support (рукотворный bin: корень/объект f1=0, плюс элемент
f1=0 для edit-existing навыков — форма 4444, макет 5555, подсистема 6666).
Структура под конвенцию каждого навбыка: owner/root для add/compile/edit
конфигурации; плоский Locked/Ext для help-add (EPF-стиль).

Заодно исправлен пред-существующий баг help-add Detect-FormatVersion
(v1.5→v1.6, оба порта): Substring(0, byteLength) падал на кириллическом
Configuration.xml (байт>символов). Теперь Substring по длине строки;
фикстура help-add кириллическая — регрессия фикса покрыта тестом.

Все 13 guard-кейсов зелёные на PowerShell и Python; deny через exit≠0 +
stderr "support-guard". Существующие кейсы не затронуты.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:45:50 +03:00
Nick Shirokov b17dd5d04c feat(mutators): размножить support-guard на остальные навыки-мутаторы
Контракт Assert-EditAllowed (дословная копия из meta-edit, оба порта)
добавлен в 13 навыков-мутаторов. Всем единый вызов require=editable —
«кого проверять» решает не навык, а walk-up по файловой системе от пути
цели:
  - целевой файл имеет root-uuid → его f1 (правка существующего элемента);
  - иначе ближайший вверх <dir>.xml с uuid → f1 владельца (добавление
    дочернего: форма/реквизит/макет к объекту);
  - иначе корень Configuration.xml → f1 корня (новый объект верхнего уровня).

Это воспроизводит семантику поддержки 1С автоматически, поэтому один и
тот же навык проверяет разное по состоянию дампа: skd-compile/mxl-compile/
form-compile в существующий макет/форму → f1 этого элемента (modify), в
несуществующий → f1 владельца. Проверено обоими сценариями.

Навыки: form-edit, form-add, form-compile, skd-edit, skd-compile, cf-edit,
subsystem-edit, subsystem-compile, interface-edit, template-add, help-add,
mxl-compile, role-compile. Диагностика через [Console]::Error.WriteLine +
exit 1 (как в эталоне). Версии подняты в обоих портах.

Проверено: deny на обоих портах (крафт-фикстуры на копиях, корпус не
тронут); все 16 навыков-мутаторов зелёные на PowerShell и Python
(264 кейса). BOM сохранён везде.

Follow-up (в upload-плане): пред-существующий баг help-add
Detect-FormatVersion (Substring на кириллице, до гарда, не связан);
авторезолв пути в meta-edit; per-skill committed deny-тесты.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:27:38 +03:00
Nick Shirokov 2136245b69 feat(meta-edit,meta-compile,meta-remove): support-guard перед правкой объектов на поддержке
Пилот энфорсмента 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>
2026-06-20 14:57:14 +03:00
Nick Shirokov 489b8389aa feat(form-info,skd-info,role-info,subsystem-info,mxl-info): строка состояния поддержки
Размножение per-object паттерна состояния поддержки из meta-info на
остальные info-навыки. Унифицированный helper Get-SupportStatusForPath
(нативная копия в каждом скрипте): walk-up от пути цели — берёт uuid
ближайшего метафайла элемента (форма/макет/роль/подсистема, либо сам
целевой .xml) и корень конфигурации с ParentConfigurations.bin, затем
G-vs-f1 и консервативная свёртка min(f1) по блокам поставщиков.

Резолв точный на уровне элемента: форма с индивидуально включённым
редактированием (Валюты.ФормаСписка f1=1) показывает «редактируется»,
а форма того же объекта на замке (ФормаЭлемента f1=0) — «на замке».

form-info v1.4, skd-info v1.7, role-info/subsystem-info/mxl-info v1.1.
Проверено на корпусе (acc G=1 → read-only, erp → снято) — оба порта
байт-в-байт. Тесты: все 7 info-навыков зелёные на PowerShell и Python.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 14:14:47 +03:00
Nick Shirokov 96660f4d9d feat(cf-info,meta-info): вывод состояния поддержки из ParentConfigurations.bin
Декодер Ext/ParentConfigurations.bin (нативная копия в каждом скрипте,
без общего модуля — по конвенции автономности навыков; single-pass,
не падает на битом/пустом файле).

cf-info (v1.3): блок «Поддержка:» в overview/full — на поддержке /
возможность изменения вкл-выкл / счётчики на замке/редактируется/снято
(только при G=0) / снята полностью / расширение (CFE). При G=1 показывает
read-only без вводящих в заблуждение счётчиков; тяжёлый скан 7.4МБ
пропускается, когда не нужен. При K>1 перечисляет конфигурации поставщика.

meta-info (v1.3): строка «Поддержка:» под заголовком объекта — walk-up к
корню конфигурации, статус с учётом G-vs-f1 и консервативной свёртки
min(f1) по блокам поставщиков. Для на-замке/read-only — короткое
последствие+действие (cfe-*), для остальных терсно.

Проверено на корпусе и размеченных дампах (acc G=1, erp снято,
ЧастьОбъектов, Корень, НесколькоПоддержек K=7 мультивендор, CFE) —
оба порта байт-в-байт. Формат: docs/1c-support-state-spec.md.

Тесты: cf-info 7/7, meta-info 17/17 на PowerShell и Python.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 13:57:31 +03:00
Nick Shirokov 75a97d51ea docs(support-state): распознавание расширения (CFE) как безопасного пути
У расширения нет Ext/ParentConfigurations.bin, поэтому правки его
исходников не ограничиваются состоянием поддержки базовой конфигурации.
Расширение распознаётся позитивно — по <ConfigurationExtensionPurpose>
в Configuration.xml, что отделяет его от случая полностью снятой
поддержки (там bin тоже почти пуст) и даёт корректную диагностику.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:58:58 +03:00
Nick Shirokov 8817f37bf0 docs(support-state): спецификация формата Ext/ParentConfigurations.bin
Описание состояния поддержки конфигурации 1С из XML-выгрузки:
глобальная «возможность изменения» (G), список конфигураций
поставщика (K блоков) и пообъектные правила (f1: на замке /
редактируется с сохранением поддержки / снят с поддержки).

Грамматика контейнера подтверждена на образцах одиночной и
множественной поддержки. Добавлено правило свёртки при конфликте
поставщиков (консервативно: любой f1=0 → замок) и алгоритм
статической проверки редактируемости объекта по пути файла.

Основа для guardrail-хука безопасной доработки типовых
конфигураций (issue #23).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:13:32 +03:00
Nick Shirokov ae82412377 feat(switch): добавить платформу Yandex Code Assistant (#22)
Code Assistant ищет навыки в .codeassistant/skills/ (приоритетнее .agents/).
Добавлен отдельный ключ codeassistant в реестр switch.py, пункт в
интерактивное меню, строка в таблицу README и две записи в матрицу
build-ports (powershell + python).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
w-2026-06-14
2026-06-14 14:07:24 +03:00
Nick Shirokov a38bb55bca chore(tests): refresh form-info/rich-form снапшот (пред-существующий несвежий)
Снапшот form-info отставал от давних сертифицированных фич form-compile (есть в
собственных снапшотах form-compile): <ShowTitle> у группы + полный AdditionSource
+ companion-панели у табличных дополнений (SearchString/ViewStatus/SearchControl)
+ каскадная перенумерация id. Контент не теряется — только добавления и сдвиг id.
Не связано с правками этой сессии (фейл воспроизводился и на пред-сессионном
компиляторе). Полный регресс: 427/427.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 13:53:01 +03:00
Nick Shirokov 1c21bef26c feat(form-compile): drop-on-miss warn для enum ориентации/behavior + выравнивание портов
Нераспознанное значение ориентации (group/columnGroup/page) и behavior теперь даёт
WARN с авторским набором допустимых значений — раньше промах по карте молча не
эмитил тег (тихая потеря). pass-through-ключи не трогаем (там verbatim, потери нет).

Заодно выровнен регистр enum-резолва ориентации между портами: py был
case-sensitive у columnGroup/page, ps1 (switch) — нет; теперь оба нечувствительны.

v1.172. Регресс form-compile 43/43 (ps1+py), form-validate 10/10.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 13:16:28 +03:00
Nick Shirokov 09d7097476 feat(form-compile): авторские references + индекс, корректность наборов значений
Каскад инструкции: ядро SKILL.md покрывает большинство задач, для редких/нишевых
конструкций — 12 тематических файлов в references/ (по индексу в SKILL.md).
Контракт references: только «как собрать DSL для задачи» — без механики эмиссии,
синонимов, авторезолва и forgiving (это тихая помощь модели); ссылки только внутри
навыка; область строго по элементу-владельцу.

Корректность ядра (наборы значений выверены по корпусу + доменно, forgiving/legacy
исключены из авторских):
- group расцеплён: ориентация (vertical/horizontalIfPossible/alwaysHorizontal) +
  отдельный ключ behavior (collapsible/popup) — popup-группы стали выразимы;
- titleLocation: полный набор none/left/right/top/bottom/auto;
- commandBarLocation += Bottom; searchStringLocation += Bottom/CommandBar/PullFromTop;
- общее свойство tooltip; events: null → авто-имя обработчика; правило уникальности имён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 13:16:22 +03:00
Nick Shirokov 717f3d8cc5 docs(form-decompile): сжать раздел «Что получаешь» + актуализировать ring3
Раздел разросся; ужал до сути (черновик, не обратим, теряет молча).
Исправлен устаревший факт: CommandInterface и ConditionalAppearance (без
scope) теперь поддерживаются (эмитятся), не валят скрипт. Падение — только
CA со scope / design-time диаграммы-планировщики / неизвестный элемент /
не-Form root. Убраны детали реализации (disable-model-invocation —
во фронтматтере) и нишевый абзац про GroupList.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 11:53:52 +03:00
Nick Shirokov e8b8d32e0d feat(form-decompile): Python-зеркало декомпилятора (порт ps1→py)
Полный порт form-decompile.ps1 v0.147 → .py (structure 1:1, как form-compile).
Двухпортовость декомпилятора замыкает dual-port для всего form-пайплайна.

Паритет ps1↔py: 1733/1733 байт-в-байт на list-iter.txt (все закрытые
кластеры), 0 расхождений, 0 крашей. Полный корпус 17k — в процессе.

Учтённые PowerShell-семантики (иначе тихие расхождения):
- `-eq`/`-ne` регистронезависимы → _ps_ieq на сравнениях заголовок↔авто-имя
  (title-суппресс: "Check date" == "check date")
- одноэлементный @() разворачивается при return без `,`-оператора
  (Build-DLInputParameters → inputParameters: объект при 1, массив при 2+)
- truthiness одноэлементного массива (@("") → falsy → дроп FunctionalOptions)
- .NET XmlDocument НЕ нормализует CRLF в InnerText (ET — нормализует):
  \r\n→&#13;\n внутри корня (не в прологе/эпилоге)
- порядок ключей .NET Hashtable (цвета) захвачен из PS 5.1, не из литерала
- [decimal] сохраняет масштаб vs [double] (Decimal в сериализаторе)

WS-стратегия: два читателя на одном ET-дереве (_text сворачивает
whitespace-only→"" как PreserveWhitespace=false; _text_ws — сырой для Resolve-WS).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 21:28:14 +03:00
Nick Shirokov 2a8d594f66 fix(form-decompile,form-compile): DataSet field TypeLink/Folder/пустой dataPath
Поле набора динсписка (settings.fields[]) — три подвида, терявшиеся при раундтрипе
(форма ИнвентаризацияНМА/ФормаПодбораДокументовЗатрат: 18 diff-строк → 0):

1. inputParameters[].typeLink {field, linkItem} — связь по типу (dcscor:TypeLink,
   субконто с типом-от-счёта). Декомпилятор склеивал InnerText в строку
   ("СчётДт"+"1"="СчётДт1") → компилятор писал xs:string. Структурный захват + эмит.
2. folder: true — поле-папка (DataSetFieldFolder, группировка СубконтоДт над
   СубконтоДт1/2/3; без <field>). Ловился только NestedDataSet; компилятор хардкодил
   DataSetFieldField + всегда <field>.
3. пустой dataPath: "" — поле с <dcssch:dataPath/> + <field> (≠ дефолт dataPath==field).
   Декомпилятор дропал → компилятор реконструировал dataPath=field. Has-Child вместо
   $dp -and; явный dataPath (вкл. "") побеждает fallback (self-closing при "").

Зеркало py (ps1==py байт-в-байт), регресс 43/43 (ps+py), широкий прогон list-top:
match 25→26, TOTAL 445→427, 0 регрессий. Декомпилятор v0.147 / компилятор v1.171.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 18:28:40 +03:00
Nick Shirokov 06331a9b80 fix(form-decompile,form-compile): dataParameters мульти-value + SpellCheckingOnTextInput
(1) dcsset:dataParameters — параметр с НЕСКОЛЬКИМИ <dcscor:value> (valueListAllowed,
напр. два DesignTimeValue Перечисление.X) — декомпилятор читал ОДНО (SelectSingleNode),
2-е/3-е дропались. Фикс: SelectNodes → массив (декомпилятор) + ветка массива в
Emit-DataParameters (компилятор ps1+py, отдельный <dcscor:value> на каждое значение по типу).
(2) SpellCheckingOnTextInput (input) → GENERIC_SCALARS (обе стороны+py).

Формы Организации/ФормаСписка (dataParameters мульти-DesignTimeValue) + ВводАдреса
(SpellChecking) → match. ps1==py байт-в-байт. Регресс 43/43.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 18:07:14 +03:00
Nick Shirokov 9ec5857e22 fix(form-compile): GUID.GUID значение → xr:DesignTimeRef (Normalize-ChoiceValue)
Значение параметра выбора (choiceParameters app:value) вида "GUID.GUID" (raw-ссылка по
метаданным.значение, оба GUID) эмитилось как xs:string: Normalize-ChoiceValue не
распознавал raw-GUID-ссылку → xs:string. Тот же класс, что choiceList DesignTimeRef-GUID
(commit 2d326c99), но другой потребитель.

Универсальный фикс: ветка GUID.GUID → xr:DesignTimeRef в Normalize-ChoiceValue (всегда
ссылка, не строка; named-ссылки Enum.X.Y детектятся ниже). Закрывает choiceParameters
и любой др. потребитель Normalize-ChoiceValue; choiceList не затронут (там явный
valueType побеждает Normalize). Зеркало py.

Форма НастройкиПрямыхВыплатФСС/ФормаЗаписи → match. ps1==py байт-в-байт. Регресс 43/43.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 17:31:56 +03:00
Nick Shirokov b5e8e1df7a feat(form-decompile,form-compile): батч простых хвостов — generic-скаляры, form Scale, CommandBar HL Auto, CheckBox FooterDataPath
Хвост из указанных форм (по 1 в корпусе, кроме CheckBox FooterDataPath):
(1) GENERIC_SCALARS (обе стороны+py): AutoCorrectionOnTextInput (input) /
    CommandUniqueness (button bool) / AllowInputEmptyMultipleValues (input bool) /
    BehaviorOnHorizontalCompression (table).
(2) Форменный <Scale> (масштаб формы) → KNOWN_FORM_PROPS.
(3) CommandBar>HorizontalLocation: компилятор через Get-HLocation скипал Auto
    (умолчание дополнений), но CommandBar хранит его фактически (декомпилятор ловит
    только при наличии) → эмит фактический, включая Auto. Зеркало py.
(4) CheckBoxField>FooterDataPath/FooterText — общие cell-свойства колонки, не ловились
    у check (как раньше расширяли на picField). Захват + эмит (ps1+py).

Выборка 9 форм: match 7/9 (остаток 2 — InputField>MultipleValuesFont структурный font
[отложен] + app:item>Value DesignTimeRef-GUID). ps1==py байт-в-байт. Регресс 43/43. Spec.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 17:25:37 +03:00
Nick Shirokov 95d8ece309 fix(form-decompile,form-compile): use:false на группе фильтра (FilterItemGroup)
Группа условий фильтра <dcsset:item xsi:type="dcsset:FilterItemGroup"> может нести
<dcsset:use>false</dcsset:use> (группа отключена, в т.ч. пустая OrGroup без детей).
Декомпилятор ловил group/items/presentation/viewMode/userSettingID, но НЕ use →
терялось; компилятор не эмитил.

Декомпилятор: захват use:false на группе. Компилятор: emit <dcsset:use>false</dcsset:use>
перед <groupType> (порядок исходника). Зеркало py. Корпус: 6 форм.

Форма ДокументооборотСКонтролирующимиОрганами/ПоказСообщений → match. ps1==py
байт-в-байт. Регресс 43/43. Spec обновлён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 17:11:38 +03:00