---
name: 1c-testbench
description: Проверить доработку 1С (.epf/.erf или XML-выгрузку) ПЕРЕД сдачей владельцу — реальной компиляцией платформой, статическим анализом BSL, сверкой имён метаданных в текстах запросов и визуальной картой форм. Брать ВСЕГДА после правки любого модуля/формы 1С, до того как отдать файл: `POST /build` у onec-build-agent даёт HTTP 200 даже на коде, который не компилируется, поэтому «агент собрал» — недостаточное доказательство. Триггеры: «проверь обработку», «прогони стенд», «скомпилируется ли», «подключится ли обработка», «проверь синтаксис 1С», «покажи форму / как выглядит интерфейс», «что видит пользователь на форме», «прогони корпус 1С», перед отправкой .epf заказчику или в git. Дополняет скилл 1c-epf (тот СОБИРАЕТ и правит, этот ПРОВЕРЯЕТ). НЕ для прошивок ЭБУ (ecu-firmware), не для PDF (pdf-visual-qa), не для рантайм-тестов на живых данных (их нет в базе — см. reference/limits.md).
---

# Стенд e2e-проверки доработок 1С

Шесть слоёв, включаются по возрастанию цены. Полный прогон реальной обработки
с 4 формами — около минуты.

| Слой | Что | Время | Инструмент |
|---|---|---|---|
| L0 gates | грабли, на которых уже обжигались | мгновенно | `tools/gates.py` |
| L0 lint | ошибки разбора BSL, стандарты 1С | ~10 с | `tools/lint_bsl.py` |
| L0.5 meta | имена метаданных в текстах запросов и `<query>` схем СКД (`.erf`, включая UNION) vs конфигурация | ~1 с | `tools/meta_check.py` |
| L0.5 mxl | имена макетов/областей в `ПолучитьМакет`/`ПолучитьОбласть` vs `Templates/` | ~1 с | `tools/mxl_check.py` |
| L1 platform | компиляция настоящей платформой (`.epf` И `.erf`) | ~35 с | `tools/tb.py` → `ext_wrap` + `v8run` |
| L3a render | визуальная карта форм (HTML + JSON) | мгновенно | `tools/render_form.py` |

`/CheckModules` не проверяет НИ схему СКД, НИ имена макетов/областей —
опечатка в `Документ.X` внутри `<query>` СКД или в `ПолучитьОбласть("Y")`
проходит платформенную компиляцию чисто (проверено эмпирически на реальных
файлах). L0.5 meta/mxl — единственный слой, который это ловит.

## Как гонять

```bash
# всё сразу: .epf/.erf или каталог XML-выгрузки
python3 ~/.claude/skills/1c-testbench/tools/tb.py check ~/Downloads/ОбработкиЭкспорт/Имя.epf

# быстрый цикл во время правок — без платформы
python3 .../tools/tb.py check <каталог> --fast

# машинный отчёт (для хука, для агента)
python3 .../tools/tb.py check <путь> --json /tmp/tb.json
```

Код возврата: `0` — можно отдавать, `1` — есть блокирующие находки.
Флаги: `--fast` (без платформы), `--no-render` (без карт форм),
`--json <файл>`.

**Вердикт `ЧИСТО` означает ровно одно: обработка скомпилируется и
подключится.** Что она вернёт на живых данных — стенд не знает и не
притворяется, что знает. Перед словами «работает» смотри
`reference/limits.md`.

## Разовая подготовка

```bash
bash ~/.claude/skills/1c-testbench/tools/setup.sh
```

Ставит BSL LS (через `gh-proxy.com` — напрямую из РФ душится), проверяет
Java 21, делает стенд-базу `ib_stand` копией базы с конфигурацией, строит
индекс метаданных, создаёт каталог карт форм.

Индекс метаданных пересобирать после каждого обновления конфигурации:
```bash
python3 .../tools/meta_check.py index
```

## Как это устроено внутри

**L1 — единственный способ заставить платформу скомпилировать внешнюю
обработку.** Штатного batch-ключа для `.epf` не существует, поэтому
`ext_wrap.py` оформляет обработку объектом расширения конфигурации
(`ExternalDataProcessor` → `DataProcessor`, `ObjectBelonging=Native`,
`InternalInfo` с `GeneratedType`), грузит расширение в стенд-базу и вызывает
`/CheckModules -Extension`. Модули `.bsl` копируются байт-в-байт — меняются
только метаданные, иначе проверялся бы не тот код, который уходит заказчику.

