История изменений
Что менялось в инструментарии xbsl от версии к версии, с разбивкой по дням.
Заметные изменения инструментария xbsl – движка на Python, на котором работают линтер, серверы
LSP и MCP, индекс документации и скаффолдинг метаданных. Записи сгруппированы по дням; версии,
вышедшие в этот день, перечислены в заголовке. Формат основан на
Keep a Changelog, проект следует
семантическому версионированию. У расширения VS Code своя история в
editors/vscode/CHANGELOG.ru.md.
Записи используют русские написания имён метаданных платформы (Наименование, Код, Реквизиты);
английские написания – в английской истории.
06.09.2026 – 0.94.0
Добавлено
code/param-redeclared: локальнаязнч/пер/испс именем параметра своего же метода. Компилятор отвечает “Переменная с именем X уже определена” только при применении сборки, и стенд откатывается; линтер называет совпадение в строке объявления, вложенные блоки включительно, в обеих орфографиях. Переменные цикла ипоймать, параметры и тела лямбд не судятся: в корпусах их нет.docs_symbolиdocs_pageотвечают кратко или одним разделом. Страница типа – десять тысяч знаков: конструкторы, каждое свойство, списки унаследованного, – а вопросу “что это за страница и о чём она” хватает шапки:brief=Trueотдаёт краткое описание и имена разделов,section="Свойства"– шапку и один раздел (принимается и английское имя раздела); неизвестный раздел отвечает перечнем имён на выбор.- Посевы паритета покрывают 62 правила 120 посевами (было 41 посев на 23 правила). Правила, судящие текст по словарям платформы, – свойства реквизитов, компоненты форм, окружение модулей, язык запросов, размеры и компоновка, – несут теперь русский случай и английского близнеца, написанного руками; четыре известных пробела помечены причинами: два за словарём членов, два за переводчиком.
Изменено
meta_add_fieldназывает заведённую секцию и указывает на соседнюю (то же уadd-fieldи запроса LSPxbsl/metaAddField). Данные регистра лежат вИзмеренияиРесурсы, и реквизит, запрошенный у регистра с ресурсами без реквизитов, молча заводил новую секциюРеквизитыв конце файла – поле потом переставляли руками вместе с UUID. Секция заводится по-прежнему, ноnotesговорят об этом и называют вид поля (здесьресурс, и наоборот), который положил бы элемент рядом с существующими полями; элемент существующей секции, как и раньше, встаёт в её конец – теперь это держит тест.
Исправлено
- Переводчик пишет
.Ссылкафасета проекта словомReference(Строчка.Ссылка.ЗагрузитьОбъект()!->Line.Reference.LoadObject()!): приёмник, типизированный фасетом объекта проекта – объявленным, выведенным или загруженным из ссылки, – несёт слово фасета, приёмник без типа – когда цепочка дальше зовётЗагрузитьОбъект; свойствоСсылканадписи и картинки остаётсяLink, а квалифицированная запись словаря по-прежнему отвечает первой. - Умолчание, квалифицированное своим перечислением, переводится целиком
(
ЗначениеПоУмолчанию: Состояния.Открыт) там, где соседТипназывает перечисление проекта, – форма, о которой сообщаетyaml/enum-default-value, а английское дерево не могло её нести, пока значение оставалось русским. Автоу свойства с объединённым типом переводится (МаксимальнаяШирина: Авто,Высота: Авто,Подсказка: Авто->Auto): значение, совпадающее с членом объединения свойства, – этот член в написании платформенной пары типов, а не данные.yaml/ref-needs-nullableраспознаёт ссылочный тип и по английскому написанию фасета (Applications.Reference): yaml-ветка держала фасетСсылкав регулярке и в гейте, и переведённое описание проходило без замечания.code/member-kind-mismatchсудит вид члена и в английском написании типа и члена (TimeZone.Currentбез скобок): таблица видов ключуется русскими именами каталога (ЧасовойПояс.Текущий), обе стороны теперь приводятся к ним через словарь.
05.09.2026 – 0.93.0
Добавлено
meta_add_formумеет форму записи регистра сведений (forms=["record"]). У регистра нет формы объекта – правится его ЗАПИСЬ, и формуФормаЗаписи<Регистр.Запись>с полями по измерениям и ресурсам приходилось писать руками; заодно отказ по форме объекта теперь называет форму записи, а не одну лишь форму списка.meta_new_objectпринимает базовый тип компонента интерфейса (base). Заготовка всегда наследовала форму с шаблоном, а самый частый базовый тип живого проекта –Группа(31 против 7 у голой формы): весь блокНаследуетпереписывался руками.yaml/slot-needs-list(тир D, ошибка) – слот, описанный списком, получил один компонент. Компонент, записанный подСодержимое:без дефиса, – это не список из одного: yaml разбирается, ключи на месте, а применение отвергает разметку уже на сервере и откатывает проект на прежнюю сборку. Форму значения судит ui-схема, а не имя свойства: у шаблона формы то жеСодержимоезаконно держит один компонент.
04.09.2026 – 0.92.0
Добавлено
code/member-kind-mismatch(тир D, ошибка) – метод стандартной библиотеки, прочитанный как свойство, и свойство, вызванное как метод. Член существует, неверна форма обращения: применение отвергает проект сообщениемUnknown constantлибоUnknown method, и ни одно из них не называет ни вида члена, ни лечения.code/unknown-form-component(тир D, ошибка, файловое) – обращение к компоненту, которого нет в разметке формы.Компоненты.X– статическая карта из разметки, и имя без пары в ней не существует: применение отвергает проект, а до этого не видит никто – имя переживает компонент, который вынесли из разметки и не вернули.code/server-annotation-in-client-module(тир D, ошибка) – зеркало проверки клиентских аннотаций. Модуль сОкружение: Клиент, несущий@НаСервере, компилируется для сервера, где типа модуля нет, и применение отвергает каждый такой метод сообщением, в котором нет ни окружения, ни имени модуля.xbsl translate --unusedназывает пары, которых проект уже не использует;--pruneих снимает. Удаление кода оставляет за собой имена и строки комментариев, и сказать об этом было некому: строгий проход судит непокрытое, а таблица записей показывает, где пара объявлена, а не используется ли она.- Отчёт
xbsl translateговорит, когда словарь отстал от исходников – сколько файлов правились после него и какой из них позже всех (в json – полеdictionary_behind). Сверяются времена правки, поэтому отметка остаётся примечанием и вердикта не меняет.
Исправлено
- Тень имён проекта пропадала на файлах с CRLF. Регулярка, собирающая имена yaml, кончалась якорем конца строки, а в многострочном режиме он совпадает перед переводом строки. Пустая тень – это ложные находки правила уровня ошибки: объект проекта, названный как тип платформы, объявлялся неизвестным членом.
- Неизвестное значение
kindотвергается, а не отвечает пустым списком. Имя секции во множественном числе не совпадало ни с чем, и ответ приходил пустым – неотличимо от “словарь покрывает всё”; прогон, поверивший такому ответу, оставлял пробелы до строгого прохода. translate --setназывает перезаписанные пары. В отчёте был только счётчик, и какие именно ключи получили новое значение, оставалось искать диффом словаря.- Строка локализации со знаком, значимым для yaml, больше не ломает файл. Квотируется то, что без кавычек не прочиталось бы обратно; обычная фраза остаётся без кавычек. Новая строка дописывается и в готовые файлы перевода значением языка по умолчанию.
- Первое измерение регистра занимает место заглушки, а не встаёт рядом с ней, а
Длинастандартного поля проверяется инструментом: предел платформы ловил линтер следующим прогоном, по файлу, который инструмент уже написал. yaml/validназывает тернарное выражение с пробелами. YAML читает такое началом вложенного отображения, и жалоба приходит на строку, где отображения нет.- Клиентский общий модуль ловится у любого серверного потребителя, а не только у HTTP-сервиса, а три проверки окружения подняты до ошибки: матрица прогнана через компилятор, и каждый промах – отказ компиляции с откатом проекта.
- Номер сборки записывается в индекс только своей версии. Извлечение под чужим именем дописывало, что каталог держит сборку версии, из которой он никогда не брался.
02.09.2026 – 0.89.0, 0.90.0, 0.91.0
Добавлено
meta_add_fieldзнает стандартные реквизиты.НомериДатадокумента,Код,НаименованиеиВладелецсправочника судятся своим классом дескриптора – как их уже диспетчеризовалmetadata_schema, – поэтомуДлина,Уникальностьи блокАвтонумерацияпринимаются, а не отвергаются как неизвестные свойства обычного реквизита, иtypeможно не указывать там, где класс его задаёт. Значения свойств принимают вложенный блок словарём или ключом через точку и список последовательностью (CLI--prop, LSP и MCP одинаково); блок класса, которого метамодель не описывает, отвергается по имени как известное ограничение.meta_set_field_propertyпринимает те же формы и заменяет вложенный блок целиком.- У
lint_pathsпоявился параметрroot, как у инструментовmeta_*. Относительныеpathsиbaselineсчитаются от корня вызывающего, а не от рабочего каталога сервера, – сессия в git worktree больше не проверяет другой чекаут, принимая его чистый ответ за свой; находки несут абсолютные пути, сводка называетroot. code/foreign-not-public(тир D, error, по проекту) – сторона кода дляyaml/foreign-not-public. Обращение из модуля к элементу чужой подсистемы сОбластьВидимости: ВПодсистеме(или без свойства – это умолчание) компилятор отвергал на деплое, а линтер молчал:code/missing-importнепубличную цель нарочно не судит. Судятся позиции типов и корни цепочекМодуль.Метод(); модуль проекта вне подсистем – чужой для всех.xbsl baseline add <пути> --rule <правило> [--reason ...]дописывает в базлайн только новые находки одного правила: новый файл встаёт на своё место, остальное не двигается, чужие причины не трогаются, повтор ничего не меняет;--format jsonотдаёт{baseline, added, findings, written}. Сохранение бережёт переносы строк и BOM файла, новый файл пишется с LF.- У всех инструментов MCP
meta_*появился параметрroot– корень вызывающего: относительные пути считаются от него, а не от рабочего каталога сервера, ответы несут абсолютные пути и полеroot. - Посевы паритета: 27 новых посевов на 14 правил, судящих по словарям платформы; английский близнец посева пишется руками по данным, вывод переводчика сверяется третьим деревом.
Изменено
- Правила видимости читают биндинги и квалифицированные имена. Пробник, применённый на
сервере, отверг биндинг на непубличный элемент чужой подсистемы, квалифицированный биндинг
Подсистема::Элементи квалифицированное обращение из кода с тем жеТип "..." недоступен из-за модификатора видимости, что и позиции типов, – поэтомуyaml/foreign-not-publicсудит корни цепочек биндингов (за вычетом того, что объявляет парный модуль) и квалифицированные имена в биндингах и позициях типов, аcode/foreign-not-public– квалифицированные имена, по названной в них подсистеме. Правила импорта квалифицированную запись по-прежнему не трогают: импорт ей не нужен. - Отчёт
xbsl translateзаканчивается вердиктомГОТОВО/НЕ ГОТОВО: токенов N, фраз M– хвост лога больше не читается как успех при сотнях пропусков; в json добавленready, код возврата прежний. - Инструменты перевода отказывают, если словаря рядом с корнем нет, и называют, где его
ищут (и где он лежит, если ниже корня);
translate_gapsотдаётdictionary. CLI так же:--gapsбез словаря отказывает, отчёт пишетdictionaryв JSON. - Базлайн судится только в пределах запрошенных путей: записи чужих файлов –
непроверенные, не устаревшие (запрос двух файлов через MCP отвечал “0 погашено, 76
устаревших” на чистом проекте).
baseline_not_checkedразбит на_rulesи_paths. - Сводка называет, чем судили:
engine,pluginsс версиями,rules {active, total, plugin}в json CLI и ответах MCP, строка “Набор прогона” в тексте. - Экстрактор терминов кладёт члены классов Constants под их тип и дополняет
typesпарами из классов – чтобы они заработали, данные нужно пересобрать.
Исправлено
- Закрыты два пробела паритета:
yaml/unexpected-type-argumentиyaml/enum-needs-nullableсудят английское дерево так же, как русское. Первое отсекало только по ключуТип:, не канонизировало ни компонент, ни голову типа и сочло бы английское умолчание чужим; теперь ключ, компонент, свойство и голова канонизируются, а аргумент сравнивается с умолчанием имя за именем в любом написании. Второе узнавало поле ввода по рукописномуInputField, которого не пишет ни один сериализатор: платформа пишетEdit, и написания берутся из данных.code/reserved-nameтеперь сообщает и оTypeс заглавной – живой apply отверг его так же, какТипиtype. Посевов паритета 41, расхождений 0, известный пробел остался один (каталог членов). - Экстрактор терминов заполняет пробелы общей таблицы термами, заявленными классами. У
встроенного реквизита кода не было общего написания:
Code/Кодзаявляют термом десяток классов, а чтение по соседству отвергаетCodeкак английского кандидата – так называется атрибут class-файла. Без парыyaml/unknown-attribute-propertyтерпело ключи реквизита кода у любого реквизита английского дерева с латинским именем –Lengthу числа не сообщалось. Заявленный терм отвечает только там, где соседство ничего не решило, – устоявшиеся написания на месте; данные, пересобранные с исправлением, пару несут. - Имя внутри выражения типа в коде переводится как тип. Обход токенов не отличал типовую
позицию от обращения к члену, и
.Ссылкав типе параметра, объявления, конструктора, приведения или аргумента типа уходила свойствомLink, а не фасетомReference– английское дерево не компилировалось, а посев паритетаcode/unknown-ns-objectпришлось пометить известным. Границы выражений типа теперь даёт парсер, и имя внутри них разрешается так же, как тип в yaml. - Член локальной переменной без записанного типа берётся по выведенному типу
(конструктор, приведение, литерал), написание – из таблицы владельца с проходом по базовым
типам (
Соответствие.Удалить–Remove);code/unknown-memberпринимает написание предка. - Умолчание поля, типизированного перечислением проекта, переводится и в свойствах
компонента интерфейса, тип читается как в
yaml/enum-default-value. - Две слепоты на английском дереве:
code/global-unavailableне узнавал глобальное имя в английском написании,yaml/unknown-typeне читал ключType:.
30.08.2026 – 0.86.2, 0.87.0, 0.88.0, 0.88.1, 0.88.2
Добавлено
- Каталог типов пополняется тем, что справка не описывает. Дистрибутив описывает stdlib дважды, и в разметке сервера LSP типов больше: 16 типов Std жили только там, включая всю ветку Избранного, обращения к которой читались как необъявленное имя. Состав берётся из разметки, русские написания членов – из объявлений в классах поставки.
classcode.declared_terms– пара, прочитанная вместе с полем, в которое её кладут. Вид члена говорит ИМЯ статического поля (LINK_PROPERTY_TERM,SWITCH_SCREEN_METHOD_TERM): по самой паре свойство от метода и метод от его параметра не отличить.yaml/duplicate-key(тир A, error) иcode/duplicate-annotation(тир C, error) – дубли, которые раньше показывала только серверная компиляция. Скалярный ключ, заданный в одном узле YAML дважды, загрузчик молча схлопывает – последнее значение побеждает, слитый узел проходит все проверки схемы, и первым падал деплой; правило читает composed-дерево, где дубли ещё видны, помечает повтор и называет строку первого вхождения (ключ слияния<<и нескалярные ключи не судятся). Повторная аннотация у одного объявления – ошибка “Annotation … is already placed” – тоже была видна только на деплое.- Три правила объявления динамического списка.
yaml/dynlist-joined-table-param(error) – параметры и биндинги в присоединённых таблицах: отказ списка в рантайме при молчащем компиляторе;yaml/list-form-needs-dynlist(error) –ФормаСпискас массивной таблицей без динамического списка: пункт навигации молча исчезает;yaml/dynlist-filter-disabled(warning, проектное) – выключенный отбор, включаемый парным модулем: гонка первого показа, первый кадр показывает всю таблицу. - Комбинации свойств, половину которых платформа молча не рисует.
yaml/badge-column-image(warning) –Изображениеу колонки сВид: Значок: значение рисуется тегами-пилюлями, а картинка задокументирована только дляВид: Картинка;yaml/value-choice-title(warning) –ЗаголовокуВыборЗначенияс явным видомПереключательне рисуется, и поле остаётся без подписи;yaml/popup-in-markup(warning, проектное) – всплывающий компонент, сырой тип или проектный наследник через замыкание поНаследует, размещён в yaml-разметке: содержимое рисуется в строке формы до открытия окна, лечение – собирать окно кодом (новыйВсплывающийКомпонент+ОткрытьВоВсплывающемОкне);yaml/col-width-needs-no-stretch(info, выключено по умолчанию) – числовая ширина колонки таблицы без явногоРастягиватьПоГоризонтали: при растягивании ширина работает как доля, а не пиксели – сосед семьиsize-needs-no-stretch, включается точечно при симптоме на экране. yaml/enum-default-value(тир D, error, проектное) иyaml/event-property-type(тир D, error).ЗначениеПоУмолчаниюполя с типом перечисления проекта обязано быть голым именем объявленного значения: запись с именем типа (ВидимостьМетки.Невидимая) и несуществующее имя линтер прежде пропускал, а сборка отвергала их только при применении (“Неизвестный элемент перечисления”); у английского дерева ловится и русское значение, оставленное переводчиком при английских элементах. Тип свойства события журнала вне закрытого списка платформы – перечисление проекта отвергает серверная компиляция ценой деплоя; список берётся из метамодели, в сообщении – допустимые типы и совет писать вариантные значения строковыми кодами с перечнем вОписаниесвойства.code/load-object-unwrap(тир D, warning) иcode/image-binding-server-call(тир D, info, проектное) – данные приезжают не так, как читается по коду. Форс-разворот “!” результатаЗагрузитьОбъект()у ссылки, взятой из поля другой записи или строки табличной части, – висячая ссылка после физического удаления роняет весь обход, результат нужно проверять на Неопределено. Биндинг свойстваИзображениес вызовом, разрешающимся – напрямую или транзитивно – в серверный метод: картинка приезжает отдельным серверным вызовом после отрисовки и перезапрашивается при каждой перерисовке, лечение – поле присоединённой таблицы либо клиентские данные.code/permission-right-not-computable(тир D, error, проектное). Право, выданное обработчиком вычисления разрешений, должно быть объявлено вычислимым в yaml сущности – иначе сборка применяется, а пересчёт разрешений падает уже в рантайме; права собираются из конструкторовРазрешениеДоступатранзитивно по вызовам проекта, делегирование в общий модуль прав показывается с привязкой к сущности.
Изменено
- Фикстуры правил и примеры в документации переведены на словарь демонстрационного проекта (0.88.1). Имена в примерах должны читаться сами по себе, а не отсылать к чужому решению; заодно к тому же словарю приведены таблицы правил обоих изданий.
- Описание пакета называет перевод, MCP-сервер и расширение – и стало английским. Сводка
на карточке PyPI перечисляла линтер, LSP, документацию и скаффолдинг – набор, от которого
инструментарий уже ушёл, – и была единственной русской среди соседних пакетов, хотя
возглавляет английский README. Ключевые слова пополнены
mcpиtranslation. yaml/missing-importчитает и корни цепочек в биндингах разметки. Обращение=ЧужойМодуль.Метод()из свойства-биндинга достигает чужой подсистемы так же, как позиция типа, но без строки импорта отказ приходил только серверной компиляцией ценой деплоя; всё, что объясняет имя само по себе, – объявления этого yaml, парного модуля, неявные имена платформы – вычитается.yaml/empty-group-sizedловит и размер-биндинг (Высота: =...) у пустой группы безИмя. Безымянная распорка с вычисляемым размером выглядит как пустая группа и молчала; именованные пустые контейнеры, наполняемые из кода, не флагуются.
Исправлено
- Умолчание поля-перечисления переезжает вместе со своим перечислением (0.88.2). Метамодель
типизирует
ЗначениеПоУмолчаниюобычным объектом, поэтому имя элемента оставалось русским рядом с переведённым перечислением, и сборка отвергала пару ошибкой “Неизвестный элемент перечисления” – видно это было только при применении. Судится узко: тип поля должен быть голым именем проекта, а значение – словом, которое знает словарь. --data-dirне доходил до параллельных воркеров. Закреплённый корень живёт в глобальной переменной процесса, а порождённый воркер стартует без неё и брал УСТАНОВЛЕННЫЕ данные: прогон читал не тот набор, о котором его просили, и молчал об этом.
28.08.2026 – 0.83.0, 0.84.0, 0.85.0, 0.86.0, 0.86.1
Добавлено
yaml/computed-binding-assigned(тир D, warning, проектное). Каждый экземпляр компонента связывает свойство вычисляемым выражением, а компонент присваивает это свойство в своём модуле – на присваивании платформа падает (IllegalStateException) при каждом срабатывании этого кода. Сужения выведены разведкой: именованный аргумент – не присваивание, а экземпляр из кода, связь голым путём, литерал или экземпляр без связи делают присваивание законным – защищённый компонент из живого корпуса остаётся в тишине.yaml/inline-command-name(тир A, error). Команда, объявленная прямо в разметке (инлайновый фрагмент командного интерфейса или команда-свойство), не может нестиИмя: платформа отвергает узел на применении – “Имя команды разрешено задавать только в элементах проекта типа фрагмент командного интерфейса” – и стенд откатывается, то есть дефект стоил цикла деплоя. Фрагмент ОТДЕЛЬНЫМ элементом проекта пропускается целиком: там этот ключ и есть смысл. Оба написания компонентов-команд берутся из словарей платформы.yaml/localization-missing-import(тир D, error, проектное). Неквалифицированной ссылке$Словарь.Ключ, чей словарь лежит в другой подсистеме, нужна эта подсистема в секцииИмпортТОГО ЖЕ yaml – импорт в парном модуле разметку не покрывает, и применение отвергает узел как неимпортированное пространство имён. Правило повторяет правила разрешения из документации: локальный словарь побеждает, импортированная подсистема разрешается, квалифицированная форма$Подсистема::Словарь.Ключработает без импорта и не трогается, кандидаты – только публичные чужие словари.translate_setпринимает пачку файлом. Новыйedits_file(MCP) передаёт сотни записей без килобайтов экранированного JSON в аргументе, а--set(CLI) читает те же два формата: yaml самого словаря – секцииtokens/phrases/literals, то же квотирование, пустое значение снимает запись – рядом со списком JSON[{key, value, kind}], который отдают скрипты. Файл без единой записи отвергается, а не читается как “менять нечего”.- У
translate_gapsпоявился компактный режим. Сcompactв строке только{key, kind, count}– рабочий список, который и нужен переводчику; полная страница из сотен пропусков с местами и подсказками не влезала в ответ инструмента. tools/parity_seed.py– посевная проверка паритета двух написаний. Прежний замер был счётным диффом русского дерева против его перевода и слеп к правилу, у которого счёт нулевой с обеих сторон: в этой тени и жилstructure/xbsl-pair, сообщавший о каждом английском модуле порождаемого типа, – ни одно считаемое дерево такого не несло. Проверка сеет свой случай сама: маленькое русское дерево и вердикт, который правило ему должно, а английский близнец берётся из собственного переводчика инструментария, а не из второй заготовки, поэтому проверяется то самое написание, которое инструментарий порождает. Вердикт называет виноватую сторону и её промах (en-misses,en-invents): таблица без английского написания заставляет правило пропускать, а без русского прочтения – выдумывать. Посев, переставший сеять свой случай, даётstale, а не проходит молча; весь каталог гоняетtests/test_parity_seed.pyна каждом прогоне тестов. Дыру, которую сегодня не закрыть, сеют с причиной черезknown=: она даётknown (...)вместо провала, а как только начнёт сходиться – даётfixed!и роняет прогон, чтобы отметка не пережила дыру. Первая такая уже записана:code/unknown-memberнамеренно пропускает латинские написания членов, и словаря членов пока не хватает, чтобы это снять.- Имена членов платформенных типов извлекаются в обоих написаниях. Справочная
документация существует только по-русски, поэтому каталог хранил члены типа лишь под
русскими именами – и правилу, судящему член в АНГЛИЙСКОМ проекте, сравнивать было не с чем.
Пары объявляет сам дистрибутив: 670 типов, 5251 пара, новая секция
member_namesвuiterms.json. Хранится по типам, а не одной таблицей: соответствие не однозначно – одно русское слово отвечает разным английским у разных типов, и плоская таблица потеряла бы треть секции.
Изменено
- Проблема переворота локализации называет ключ так, как он записан в ИСТОЧНИКЕ. Отчёт
говорил
'TaskCheckbox' has no en valueо строке, которая в базовом файле зовётсяЗадачаФлажок, отправляя читателя к обратному словарю; теперь первым идёт имя из источника, перевод – рядом в скобках.
Исправлено
- Английские написания членов берутся из того, что дистрибутив ОБЪЯВЛЯЕТ, а не из близости
имён друг к другу. Прежний способ мог принять за член имя параметра: замер показал две
неверные пары из 2015, и обе давали метод, которого у типа нет (
CharAtстроки выходилSymbol,Scheduleобновляющего задания –ScheduleWithoutTransaction), то есть переведённое дерево не скомпилировалось бы. Имя, объявленное и методом, и свойством, отдаёт написание метода. Данные надо пересобрать (xbsl extract --only terms,uiterms), после чегоcode/unknown-memberперестаёт сообщать о верном вызове. meta_project_info(иproject-infoв CLI) отвечает узко:kind,subsystem,brief. Всё дерево одним куском на живом проекте не помещалось в ответ инструмента – 143 КБ по исходникам живого корпуса, – и вопрос “какие объекты вида X тут есть” стоил двух лишних шагов: сохранить в файл и грепнуть. Краткий режим отвечает 5 КБ (381 объект, 22 вида), отбор по виду – 24 КБ. Счётчики по видам (object_counts) идут в КАЖДОМ ответе, отобранном или нет, чтобы отбор, не нашедший ничего, не читался как пустой проект, а полеfilterназывает, что осталось за кадром.- Базлайн стал переносимым между машинами: путь ВНУТРИ текста находки приводится к его собственной форме. Межфайловые правила называют второй файл так, как его получил прогон – разделителями своей ОС и абсолютным путём, если абсолютным был корень, – а личность записи это её текст. Из-за этого базлайн, записанный на Windows, в Linux-CI ничего не гасил и объявлялся устаревшим с обеих сторон (на одной ревизии живого корпуса локально “погашено 97, устаревших 2”, в CI – “89 и 7”). Теперь путь в сообщении читается так же, как путь файла: POSIX, относительно каталога базлайна. Прежние файлы работают без переписывания – общая форма считается с обеих сторон сравнения.
- Каталог словаря перевода больше не считается исходником проекта. Прогон, чей корень
стоит ВЫШЕ проекта (корень репозитория), находит рядом каталог словаря, а его файлы – yaml
той же формы: их собственные комментарии возвращались непереведённой прозой. На проекте
корпуса такой прогон показывал 871 пропуск фраз и покрытие 99,19% там, где сам проект даёт
100%. Цифра выглядит достоверной и уводит в расследование несуществующей дыры. Теперь обход
пропускает каталог
xbsl-translation(и одноимённый файл), а также словарь, названный вызывающей стороной, где бы он ни лежал. translate_setрапортовал о снятии записи, которого не происходило. Пакет, снимающий запись в файле и одновременно добавляющий новую с целью в ТОТ ЖЕ файл, терял снятие: добавление собирало текст файла заново с диска, затирая уже посчитанные правки, а отчёт при этом писалremoved: 1. То же касалось исправления записи в файле-цели. Теперь новые записи ложатся поверх уже посчитанного текста.code/unknown-memberсудит английские написания членов. Прежде правило глушило любой латинский член: при русском каталоге судить их значило бы сообщать о верном коде. Теперь тип, чей набор членов словари называют ЦЕЛИКОМ, судится в обоих написаниях; один член без названной пары оставляет свой тип несудимым по-английски, и правило сохраняет договор об отсутствии ложных срабатываний. Покрыты четыре типа из пяти.- Структура, объявленная самим модулем, больше не судится как одноимённый платформенный тип. Правило файловое и о проектных типах не знает, но собственные объявления модуля лежат прямо в нём – а структура проекта, чьё имя совпало с платформенным типом, получала замечания о собственных же полях.
- Дерево формы накрывает список, записанный на столбце собственного ключа. Yaml такое
написание разрешает; диапазон узла брался обходом отступов, поэтому такой список выглядел
без отступа вовсе и узел заканчивался через строку после начала. Узел, переставший
накрывать своих детей, обрывал спуск
node_at, и любая правка конструктора ниже него отклонялась. Накрытие стало инвариантом, а не следствием обхода: узел растягивается по своим детям, а их границы приходят из разметок самого yaml. - Отклонённая правка формы называет, что нашла. Сообщение не называло ни места, ни того, что там стоит; теперь оно называет строку, смещение и узел, который держит там дерево.
- Запись словаря с
::в ключе больше не рвётся надвое. Читатель записей заканчивал обычный ключ на первом двоеточии, тогда как yaml заканчивает его двоеточием С ПРОБЕЛОМ – и фраза, цитирующая платформенную форму путём видаStd::Jobs::JobsForm, разрезалась посреди слова, а хвост ключа сохранялся как часть перевода. Никто не жаловался: обе половины – годные строки, и порча всплывала лишь пропавшей из покрытия фразой. Касается всех мест записи –translate_set, ключа--setв CLI, панели редактора. naming/prefix-by-kindчитает английские имена. Голова английского составного имени – его последнее слово, поэтому переведённый элемент несёт то же слово вида ПОСТФИКСОМ – правило же требовало русский префикс дословно и сообщало о каждом таком элементе переведённого дерева; ожидаемое написание в сообщении следует алфавиту имени, английские слова берутся из словаря платформы.- Три рукописных английских написания не совпадали ни с чем и теперь берутся из данных.
Свойство веса растягивания у
yaml/card-literal-stretch-weightи фасет ссылки уyaml/ref-input-auto-commandsиcode/ref-field-needs-reqбыли написаны руками, а сериализатор пишет их иначе – правила молчали на переведённом дереве (один из тестов закодировал неверное написание фасета и не мог сработать в принципе). Написания берутся из словарей свойств и фасетов; паритет замерен полным прогоном переведённого дерева против русского файл-в-файл. structure/xbsl-pairузнаёт английский модуль порождаемого типа. Модуль, расширяющий тип, который порождает элемент, несёт хвост этого типа и своего описания не имеет –Prices.RecordSet.xbslописан файломPrices.yaml. Хвосты брались из каталога, где они записаны по-русски, и латались руками единственным словомObject, поэтому любой другой английский модуль читался как модуль без описания и получал замечание – то, чего его русский близнец никогда не получал. Теперь оба написания выводятся из словарей платформы: набор суффиксов вырос с 39 до 76, и русских хвостов без английского близнеца не осталось.- Рукописная английская колонка хвостов порождаемых типов убрана. Девять её имён из
тринадцати повторяли то, что уже отвечают словари, а четыре были догадками, которых
платформа не подтверждает:
Ref,RecordManagerиSelection– привычки 1С:Предприятия (в Элементе эти роли зовутсяReferenceиRecord, аSelectionсловарь читает как выделение в интерфейсе). Стоя только на английской стороне, они прощали в одном написании ровно то, о чём правило сообщает в другом. Осталась одна ПАРА, которой в словарях нет вовсе, – она сохранена целиком, чтобы деревья не разошлись. - Таблицы каталога у правил семантики сбрасываются при смене корня данных. Четыре таблицы читали каталог одной версии и держали его в кэше без регистрации сброса, поэтому после переключения на другой корень продолжали отвечать по прежней версии.
27.08.2026 – 0.81.0, 0.82.0
Добавлено
naming/filler-wordиnaming/numberсудят английские имена. Переведённое дерево прежде проходило оба правила молча. Список пустышек ведётся в обоих написаниях, и русская пустышка-префикс ловится там, куда её ставит перевод, – в конце составного имени (УправлениеСкладами–WarehouseManagement). Голова английского составного имени – его последнее слово (BankAccounts–Accounts), число головы определяется суффиксной эвристикой с перечнем неправильных множественных – морфологический extra для этого не нужен; несчисляемые слова и неоднозначный хвост-osостаются нерешёнными, а не угадываются. Исключения стандарта (TaskData,MessageQueue) известны тоже в обоих написаниях.- Переведённое описание разбирается как исходное. Ключ имени (
Name:) и ключи секций (Attributes:,TabularParts:и остальные) правила имён и индексатор читают в любом написании; английские написания берутся из метамодели, а не из рукописного списка. - Локализуемые значения yaml переводятся планом литералов. Значение, которое метамодель
объявляет локализуемым текстом (
Localizable), – представления команд, прав доступа и перечислений – читает человек на странице: теперь оно либо названо записью плана литералов целиком, либо предъявлено пропуском, как шаблон представления события. СвойствоОписание– документация разработчика: остаётся данными и в пропуски не попадает. - Предупреждение
literal-data-value: запись словаря сдвинула литерал, равный значению из json-ресурса проекта. Такой литерал обычно сравнивается с этими данными (разбор начального заполнения), а данные перевод не трогает – после сдвига сравнение молча пустеет; класс найден ревизией английской сборки пилотного проекта, где полный пересев терял раскладку карточек. Литерал-данные помечается записью со значением, равным ключу: покрытие засчитано, текст не движется, предупреждения нет. Предупреждение выдаётся на разный текст один раз на файл. - Отчёт перевода печатает предупреждения списком – файл, строка, вид и текст (первые двадцать), а не одним числом: прежде за подробностями приходилось ходить в json-режим.
- Суффиксы литерала длительности переводятся (
300мс->300ms,2д14ч30м5с6мс->2d14h30m5s6ms). Состав русских суффиксов – справка типа Длительность, английские написания подтверждены компилятором платформы (пробная сборка принимает2d14h30m5s6ms). Число, склеенное с буквами вне набора суффиксов, не трогается.
26.08.2026 – 0.79.0, 0.79.1, 0.79.2, 0.80.0
Добавлено
yaml/duplicate-subtree– поддерево разметки, скопированное в другой файл. Слепок по устройству, имена и тексты в счёт не идут: новую форму заводят копированием соседней, и копию переименовывают. Порог 40 узлов и оба исключения выведены замером, а не выбраны; выключено по умолчанию – мера одинаковости решение проекта.yaml/toggle-command-pair– пара обычных команд с зеркальнойВидимость. Две соседние команды, из которых видима ровно одна (=Xи=не X), изображают одну команду с двумя состояниями – у платформы она есть готовой:ПереключаемаяКоманданесёт представления и изображения обоих состояний, а состоянием владеет сама платформа. Общий обработчик пары усиливает картину, но не требуется.
Исправлено
- Шаблон представления вида события переводится целиком, а не одними выражениями. Проза, которую читают в журнале, оставалась русской молча – теперь она берётся из плана литералов по всему значению, а чего план не назвал, попадает в отчёт пропусков.
- Имя именованной группы образца и вызов, который её читает, двигаются вместе. Обе стороны
берут написание из одного источника; прежде объявление в образце не смотрел никто, а
аргумент
Группа("Имя")переводился, и платформа отвечала “нет группы захвата с таким именем”. - Устаревшими считаются только записи тех правил, которые в прогоне были. Правило,
оставленное за набором (сужение
--select, выключено по умолчанию, неизвестно установленной надстройке), находок не даёт по построению – и его записи объявлялись устаревшими, будто долг выплачен. Из-за этого две среды спорили об одном базлайне: MCP-сервер на надстройке постарше насчитывал 48 устаревших записей на дереве, которое CI с теми же правилами считал чистым. Такие записи считаются отдельно (“записей базлайна не проверено”, ключbaseline_not_checkedв json), и--prune-baselineих больше не снимает. - Словарь перевода проекта больше не судится правилами схемы yaml. Пара
Ид: Idв файле каталогаxbsl-translation– это перевод имени, а не идентификатор объекта, иyaml/id-uuidчитал её как негодный Ид. Файл словаря распознаётся по собственному содержимому – версии формата и разделу перевода, – поэтому проверка остаётся файловой и не ходит по дереву на каждое нажатие клавиши. Остальные правила модуля молчали на словаре и раньше: у него нет ВидЭлемента. code/duplicate-method-body: какое из остальных мест названо в сообщении, не зависит от порядка обхода файлов. Прежде CLI и редактор могли назвать разные места одной и той же копии, и запись базлайна, ключуемая по сообщению, переставала совпадать.
25.08.2026 – 0.76.0, 0.77.0, 0.78.0
Добавлено
code/duplicate-method-body– одно тело, написанное дважды в разных файлах. Сравнивается нормализованное тело от пяти строк, поэтому переформатированная копия остаётся копией; платформенный хук отделяется аннотацией@Обработчик. Выключено по умолчанию.code/client-available-unused– метод открыт клиенту, но клиент его не зовёт. Аннотация открывает поверхность, которой никто не пользуется; употреблением считается упоминание в клиентском модуле, в клиентском методе серверного модуля, в yaml и в строковом литерале. Выключено по умолчанию, какcode/unused-method.code/access-context-read-noop– холостое расширение контекста доступа чтением. У типа в yaml стоитЧтение: РазрешеноВсем, то есть выдавать нечего, а вызов создаёт впечатление защищённости. Замечание указывает на само право: одно в списке – уходит вся строка, среди других – только оно.yaml/unused-component– компонент интерфейса, которого никто не размещает.code/unused-methodтакой компонент не видит принципиально: его методы зовёт его же yaml. Имя, написанное КЛЮЧОМ словаря, употреблением не считается; точка входа и глобально видимый компонент не судятся, а прогон обязан покрывать проект целиком.code/query-in-loop– запрос внутри цикладля/пока. Каждый виток – отдельное обращение к базе, поэтому цена метода растёт вместе с данными и вылезает только на настоящих объёмах. Замена – один запрос по всему набору: значения витков уходят массивом в условиеВ.
Исправлено
code/duplicate-method-bodyназывает ФАЙЛ второй копии, а не путь, которым до него дошли. Прогон называет файлы так, как его позвали, поэтому сообщение – и запись базлайна, ключуемая по нему, – расходились между CLI, редактором и другой машиной.- Таблица предложения ИЗ считается употреблением объекта. Голый идентификатор не
примыкает ни к точке, ни к скобке, поэтому
ИЗ Товары КАК Т– строка, за которой обязано следовать переименование, – употреблением не была вовсе: на живом проекте индекс прибавил 374 таких ссылки. - Значение перечисления в блоке, которого нет в ui-схеме, переводится. Элемент сортировки списка и элемент его отбора схема не описывает, поэтому ключ рядом со значением становился английским, а само значение оставалось кириллическим – сборка такое отвергает. Свойство в таком блоке названо по своему перечислению, его таблица и отвечает.
- Редактор читает файлы запросов виртуальных таблиц – как давно читает CLI. Прогон
по проекту, открытый буфер и индекс проекта пропускали
.xbql, поэтому одно и то же нарушение было видно или нет в зависимости от того, кто спрашивает, а употребления объекта в запросе не попадали в поиск использований.
24.08.2026 – 0.74.0, 0.75.0
Добавлено
translate --table– записи словаря, пропуски и сводка за ОДИН проход. Таблица словаря в редакторе спрашивает движок именно об этом, и порознь ответ стоил двух одинаковых обходов исходников в двух процессах плюс третьего чтения того же словаря: на живом проекте – около девяти секунд, и повторялись они после каждой записанной ячейки.- Квалифицированная запись словаря действует и на поле СТРУКТУРЫ. Поля одной структуры живут
в общем пространстве имён, поэтому два русских имени, переведённые в одно английское, – это
структура, которую компилятор отвергает; раньше это лечилось только правкой русского исходника.
Теперь
<Структура>.<Поле>переименовывает объявление, все обращения через получателя с объявленным типом и ключ парного json-ресурса разом. Написанный получатель по-прежнему отвечает первым: запись, квалифицированная именем переменной, продолжает работать. - Коллизию полей одной структуры видит транслятор. Прежде о ней говорил только компилятор –
тот же класс, что коллизия имён методов, но без своего сообщения. Теперь она попадает в список
проблем и роняет
--strict. - Переименование и удаление объекта забирают виртуальную таблицу его списка. Пара
<Имя>СписокТаблица(.yamlплюс запрос.xbql) не входила ни в одно семейство файлов, а сами файлы.xbqlне просматривались вовсе – в них стоит имя объекта, и переименованный справочник оставлял за собой запрос к несуществующей таблице. Английское написание пары знает то же правило.
Изменено
- Член платформы без английского написания – пропуск ПЛАТФОРМЫ, а не словаря. Сводка
показывала
platform_gaps: 0, и тут же список пропусков называл метод массива недостающим именем: счётчик противоречил списку. Записать такое имя в словарь значило бы выдумать английское написание платформенного члена, которое компилятор откажется принять. Теперь имя, которое платформа объявляет своим членом, а данные не спеллят, идёт в платформенные пропуски. --strictроняет прогон и на платформенных пропусках. Такое имя остаётся кириллическим в переведённом дереве, то есть сборка его отвергнет, – гейт молчать не должен. Лечится это не словарём, а данными платформы, поэтому в отчёте пропуск по-прежнему назван отдельно.- Словарь перевода читается быстрым загрузчиком yaml. На словаре живого проекта (3.6 МБ, 39 файлов) 1.4 с против 0.11 с; чистый питоновский загрузчик оставлен запасным для сборок без libyaml.
Исправлено
- Литерал запроса для неопределённого значения переводится в
UNDEFINED, а не вNULL. Таблица ключевых слов берётся из данных компилятора, литералов в ней нет вовсе, и слово проваливалось в плоский словарь – а тот даёт емуNULL, отдельное зарезервированное слово, которому не отвечает ни одно русское написание. Компилятор принимает и то и другое, поэтому все проверки оставались зелёными; на работающем приложении условие сNULLне истинно никогда, и запрос возвращал пусто. Встречено вживую на переведённом корпусе, где разом замолчали три места, зависевшие от такого условия. ЛитералыTRUE,FALSEиUNDEFINEDтеперь называет сам движок – вместе с однословными ключевыми словами, которым экстрактор даёт неверную пару.
23.08.2026 – 0.73.0
Добавлено
form/handler-signature– обработчик, сигнатура которого противоречит событию компонента. Делегат берётся из ui-схемы с подстановкой аргументов типа самого компонента и сверяется с методом парного модуля. Аритет, базовый тип и неподставленный параметр типа не судятся: разведка на четырёх корпусах (483 обработчика) показала, что каждый из них законен.typography/yo-in-text– буква “ё” в тексте, который читает пользователь. Видимые свойства компонентов и элементов плюс каждая запись словаря локализованных строк; привязка, ссылка и техническая строка не трогаются. Есть автопочинка – кроме случая, когда буква несёт смысл. Выключено по умолчанию, как и прочая типографика.
Изменено
- Новый файл словаря создаётся с нейтральным заголовком. Раньше он сообщал о панели
редактора, кто бы его ни писал;
translate_set(..., comment=...)иxbsl translate --commentставят туда тему самой порции. Существующий файл свой заголовок сохраняет.
Исправлено
- Коллизию имён МЕТОДОВ транслятор видит. Два русских имени, которые английский пишет
одинаково, сталкиваются в общем модуле, и такой модуль компилятор отвергает – а проверка знала
имена метаданных и локальные имена метода, но не сами методы. Теперь коллизия идёт в
problems(их отдаётtranslate_status, на них падает--strict), аtranslate_setотвечает полемcollisions, когда значение уже занято в той же области. - Значение, по которому выбирается диспетчеризуемый блок, переводится. Вид расписания – не тип, не свойство и не значение перечисления, поэтому пары ему не давал ни один словарь. Аннотация метамодели называет оба написания: экстрактор несёт английское, а рукописная пара для стандартного реквизита кода ушла.
- Семь перечислений, у которых английские написания были сдвинуты на значение. Значения – аргументы конструктора, и класс объявляет их в порядке своих полей, а он не всегда начинается с английского имени. Порядок написан в самом пуле.
- Два ключевых слова языка запросов, которые экстрактор читал неверно. За словом, у которого английского написания нет, идёт его транслитерация, и при чтении подряд она становилась “английским” для следующего. Пул читается парами; список-обход на стороне транслятора снят.
- Два правила, мимо которых проходил английский проект.
yaml/standard-field-lengthчитал секцию реквизитов только русскими ключами, аyaml/presentation-fieldсверял тип реквизита с русским написанием строкового типа. Имена стандартных реквизитов берутся в написании самого файла, поэтому русский проект не страдает. - Правило о пробелах словаря больше не судит сам словарь. Его файлы русские по построению, и
на покрытом проекте правило выдавало 826 “пробелов” – все свои же. Оно остаётся выключенным
(каждый файл проходит перевод целиком, прогон удваивается), а у инструмента MCP появился
параметр
enable– близнец флага--enable. - Сервер MCP применяет базлайн проекта – как это делает CLI. Один и тот же каталог читался
чистым в терминале и грязным через агента. Файл ищется над проверяемыми путями,
baselineназывает другой,no_baselineпросит показать замороженные. - Первый реквизит новой табличной части замещает заглушку. Заглушка узнаётся и по имени, и по типу, поэтому переименованный автором реквизит не трогается.
21.08.2026 – 0.72.0
Добавлено
- Машинный перевод предлагает записи, которых не хватает в словаре.
xbsl translate --suggestспрашивает внешний сервис – Yandex Translate или Google Translate, выбор идёт по тому, какие ключи заданы, – про каждую запись, которую словарь ещё не покрывает, и просто показывает ответ, а не записывает его сам: слово принимает человек. Секция словаряtermsуходит вместе с запросом глоссарием, поэтому термин, который проект уже закрепил, сохраняет написание и внутри переведённого сервисом предложения. Ответ кэшируется по исходному тексту и глоссарию, с которым он получен, поэтому повторный запуск по тем же пробелам не делает ни одного запроса – отчёт считает, сколько ответов взято из кэша. Ключ никогда не попадает в командную строку: движок читает его из окружения, а в панели переводов VS Code появилась кнопка “Запросить машинный перевод” – она проходит тем же запросом по открытой таблице и подставляет каждую догадку одним щелчком, как уже умело платформенное написание; свой ключ панель хранит в SecretStorage, а не в настройке.
20.08.2026 – 0.70.0, 0.71.0, 0.71.1
Добавлено
- Третий план словаря –
literals. Строковый литерал переводчик оставлял данными и молчал о нём: в переведённом дереве оставались кириллические сообщения и ключи, записанные строкой (ключ хранилища параметров, имя поля контракта). Теперь команда перечисляет такие литералы в планеliterals– ключ и значение пишутся ровно так, как текст стоит в исходнике между кавычками, – и движок заменяет литерал целиком. Код внутри интерполяций значения переводится обычным порядком, поэтому автор словаря не обязан знать английские написания имён. Литерал внутриЗапрос{},Образец{}и других разрешимых литералов не трогается: там это код. Непокрытые литералы честно попадают в отчёт, в--gaps --kind literal, в инструменты MCP и в находкуconventions/missing-translation– покрытие словаря они при этом не портят, у них свой счёт. - Комментарий переносится по ширине заново. Перевод сохраняет разбиение строк один в один, и
комментарий, ставший длиннее исходного, вылезал за предел ширины – на настоящем проекте это
давало сотни находок
style/line-lengthтам, где исходное дерево чистое. Теперь блок комментария переразбивается по той же ширине, которой пользуется правило. Рамки и разделители, списки, таблицы и образцы кода, а также строки, длинные уже в исходнике, остаются нетронутыми.
Исправлено
- Имя параметра маршрута переезжает вместе с кодом, который его читает. Шаблон
/res/{код}– это данные (адрес набирает посетитель), но имя в фигурных скобках объявляет параметр, и обработчик читает его ПО ЭТОМУ ИМЕНИ. Оставленное как есть, оно расходилось с переведённым обращением: обработчик спрашивал параметр, которого маршрут не объявляет, получал пустоту и отдавал не тот ответ – статика приезжала с типом text/plain. - Правила судили о переведённом дереве строже, чем об исходном. Компилятор платформы принимал дерево, а линтер находил в нём ошибки, которых в исходнике нет: производный тип объекта, маркер имени исключения, блок использования подсистемы, nullable у члена, значение перечисления и штатная таблица запроса узнавались только в русском написании. Теперь оба написания судятся одинаково: шесть правил, на которых расходились русское и переведённое деревья одного проекта, дают на них один и тот же набор находок.
- Значение перечисления с именем
Noпропадало из объявления. Читатель yaml разбирает документ по YAML 1.1, гдеNo– это ложь, поэтому элемент терялся, а каждое обращение к нему приходило находкойcode/unknown-enum-value– при том, что тот же файл платформа принимала. - Ключ словаря с кавычкой внутри читался неправильно и дублировался при записи. Строка комментария, которая что-то цитирует, – обычный ключ словаря; читатель обрывал его на первой внутренней кавычке, писатель не находил такую запись и добавлял её второй раз, после чего словарь отказывался грузиться дублем.
- Команда
xbsl translate– перевод исходников проекта на английские написания. Токены платформы переводятся по метамодели и словарям данных (ключевые слова – формой того же регистра, ключи yaml – по классу узла, значения перечислений – внутри своего перечисления, выражения типов – с фасетами, ключевые слова запросов – внутри блоковЗапрос{}, код внутри интерполяций строк – как обычный код); СОБСТВЕННЫЕ имена проекта и строки комментариев – по словарю проекта: каталог yaml-файлов (xbsl-translationрядом с проектом или выше) с двумя планами –tokens(идентификатор целиком -> идентификатор целиком) иphrases(строка комментария -> перевод). Файлы и каталоги переименовываются той же картой токенов,Идне меняются, а раскладка словарей локализации переворачивается: секция целевого языка становится базовой, исходные значения уезжают вЛокализация/<Код>/, языки проекта в дескрипторе следуют за этим.--coverageсчитает долю словаря по каждому объекту метаданных,--missingпишет непереведённый остаток заготовкой словаря,--strict– гейт публикации в CI; всё, чему данные не знают английского написания, честно остаётся как написано и попадает в отчёт – никогда не угадывается. - Имена, объявленные проектом, закрыты от платформенных таблиц. Слово, которое знает и платформенный словарь – значение перечисления, реквизит, ключ словаря локализации, – переводится ТОЛЬКО словарём проекта: объявление и все обращения переезжают вместе или вместе ждут записи. Без этого гейта модуль уже зовёт английское имя, пока yaml всё ещё объявляет русское значение, и сборка отвергает дерево.
- Словарь отвечает ТАБЛИЦЕЙ, а инструменты его наполняют.
xbsl translate --gapsпоказывает недостающее (по убыванию частоты, с местами употребления и собственным написанием платформы как подсказкой),--entries– то, что словарь уже говорит, с файлом и строкой каждой записи,--set– запись: добавить, исправить на месте, снять обнулением значения. Те же четыре вопроса есть инструментами MCP (translate_status,translate_gaps,translate_entries,translate_set), поэтому наполнение словаря на тысячи записей больше не требует вычитывать файлы. Писатель встраивает запись в существующий файл, копируя отступ у соседей секции: словарь, заведённый двумя пробелами, после правки остаётся валидным, а комментарий в голове секции читателю таблицы не мешает. Находкаconventions/missing-translationнесёт то, что нужно клиенту для исправления, – точный ключ, его вид и подсказку – в новомDiagnostic.data, который пробрасывают и языковой сервер, и машинный отчёт. - Ключи json-ресурсов переезжают вслед за полями структур. Структура читает свой ресурс по ИМЕНИ ПОЛЯ, поэтому ключ данных – то же имя, записанное во второй раз; переименовать поле и оставить ключ значит не связать ничего, причём молча: настройки чтения пропускают неизвестное свойство и инициализируют отсутствующее поле, и переведённый проект компилируется, применяется и стартует с пустыми данными. Переезжают только ключи, называющие поле структуры проекта; значения и ключи, которых не объявляет ни одна структура (карта по содержимому, внешний контракт), остаются как написаны, а перезапись идёт по местам – форматирование файла сохраняется. Компилятор о таком не скажет ничего: разъехавшееся имя – это данные.
- Путь ресурса в строке переезжает вслед за файлом. Дерево переименовывает файлы и
каталоги ресурсов, поэтому литерал, который адресует ресурс (путь вида
"<Каталог>/%<Поле>.svg"), обязан следовать за ними; иначе платформа не находит ресурс, а проект, поймав это исключение, рисует пустое место. Переводятся только литералы ФОРМЫ пути – оканчиваются известным суффиксом ресурса, каждый сегмент читается как имя файла: регулярное выражение с косыми чертами и именованными группами под это не подходит и остаётся данными. - Правило
conventions/missing-translation(info, выключено по умолчанию, область – проект) – имя или кириллическая строка комментария, которых ещё нет в словаре перевода проекта; одна находка на первое вхождение в файле. Область проектная не для удобства: “своё ли это имя проекта” – факт проектный, объявление может лежать в yaml, о котором модуль не знает. Слово, которое знает и платформа, тоже пробел, если его объявил проект, – пофайловая проверка молчала бы ровно там, где переведённое дерево разъезжается. Правило молчит, пока словарь не найден, поэтому его видит только проект, который переводит исходники.
19.08.2026 – 0.69.1, 0.69.2, 0.69.3
Изменено
- Примеры в описаниях правил и фикстуры тестов приведены к словарю демо-проекта. На поведение движка не влияет.
Исправлено
yaml/dynlist-column-sort-lostне судит колонку, которая сама выключила сортировку. СвойствоОтключитьСортировку: Истина(DisableSorting: True) правило не читало вовсе, и колонка-значок состояния с вычисляемым значением приходила замечанием. Терять там нечего: сортировки у такой колонки нет по объявлению.
17.08.2026 – 0.69.0
Добавлено
- Правило
yaml/localization-key-unique(error, в наборе по умолчанию) - ключ, объявленный в словаре локализованных строк дважды. Охват выяснил компилятор на одноразовом проекте из трёх словарей: у секций ОДНО пространство имён, файл перевода судится тоже, и все три отказа звучат “имя не уникально”. Отказ приходит на применении, то есть откатывается весь проект - один повторённый ключ стоит полного цикла деплоя, а в словаре на несколько сотен ключей дубль глазами не виден. Любой читатель yaml оставляет ПОСЛЕДНИЙ из повторов, поэтому до применения его никто не замечал; правило читает узлы разбора. - Правило
code/module-var-not-const(error, в наборе по умолчанию) - объявлениепер/знч/испна уровне МОДУЛЯ, где живёт только константа. Значение константы вычисляется при компиляции, а остальным модификаторам нужен работающий метод, чтобы вычислить выражение инициализации. Разбор принимает там все четыре (правило грамматики общее с полем объекта) - поэтому раньше это выяснялось только на деплое. - Правило
code/use-needs-closeable(error, в наборе по умолчанию) - модификаториспу типа, который описан каталогом и не наследуетЗакрываемое. Модификатор существует ради автоматическогоЗакрыть()на выходе из области видимости, поэтому компилятор отвергает объявление. Тип, до которого не дотянулся вывод, и тип, которого в каталоге нет, не судятся. - Дерево компонентов берётся частями -
meta_component_treeи CLIform-treeпринимают поддерево (по идентификатору узла или по имени компонента), предел глубины и выдачу без записей свойств. Настоящая форма дала четверть миллиона символов, и чтобы посмотреть одну группу, приходилось читать всё; та же форма отвечает на обзорный вызов семьюстами символами. Обрезанный узел об этом сообщает, а компонент без свойств называет их число.
16.08.2026 – 0.68.0, 0.68.1, 0.68.2
Добавлено
- Правило
yaml/missing-subsystem-usage(warning, в наборе по умолчанию) – подсистема импортирует другую, а в своём описании не объявила её используемой. Такой проект не применяется, и раньше это выяснялось только на деплое. - Правило
code/missing-import(warning, в наборе по умолчанию) – модуль пользуется типом или модулем чужой подсистемы, не импортировав её. Компиляция падает на этой строке, а линтер о ней молчал: проверка была только для yaml.
Изменено
- Строка из одних пробелов – замечание вида info. Отступ пустой строки ничего не меняет ни для компилятора, ни для читателя, и правила про него у платформы нет. Хвост после кода остался предупреждением: там в строке есть содержимое.
- Подсказка отвечает после данных объекта формы. Имя
Объектобъявлено аргументом базового типа формы; теперь оно типизировано, а с ним – и циклы по табличным частям. - Подсказка отвечает после значения перечисления и после переменной такого типа. Значение это член перечисления, а его члены – методы модуля рядом.
- Цикл по списку значений типизирует переменную.
для Вариант из [Роль.Админ, Роль.Обычный]берёт тип у самих элементов; если они разного типа, переменная остаётся нетипизированной. - Подсказка отвечает после пойманного исключения и после команд формы. Тип исключения
написан в самом объявлении, а команды вроде
Записатьформа получает от типа, который наследует; после таких имён точка молчала. - Подсказка отвечает после параметра лямбды.
Список.Преобразовать(Э -> Э.предлагает члены элемента коллекции, а лямбда над результатом запроса – колонки выборки. - Табличная часть в запросе отвечает своими полями.
ИЗ Товары.Состав КАК Считается как таблица, и послеС.идут реквизиты части и стандартные поля строки. - Точка после компонента формы отвечает – и методами его собственного модуля, и членами его типа; цепочка через компонент доходит до конца.
- В английском проекте подсказка называет члены платформы по-английски. Раньше список после точки был русским, каким бы ни был язык проекта.
- Вывод типа выражения отвечает чаще. Он узнал литералы запроса, образца и ресурса, а переменная цикла получает тип элемента коллекции.
Исправлено
- Метод из подсказки вставляется со скобками. Список методов собирается в двух местах, и скобки клало только одно – в остальных вставлялось голое имя.
- Тип предлагался дважды. Список членов объекта называл локальные типы и табличные части и общей строкой “тип”, и точной; теперь строка одна, точная.
- После
новый Имя.предлагаются только типы. Методы модуля и члены менеджера в конструкторе стоять не могут и лишь вытесняли типы из видимой части списка. - В 0.68.0 точка после компонента формы молчала, если у компонента нет своего модуля, а тип записан с аргументом – а так записано большинство.
- Индекс терял признак пустого значения у типа результата метода – из-за этого всякое значение, пришедшее из проекта, выглядело непустым.
- Окружение метода не различало блоки: имя, объявленное в одном цикле, отвечало и в другом. Теперь видимость считается по правилам платформы – от объявления до конца блока.
- Реквизиты своего типа не попадали в окружение, и реквизит, названный как стандартный тип, читался как этот тип.
- Операция
??называла тип по правой стороне, хотя значение бывает и левым. Теперь несогласные стороны дают “неизвестно”. - Экстрактор терминов терял имена, написанные двумя алфавитами (
FtpИсточник,SeoОписание): у них не оказывалось английской пары, хотя в дистрибутиве она есть. Заодно из словаря ушли несколько ложных пар.
15.08.2026 – 0.66.0, 0.66.1, 0.67.0
Добавлено
- Вывод типа выражения (
xbsl.typeinfer) – тип получателя, члена, конструктора, приведения и настойчивой операции по данным платформы. Там, где данные тип назвать не позволяют, модуль отвечает “неизвестно”, а не догадкой. - Правило
yaml/ref-input-auto-commands(info, выключено) – ссылочное поле ввода без своихКоманды: платформа рисует рядом кнопку открытия значения в отдельном окне. Чаще всего она и нужна, поэтому правило отвечает на вопрос “откуда кнопка”, а не сообщает об ошибке. - Запрос
xbsl/localizationStrings: движок отдаёт все локализованные строки проекта на выбранном языке. Ключ без перевода остаётся с текстом языка по умолчанию – так же, как подставляет платформа.
Изменено
- Подсказка отвечает там, где раньше молчала. На живом проекте четверть точек оставалась без
ответа; молчание сократилось на треть. Тип переменной теперь берётся из литерала
(
знч Ключ = ""– этоСтрока) и из вызова без квалификатора – метода своего же модуля, которым модуль зовёт собственный код. Настойчивая операция больше не обрывает цепочку, переменная цикла берёт элемент из записанного типа коллекции, а объявление внутри цикла опирается на переменную цикла. Значение компонента интерфейса отвечает своими свойствами, методами своего модуля и членами платформенного типа, который он наследует. Внутриновый Тип(предлагаются имена того, что тип несёт, вместе сИмя =. Запрос, объявленный черезисп, доносит колонки до цикла. - Пространство фасетов отвечает после точки. Фасет назван двумя сегментами
(
Сущность.Право), и каталог хранит его так же – первый сегмент сам по себе типом не был, поэтому молчали и подсказка, и цепочка. Теперь пространство предлагает фасеты, которые могут за ним стоять, а цепочка разрешает двухсегментный корень. - Типы, которые порождает объект, несут его данные.
Товары.Объектотвечает реквизитами и табличными частями своего yaml, табличная часть – отдельный тип со своими реквизитами, аТовары.Ссылка– тем, что вид даёт ссылке. Каталог описывает их по ВИДУ, и собственные данные объекта присоединяются к описанию. - Член типа, который расширяет модуль, доступен по голому имени. В модуле
Товары.ОбъектголоеСостав– это его табличная часть, а не неизвестное имя: точка после неё отвечает, а цикл по ней берёт тип строки. Тип объекта теперь несёт объявленный тип каждого своего члена. - Однострочный запрос отвечает колонками у самого результата. Такой запрос читают прямо с переменной, без цикла, – колонки доносились только до переменной цикла.
- Обобщённый член разрешается по аргументам, которые написаны в коде.
Массив<Каталог.Карточка>.Первый()отвечаетКаталог.Карточка,Соответствие<Строка, Число>.Получить(...)–Число: каталог называет такой результат ПАРАМЕТРОМ типа, и списки параметров теперь извлекаются вместе с ним.
Исправлено
- Обобщённый МЕТОД терял и сигнатуру, и тип результата. Параметры печатаются между именем
и скобкой (
ПрочитатьОбъект<ТипОбъекта>(...)), а разбор требовал имя сразу со скобкой – метод не получал ни того, ни другого. Устаревшая перегрузка добивала: её результат расходился с актуальным, и член отбрасывался целиком. Теперь читаются оба, актуальная форма старше формы совместимости, а параметры типа метода извлекаются –СериализацияJson.ПрочитатьОбъект(Текст, Тип<Пакет>)отвечаетПакет. - Коллекция не знала типа ничего, что возвращает. Базовые типы обобщённого печатаются с
аргументом (
Коллекция<ТипЭлемента>), а извлечение читало написание целиком как имя – и уМассивоставался единственный предокОбъект, а вместе с ним терялись все унаследованные типы результатов: 779 типов не имели ни одного. Починены обе половины – извлечение читает голову имени, а загрузчик достраивает унаследованные типы результатов и типу, у которого своих нет. - Проект на английском попадает в индекс – имя элемента и его именованные разделы читались только в русском написании, поэтому английский проект давал пустой индекс: ни дерева, ни навигации, ни подсказки. Тип, который элемент порождает, регистрируется под обоими именами, и точка отвечает на то написание, которым написан код.
- Точка после элемента предлагает то, что элемент несёт – параметры элемента вида
ПараметрыРаботыКлиентав подсказку не попадали, она перечисляла одни методы вида. - Цикл по параметру типизирует свою переменную – если коллекция это параметр с типом
Массив<...>, переменная цикла оставалась без типа и точка после неё не предлагала ничего. - Опечатка в пути больше не выглядит успешной проверкой. Несуществующий путь – ошибка с внятным сообщением, а не “проверено 0 файлов, замечаний 0” при коде успеха; если путь есть, но исходников по нему нет, линтер предупреждает.
14.08.2026 – 0.64.0, 0.65.0
Добавлено
style/shadow-own-property– локальная переменная с именем свойства своего же элемента: присваивание уходит в переменную, а свойство остаётся прежним.code/unused-import– импорт подсистемы, к которой код не обращается.- Восемь правил про поведение платформы, которое компилятор принимает, а экран потом
опровергает (142 → 150):
code/permission-handlers-need-recalc– обработчик разрешений объявлен, а пересчёта нет нигде: правка алгоритма молча не действует на существующих данных.yaml/dynlist-row-editing–ПриРедактированииСтрокиу плоского списка: платформа это событие не вызывает, по нажатию открывается автоформа.yaml/localization-ref-to-template– ссылка$Словарь.Ключна ключ из секции шаблонов: применение падает “не удалось найти локализованную строку”.yaml/insert-row-needs-align– горизонтальная группа со вставкой без явного выравнивания: элемент со вставкой съезжает вниз относительно соседей.code/url-params-partial-encoding(info, выключено) – метод Url кодирует значение параметра частично, и адрес приходит обрезанным.yaml/dynlist-column-sort-lost(info, выключено) – колонка со значением-вызовом: щелчок по заголовку сортирует не по ней.yaml/matrix-group-max-width(info, выключено) – числовой максимум ширины у матричной группы: телефон рисует страницу десктопной шириной.yaml/card-literal-stretch-weight(info, выключено) – вес растягивания у карточки: в вертикальной колонке она схлопывается в Safari.
Изменено
- Литерал коллекции называет тип.
знч Пользователи = <Строка>[]– объявление не хуже конструктора, и несуществующий член массива после него теперь виден. - Файлы запросов
.xbqlпопали под проверку. Раньше неизвестную таблицу в них находил только серверный компилятор.
Исправлено
- Английские написания аннотаций.
@OnServerи его собратья читались как отсутствие аннотации, и метод проверялся по умолчанию. Теперь обе формы равноправны – в аннотациях, областях видимости и ключах событий формы. - Две дыры в разборе. Скобка в начале строки больше не приклеивается к предыдущему
выражению, а запись
пер Попытка: (()->Булево)? = Неопределеноразбирается: раньше на ней рассыпался весь файл. - События типа.
Кнопка.ПриНажатии = &Обработатьбольше не выглядит обращением к несуществующему члену; опечатка в имени события ловится по-прежнему. - Уникальность
Идсчитается в пределах владельца. Одинаковый идентификатор у реквизитов РАЗНЫХ объектов платформа принимает – так сделано в её же демо-проекте; проверяются идентификаторы объектов по проекту и идентификаторы элементов внутри своего файла. Заодно правило читает и английский ключId. - Три правила перестали спорить с законным кодом:
Ключу строки динамического списка, обязательное поле и параметр события со ссылочным типом, стандартный реквизит безИд. - Ссылки в README снова открываются: перекладка руководства оставила по тринадцать битых на язык. Теперь их бережёт тест.
- Сброс метамодели чистит и кэш
key_aliases– после смены корня данных дерево метаданных редактора могло показывать пары старой версии. - Сторож языка проверяет и неотслеживаемые файлы – новый модуль с голой кириллицей проскакивал мимо локальной проверки и всплывал в CI.
13.08.2026 – 0.63.0
Добавлено
- Правило
yaml/binding-needs-auto: биндинг с nullable-возвратом на свойстве, у которого нет пустого значения. Клиент пишет “Неожиданное значение” в серверный лог на каждом пересчёте – в браузере этого не видно, на живом проекте накопилось почти две тысячи записей. - Правило
yaml/date-input-needs-plain-date: поле ввода даты с nullable-типом. Применение проходит чисто, но поле не рисуется, а опустевшая группа исчезает целиком. Лечение – непустой тип: “не задано” выражается пустой датой.
Исправлено
yaml/ref-needs-nullableпроверяет и союзы. Союз со ссылкой и без пустого значения не применяется – в том числе смешанный вродеСтрока|Товары.Ссылка; подсказка – добавить|?.
11.08.2026 – 0.62.0
Добавлено
- Правило
code/component-in-server-context: компонент интерфейса в серверном окружении. Тип компонента живёт на клиенте, поэтому серверная компиляция отвечает “Переменная X не определена”, а стенд молча откатывается на прежнюю сборку. - Ключ
--outу проверки: отчёт пишется в файл UTF-8 без BOM. Перенаправление оболочки на Windows добавляет BOM, о который падает разбор JSON.
Исправлено
- Свойство события журнала событий получает
Ид. Добавление поля теперь сверяет идентификатор с метамоделью в обе стороны: где он нужен – дописывает, где лишний – снимает.
09.08.2026 – 0.58.0, 0.59.0, 0.59.1, 0.60.0, 0.61.0
Добавлено
- Файл запроса
.xbqlстал языком. Подсветка и подсказка ввода: грамматика собрана из словаря самой платформы, весь файл считается запросом, и после псевдонима таблицы приходят её поля. Тот же словарь подсвечивает блокЗапрос{...}внутри модуля. - Переменная цикла
для X из Коллекцияполучает тип – по элементу коллекции. Для этого у структуры в индексе появился тип каждого поля; коллекция с двумя параметрами типа элемента не называет, и там подсказка молчит. - Члены типов-одиночек видов появились в данных: с 12 видов из 41 до 31.
- Вызов метода вида типизируется. Тип результата берётся из сигнатур документации (25 видов
из 31), поэтому подсказка знает, что вернули
Получить()набора констант,НайтиПоКоду()иПолучитьСсылку()справочника. - Свойства и методы менеджера вида разделены – подсказка подставляет скобки методу и не подставляет свойству.
- Правило
code/unknown-structure-field: поле структуры проекта сверяется с её объявлением (правил стало 139). - Устаревшие записи базлайна видны и вычищаются:
--stale-baselineперечисляет записи, которые больше ничего не гасят,--prune-baselineудаляет их, не трогая живые. - Линт сам находит базлайн проекта – ищет
.xbsllint-baselineвверх от проверяемых файлов и называет найденный путь;--no-baselineотключает поиск. - Ответы инструментов называют источник данных.
--version, MCPversion_infoи журнал запуска LSP несут корень данных и то, откуда он взят. conventions/untranslated-code-literal– видимый пользователю текст, оставшийся литералом в модуле (по умолчанию выключено).
Изменено
- Подсказка после точки предлагает то, что каталог знает о виде – вместо универсального списка, из-за которого всплывали несуществующие имена.
code/unused-methodсудит публичное API общих модулей. Метод глушат только аннотации, называющие вызывающего вне проекта; аннотации видимости и окружения больше не глушат.- Словарь видов элементов выводится из дистрибутива: видов стало 41 против 35, и журнал данных, панель отчётов и процесс интеграции перестали выглядеть неизвестными платформе.
yaml/unknown-propertyсудит 18 видов вместо 13.- Правила ресурсов знают оба написания каталога – платформа принимает
Resourcesнаравне с русским именем. - Скаффолдинг обработки: реквизиту не пишется
Ид(у него нет такого свойства), создаётся пара модулей, а обработчик операции дописывается в модуль объекта. - Английские сообщения говорят по-английски – имена платформы и ключевые слова в сообщениях правил и в справке CLI подставляются на языке читателя.
- Белые списки имён вычищены компилятором: из 25 заявок 12 оказались ложными, таблица имён сущности сократилась с 15 записей до 4 подтверждённых.
Исправлено
- Типы, описанные в метаданных, не давали подсказок после точки – индексатор пропускал поля структур и константы набора.
- Правило
code/unknown-structure-fieldпадало в выпущенном колесе (0.59.0) – обход дерева читал узел способом, недоступным в нативной сборке. - Итоговая строка базлайна считает записи, а не подавления: у одной записи их может быть несколько. Прежнее число осталось в json.
- Подсказка в начале сеанса не знала объектов проекта – ждала фоновый проход. Теперь запрос, пришедший раньше, строит индекс сам.
08.08.2026 – 0.57.2
Исправлено
- Навигация LSP больше не ждёт линт всего проекта. Индекс строится первым, а запрос, пришедший раньше, строит его сам. На проекте среднего размера навигация оживает за 1,9 с вместо 7,2 с.
07.08.2026 – 0.54.0, 0.54.1, 0.55.0, 0.56.0, 0.57.0, 0.57.1
Добавлено
- Свойства элементов секций пишет инструмент (0.57.0).
meta_add_fieldпринимаетprops, парныйmeta_set_field_propertyправит уже существующее свойство; имена сверяются с классом элемента, значение уходит скаляром и берётся в кавычки только там, где это необходимо. То же в CLI (--prop,set-field-property) и в LSP. Представлениепри создании объекта (0.57.0):meta_new_objectпринимаетpresentation. У отчёта и команд это заголовок, у справочника, документа, плана обмена и хранилища настроек – имя строкового реквизита; заголовок в этом месте отклоняется с объяснением.- Локализация элемента строк (0.57.0):
meta_add_localizationсоздаёт файл перевода со значениями языка по умолчанию,meta_localization_infoотвечает, какие языки заявлены и какие переводы уже есть. Язык принимается написанием проекта или кодом папки. - Форма обработки (0.57.0):
meta_add_formгенерируетФормаОбработки– поля по реквизитам и команды операций через типКоманды, поэтому новые операции попадают на форму сами. - Схема метаданных отвечает и на имя класса-дескриптора (0.57.0): спросить можно тем именем, которое сама схема и называет.
- Схема метаданных называет, к какому типу реквизита относится свойство (0.56.0). Пер-типовые
свойства несут
applies–string,numberилиreference, ровно так, как применимость записана в документации вида. - Английские имена служебных файлов разрешаются всюду (0.55.0). Платформа принимает
Project.yamlиSubsystem.yaml; прежде проект с такими именами не находился вовсе. meta_delete_object/xbsl delete-object: удаление объекта целиком – пара yaml с модулем, формы объекта и компонент строки списка. Каждое оставшееся упоминание имени называется файлом и строкой, но не правится; до--applyкоманда отвечает планом.- Правило
conventions/untranslated-visible-literal– видимый текст, оставшийся кириллическим литералом там, где то же свойство проект уже вынес в словарь локализации. Судятся только ключи, которые проект где-то локализует. - Повторная регистрация идентификатора правила замещает прежнее, а не дублирует находки: правило, переезжающее между плагином и движком, какое-то время живёт в обоих.
xbsl extract --keep-previousсохраняет снимок данных прежней сборки, поэтомуxbsl data-diffработает сразу после регенерации.- Окружение называет себя само:
--versionперечисляет надстройки с версиями, MCPversion_infoотдаёт тот же срез данными, LSP пишет его в журнал запуска.
Исправлено
- Модуль формы англоязычного проекта больше не полон ложных ошибок (0.57.1). Базовый тип
компонента искался по русскому ключу
Наследует, поэтому в английском проекте каждое обращение к члену базового типа объявлялось неизвестным именем. Члены базового типа теперь принимаются в обоих написаниях. - Правило перестало молчать на несуществующих командах формы (0.57.1).
ВыполнитьЗаписатьиВыполнитьЗаписатьИЗакрытьчленами платформы не являются: встроенная команда – это свойство, а её запуск –ЗаписатьИЗакрыть.Выполнить(). yaml/presentation-fieldбольше не судит набор констант (0.57.0): секции реквизитов у него нет, и правило требовало невозможного. У справочника заголовок в этом свойстве по-прежнему ошибка.- Вставка в секцию не ломает файл с CRLF (0.57.0) – прежде в файле оставался одиночный
\r, и git нормализовал перевод строки во всём файле. - Английская справка пишет английские написания имён (0.57.0) там, где платформа их объявляет.
- Объекты англоязычного проекта больше не выпадают из разрезов по видам (issue #1). Вид разрешается по таблице видов самого сериализатора; все прежние написания остаются принятыми.
- Каталог данных по умолчанию у экстракторов указывал внутрь пакета дважды – прогон без
--data-dirмолча писал не туда. - Собственные JSON-файлы терпимы к BOM, а ошибка разбора называет файл.
self-updateвыбирает колесо по платформе, а не по виду установки – прежде одно переносимое обновление навсегда оставляло установку переносимой.
03.08.2026 – 0.53.0
Добавлено
- Ключи словаря индексируются как члены. У элемента
ЛокализованныеСтрокинет модуля, поэтому переход, ссылки и подсказка не знали оСловарь.Ключ(); теперь строка становится описанием в подсказке, а число параметров шаблона считается по старшей подстановке. - Экстрактор документации читает раздел событий. Прежде каталог утверждал, что у кнопки нет
ПриНажатии, а сравнение версий отчитывалось о мнимых удалениях. Чтобы это подействовало, данные нужно перегенерировать. - Заготовка метода для обработчика, который не является событием формы – строится по соседнему обработчику того же ключа; соседа нет – заготовка без параметров, и об этом сказано.
- Маршрут добавляется без сборки его текста:
xbsl/metaAddRouteпринимает шаблон вместе с методами, аxbsl/httpMethodsотвечает списком допустимых методов.
Изменено
- Сторож языка судит и цитаты: русское имя в комментарии – находка и в обратных кавычках, если словарь компилятора знает английское написание.
31.07.2026 – 0.49.0, 0.50.0, 0.51.0, 0.52.0
Добавлено
- Карточка платформенного метода показывает параметры. Сигнатуры извлекаются из документации, унаследованный метод получает сигнатуру того типа, который его объявляет. Данные нужно перегенерировать.
- Подсказка отвечает по платформе и по глобальному каталогу, а не только по проекту: у члена платформенного типа карточки не было вовсе, а глобальные имена до неё не доходили.
- Карточка проектного метода несёт сигнатуру и описание, а возвращаемое значение получает тип:
после
знч П = Модуль.Метод(...)точка предлагает члены того, что метод вернул. - Правило
code/unclosed-resource(правил стало 136): досрочныйвозвратилипрерватьпосреди перебора результата запроса оставляет его открытым. Лечение – модификаторисп.
Изменено
- Язык исходников охраняется, а не помнится:
tools/langguard.pyчитает добавленные строки и сообщает о кириллице в комментариях, docstring’ах и именах Python; CI гоняет его на каждый push. - Оба английских чейнджлога охраняются – и словарным правилом, и бессловарным, поэтому публичный клон без словаря терминов тоже под охраной.
- MCP-сервер работает на обоих мажорах
mcp, пин снят (mcp>=1.2,<3): импорт сначала пробует новое расположение класса, затем старое.
Исправлено
self-updateсразу после релиза больше не говорит, что колеса нет: список файлов берётся из simple-индекса, а не из отстающих JSON-метаданных.- Ссылка на документацию у члена больше не ведёт в случайную статью – страница разрешается через приёмник, а не поиском по голому имени.
29.07.2026 – 0.48.0
Добавлено
- Стандарт “Имена переменных и констант” стал правилами (правил стало 135). Шесть новых правил
style/: абстрактное имя, однобуквенное имя, отрицание в имени булева, тип в имени переменной, числительное в имени константы и переменная с именем элемента проекта. Все шесть –warning.
Изменено
style/abbreviation-caseчитает и кириллические аббревиатуры (Ид,Ндс,Фио): группа заглавных в имени даёт находку с подсказкой, как латинская.
Исправлено
self-updateнативной установки обновляет сам себя. Прежде команда предлагала снять собственное дерево процессов, а общие библиотеки в корнеsite-packagesперезаписывались на месте и падали, пока их держит работающее обновление. Теперь предки и потомки команды из держателей исключены, а такие библиотеки откладываются переименованием.
28.07.2026 – 0.47.0, 0.47.1, 0.47.2
Добавлено
code/unknown-tabular-member– член, вызванный у строк табличной части, обязан быть у типа-массива. Получатель типизируется метаданными проекта, поэтому прежние правила о членах эту форму не видели:Объект.Шаги.Количество()проходил линт, а применение отвергало вызов (у массива –Размер).code/global-unavailable– глобальное имя, вызванное вне своего окружения.Сообщитьсуществует только на клиенте,ВычислитьиВыполнить– только на сервере; окружение метода берётся из вида элемента, пока@НаСервереили@НаКлиентене закрепят сторону.code/collection-field-needs-req– поле структуры с обобщённым типом, который не построить пустым.ЧитаемыйМассив<Строка>применение отвергает, аМассив<Строка>– случай обратный; что к чему относится, теперь факт в каталоге типов.code/var-needs-init– переменная объявлена типом без конструктора и без значения по умолчанию. Лечится либоТип?с проверкой, либо чтением нужного внутри попытки.
Изменено
- Тексты двух новых правил говорят словарём демо-проекта (
Задачи/Шаги), как и остальная документация.
Исправлено
- Extra
mcpзакреплён ниже 2. Вышедший в тот же деньmcp 2.0.0убрал модуль, который импортирует MCP-сервер, и свежая установка не поднималась.
27.07.2026 – 0.41.0, 0.42.0, 0.42.1, 0.43.0, 0.44.0, 0.45.0, 0.46.0
Добавлено
code/bound-property-assign– свойство, вычисляемое выражением, из кода не присваивают. Платформа такое присваивание отвергает, а в типовомпопытка/пойматьотказ не виден вовсе. Связь с данными (=Запись.Значение) правило не трогает: судится форма выражения.style/redundant-typeвидит типизированный пустой литерал:пер Артикулы: Массив<Число> = <Число>[]называет тип дважды. Распознаётся только массив.xbsl/metaKeys– пары ключей элемента для поверхностей вне python. Дерево метаданных редактора разбирает yaml само, и у английского объекта ветки были пусты.
Изменено
- Соглашения платформы по написанию кода стали стандартом: семь правил
style/работают по умолчанию и сообщают на уровнеwarning– длина строки, сравнение сИстина/Ложь, UpperCamelCase, литералы коллекций, интерполяция, лишний.ВСтроку(), регистр аббревиатур. Накопленному долгу место в базлайне. - Выключенное правило само говорит, почему, прямо в
--list-rules; в машинном списке причина приходит полемoff_reason. - Каталог типов хранит объединение целиком (
Авто|БулевовместоАвто), поэтому данные отличают булево от значения, которое может быть булевым. - Все тексты
self-updateуведены в каталог сообщений –--lang enотвечает по-английски.
Исправлено
- То, что скаффолдинг пишет, теперь на языке проекта. Форма, созданная в английском проекте, приходила с русскими ключами и русскими именами типов; ключи и имена берутся из данных самой платформы, имена автора не трогаются.
- О том, что данные назвать не могут, инструмент говорит – английских значений интерфейсных перечислений в поставке нет, и отчёт называет такие значения, а не выдумывает их.
style/boolean-compareбольше не срабатывает там, где сравнение обязательно. Краткая форма не компилируется, как только значение nullable или составное, поэтому операнд типизируется, и нарушением сравнение остаётся, только когда тип ровноБулево.- Скаффолдинг читает проект, написанный английскими написаниями ключей. Прежде часть операций отвечала “объект не найден”, а три – успехом с неверным результатом.
- Параллельный прогон выпущенного колеса больше не обрывается. Результат воркера вёз кэш файла, который в нативной сборке не распаковывается; кэш больше не пересекает границу процессов, и результат похудел с 1,96 МБ до 0,58 МБ.
- Переименование объекта, отличающееся только регистром, больше не отклоняется – на регистронезависимой файловой системе оно выполняется через временное имя, а сбой откатывается.
- Переименование по регистру предупреждает о системе контроля версий: git на такой файловой системе покажет кириллическое переименование как удаление и добавление.
- Проектное правило локализации больше не гоняет между процессами целые исходники – в факт едут только вызовы, стоящие рядом со сравнением.
26.07.2026 – 0.36.1, 0.37.0, 0.37.1, 0.37.2, 0.37.3, 0.38.0, 0.39.0, 0.40.0
Добавлено
- Четыре правила: права по объектам и локализация (правил стало 122).
code/per-object-permissions-need-common– общий обработчик разрешений обязателен и при per-object;code/permission-field-not-declared– поле вне объявленного списка расчёта;yaml/placeholder-key-in-strings– подстановка в секцииСтроки, которая компилируется в метод без параметров;code/compare-with-localized– сравнение с локализованным значением, которое на другом языке молча не срабатывает. yaml/delete-current-needs-immediate(правил стало 118):УдалятьТекущийу владельца, который только помечает запись, роняет применение всего проекта.- Два правила про окружение исполнения (правил стало 117):
code/client-available-needs-context–@ДоступноСКлиентау метода компонента интерфейса безстатическийили@Контекстный;code/server-module-in-client-context– обращение к серверному общему модулю из клиентского метода. Оба отказа видны только серверной компиляции. - Пять правил про то, что платформа принимает, но не делает (правил стало 115): пустая группа с
заданным размером, слишком длинная подсказка,
Закрыть()в собственномПередЗакрытием, несуществующая функция языка запросов и каталоги проекта, разошедшиеся с дескриптором.
Изменено
- Сторож английских документов: русские написания имён платформы в английских текстах бракует тест, а не глаз. Знает три законных случая – имя файла, одиночная буква как предмет разговора и ссылка на русского близнеца.
- Тексты говорят о фактах, а не о том, как они получены (0.37.1–0.37.3). Что принимает компилятор и от чего страхует правило – осталось, прочее убрано; поведение правил не менялось.
Исправлено
- Сторож синхрона смотрел четыре места из восьми, поэтому счётчики правил на страницах сайта разъехались незамеченными. Теперь проверяются все восемь.
- Обход дерева пропускал всё, что внутри условия – ветви
еслихранятся парами, а обходчик спускался только в списки узлов. - Колесо 0.36.0 не проверяло ничего: обход дерева в одном правиле опирался на способ, которого в нативной сборке нет. В тестах такой обход теперь ловится миной.
- Падение одного правила больше не роняет прогон – ошибка правила стала отдельной находкой под его же идентификатором, остальные правила отрабатывают.
25.07.2026 – 0.35.0, 0.36.0
Добавлено
- Два правила про статический метод (
code/this-in-static-method,code/instance-call-from-static): контекста объекта у него нет, поэтомуэтотв теле и голый вызов обычного метода того же владельца компилятор отвергает. code/local-method-cross-module(правил стало 101):Модуль.Метод(...)обязан звать метод с аннотацией видимости – без неё метод виден только в своём модуле.
Изменено
code/unknown-static-memberтипизирует значение, пришедшее из чужого модуля: каждый модуль публикует типы возврата своих методов, и проектная фаза связывает с нимиМодуль.Метод(...).- Скаффолдинг пишет слот по его кардинальности: первый ребёнок слота-массива ложится элементом списка, а не одиночным вложенным мэппингом, иначе сборка отвергает форму.
Исправлено
- Проект, записанный английскими написаниями метаданных, судится наравне с русским. Прежде
правила искали
ВидЭлемента, не находили и пропускали файл целиком – в нём не ловилась даже опечатка. На русских исходниках находки остались прежними. - Формы тоже: английский компонент разбирается и судится. Модель формы читает ключи через словарь мета-объектов компилятора, поэтому конструктор, панель структуры и правка видят одно дерево независимо от языка файла.
- У демо-проекта появился английский двойник (
demo-en/), и он же сторож: тест требует, чтобы оба двойника давали одни и те же находки на тех же строках. - Скаффолдинг пишет на языке проекта – язык определяется по большинству файлов, а не настройкой.
- Публичный CI был красным с прошлого релиза, и вскрыла это имитация клона без данных: три теста двуязычия ждали написаний, которых в таком клоне нет.
- Инструмент MCP с опиской в имени аргумента теперь падает, а не отрабатывает молча со значениями по умолчанию.
24.07.2026 – 0.32.0, 0.33.0, 0.34.0
Добавлено
- Правило
yaml/unexpected-type-argument(правил стало 100): параметр типа у свойства, которое ui-схема объявляет без параметра, – это другой тип, и применение его отвергает. - Ui-схема несёт раздел
type_params– параметры типа дженериков и их умолчания; без него проверка выше давала ложные срабатывания. ui_schemaотвечает и на имена вне палитры – команды, фрагменты и группы командного интерфейса, элемент списка значений.xbsl extract– генерация датасета командой CLI. Экстракторы переехали в пакет, поэтому установленный пакет генерирует данные без клона репозитория.xbsl data-diff [старая] [новая]– что изменилось в платформе между двумя версиями данных. Члены сравниваются с развёрнутым наследованием,--format text|md|json.- Индекс версий двигает умолчание только вперёд: регенерация старой версии его не сбивает.
- Правило
code/invalid-string-escape– недопустимая управляющая последовательность в строковом литерале ловится до серверной компиляции. - MCP
ui_schema: параметрыbriefиproperty– строка на свойство вместо полной схемы и полная запись одного свойства. - Схема метаданных разворачивает закрытое ограничение типа свойства в список допустимых значений.
Исправлено
code/unknown-memberсудит и переменные дженерика по его голове: уЧитаемыйМассив<Задача>набор членов тот же, что уЧитаемыйМассив, а прежде параметризованный тип пропускался целиком.- Поиск по документации не отвечает пустотой на многословный запрос – когда ни одна страница не несёт всех слов, поиск ослабляется до “любое из слов”.
xbsl extract --helpназывает команду, а не путь интерпретатора.- Экстрактор stdlib снова распознаёт компоненты интерфейса новых дистрибутивов – маркером служит и адрес ссылки, а не только квалифицированное имя.
- Переменная по имени
Запросбольше не читается ключевым словом – без{это обычное имя. - Проверка одиночного файла не теряет тень парного yaml, поэтому реквизит формы не судится как одноимённый тип stdlib.
- Ховер не документирует как тип stdlib ни объявленную переменную с невыведенным типом, ни имя, объявленное парным yaml.
23.07.2026 – 0.31.0, 0.31.1
Изменено
- Каталог типов stdlib записывает более полные типы членов и досбирает поверхности со страниц-топиков, поэтому проверки членов и подсказка совпадают с тем, что платформа предоставляет (0.31.0).
Исправлено
code/resource-bare-nameне считает ссылкуinbase/...путём с каталогом: ресурс, загруженный в базу приложения, – это ключ поиска (0.31.0).- Ключ ресурса – путь относительно каталога
Ресурсыподсистемы: ссылки на подкаталоги легальны (0.31.1).
22.07.2026 – 0.28.0, 0.29.0, 0.30.0, 0.30.1
Добавлено
- Сайт документации (docs.keyfire.ru/xbsl), полный справочник команд и справка – целиком на русском и английском (0.29.0).
- Метамодель разрешает схему элемента коллекции – значения перечисления, реквизита, измерения, ресурса, поля структуры, – поэтому линтер видит полную схему со значениями по умолчанию (0.29.0).
- Операция удаления обработчика формы (
xbsl/removeHandler): отвязывает событие и удаляет его метод одним изменением (0.28.0).
Изменено
- Быстрее на больших проектах: кэши слоя данных, разбор YAML через libyaml, пулы воркеров по размеру задачи (0.30.0).
- Ховер типа несёт его описание из документации, а не одну ссылку (0.28.0).
- Подсказка проходит цепочку членов за ссылкой-свойством, сторож останавливает обход на границе замыкания stdlib (0.30.1).
Исправлено
yaml/bare-object-valueдопускает$-ссылку на локализованную строку там, где ждут литерал (0.30.1).- Перегенерированные данные подхватываются без перезапуска (0.30.1).
- Серверы за необязательными extras на минимальной установке аккуратно пропускаются, а не падают импортом (0.30.1).
21.07.2026 – 0.25.0, 0.26.0, 0.26.1, 0.27.0
Добавлено
- Четыре правила линтера:
yaml/bare-object-value(голое слово там, где ждут литерал или биндинг),code/resource-bare-nameиcode/unknown-resource(ресурс голым именем файла) иyaml/no-expression-in-literal(0.26.0). - Три правила движка:
yaml/ref-needs-nullable,yaml/unknown-enum-valueиyaml/standard-field-length(0.25.0). - Единое API метамодели – типы свойств, перечисления и значения по умолчанию через один интерфейс (0.27.0).
Изменено
- Скаффолдинг принимает вид элемента на любом языке платформы (0.26.0).
- Языковые данные приходят из компилятора, а не из констант (0.26.0).
code/undefined-nameчитает имена и в интерполяции строк (0.25.0).- Подсказка следует языку разработки проекта (0.26.1).
Релизы до 0.25.0 предшествуют этой истории изменений. История продукта до 0.1.0 – в CHANGELOG расширения VS Code.