From 79beba2d1fa2ca372203f25ad96a2ac9125421cd Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 26 Jul 2026 16:25:38 +0300 Subject: [PATCH] =?UTF-8?q?fix(xdto-compile,xdto-validate):=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=B7=D0=BD=D0=B0=D0=BA=20=D1=84=D0=B8=D0=BA=D1=81=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B7?= =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B1=D0=B5=D0=B7?= =?UTF-8?q?=20=D1=81=D0=B0=D0=BC=D0=BE=D0=B3=D0=BE=20=D0=B7=D0=BD=D0=B0?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В модели XDTO fixed — булев признак, а значение лежит в default; в XML-схеме fixed="V" совмещает и признак, и значение. Компилятор оба идиома принимал, но не проверял принятое: зеркало xdto:fixed="true" без default собиралось молча в пакет, который платформа отвергает («Отсутствует фиксированное значение свойства»). Прощающий ввод был сделан наполовину. xdto-validate v1.1 — два ERROR: значение попало в признак (fixed не булев) и признак без значения. Формулировка второго повторяет платформенную дословно, чтобы отказ загрузки и наш вывод читались как одно и то же. xdto-compile v1.1 — то же условие предупреждением на сборке, то есть на шаг раньше db-update, где починить дешевле. Кейсы: оба идиома плюс только default и атрибут (загружается в базу); зеркало без значения — проверка диагностики, из платформенной верификации исключено штатным skipPlatformVerify, пакет невалиден by design. Правило откалибровано корпусом (760 пакетов, оба рантайма): 0 ложных срабатываний, состав предупреждений не изменился. Round-trip остался 760/760 байт-в-байт. Co-Authored-By: Claude Opus 5 (1M context) --- .../xdto-compile/scripts/xdto-compile.ps1 | 5 +- .../xdto-compile/scripts/xdto-compile.py | 6 +- .../xdto-validate/scripts/xdto-validate.ps1 | 15 +- .../xdto-validate/scripts/xdto-validate.py | 19 +- .../cases/xdto-compile/fixed-idioms.json | 9 + .../cases/xdto-compile/fixed-idioms.xsd | 13 + .../xdto-compile/fixed-mirror-no-value.json | 15 ++ .../xdto-compile/fixed-mirror-no-value.xsd | 10 + .../snapshots/fixed-idioms/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../fixed-idioms/Languages/Русский.xml | 16 ++ .../XDTOPackages/fixed_idioms.xml | 16 ++ .../XDTOPackages/fixed_idioms/Ext/Package.bin | 8 + .../snapshots/fixed-idioms/fixed-idioms.xsd | 13 + .../xdto-validate/fixed-without-value.json | 17 ++ .../pkg-fixed/XDTOPackages/fixedbad.xml | 16 ++ .../XDTOPackages/fixedbad/Ext/Package.bin | 8 + 17 files changed, 450 insertions(+), 6 deletions(-) create mode 100644 tests/skills/cases/xdto-compile/fixed-idioms.json create mode 100644 tests/skills/cases/xdto-compile/fixed-idioms.xsd create mode 100644 tests/skills/cases/xdto-compile/fixed-mirror-no-value.json create mode 100644 tests/skills/cases/xdto-compile/fixed-mirror-no-value.xsd create mode 100644 tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Configuration.xml create mode 100644 tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms.xml create mode 100644 tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-compile/snapshots/fixed-idioms/fixed-idioms.xsd create mode 100644 tests/skills/cases/xdto-validate/fixed-without-value.json create mode 100644 tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad.xml create mode 100644 tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad/Ext/Package.bin diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 index 3d211d41..69225b1f 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 @@ -1,4 +1,4 @@ -# xdto-compile v1.0 — Build a 1C XDTO package from an XML Schema (XSD) +# xdto-compile v1.1 — Build a 1C XDTO package from an XML Schema (XSD) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory=$true, ParameterSetName='File')] @@ -465,6 +465,9 @@ function Build-Property([System.Xml.XmlElement]$el, [bool]$isAttribute) { if ($null -ne $mFixed) { Add-Attr $p "fixed" $mFixed Add-Attr $p "default" (XA $el "default") + if ($mFixed -ceq "true" -and $null -eq (XA $el "default")) { + Warn "Свойство `"$(XA $el 'name')`": xdto:fixed=`"true`" без default — платформа отвергнет пакет («Отсутствует фиксированное значение»). Значение задаётся атрибутом default, либо пишите XSD-форму fixed=`"значение`"" + } } elseif ($null -ne (XA $el "fixed")) { Add-Attr $p "fixed" "true" Add-Attr $p "default" (XA $el "fixed") diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.py b/.claude/skills/xdto-compile/scripts/xdto-compile.py index d02da784..cb2c1e77 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.py +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.py @@ -1,4 +1,4 @@ -# xdto-compile v1.0 — Build a 1C XDTO package from an XML Schema (XSD) (Python port) +# xdto-compile v1.1 — Build a 1C XDTO package from an XML Schema (XSD) (Python port) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -516,6 +516,10 @@ def build_property(el, is_attribute): if m_fixed is not None: add_attr(p, "fixed", m_fixed) add_attr(p, "default", el.get("default")) + if m_fixed == "true" and el.get("default") is None: + warn('Свойство "' + str(el.get("name")) + '": xdto:fixed="true" без default — ' + "платформа отвергнет пакет («Отсутствует фиксированное значение»). " + 'Значение задаётся атрибутом default, либо пишите XSD-форму fixed="значение"') elif el.get("fixed") is not None: add_attr(p, "fixed", "true") add_attr(p, "default", el.get("fixed")) diff --git a/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 b/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 index 3a79b0ef..8d4ba159 100644 --- a/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 +++ b/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 @@ -1,4 +1,4 @@ -# xdto-validate v1.0 — Validate a 1C XDTO package +# xdto-validate v1.1 — Validate a 1C XDTO package # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -363,9 +363,20 @@ foreach ($p in $pkg.SelectNodes("//*[local-name()='property']")) { if (-not $p.HasAttribute("name") -and -not $p.HasAttribute("ref")) { Report-Error "Свойство без name и без ref" } + # В модели XDTO fixed — булев признак, само значение лежит в default. + # В XML-схеме наоборот: fixed="V" совмещает признак и значение. + if ($p.HasAttribute("fixed")) { + $fx = $p.GetAttribute("fixed") + $pName = if ($p.HasAttribute("name")) { $p.GetAttribute("name") } else { $p.GetAttribute("ref") } + if (@("true", "false") -cnotcontains $fx) { + Report-Error "Свойство `"$pName`": fixed=`"$fx`" — в модели это булев признак, значение задаётся в default (в XML-схеме признак и значение совмещены в fixed)" + } elseif ($fx -ceq "true" -and -not $p.HasAttribute("default")) { + Report-Error "Отсутствует фиксированное значение свойства '$pName': есть fixed=`"true`", нет default" + } + } if ($script:stopped) { break } } -if (-not $script:stopped) { Report-OK "Свойства: form и кратности корректны" } +if (-not $script:stopped) { Report-OK "Свойства: form, кратности и фиксированные значения корректны" } # --- 10b. Structural consistency --- diff --git a/.claude/skills/xdto-validate/scripts/xdto-validate.py b/.claude/skills/xdto-validate/scripts/xdto-validate.py index 57437cc7..880feef7 100644 --- a/.claude/skills/xdto-validate/scripts/xdto-validate.py +++ b/.claude/skills/xdto-validate/scripts/xdto-validate.py @@ -1,4 +1,4 @@ -# xdto-validate v1.0 — Validate a 1C XDTO package (Python port) +# xdto-validate v1.1 — Validate a 1C XDTO package (Python port) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os @@ -385,10 +385,25 @@ for p in pkg.iter(): report_error(f'Свойство "{p.get("name")}": lowerBound ({lb}) больше upperBound ({ub})') if p.get("name") is None and p.get("ref") is None: report_error("Свойство без name и без ref") + # В модели XDTO fixed — булев признак, само значение лежит в default. + # В XML-схеме наоборот: fixed="V" совмещает признак и значение. + fx = p.get("fixed") + if fx is not None: + p_name = p.get("name") if p.get("name") is not None else p.get("ref") + if fx not in ("true", "false"): + report_error( + f'Свойство "{p_name}": fixed="{fx}" — в модели это булев признак, ' + "значение задаётся в default (в XML-схеме признак и значение совмещены в fixed)" + ) + elif fx == "true" and p.get("default") is None: + report_error( + f"Отсутствует фиксированное значение свойства '{p_name}': " + 'есть fixed="true", нет default' + ) if state["stopped"]: break if not state["stopped"]: - report_ok("Свойства: form и кратности корректны") + report_ok("Свойства: form, кратности и фиксированные значения корректны") # ── 10b. structural consistency ────────────────────────────── diff --git a/tests/skills/cases/xdto-compile/fixed-idioms.json b/tests/skills/cases/xdto-compile/fixed-idioms.json new file mode 100644 index 00000000..4aa7f72a --- /dev/null +++ b/tests/skills/cases/xdto-compile/fixed-idioms.json @@ -0,0 +1,9 @@ +{ + "name": "оба идиома fixed: XSD-форма fixed=\"значение\" и модельное зеркало xdto:fixed", + "caseFiles": ["fixed-idioms.xsd"], + "params": { "xsdFile": "fixed-idioms.xsd" }, + "validatePath": "XDTOPackages/fixed_idioms", + "expect": { + "files": ["XDTOPackages/fixed_idioms.xml", "XDTOPackages/fixed_idioms/Ext/Package.bin"] + } +} diff --git a/tests/skills/cases/xdto-compile/fixed-idioms.xsd b/tests/skills/cases/xdto-compile/fixed-idioms.xsd new file mode 100644 index 00000000..72e31147 --- /dev/null +++ b/tests/skills/cases/xdto-compile/fixed-idioms.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/tests/skills/cases/xdto-compile/fixed-mirror-no-value.json b/tests/skills/cases/xdto-compile/fixed-mirror-no-value.json new file mode 100644 index 00000000..253ce21c --- /dev/null +++ b/tests/skills/cases/xdto-compile/fixed-mirror-no-value.json @@ -0,0 +1,15 @@ +{ + "name": "зеркало xdto:fixed=\"true\" без default — предупреждение на сборке, а не отказ платформы на db-update", + "caseFiles": ["fixed-mirror-no-value.xsd"], + "params": { "xsdFile": "fixed-mirror-no-value.xsd" }, + "expect": { + "files": ["XDTOPackages/fixed_mirror_no_value.xml", "XDTOPackages/fixed_mirror_no_value/Ext/Package.bin"], + "stdoutContains": [ + "БезЗначения", + "xdto:fixed=\"true\" без default", + "Отсутствует фиксированное значение" + ] + }, + "noSnapshot": "проверяется диагностика сборки; заведомо невалидный пакет эталоном фиксировать нечего", + "skipPlatformVerify": "пакет невалиден by design — кейс проверяет, что о его невалидности предупредят на сборке; платформа отвергает его теми же словами («Отсутствует фиксированное значение свойства»)" +} diff --git a/tests/skills/cases/xdto-compile/fixed-mirror-no-value.xsd b/tests/skills/cases/xdto-compile/fixed-mirror-no-value.xsd new file mode 100644 index 00000000..3f5f0543 --- /dev/null +++ b/tests/skills/cases/xdto-compile/fixed-mirror-no-value.xsd @@ -0,0 +1,10 @@ + + + + + + + diff --git a/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Configuration.xml b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Configuration.xml new file mode 100644 index 00000000..30d3b85c --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + fixed_idioms + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Languages/Русский.xml b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms.xml b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms.xml new file mode 100644 index 00000000..7816ac50 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms.xml @@ -0,0 +1,16 @@ + + + + + fixed_idioms + + + ru + fixed_idioms + + + + urn:test:fixed + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms/Ext/Package.bin b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms/Ext/Package.bin new file mode 100644 index 00000000..43a51af0 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/XDTOPackages/fixed_idioms/Ext/Package.bin @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/fixed-idioms.xsd b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/fixed-idioms.xsd new file mode 100644 index 00000000..72e31147 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/fixed-idioms/fixed-idioms.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/tests/skills/cases/xdto-validate/fixed-without-value.json b/tests/skills/cases/xdto-validate/fixed-without-value.json new file mode 100644 index 00000000..f053e200 --- /dev/null +++ b/tests/skills/cases/xdto-validate/fixed-without-value.json @@ -0,0 +1,17 @@ +{ + "name": "fixed без значения и значение внутри fixed — платформа такой пакет отвергает", + "caseFiles": [ + "pkg-fixed/XDTOPackages/fixedbad.xml", + "pkg-fixed/XDTOPackages/fixedbad/Ext/Package.bin" + ], + "params": { "packagePath": "pkg-fixed/XDTOPackages/fixedbad" }, + "expectError": true, + "expect": { + "stdoutContains": [ + "Отсутствует фиксированное значение свойства 'БезЗначения'", + "Свойство \"ЗначениеВПризнаке\": fixed=\"Р\"" + ], + "stdoutNotContains": ["Правильное", "НеФиксированное"] + }, + "noSnapshot": "навык только читает — сравнивать нечего, проверка через stdoutContains" +} diff --git a/tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad.xml b/tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad.xml new file mode 100644 index 00000000..ac88a7bb --- /dev/null +++ b/tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad.xml @@ -0,0 +1,16 @@ + + + + + fixedbad + + + ru + fixedbad + + + + urn:test:fixedbad + + + diff --git a/tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad/Ext/Package.bin b/tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad/Ext/Package.bin new file mode 100644 index 00000000..73fb8243 --- /dev/null +++ b/tests/skills/cases/xdto-validate/pkg-fixed/XDTOPackages/fixedbad/Ext/Package.bin @@ -0,0 +1,8 @@ + + + + + + + +