Тупики, которые уже проверены и повторять их не надо (`/CheckConfig`,
HTTP 200 от `/build`, частичная загрузка) — в `reference/limits.md`.

## Принцип: только программно, никакой интерактивности

Стенд не кликает и не водит мышью по GUI 1С — ни для проверки, ни для
осмотра. Все слои — детерминированные вызовы (batch-Конфигуратор, BSL LS,
парсер XML). Толстый клиент 1С на этой машине рендерится чисто (проверено
2026-07-30, прежняя запись «криво» была ошибочной), но это не повод его
драйвить кликами — Accessibility-автоматизация сюда сознательно не введена.

## Релей контекста (когда не хватает реальных данных)

Дев-база = только конфигурация, без документов (см. `reference/limits.md`).
Если проверке для детальности нужны реальные данные — стенд **не
подключается к проду напрямую и не запрашивает такой доступ**. Вместо этого:

```bash
# 1. агент формулирует точный запрос
python3 .../tools/context_relay.py request "<текст запроса 1С>" --format csv

# 2. пользователь сам выполняет его в проде и отдаёт результат
# 3. агент кладёт результат в изолированную песочницу
python3 .../tools/context_relay.py ingest <id> <файл-с-результатом>

python3 .../tools/context_relay.py list   # что открыто / что выполнено
```

Данные оседают в `sandbox/data/<id>/` — обычные локальные файлы, дальше
читаются как фикстуры. Ни строки подключения, ни кредов, ни сетевого пути к
проду в этом дереве никогда не появляется. Протокол и гарантии —
`sandbox/README.md`.

## Визуальный слой

`render_form.py` строит карту формы из `Form.xml`: группы, страницы, поля,
таблицы с колонками, кнопки с цветом и подменю, флаги «только просмотр» /
«скрыт» / «недоступен». Подписи берутся так, как их видит пользователь:
свой заголовок → синоним реквизита объекта → заголовок реквизита формы →
последний сегмент `DataPath`.

Карты складываются в `~/Разработки/.tb_preview` и отдаются dev-сервером
`1c-form-maps` (`.claude/launch.json`, порт 8911) — превью-панель даёт DOM и
скриншот только по HTTP, `file://` показывает статичный снимок.

```bash
# посмотреть формы: preview_start {name: "1c-form-maps"} → localhost:8911/
python3 .../tools/render_form.py <каталог выгрузки> --json /tmp/forms.json
```

Это карта по метаданным, **не пиксельная копия клиента 1С**. Пиксели может
показать только настоящий клиент; на macOS он рендерит криво (правило
владельца — не открывать), а `screencapture` у Claude заблокирован TCC.

## Регрессионный корпус

Стенд проверяет обработки, корпус проверяет стенд: берёт рабочую обработку,
вносит один известный дефект и требует, чтобы сработал именно тот слой,
который обязан. Плюс контрольный кейс без дефекта — на ложные срабатывания.

```bash
python3 ~/.claude/skills/1c-testbench/tests/run_corpus.py         # с платформой
python3 .../tests/run_corpus.py --fast                            # без платформы
python3 .../tests/run_corpus.py --case quote_object
```

**Каждый новый инцидент в проде → новый кейс в `tests/run_corpus.py`.** Это
и есть то, что делает «мельчайшие тонкости» списком, а не декларацией:
стенд ловит ровно то, на чём уже спотыкались, и не даёт спотыкнуться дважды.

## Окружение

| Переменная | Смысл | По умолчанию |
|---|---|---|
| `ONEC_V8_DIR` | каталог платформы | `/opt/1cv8/8.3.27.1859` |
| `ONEC_TB_IB` | стенд-база | `~/Services/onec-build-agent/ib_stand` |
| `ONEC_TB_UID` | uid базы с конфигурацией для `/dump-epf` | `1005954706` |
| `ONEC_CONF_DIR` | XML-выгрузка конфигурации для индекса | `~/Downloads/ОбработкиЭкспорт/НоваяКонфа` |
| `ONEC_TB_PREVIEW` | каталог карт форм | `~/Разработки/.tb_preview` |
| `BSL_LS_JAR`, `BSL_LS_JAVA` | BSL LS и Java 21 | `~/.local/share/bsl-language-server/…`, `/opt/homebrew/opt/openjdk@21/bin/java` |
