modify-attribute/-dimension/-resource: LinkByType ({dataPath,linkItem}) и
ChoiceParameterLinks ([{name,dataPath,valueChange}]) — порт эмиттеров Emit-LinkByType/
Emit-ChoiceParameterLinks в meta-edit (используют xr: namespace, уже в Import-Fragment;
app не нужен). Портированы вспомогательные Expand-DataPath (+Resolve-StdAttrEn на
существующих reserved-картах), Get-ChElProp, ConvertFrom-ChLinkShorthand. Прощающий
ввод путей (короткое имя реквизита → полный путь).
Cert декомпиляцией: выход meta-edit БАЙТ-В-БАЙТ совпадает с meta-compile для того же
ввода (ps1 и py; py-lxml пишет LF vs ps1 CRLF — нормализуется раннером/git).
verify-snapshots --case modify-attribute-structural (расширен) грузится в 1С.
meta-edit 14/14 ps1+py.
Остаток Шага 3: fillValue явный + choiceParameters (fill-ref машинерия + фикс app-namespace).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
modify-attribute/-dimension/-resource теперь умеют задавать структурные свойства
реквизита (не только скаляры): Format/EditFormat/ToolTip (ML-строки через
существующий Build-MLTextXml) + ChoiceForm. Ветки-диспетчеры в switch перед default,
по образцу ветки type (replace-or-create). Отсутствующее свойство создаётся в
канонической позиции (Insert-PropertyInOrder из Шага 1). Ключи — PascalCase
XML-имена (консистентно с существующей modify-конвенцией CodeLength/Indexing).
Побочный фикс: Set-AttrPropertyElement (ps1) через InsertBefore+RemoveChild вместо
InsertAfter+Remove-NodeWithWhitespace — последний склеивал (</PasswordMode><Format>),
т.к. в XmlDocument ведущий whitespace — отдельный узел; py (tail-модель) был корректен.
Cert: verify-snapshots --case modify-attribute-structural — Format/EditFormat/ToolTip/
ChoiceForm (с реальной формой через form-add preRun) грузятся в 1С. meta-edit 14/14
ps1+py; byte-паритет ps1==py (после нормализации раннера).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
modify-property и default-ветка modify-attribute/-dimension/-resource раньше при
отсутствии элемента свойства делали тихий Warn+no-op — правка молча терялась
(модель думала, что применилось). Теперь: известное отсутствующее свойство
СОЗДАЁТСЯ (в канонической позиции по attrPropOrder для реквизитов, append для
объектных — порядок 1С терпит, cert Шаг 0); неизвестное имя (опечатка) → внятная
ошибка exit≠0. Наборы известных свойств — union по корпусу acc+erp 8.3.24
(knownObjectProps 133, knownChildProps 40); attrPropOrder — из Build-AttributeFragment.
Новый хелпер Insert-PropertyInOrder. ps1+py зеркально.
Cert: Шаг 0 (навыками db-*) — 1С грузит и применяет объект со свойством вне
канонической позиции → append безопасен. Load-cert create-if-missing выхода —
LoadConfigFromFiles+UpdateDBCfg успешны. verify-snapshots --skill meta-edit 9/9.
Тесты: error-modify-property-typo + error-modify-attribute-typo (expectError) +
integration meta-edit-create-if-missing (compile→editFile удалить→правка→assert).
meta-edit 13/13 ps1+py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20 валидных типов метаданных без глубоких правил (Subsystem/Role/CommonForm/
CommonCommand/CommandGroup/CommonAttribute/CommonTemplate/CommonPicture/
SessionParameter/SettingsStorage/FilterCriterion/FunctionalOption/
FunctionalOptionsParameter/Language/Style/StyleItem/WSReference/XDTOPackage/
DocumentNumerator/Sequence) раньше падали как "Unrecognized" + exit 1 — ложная
ошибка на валидном объекте. Теперь для них базовая структурная проверка
(root/uuid + Name-идентификатор) с ранним выходом, без type-specific правил.
Имена типов взяты из LocalName реальных файлов корпуса. По-настоящему неизвестный
тип по-прежнему отвергается.
Побочно: прощающий ввод для плоских объектов (один .xml без папки —
SessionParameter, CommonAttribute, DefinedType, ...) — раньше не находились по
голому имени Dir/Name (fallback покрывал только папочные Dir/Name/Name.xml),
добавлено дописывание .xml.
Тесты (фикстуры не самописные): valid-sessionparameter-basic (meta-compile preRun) +
real-erp-sessionparameter (external, скип на Mac) + error-unknown-type (реальный
каталог корпуса с переименованным корневым тип-элементом). meta-validate 21/21 ps1+py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Check 16: все <v8:Type> вида CatalogRef.X / DocumentRef / EnumRef / DefinedType /
ChartOf*Ref / BusinessProcessRef / ExchangePlanRef / TaskRef проверяются на наличие
объекта в конфигурации (Dir/X.xml или папка Dir/X).
WARN-уровень, не error: ложное срабатывание на частичных выгрузках хуже пропуска.
Расширения (CFE) пропускаются по маркеру ConfigurationExtensionPurpose — их типы
ссылаются на объекты базовой конфигурации, отсутствующие в выгрузке расширения.
Дедуп по ref-ключу; маппинг тип→каталог согласован с TYPE_TO_DIR (verify-snapshots).
Тесты: valid-reftype-resolves (self-ref, -Detailed, OK) + warn-reftype-missing
(WARN, exit 0). meta-validate 18/18 ps1+py. Анти-дрейф OK.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Check 15: команды в ChildObjects — Group обязателен и валиден (allowlist групп
раздела/формы + CommandGroup.<Имя>); секционная группа (NavigationPanel*/ActionsPanel*)
несовместима с commandParameterType; UUID/Name команды. Зеркало правил meta-compile v1.65
(команды раньше не валидировались вообще → пустой/неверный Group уходил в load-ошибку).
ps1+py идентично.
Тесты: valid-catalog-commands (preRun, группы раздела+формы) + 2 expectError-fixture
(пустая группа; секц.группа+параметр). meta-validate 16/16 ps1+py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Category добавлена в validEnumValues (NavigationPanel/ActionsPanel/FormCommandBar/
FormNavigationPanel) — опечатка даёт ошибку со списком валидных, как у прочих
перечислений. Симметрично валидации group у команд. Зеркало ps1+py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CommandGroup.category — допустимые значения (из upload/meta/CommandGroups):
NavigationPanel/ActionsPanel (командный интерфейс раздела) или FormCommandBar/
FormNavigationPanel (командный интерфейс формы). + связь с command.group=CommandGroup.<Имя>.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
«Секционные» — выдуманный термин, в 1С его нет. Группы противопоставляются как
командный интерфейс РАЗДЕЛА (панель навигации/действий) и ФОРМЫ. Поправлены
reference/blocks.md, тексты ошибок и комментарии (ps1+py). Поведение не изменилось
(имена переменных внутренние; expectError-подстроки на месте).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Emit-Command: резолв группы (Resolve-CommandGroup) — русские подписи групп
(«Панель навигации.Важное» → NavigationPanelImportant и т.д.), `ГруппаКоманд.X`
→ `CommandGroup.X`. Закрыты два пробела валидации (найдены при 1С-cert):
- пустая/опущенная group → ошибка с подсказкой (список валидных групп), а не
молчаливый незагружаемый <Group/>;
- секционная группа (NavigationPanel*/ActionsPanel*) + commandParameterType →
ошибка (тип параметра доступен только для групп формы/CommandGroup — подтверждено
выгрузкой ЕРП: команды с параметром только в Form*/CommandGroup).
Списки групп из реального erp_8.3.24. Зеркало ps1+py (идентично).
reference/blocks.md: каноничный список групп + правило параметра (без прощающего
ввода — usage-голос). Тесты: catalog-command-groups (рус-синонимы/секц/форма/кастом
через preRun CommandGroup, 1С-cert ✓) + 2 expectError (пустая group; секц+параметр).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DocumentJournal добавлен в список поддерживаемых типов form-add — журналы
теперь принимают форму (списочную, через общий DynamicList-путь). Нужно для
1С-сертификации журналов, ссылающихся на собственную defaultForm. Зеркало ps1+py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
В charts.md createOnInput был документирован у ChartOfCharacteristicTypes,
но не у ChartOfAccounts/ChartOfCalculationTypes (в одном файле — несогласованно,
читатель мог решить, что у них его нет). Добавлен с фактическим значением
DontUse (как эмитит компилятор).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Единый дефолт Managed вместо per-type Automatic/Managed — удобно для создания
новых объектов (Automatic задаётся явно). Роундтрип остаётся байт-в-байт:
дефолт компилятора и порог omit-on-default декомпилятора сдвинуты синхронно —
объекты с Automatic теперь несут ключ в DSL явно, с Managed — опускают,
итоговый XML с обеих сторон не меняется. Зеркало ps1+py в обоих навыках.
Заодно вылечена латентная рассинхронизация AccountingRegister/CalculationRegister
(компилятор Automatic vs порог Managed).
Верификация: роундтрип-инвариант на реальном корпусе 7/7 match, 0 диффов
(Automatic+Managed справочники, ПС, Sequence, РБ); полный набор тестов 514/514;
пересъём снэпшотов — 91 файл, дрейф ровно DataLockControlMode Automatic->Managed,
ноль посторонних; py-паритет.
meta-compile v1.63 / meta-decompile v0.54
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Порезал документацию по слою абстракции и форме DSL вместо внутренней
таксономии 1С: тонкий SKILL.md с двухосевым индексом + 13 reference-файлов
(по типу/семейству + кросс-типовые attributes.md/blocks.md) взамен 4 types-*.md.
Вынес в поставку объектную форму реквизита/ТЧ и блоки объекта (fillValue,
choiceParameters, представления, команды, predefined и т.д.) — раньше жили
только в dev-спеке, модель их не видела. Usage-голос: каноничная форма,
дефолты, значения перечислений; без внутряка (синонимы/резолв/декомпилятор,
колонка XML). Починены противоречия дефолтов и убраны фантомные свойства
(по аудиту компилятора).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Порт meta-decompile.ps1 → meta-decompile.py 1:1 (lxml.etree для полного XPath 1.0,
собственный JSON-эмиттер зеркалирован, split_camel_words идентичен meta-compile.py).
Трапы: -ne CI vs -cne CS (Predef-счета/виды расчёта); unwrap одноэлементного @() при
return $arr в Parse-ChoiceParameter* (без ,$arr) → скаляр. Валидация: побайтовая сверка
ps1==py 2639/2639 (acc+erp, все 35 типов), паритет кодов выхода.
Переработка SKILL.md: инструкция под реальный кейс — заготовка для сборки НОВОГО объекта
по образцу; предупреждение о потере идентичности (UUID/модули/формы не сохраняются →
не для правки/бэкапа/переноса того же объекта).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24-й тип. Решение по общим формам (совместно с пользователем): meta-compile делает то,
что вне компетенции form-compile — МЕТАДАННЫЕ + структуру файлов + регистрацию (как
form-add для форм объектов); СОДЕРЖИМОЕ формы (Ext/Form.xml) наполняет form-compile,
оно НЕ роундтрипится.
- Метаданные CommonForm: FormType(Managed)/IncludeHelpInContents/UsePurposes(набор
ApplicationUsePurpose, дефолт [Platform+MobilePlatform]Application)/UseStandardCommands
(дефолт false, корпус 1314/760)/презентации. Без InternalInfo/ChildObjects.
- **Заготовка структуры под компиляцию**: Ext/Form.xml (пустая управляемая форма —
AutoCommandBar+ChildItems, зеркало form-add) + Ext/Form/Module.bsl + регистрация
<CommonForm> в Configuration.xml. form-compile/form-edit далее наполняют форму.
- Декомпилятор: гейт +CommonForm; захват formType/usePurposes(omit при дефолте)/
extendedPresentation; useStandardCommands дефолт false (как Enum).
МЕТАДАННЫЙ роундтрип: ПОЛНЫЙ КОРПУС acc+erp 836/836 byte-exact, TOTAL 0. Регресс 62/62
ps1+py, ps1==py identical (вкл. Form.xml/Module.bsl-заготовку). spec §7.15e, кейс common-form.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18-й тип, 1381 объект acc+erp. Компилятор НЕ поддерживал FO вовсе (новый тип
с нуля): +validTypes/typePluralMap/dispatch/Emit-FunctionalOptionProperties +
рус.синоним ФункциональнаяОпция. FO без InternalInfo/ChildObjects/модулей —
Emit-InternalInfo уже раннее-возвращает без generatedTypes-записи, ChildObjects/
модули гейтятся списками типов → FO их не получает.
- Свойства: Location (хранилище значения), PrivilegedGetMode (дефолт true —
корпус 2864/2864), Content (список зависимых объектов → <xr:Object>). Декомпилятор
снят гейт +FO; захват location/privilegedGetMode(omit-true)/content.
- Прощающий ввод MDObjectRef-путей (Normalize-MDObjectRef): русские корни
метаданных+подвидов (Документ→Document/ТабличнаяЧасть→TabularSection/Реквизит→
Attribute/Измерение→Dimension/Ресурс→Resource/…) на чётных позициях-видах; имена
не трогаются. Только компилятор (декомпилятор пишет полный англ. путь →
роундтрип byte-exact). Location/Content — полные внешние ссылки, self-формы нет.
ПОЛНЫЙ КОРПУС 1381: 1380 byte-exact order-preserved + 1 MAX_PATH-артефакт харнеса
(имя 157 симв.; объект компилируется в короткий путь ✓). Регресс 55/55 ps1+py,
ps1==py identical. spec §7.7a, кейс functional-option.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
14-й/15-й типы, 2546 объектов acc+erp. Рерайт Emit-ReportProperties/
Emit-DataProcessorProperties на общие хелперы (был легаси-хардкод Comment/
UseStandardCommands/формы/презентации). Декомпилятор: снят гейт +оба;
Report-специфика (defaultForm/mainDataCompositionSchema/*SettingsForm/
defaultVariantForm/variantsStorage/settingsStorage/extendedPresentation),
DataProcessor-специфика (defaultForm/auxiliaryForm/extendedPresentation).
Общие фиксы (не только Report/DataProcessor):
- Emit-VerbatimRef: ссылки форм/схем/хранилищ без Normalize-FormRef — имя формы
может быть буквально «Форма» (Normalize перевёл бы имя-сегмент Форма→Form).
- Пустой <Type/> (реквизит без типа): маркер typeEmpty (декомпилятор type:"",
компилятор <Type/> + FillValue nil вместо xs:string). Отличаем present-"" от absent.
- Платформенные типы v8:-префикса (ValueTable/ValueTree/ValueList/StandardPeriod/…),
current-config cfg:-типы (ConstantsSet/ReportBuilder/*Object.X), выделенные ns
(Chart/SettingsComposer/SpreadsheetDocument) — компилятор возвращал голое имя.
- Expand-DataPath: голый (отрицательный) индекс-маркер (-8 в ChoiceParameterLinks) verbatim.
Class-2: UseStandardCommands дефолт true (совместно с пользователем — авторски-
безопасно: доступность через стандартный командный интерфейс; при false и без
переопределения размещения команд объект доступен лишь по навигационной ссылке).
Декомпилятор явно фиксирует false. У DataProcessor мода корпуса и так true.
ПОЛНЫЙ КОРПУС 2546: match 2546/2546, TOTAL 0, byte-exact order-preserved (сверено
с реальными 1С-файлами). Регресс 52/52 ps1+py, ps1==py identical. spec §7.11/§7.12,
кейсы report-full/data-processor-full.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Блок «Register in Configuration.xml» py-порта пересоздавал весь файл через
ElementTree.write, который объявляет в корне только namespace из имён элементов/
атрибутов и молча выкидывает объявления, живущие лишь в значениях атрибутов
(xsi:type="app:ApplicationUsePurpose" в UsePurposes). Необъявленный префикс → XDTO
читает значение как anyType → Конфигуратор отказывается грузить Configuration.xml.
Теперь ET используется только read-only (поиск ChildObjects + проверка дубля), а
запись — текстовой вставкой в исходное содержимое с сохранением BOM/EOL/всех xmlns
байт-в-байт (как уже делает subsystem-compile). Многострочная группировка по типу,
обработка self-closing <ChildObjects/>, идемпотентность сохранены.
PS1-порт (XmlDocument хранит xmlns как атрибутные узлы) багу не подвержен —
функциональных правок нет, версия синхронно поднята до v1.15.
tests(runner): снят xmlns-strip нормализатора для Configuration.xml — он маскировал
баг и прятал бы регрессии. Полный python-suite 472/472; на старом коде un-masked
runner ловит поломку (30/33). Радиус изменения нулевой (прочие навыки не роняют xmlns).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Тип метаданных Bot (Боты, платформа 8.3.18+) присутствует в
ChildObjects новых конфигураций, но не входил в зашитый список
типов — cf-validate падал с «Unknown type 'Bot'».
- cf-validate: Bot добавлен в список типов и маппинг каталогов (→ Bots)
- cf-edit: Bot в порядке типов + каталог + синоним DSL «бот»
- cf-info: Bot в порядке типов + рус. название «Боты»
- docs/1c-configuration-spec: Bot в перечне ChildObjects (поз. 11)
- tests: фикстуры + кейсы на Bot для cf-validate/cf-edit/cf-info
Позиция Bot — сразу после CommonModule (по выгрузке Конфигуратора).
Разнесение алгоритмов по версии формата/режиму совместимости
остаётся отдельной задачей бэклога.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Декомпилятор клал xs:decimal FillValue как строку ($fvText) → на составном типе
компилятор берёт xsi-тип из JSON-значения (строка "0" → xs:string, число 0 →
xs:decimal) → тип терялся, регенерился xs:string вместо xs:decimal. У плоского
Number эмиссия и так type-aware, поэтому вылезало только на составных.
Фикс: захват decimal как число ([long]/[double]). Роундтрип Document match
130→142, TOTAL 62→24. Catalog без изменений (52/12), 0 крашей.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Загрузка XML с PreserveWhitespace=false рубила пробельное содержимое → FillValue
из одних пробелов (`<xr:FillValue xsi:type="xs:string"> </>`) декомпилировался
как пустой → компилятор эмитил typed-empty, роундтрип диффил (known NOT COVERED
с v1.27). Включение PreserveWhitespace=true захватывает пробелы, компилятор их
эмитит через Esc-XmlText.
Чистый выигрыш без регрессий (валидировано): Catalog match 44→52, TOTAL 28→12;
Document match 118→130, TOTAL 94→62; 0 крашей, 0 паразитных whitespace-ADDED.
Остаток FillValue — нишевые typed-fillValue (LineNumber decimal-0, composite-Number
type-loss, DTR).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Get-ChoiceParamValue возвращал 1-элементный ArrayList → PowerShell разворачивал
коллекцию при `return` в скаляр → FixedArray с одним элементом декомпилировался как
скалярное значение → компилятор эмитил `app:value` вместо `v8:FixedArray`+`v8:Value`.
Фикс: унарная запятая `return ,$arr`. Многоэлементные массивы не задевало (не
разворачиваются). Компилятор на явном `["x"]` был корректен — баг чисто декомпиляторный.
Роундтрип Document: Attribute>Value 54→0, TOTAL 166→94, match 109→118/151.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
В конфигураторе «Количество субконто» недоступно, пока не указан план видов характеристик видов
субконто. Зеркалим: дефолт maxExtDimensionCount = 3 при заданном extDimensionTypes, иначе 0.
Раньше компилятор всегда ставил 3 → план счетов «с нуля» без ПВХ был невалиден для 1С
(«у плана счетов с количеством субконто ≠ 0 должен быть установлен план видов характеристик»).
Декомпилятор зеркалит дефолт (с ПВХ 3, без 0) → omit-on-default сохранён. Роундтрип 3/3 match
(корпус несёт ПВХ → 3 опускается, без изменений). Регресс 47/47 ps1+py, form-compile 12/12.
spec §7.2c.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
«Только обороты» (<Turnover>) — предопределённый (встроенный) признак учёта субконто. Теперь он
выражается токеном `Turnover` (синонимы ТолькоОбороты/«Только обороты») в том же списке признаков,
что и добавленные: "Номенклатура | Turnover, Суммовой". Строковая форма стала полностью
самодостаточной — объектная {type, turnover?, flags?} остаётся принимаемым эквивалентом.
Компилятор вынимает токен turnover из списка flags (регистронезависимо) → <Turnover>true.
Декомпилятор всегда пишет строкой, ставя `Turnover` первым при Turnover=true (объектную форму
больше не порождает). Роундтрип 3/3 match; обе формы + смешанный массив проверены, ps1↔py identical.
Регресс 47/47 ps1+py. spec §7.2c.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Предопределённые виды характеристик несут тип значения на элемент. Раньше это
требовало объектной формы; теперь тип выражается короткой строкой после ':' —
как в полях СКД/реквизитах:
"(Код) Имя [Наименование]: Тип" (тип составной через '+')
Правило: нет ':' → без блока Type (Catalog-стиль); непустой тип → короткая
строка; пустой <Type/> / папки / с детьми → объектная форма (ключ type).
Разбор зеркалит Parse-CalcShorthand: сначала вынуть [Наим] (может содержать ':'),
затем отделить тип по ':'. Компилятор принимает обе формы, декомпилятор пишет
короткую для плоских элементов.
На ВидыСубконтоХозрасчетные все 63 предопределённых из объектов стали
компактными строками. Роундтрип/вывод XML не меняется (52 TOTAL). Регресс 47/47
ps1+py, ps1↔py identical. spec §7.2b, кейс chart-of-characteristic-types.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Третий тип после Catalog/ExchangePlan. Декомпилятор расширен на ПВХ. Компилятор
Emit-ChartOfCharacteristicTypesProperties переписан на общие хелперы в каноническом
порядке; новое — блок Type (тип значения характеристики, составной) и
CharacteristicExtValues; иерархия папки+элементы. StandardAttributes-профиль ПВХ
(Наименование=ShowError, Родитель=FFV=true), блок условный.
Крупная новая фича — предопределённые виды несут ТИП НА ЭЛЕМЕНТ: ключ `type` в
объектной форме predefined (строка/массив; '' → пустой <Type/>). Root-элемент
PlanOfCharacteristicKindPredefinedItems.
Общие фиксы (не только ПВХ):
• Get-TypeShorthand ищет квалификаторы String/Number/Date по всему typeNode —
составной тип значения группирует квалификаторы в конце, не сразу за типом.
• Expand-DataPath гард [:/]: спец-путь 0:GUID/0:GUID (зависимости ПВХ) не разворачивается.
• Контекст реквизита ПВХ = catalog (у него полные Use/FillFromFillingValue/DataHistory).
• TabularSection Use, GeneratedType Characteristic-префикс, CodeSeries +WholeCharacteristicKind.
Роундтрип 24 ПВХ: match 0→16, TOTAL 4929→52 (−99%). Остаток (8) — принятые хвосты
(FillValue-пробелы, TS-LineNumber-опущение). Catalog/EP не регрессировали
(108/120, 39/42). Регресс 47/47 ps1+py, ps1↔py identical (6/6 ПВХ). spec §7.2b,
кейс chart-of-characteristic-types (+valueType/predefined-with-type/standardAttributes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>