From 60c044520fcdf5af224ea817da62dee9a4327260 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Fri, 18 Sep 2026 00:42:42 +0600 Subject: [PATCH] [2026-09-18] eagle: personal/projects/zont-config-compiler.md --- personal/projects/zont-config-compiler.md | 89 +++++++++++++++++------ 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/personal/projects/zont-config-compiler.md b/personal/projects/zont-config-compiler.md index dc1cff80..fe500438 100644 --- a/personal/projects/zont-config-compiler.md +++ b/personal/projects/zont-config-compiler.md @@ -3831,40 +3831,87 @@ for obj in obj_list: пропадает **без единого сообщения об ошибке**. Признак: `exit=0`, строка отсутствует и в старом, и в новом номере. -### 25.10. 🎯 ОТКРЫТОЕ РЕШЕНИЕ (вопрос задан Alex, ответа нет) +### 25.10. ✅ ЗАКРЫТО: вариант 1 — только объекты-листья (решение Alex: «1») -Правка трёх барьеров = открыть авто-id для всех секций. Выбор объёма: +| Вариант | Решение | +|---|---| +| ~~2. Все секции~~ | ⛔ отвергнут: требует `_body_type` до присвоения id + снятие барьера в 6+ циклах | +| **1. Только объекты-листья** | ✅ **ВЫБРАН ALEX** | -| Вариант | Что делается | Объём / риск | +**Реализация (круг 50, закрыт):** + +| Что | Место | Статус | |---|---|---| -| **1. Только объекты-листья** *(рекомендация)* | 3 правки условий допуска; объекты, на которые ссылаются по типу, продолжают требовать явный `id` | ~30 мин, риск низкий | -| **2. Все секции** | дополнительно снять барьер «`id` у каждой записи» в 6+ циклах + разобрать `_body_type` (тип объекта нужен ДО присвоения id) | ~2 ч, риск средний — можно молча сломать ссылки по типу | +| Барьер `'id' in obj` снят в цикле `TYPE_ORDER` | `yml-to-config.py` | ✅ | +| То же в цикле орфанов | там же | ✅ | +| `_LEAF_TYPES = {9}` — белый список (только `relay_commands`) | модульная константа | ✅ | +| `_is_leaf_without_id(obj, obj_type)` — отказ с понятным текстом для остальных | там же | ✅ | +| **Валидация ссылок в актуальной форме** (`trigger`/`steps`) | `validate_config` | ✅ | -Аргумент за вариант 1: закрывает реальный сценарий («написал новую реле-команду, номер придумался -сам»). Объекты-источники всегда заводит прибор, и номер им выдаёт контроллер, а не мы. +**Формы, которые теперь принимает энкодер:** -### 25.11. 📌 Статус на конец сессии 2026-09-18 (для следующей) +```yaml +# id не указан -> выдаётся свободный из 4098..19999 (тип 9) +- set_relay: + descr: 'Включить реле «Реле 13/9: Рад. ванная 2эт»' + target: 9464 + value: true +# -> #Z4101=9,'Включить реле «Реле 13/9: Рад. ванная 2эт»',9464,'1' +``` + +#### ✅ Валидация ссылок — что теперь отклоняется (exit=4, конфиг НЕ пишется) + +``` +❌ VALIDATION ERRORS: + - Object 9564: set_relay.target references non-existent id 99999 (нет строки #Z99999 в выводе) + - Object 8456: call_sub references non-existent id 88888 (нет строки #Z88888 в выводе) +``` + +Проверяются: `set_relay`/`set_contour_target`/`activate_mode`/`set_sensor`/`set_analog_output`/ +`set_contour_temp` → `target`; `value` — если ссылка (`{id: ...}`); `call_sub`, `send_sms`; +`trigger.step_id`, `trigger.object`, `trigger.left.object`; рекурсивно `then`/`else`/`action`/`steps`/`if`. + +База допустимых id — **сами строки вывода** (`_present = set(output_ids)`), не YAML: объект может +быть в YAML и не выпуститься, тогда ссылка висит в воздухе (питфолл 97). + +#### 🔴 ПИТФОЛЛ 105 — «валидация ссылок есть» ≠ «валидация ссылок работает» + +Блок «4. Validate ID references in scenarios» в `validate_config` **существовал** — но читал +`scenario.get('when', {}).get('relay_id')` и `then.actions`. Это форма **до кругов 39-49**; в актуальном +YAML этих ключей нет вовсе. Валидатор работал вхолостую: подмена `target` на `99999` проезжала молча +(exit=0, мусор уезжал в контроллер). + +**Урок:** при смене формы хранения ключа искать **всех** читателей, включая валидаторы. Признак мёртвого +кода — ключ, которого нет ни в одном артефакте (`grep 'when\.\|then\.actions'` по `zont_config/*.yml` → 0). + +### 25.11. 📌 Статус на конец круга 50 (2026-09-18) — ЗАКРЫТ, ЗАПУШЕН + +**HEAD: `7e34ee1`** — «авто-id для листьев + валидация ссылок (круг 50)», `origin/main` = HEAD. | Позиция | Состояние | |---|---| -| Аллокатор, окно, hard fail | ✅ **написано** в `yml-to-config.py` (**НЕ закоммичено**) | +| Аллокатор, окно `4098..19999`, hard fail | ✅ в `yml-to-config.py`, **закоммичено** | | Регресс 9/9 | ✅ `759 → 759`, расхождений 0 | -| Авто-id end-to-end | ❌ **не работает**: барьеры §25.9 не сняты | -| Валидация ссылок | ❌ нет (питфолл 103) | -| Рабочее дерево | `yml-to-config.py` изменён, **113+/26−**, поверх `5d31d6e` | +| Авто-id end-to-end (тип 9, без id) | ✅ **работает**: одна строка заменена, тело и target сохранены | +| Валидация ссылок | ✅ **есть**: exit=4, конфиг не пишется, текст с указанием объекта | +| Push | ✅ `5d31d6e..7e34ee1` → Gitea | -🔴 **Работа НЕ закоммичена.** Коммит — по команде Alex (питфолл: он сам скажет). -Правки внесены скриптами `/tmp/patch_autoid.py`, `/tmp/patch_autoid2.py`, `/tmp/patch_autoid3.py` -(идемпотентные, проверка `count == 1`, печатают OK/SKIP). +**Скрипты правок (идемпотентные, `count == 1`, печатают OK/SKIP):** `/tmp/patch_autoid.py`, +`/tmp/patch_autoid2.py`, `/tmp/patch_autoid3.py`, `/tmp/patch_autoid4.py`, `/tmp/patch_validate_refs.py`. **Инструменты диагностики (в `/tmp`, не в репо):** `/tmp/dbg50.py` (трассировка `build_line`, -минимальный кейс сценария), `/tmp/dbg_relaycmd.py` (барьер `'id' in obj`), -`/tmp/test_autoid.py` (тест авто-генерации), `/tmp/test_autoid_granica.py` (граница: какие объекты -можно без id), `/tmp/accept_autoid.py` (приёмка: замена id + ссылка в никуда). +минимальный кейс), `/tmp/dbg_relaycmd.py` (барьер `'id' in obj`), `/tmp/test_autoid.py` (тест генерации), +`/tmp/test_autoid_granica.py` (граница: какие объекты можно без id), `/tmp/accept_autoid.py` +(приёмка: замена id + ссылка в никуда), `/tmp/show_ref_error.py` (текст ошибки валидации). -**Риски (актуальны):** (а) ссылки в новые объекты — реальная проблема, требует решения шага 3; -(б) порядок эмиссии: `S`-блоки первыми, `Z` — после, id нужен раньше строки; -(в) ~~верхняя граница~~ — ✅ **ЗАКРЫТО**: фикс-окно `4098..19999`, решение Alex. +**Остаток (не сделано):** +1. Авто-id для объектов-источников (ссылки по типу: контуры 16, датчики 27) — нужна правка `_body_type`. +2. Секции `actions` / `mqtt_topics` / `gui_switches` — цикл требует `id` у каждой записи. +3. Расширение `_LEAF_TYPES`: каждый новый тип обязан пройти замер `test_autoid_granica.py`. + +**Риски:** (а) ссылки в новые объекты — решены валидацией (ссылка в никуда = ошибка); +(б) порядок эмиссии: `S` первыми, `Z` — после, id нужен раньше строки — учтено через `_alloc_id` в трёх +узких местах; (в) ~~верхняя граница~~ — ✅ закрыто фикс-окном. ---