bsl-architecture-review · diff
git:20260810.096e1f4 to git:20260901.3570af2
2 added, 2 removed. Audit A to A.
---
name: bsl-architecture-review
description: >-
Контур проверки архитектуры кода 1С: распределение ответственности, границы и контракты,
связанность модулей, ветвление вместо диспетчеризации, дублирование, переусложнение.
Принципы SOLID, GRASP и паттерны проектирования в их штатной для 1С реализации.
Уровень «требует нового шва» — то, что не чинится заменой строк внутри метода.
Вызывается оркестратором quality-gate; напрямую — по запросу «архитектурное ревью»,
«разнести ответственность», «это нарушение SOLID», «оцени структуру модуля».
license: MIT
---
# bsl-architecture-review — контур архитектуры
Проверяет то, что **не чинится внутри тела метода**. Граница с контуром кода механическая, а
не тематическая:
> Фикс укладывается в замену строк внутри метода — это код. Фикс требует нового шва
> (выделение метода, перенос в другой модуль, новый экспорт, изменение «кто кого вызывает»,
> ввод диспетчера) — это архитектура.
Полные правила границы, дедупликации находок и шкала severity — в `shared/routing-contract.md`
на уровне плагина. Здесь они намеренно не дублируются: копия разъедется с оригиналом при первой
же правке, а это ровно тот дефект, который контур и ищет.
<ЖЁСТКИЙ-ШЛЮЗ>
Только анализ и отчёт. Архитектурная правка без согласования недопустима: она затрагивает
вызывающих и переживает автора. Находка без предложенной целевой структуры не выпускается.
</ЖЁСТКИЙ-ШЛЮЗ>
## Глубина
Приходит от оркестратора вместе с профилем изменения. Контур свои пороги не пересчитывает.
| Класс | Уровень | Что смотрим | Бюджет обращений к индексу кода |
|---|---|---|---|
| C0, C1 | не запускается | — | — |
| C2 | 1–2 | тела изменённых методов; при необходимости — экспорты модуля и его вызывающие | ≤4 |
| C3 | 3 | плюс связи подсистем, проектирование метаданных, карта ответственностей | ≤8 |
Бюджет объявляется явно, потому что индекс кода режет выдачу по числу вызовов: без бюджета
контур либо не доберёт фактов, либо упрётся в лимит на середине и отчитается по неполным данным.
Архетипы поднимают уровень независимо от класса: новый общий модуль — минимум уровень 2,
новый объект метаданных — уровень 3, интеграция и CFE-перехват — минимум уровень 1.
---
## Как работает: измеримые сигналы, а не «прочитай и подумай»
- Источник истины — `references/signs-map.json`: одиннадцать признаков, у каждого сигнал, порог,
+ Источник истины — `references/signs-map.json`: у каждого признака сигнал, порог,
**контр-сигнал** и ссылки на принципы. Человекочитаемая версия — `signs-map.md`.
Порядок работы с каждым кандидатом:
1. **Измерь сигнал.** Не «мне кажется, модуль перегружен», а «14 экспортных методов
кластеризуются в 4 несвязанные группы».
2. **Проверь контр-сигнал.** У каждого признака есть законная форма, в которой он не является
дефектом. Ложноположительная архитектурная находка дороже пропущенной: она провоцирует
переделку работающего кода.
3. **Запроси принцип** по URL через MCP `v8std` — формулировка берётся из источника, а не по
памяти.
4. **Сформулируй целевую структуру.** Какие методы, модули и поля появляются, что удаляется.
### Симметрия: пере-абстракция ловится так же строго
Механизм расширяемости с единственной реализацией, «стратегия» на одну ветку, абстракция без
второй точки изменения — это находка уровня 🟠 с формулировкой «предъявите вторую реализацию
или упростите».
Эта половина контура направлена в первую очередь на код, написанный языковой моделью: типовой
отказ лежит именно здесь, а не в недостатке абстракций. Правило трёх обобщает после третьего
повторения, не раньше.
---
## Три ограничения точности
Без них контур теряет доверие после первой же ложной находки.
**1. Одноимённые методы в разных объектах — норма для 1С.** Индекс кода различает точные и
эвристические совпадения. Любая эвристика, опирающаяся на счётчик вызывающих, требует точного
разрешения; при эвристическом — понижай severity на ступень и формулируй находку как вопрос,
а не как утверждение.
**2. Полнотекстовый поиск доказывает наличие, но не отсутствие.** Он ограничен числом
просматриваемых файлов. Область поиска — явный список файлов из диффа; пустой результат даёт
формулировку «в изменённых файлах не найдено», но никогда — вердикт «чисто».
**3. Пороги статического анализатора принадлежат проекту.** Конфигурация анализатора может
отключать диагностики или ограничивать анализ отдельными подсистемами — тогда изменённые
прикладные файлы вообще не попадут в анализ. Держи свои пороги независимыми и используй
анализатор как дешёвый предфильтр кандидатов, никогда — как источник самой находки.
**Отдельное жёсткое правило про мёртвый экспорт.** В 1С экспортные методы вызываются не только
из кода: подписки на события, команды, регламентные задания, настройки библиотек живут в XML;
плюс расширения и внешние обработки. Находка «экспорт без потребителей» **не выводится вообще**,
пока не проверены триггеры — иначе контур предложит удалить работающий механизм.
---
## Нет индекса кода — четыре признака уходят в `skipped`, а не в «чисто»
Признаки `ARCH-A1`, `ARCH-A7`, `ARCH-A9` и `ARCH-A11` опираются на граф вызовов: кластеризация
экспортов по вызывающим, дублирующая валидация у вызывающего и внутри вызываемого, экспорт без
потребителей, состав проверок по обе стороны диалога. Последний признак почти всегда пересекает
границы модулей: проверки живут в общих модулях, а вызывает их модуль формы. Без индекса кода
ни один из четырёх нельзя ни подтвердить, ни опровергнуть.
**Факты по графу собирает субагент `bsl-scout`.** Передавай ему вопрос, а не задачу: «экспорты
модуля и вызывающие по каждому», «есть ли у метода вызывающие и триггеры в XML». Независимые
вопросы задавай параллельно, по одному субагенту на вопрос. Бюджет обращений к индексу
расходует он, а твой контекст остаётся под разбор. В его отчёте ищи пометку об эвристическом
разрешении вызывающих: она понижает уверенность находки на ступень и меняет формулировку с
утверждения на вопрос.
Выводы делаешь ты. Субагент возвращает факты и архитектурных вердиктов не выносит. Если
субагента в среде нет, работай с индексом сам в пределах объявленного бюджета.
Молча их не проверить — значит выдать отчёт, который выглядит полным. Это тот же класс ложной
зелени, который контур ищет в чужом коде, только внутри него самого.
Поэтому при недоступном индексе пиши в след:
```
[qg skipped: layer=arch, scope=call-graph-signs, planned=[qg:ARCH-A1,qg:ARCH-A7,qg:ARCH-A9,qg:ARCH-A11], reason=rlm_unavailable]
```
и строкой в отчёте: «признаки по графу вызовов не проверялись — индекс кода недоступен».
Вердикт «архитектурных замечаний нет» без этой оговорки не выпускается.
- Остальные семь признаков от индекса не зависят и гоняются по телам изменённых методов как
+ Остальные признаки от индекса не зависят и гоняются по телам изменённых методов как
обычно. Список зависимых живёт в машиночитаемой карте полем `requires: ["call-graph"]`, а не в
этом тексте: две копии одного знания разъезжаются при первой правке — ровно то, что ловит
признак `ARCH-A3`.
---
## Состязательный аудит на крупных изменениях
Для класса C3 с находками уровня 🔴 или 🟠 предложи в отчёте состязательный аудит: веер
ревьюеров по измерениям (ответственность, границы, связанность, дублирование, переусложнение)
и проверяющие, пытающиеся опровергнуть каждую находку.
Архитектурные находки выигрывают от этого больше кодовых: они опираются на эвристики, и доля
спорных среди них выше. Методология — `../quality-gate/references/adversarial-audit.md`.
Запуск только после явного согласия пользователя.
---
## Формат находки
Сверх общего формата обязательны четыре поля. Находка без любого из них не выпускается.
```
[🔴/🟠/🟡] <суть>
Где: <путь>::<Метод>:<строка>
Признак: qg:ARCH-AN — <название>
Сигнал: <измеренное значение> против порога <порог>
Принцип: <название> — <URL> (+ #stdNNN, если есть)
Целевая структура: <какие методы/модули/поля появляются, что удаляется>
Переусложнение: вводится сущностей N, реальных потребителей M, удаляется K
Уверенность: высокая | средняя (эвристическое разрешение вызывающих) | требует проверки
```
**Целевая структура** отличает находку от жалобы. «Модуль перегружен» без предложения, как его
разделить, не является результатом работы.
**Проверка на переусложнение** обязательна, потому что иначе контур сам становится источником
пере-абстракции: предлагает ввести три сущности там, где хватает одной.
### Записи следа
```
[qg applied: layer=arch, scope=module-responsibility, ids=[qg:ARCH-A1,std440], verdict=violation:qg:ARCH-A1]
[qg applied: layer=arch, scope=branching-dispatch, ids=[qg:ARCH-A2], verdict=clean]
[qg skipped: layer=arch, reason=volume_below_threshold]
```
---
## Специфика 1С
Каноничные реализации паттернов из литературы в 1С не работают: платформа не даёт
пользовательских иерархий классов. Штатные соответствия — в `references/patterns-in-1c.md`;
предлагать нужно именно их, а не абстрактный «интерфейс стратегии».
Антипаттерны архитектурного уровня, характерные для кода языковой модели, —
в `references/ai-antipatterns-arch.md`. Чеклист по семи областям —
в `references/checklist-architecture.md`.
---
## Принципы
- **Сигнал вместо вкусовщины.** Каждая находка — измеренное значение против объявленного порога.
- **Контр-сигнал обязателен.** Прежде чем выпустить находку, проверь законную форму признака.
- **Целевая структура обязательна.** Нет предложения — нет находки.
- **Пере-абстракция равна недо-абстракции.** Обе стороны проверяются одинаково строго.
- **Уверенность заявляется.** Эвристическое разрешение ссылок понижает severity и меняет
формулировку с утверждения на вопрос.