diff --git a/personal/projects/zont-config-compiler.md b/personal/projects/zont-config-compiler.md index 968ed38e..90e0fb4d 100644 --- a/personal/projects/zont-config-compiler.md +++ b/personal/projects/zont-config-compiler.md @@ -629,6 +629,10 @@ iconv -f cp1251 -t utf-8 out.txt | tr -d '\r' | grep '^#Z=<тип>' | 28g | 🔴 **Мусорный ярлык в `type:` ломает читаемость сильнее, чем отсутствие ярлыка** | `type: condition` у объекта с `param: target_temp` — «condition» врёт: запись 49 несёт **значение**, а не условие. Alex: «тут почему condition?». Ярлык должен называть **содержимое** (`param`), а не «формат записи» | | 28h | 🔴 **Переиспользование занятого имени ключа ломает сборку** | Алекс: «value», но `value` уже занят сырым числом в том же узле → коллизия. Решение: освободить `value` под `type`-слово, сырое число → `raw_value`. Перед вводом ключа — `grep` по **всем** использованиям имени | | 28i | 🔴 **`grep -oE` c `[^\r]*` обрезает строку на мультибайте (cp1251)** | `grep -oE "#Z9964=[^\r]*"` вернул `59,'set va` — я чуть не доложил «строка битая». Читать файл целиком через `iconv -f cp1251 -t utf-8` + `grep -nE '^#Z…='`, либо `python3` с явной кодировкой. Кириллица в cp1251 ≠ байты UTF-8, регексп рвёт её посередине | +| 28j | 🔴 **Дублирующий разбор вытесняет уже принятую форму** | Ветка `t == 'var'` в `_inline_script_body` собирала тот же `set var`, что и `set_var`, и стояла **выше** в трёх кортежах (`_script_body`, `emit_action`, `emit_step`) → в YAML появилось `type: var` + голый `object`, `set_var` исчез. Alex: «где блядь `set_var`». Новый разбор, дублирующий принятую форму, обязан её **заменить**, а не сосуществовать. Проверять порядок веток в **обеих** точках входа (§10.7, круг 29) | +| 28k | 🔴 **`elif` по типу цели недостижим — различать по наличию объекта** | `int`-цель (`#Z9964=…,42,0,1`) проходит **обе** ветки: форма-«объект» и форма-«число». `elif` бывает недостижим, а `tgt_body = None` молча роняет шаг в `descr`+`args`. Признак — `target in Z_dict`, не `isinstance(int)` (§10.7, круг 30) | +| 28l | 🔴 **`args` тела-цели не должны попадать в хвост шага** | Для составного тела (`expr`) его `args` (`[9965, 9966]`) уходили в **хвост шага** → `#Z9968=59,'set varname',9967,9965,9966` вместо `…,9967,0,0`. У формы с составным телом хвост шага всегда `[0, 0]` (§10.7, круг 32) | +| 28m | 🔴 **Правка `value` у цели-скрипта в РОДИТЕЛЕ не доезжает** | `value` формы 3 живёт в **отдельной строке цели** (`#Z9962`); родитель — лишь ссылка полем 2. Проверять подменой именно **строку источника**, иначе «правка не работает» (§10.7) | ### 7.3. Проверка гипотез @@ -1141,6 +1145,9 @@ Alex видел `field: 1` **после** переименования в `mode` - `set var1` в конфиге **10**, не 12 (в плане было 12 — ошибка счёта). Формы: 9 с ненулевым `args[0]` → получили `set_var`; `#Z8472=59,'set var1',0,0,0` (arg1 = 0) → **без** `set_var` (запись ничего не пишет, разворачивать нечего). + > ⚠️ **УСТАРЕЛО (круг 31, §10.7):** `#Z8472` теперь **тоже** получает `set_var` — + > `{name: var1, value: 0}` (форма «цель — число»). Признак — не `args[0] != 0`, а **наличие + > объекта** `args[0]` в `Z_dict`. Семантика `0` («пусто» vs «ноль») UI не подтверждена. - `set var1` — 0 не влезает в предикат намеренно: `0` = «нет цели», не id. - `storeev` — **4** записи (не 5): `I` ×2, `A` ×2. Все развёрнуты в `storeenv`. - `puts` — **5** записей → `log` (§10.3). @@ -1562,11 +1569,127 @@ curl -s --max-time 30 http://192.168.0.50/config.txt -o "config_local_${TS}.txt" > **72 сценария** (+`Values test`) · `21-13-18` = **774 строки** / 72 сценария > (`Values test` + расширенный «Простой тестовый сценарий»). -> ⚠️ **`set varname` (шаги `9963/9964/9968/9971/9973`) НЕ разворачивается** — цель это -> `#Z9962=59,'2 ;#p'` / `9966` / `9969` / `9972` (`5 ;#p`, `exp…`), т.е. **другой скрипт**, -> а не запись 49/50. Остаётся `descr` + `args`. Это не дефект: разворачивать нечего. -> Отдельный случай — `#Z9964=59,'set varname',42,0,1`: цель `42` не объект, а **число**, -> аргумент 3 = `1` (а не `0`). Форма та же `descr` + `args`. +> ✅ **`set varname` (шаги `9963/9964/9968/9971/9973/9974`) РАЗВЁРНУТЫ** — все четыре формы цели +> разобраны, см. **§10.7**. Прежняя запись «разворачивать нечего» **УСТАРЕЛА**. + +### 10.7. ✅ `set var` — ЧЕТЫРЕ формы цели (круги 29–32) — ЗАКРЫТО + +**Запрос Alex:** «Теперь разверни set var, print log и alarm нотификации» → после разбора 49/50 +(§10.6) остались шаги «Простой тестовый сценарий», где цель — **не** запись 49/50. +Alex показал блок и спросил: «это че блядь» / «где блядь `set_var`». + +#### 🔴 Круг 29: `type: var` — МОЯ выдуманная ветка, вытеснившая `set_var` + +Симптом: в YAML вместо `set_var` появилось + +```yaml +- id: 9963 + type: var + name: varname + object: 9962 # голый id — читать бессмысленно +- id: 9964 + type: var + name: varname + object: 42 + args: [0, 1] +``` + +Причина — **дублирующая ветка**: `_inline_script_body(..., t == 'var')` собирала `[59, 'set %s', +name, tgt, …]`, и в `emit_action`/`emit_step` условие `'var' in ('objstate','expr','const','var')` +стояло **выше** ветки `set_var`. Итог: для одного и того же смысла существовало **две формы**, +и новая перебила принятую. Alex: **«где блядь `set_var`»**. + +**Фикс:** ветка `t == 'var'` **удалена полностью**; `'var'` убран из трёх кортежей +(`_script_body`, `emit_action`, `emit_step`); из `_inline_script_value` убран разбор `set` — +все `set var` идут **только** через `set_var`. `type: var` в файле — **0 вхождений**. + +> 📌 Урок: **новый разбор, дублирующий уже принятую форму, обязан её заменить, а не сосуществовать.** +> Проверять порядок веток в **обеих** точках входа (`emit_action` + инлайн `emit_step`). + +#### 🔴 Круг 30: `elif` по типу цели — недостижимая ветка + +Первый фикс разделял формы по типу: `int` → объект, `elif isinstance(int/float)` → число. +Но `#Z9964=59,'set varname',42,0,1` — `42` это `int`, значит заходил в **первую** ветку, а +объекта `42` нет → `tgt_body = None` → падал в `descr`+`args`. **`elif` недостижим.** + +**Фикс:** различать **не по типу, а по наличию объекта** — `target in Z_dict`. +Порядок: цель 49/50 → объект 59 → объекта нет (число) → объект иного типа. + +#### ✅ Четыре формы цели (поле 2) — ФИНАЛ + +| # | Цель | Признак | YAML | Строка конфига | +|---|---|---|---|---| +| 1 | запись **49/50** | `_set_var_value_body(t)` ≠ None | `set_var: {id, name, type: param\|time_condition\|days_mask, …тело}` | `#Z9961=59,'set var1',9960,0,0` | +| 2 | **число** | target **отсутствует** в `Z_dict` | `set_var: {name, value: 42, args: [0,1]}` | `#Z9964=59,'set varname',42,0,1` | +| 3 | другой скрипт **59** | target есть, `entry[0] == 59` | `set_var: {name, target: , type: const\|expr\|objstate, …}` | `#Z9963=59,'set varname',9962,0,0` | +| 4 | объект иного типа | target есть, не 49/50/59 | `descr` + `args` (**без** `set_var`) | `#Z9886=59,'set var1',9885,0,0` | + +Живые примеры снимка `21-13-18`: + +```yaml +- id: 9961 # #Z9961=59,'set var1',9960,0,0 (форма 1) + set_var: {id: 9960, name: var1, type: param, object: 8560, param: target_temp, args: [0, 0]} +- id: 9963 # #Z9963=59,'set varname',9962,0,0 (форма 3) + set_var: {name: varname, target: 9962, type: const, value: 2} +- id: 9964 # #Z9964=59,'set varname',42,0,1 (форма 2) + set_var: {name: varname, value: 42, args: [0, 1]} +- id: 9968 # #Z9968=59,'set varname',9967,0,0 (форма 3, expr) + set_var: {name: varname, target: 9967, type: expr, expr: '%0 + %1', args: [9965, 9966]} +- id: 9974 # #Z9974=59,'set varname',8472,0,0 (форма 3, цель сама set) + set_var: {name: varname, target: 8472, value: 0, var: var1} +``` + +**Форма 3 подробно.** Цель — **свой объект** (`9962` = `#Z9962=59,'2 ;#p',0,0,0`), поэтому тело +разворачивается на месте родителя, но при сборке регистрируется **своей строкой** под `target` +(`_register(data['scenario_scripts'], tgt_ref, body)`). Если цель сама является `set` +(`#Z8472=59,'set var1',0,0,0`) — добавляются `value` (поле 2 цели) и `var` (имя переменной цели). + +#### 🔴 Круг 31: `elif` не покрывал `0` — «нет цели» ≠ «значение ноль» + +`#Z8472=59,'set var1',0,0,0` — цель `0`. Ранее (§10.1) он оставался **без** `set_var` +(«0 = нет цели, разворачивать нечего»). Теперь форма 2 ловит его как **число** → +`set_var: {name: var1, value: 0}`. Подмена `value: 0 → 5` даёт `#Z8472=59,'set var1',5,0,0` ✅. +Форма работает, но семантика `0` («пустая переменная» vs «значение 0») **не подтверждена UI**. + +#### 🔴 Круг 32: хвост `args` шага забирал аргументы тела-цели + +Для формы 3 `args` (напр. `[9965, 9966]` у `expr`) принадлежат **телу цели**, а не шагу. +Сборка подставляла их в хвост шага: `#Z9968=59,'set varname',9967,9965,9966` вместо `…,9967,0,0`. +**Фикс:** у формы 3 с составным телом хвост шага всегда `[0, 0]` — args ушли в тело. + +#### Питфолл: подмена `value` цели-скрипта в родителе НЕ доезжает + +`value` формы 3 живёт **в отдельной строке цели** (`#Z9962`). Правка `value` в родителе +(`9963`) не доезжает — родитель лишь **ссылка** полем 2. + +```bash +# ❌ правит не то — 9963 останется 'set varname',9962,0,0 +- id: 9963 + set_var: {name: varname, target: 9962, type: const, value: 7} # правка в родителе +# ✅ правит источник — #Z9962=59,'7 ;#p',0,0,0 +- id: 9962 + type: const + value: 7 +``` + +Проверено подменой: правка `9962` → `value: 2 → 7` доехала в `#Z9962=59,'7 ;#p',0,0,0`, +`9963` не изменился. + +#### Проверка + +| Проверка | Результат | +|---|---| +| круг `21-13-18` | ✅ `774 → 774`, ключей 774/774, различий **0** | +| `type: var` в YAML | **0 вхождений** | +| подмена формы 2 (`9964` `value: 42 → 99`) | ✅ `#Z9964=59,'set varname',99,0,1` | +| подмена формы 3 (`9962` `value: 2 → 7`) | ✅ `#Z9962=59,'7 ;#p',0,0,0`, родитель не тронут | +| подмена формы 3-цель-`set` (`8472` `0 → 5`) | ✅ `#Z8472=59,'set var1',5,0,0` | + +> ⚠️ **Двойной разбор шага** (питфолл): тело сначала разбирает `_inline_script_value`, затем — +> блок `set_var`. Оба обязаны **согласованно пропускать** друг друга; иначе `descr`+`args` +> затирают разобранную форму. + + ---