Кейсы клали расширение в `ext`, а cf-init создаёт в корне конфигурации платформенный `Ext/`.
На регистронезависимой ФС (Windows, APFS) это один каталог: эталоны годами фиксировали
слипшееся дерево — в snapshots/<case>/ext/ лежали вперемешку ClientApplicationInterface.xml
конфигурации и Configuration.xml расширения, а имя каталога в коммите зависело от того, кто
создал его первым (ext у одних кейсов, Ext у других при одинаковом входе). На Linux те же
кейсы дали бы два каталога и другой снапшот.
Переименование механическое: 64 кейса пяти навыков, 349 файлов эталонов переехали без
единой правки содержимого. Заодно переписан регистр 21 пути в индексе — git с core.ignorecase
не показывал, что файл конфигурации числится под ext/, а лежит в Ext/.
Гард в runner.mjs: имя каталога расширения из params, совпавшее без учёта регистра с тем, что
уже есть в фикстуре, валит кейс с объяснением. Проверено, что старое имя теперь не проходит.
verify-snapshots.mjs чинится тем же заходом — там нашлись две дыры:
- каталог расширения был захардкожен как 'ext', поэтому кейсы с другим именем МОЛЧА теряли
вторую половину проверки: блок загрузки расширения обходился по existsSync и в отчёте это
выглядело успехом;
- setup брался только из _skill.json, и кейсы с гейтом по версии формата (218/220/221)
проверялись на конфигурации 2.17 — то есть платформа не видела ровно того поведения, ради
которого кейс написан.
Плюс два honest-skip вместо ложных падений: режим совместимости выше платформы и формат
выгрузки новее платформы (второе читаем из ответа платформы, а не дублируем лестницу версий).
Проверено: регресс 827/0/8 (ps1) и 824/0/11 (py), гарды 5/5. Платформенная верификация:
cfe-borrow 26/28 на 8.3.27, cfe-patch-method 22/23, cfe-init 6/7, все 14 кейсов format-221
на 8.5 — остальное осознанные пропуски.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Заимствование дочерних объектов в оболочку шло по трём источникам имён:
*DataPath, <Field> и <AdditionalColumns table=...>. У формы списка с ручным
запросом реквизиты упомянуты ещё и в тексте запроса, и они не заимствовались:
на эталоне Issue66Example2 навык брал 5 реквизитов и 0 табличных частей,
Конфигуратор — 17 и 4.
Правило выведено по эталонам и совпадает с ними в обе стороны: Конфигуратор
переносит то, на что ссылается форма, а у динамического списка с ручным
запросом текст запроса — такое же место ссылки, как DataPath. Имена, которые
встречаются в <QueryText> целым словом, — это 21 из 27 дочерних объектов, и
множество совпадает со взятым Конфигуратором точно.
Разбирать язык запросов не нужно: имена-кандидаты и так фильтруются по
реальному составу объекта, поэтому лишние слова из запроса безвредны.
Состав оболочки теперь совпадает с эталонами на всех четырёх случаях:
форма документа 47 реквизитов и 2 ТЧ, список с запросом 17 и 4, список без
запроса 3 и 0 (Issue66Example3 — там правило «только видимое на форме», и
поведение не меняется), форма записи регистра 3 измерения и 1 ресурс.
По корпусу (13796 форм УТ + ERP) списков с запросом 2584, без него 2411.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Кейсов на эти сценарии не было ни одного, поэтому оба дефекта жили молча.
Фикстура main-attr-kinds: документ с табличной частью и тремя формами
(документа, списка с динамическим списком и <Settings>) плюс регистр
сведений с измерением и ресурсом и его форма записи.
Три кейса:
- форма списка с -BorrowMainAttribute: реквизит «Список» типа DynamicList
переносится вместе с <Settings>, пути «Список.*» не вырезаны, «Объект» и
придуманного <SavedData> в выходе нет;
- форма записи регистра: реквизит «Запись» нужного типа, а в оболочке
<Dimension>/<Resource>, а не <Attribute>;
- повторное заимствование по объекту с табличной частью: второй заход
добавляет недостающий реквизит, ТЧ не вложены друг в друга.
Все три падают на коде до правок и проходят после.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>