diff --git a/personal/projects/zont-config-compiler.md b/personal/projects/zont-config-compiler.md index 9cd0e864..ca6f2430 100644 --- a/personal/projects/zont-config-compiler.md +++ b/personal/projects/zont-config-compiler.md @@ -3,7 +3,7 @@ title: ⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml namespace: personal type: how-to created: '2026-09-17' -updated: '2026-09-17k31' +updated: '2026-09-17k32' tags: - personal - zont @@ -20,6 +20,8 @@ aliases: - ZONT типы объектов - ZONT object types - zont-scenario-logic-11109 + - ZONT set_var + - ZONT круг 32 - ZONT pickle - ZONT pickle_value related: @@ -2234,8 +2236,9 @@ comm -13 <(sort orig) <(sort back) # → пусто (ничего лишнег | 6 | ✅ **ЗАКРЫТ** — круг 30 закоммичен (`375d01a`). Push — отдельной командой | оба конвертера | — | | 7 | ✅ **ЗАКРЫТ** — `const` → **`pickle_value`** (круг 31, §10.12) | `10068` | — | | 8 | ✅ **ЗАКРЫТ** — операнды `expr` раскрываются телами + `op:` отдельным ключом (круг 31, §10.12) | `10077…10085` | — | -| 9 | ⛔ **ОТВЕРГНУТО** — имя `flag` для поля 4 записи-числа. Alex: «я кажется просил нахуй снести ебаный флаг!» | `10069` | форма не дана; см. §10.12 | -| 10 | что значит **поле 4 = `2`** у expr-записи (`0` = второй операнд объект, `2` = литерал)? своего имени нет — в YAML не выводится | `10077…10085` | энкодер из-за этого их пока не собирает | +| 9 | ✅ **ЗАКРЫТ** — хвост полей 3..n = ключ **`args`** (круг 32, §15.2). `flag`/`kind`/`tail` — выдумки, снесены | `10069` | — | +| 10 | что значит **поле 4 = `2`** у expr-записи (`0` = второй операнд объект, `2` = литерал)? своего имени нет — в YAML не выводится | `10077…10085` | ✅ энкодер собирает (`0 if isinstance(right_raw, dict) else 2`), но имя полю не дано | +| 11 | ✅ **ЗАКРЫТ** — `id` в `set_var`/операндах идёт **первым** ключом; `target` в `set_var` убран (дублировал id тела) | все `set_var` | — | --- @@ -2277,28 +2280,31 @@ Alex: «`left: 9146` — орфаны блядь развернуты должн | объект 59 (`objstate`/`pickle_value`) | `...,10070,10071,0` | `objstate 9838 0 0` + `5 ;#p` | | **литерал** (объекта нет) | `...,9146,-1,2` · `...,9146,1,2` | число прямо в поле 3 | -**Принятая форма:** +**Форма, принятая в круге 31 (⚠️ `target`/`operands`/`tail` отменены в круге 32 — §15.1):** ```yaml - id: 10080 # #Z10080=59,'set varname',10079,0,0 set_var: name: varname - target: 10079 + target: 10079 # ⛔ ОТМЕНЕНО → id внутри тела (§15.1) type: expr op: '-' - operands: + operands: # ⛔ ОТМЕНЕНО → left/right (§15.1) - type: var # операнд РАЗВЁРНУТ телом, не голый id name: varname value: 0 - tail: [0, 0] + tail: [0, 0] # ⛔ ОТМЕНЕНО → args (§15.2) - -1 # литерал остался числом ``` +**✅ Актуальная форма — §15.1.** Оператор — `op:` отдельным ключом; операнды — `left`/`right` +(их ровно два); у операнда `id` идёт **первым** ключом; `target` в `set_var` отсутствует. + ```yaml - id: 10032 # #Z10032=59,'expr "%0 + %1"',10030,10031,0 type: expr op: + - operands: + operands: # ⛔ ОТМЕНЕНО → left/right (§15.1) - {type: param, object: 9864, param: input_value, id: 10030} - {type: param, object: 8254, param: input_value, id: 10031} ``` @@ -2313,19 +2319,19 @@ Alex: «`left: 9146` — орфаны блядь развернуты должн **ПИТФОЛЛ 62 — третье поле едет в операнды.** Первая версия брала `f[2:]` → в `operands` попадал хвостовой `0` (поле 4) третьим элементом. Операнды = `f[2:4]`. -### 14.3. ⛔ `flag` — ОТВЕРГНУТ, форма для поля 4 записи-числа не дана +### 14.3. ⛔ `flag` — ОТВЕРГНУТ → ✅ ЗАКРЫТ хвостом `args` (круг 32, §15.2) `#Z10069=59,'set varname',42,0,1` — поле 4 = `1`. История имён для этого хвоста: | Вариант | Итог | |---|---| -| `args: [0, 1]` (коммит `07c076f`) | ⛔ Alex: «тут args убирай» | +| `args: [0, 1]` (коммит `07c076f`) | ⛔ Alex: «тут args убирай» → потом **возвращён** (§15.2) | | `kind: 0` + `flag: 1` (коммит `375d01a`) | ⛔ Alex: «блядь я кажется просил нахуй снести ебаный флаг!» | -| `tail: [0, 1]` / `raw_tail` / `_raw_field4` | ❓ предложено, ответа нет | +| `tail: [0, 1]` / `raw_tail` / `_raw_field4` | ⛔ **Alex: «это че за ебанина?»** — выдуманное имя (§15.2) | > 🔴 **Физика:** без хвоста строка соберётся `42,0,0` — **поле 4 теряется**, круг красный -> (это ровно дефект, ловившийся весь вечер, питфолл 54). Поэтому вариант «просто не писать» -> без `_raw_field4` невозможен. +> (питфолл 54). Итог: хвост пишется ключом **`args`** — тем же именем, что у всех прочих +> шагов («поля ПОСЛЕ тела»), и только если он ненулевой (`if any(tail)`). ### 14.4. ✅ `descr + args` = законная форма (подтверждено) @@ -2342,13 +2348,88 @@ Alex: «`left: 9146` — орфаны блядь развернуты должн | операнды `expr` | раскрыты телами (`type: var` / `type: param` / `type: pickle_value`) | | `descr: puts` | **0 вхождений** | -**⚠️ Энкодер ещё не собирает `op` + `operands` обратно в строку 59** — правка запланирована -(`_script_value_row`: `op` + `operands` → `[59, 'expr "%0 %1"', id1, id2, f4]`). -**До этой правки круг на `22-26-26` красный.** Круг на 8 старых конфигах после -`const → pickle_value` и раскрытия операндов — прогнать вместе с энкодером. +**⚠️ Энкодер ещё не собирает `op` + операнды обратно в строку 59** — правка запланирована +(`_script_value_row`: `op` + `left`/`right` → `[59, 'expr "%0 %1"', id1, id2, f4]`). +**✅ ВЫПОЛНЕНО в круге 32 — см. §15.** Круг на `22-26-26` **зелёный**. > 📌 **Свежие файлы на диске:** `zont_config/config_local_2026-09-17_22-26-26.{txt,yml}` -> (757 объектов, YAML — 84759 байт). Старый рабочий снимок `21-13-18` — сохранить как эталон -> круга, пока `22-26-26` не закрыт. +> (757 объектов). Старый снимок `21-13-18` (749 объектов) — эталон круга, тоже зелёный. --- + +## 15. Круг 32 — `set_var` без выдуманных ключей, `id` первым (2026-09-17, ночь) + +Коммит **`16ec710`** — «set_var: id первым ключом, хвост полей через `args` вместо выдуманных +flag/kind/tail». Alex дал три жалобы подряд, все три оказались **моими выдумками** либо багом +порядка ключей. + +### 15.1. ✅ Разбор исходных жалоб + +| Жалоба Alex | Диагноз | Фикс | +|---|---|---| +| «почему id у `set_var` стал в конце самом?» | `sv.update(sub)` вызывался **после** `sv['id'] = …`; `dict.update` дописывает новые ключи **в конец** | `id` кладётся в литерал **до** `update`: `sv = {'name': …, 'id': target}` + `sv.update(sub)` | +| «`left: {…, tail: [0,0], id: 8472}` — это че за ебанина?» | `_script_value` **сам** добавлял `tail` (моё имя), а `_operand_body` делал `body['id'] = oid` — тоже в конец | `tail` убран; в `_operand_body` — `out = {'id': oid}; out.update(body)` | +| «ФЛАГ БЛЯДЬ!!!!!!» на `flag: 1` в `set_var` | энкодер читал выдуманные `kind`/`flag` (остались от `07c076f`) | энкодер читает **`args`** = поля 3..n, дополняет нулями до 2 | + +> ✅ **Единственный законный `flag`** — **поле 1 записи 46** (`#Z10101=46,1,…` → `flag: 1`), +> §4.1. Он остаётся. `flag` **внутри `set_var`** — выдумка, снесено. + +### 15.2. ✅ Хвост полей 3..n — ключ `args` (поле 4 больше НЕ теряется) + +`#Z10069=59,'set varname',42,0,1`: + +```yaml + - id: 10069 + set_var: + name: varname + value: 42 + args: # поля 3..n, пишется только если ненулевое (if any(tail)) + - 0 + - 1 +``` + +Энкодер: `rest = sv.get('args') or []` → `pad = [0] * max(0, 2 - len(rest))` → +`[59, 'set %s' % name, val, *(rest + pad)]`. Тот же ключ `args`, что у `var`-тела и прочих шагов. + +### 15.3. 🔴 Найдены и закрыты ДВА невидимых источника потери (круг был красный) + +| Объект | Симптом | Причина | Фикс | +|---|---|---|---| +| `#Z10087` | `8472` → `0` | поле 2 — это **ссылка на объект тела**, а энкодер в обеих ветках жёстко писал `0`. Декодер клал поле 2 в `value`, но ветка «цель-число» перехватывала первой | 1) декодер: `value: target` (поле 2 как есть), 2) энкодер: условие ветки-числа сужено — `'id' not in sv`, 3) для `type: var` проверка идёт **раньше** `_script_value_row` | +| `#Z10069` | поле 4 `1` → `0` | ветка «цель-число» писала только `value`, хвост терялся | `tail = list(step[3:])`; `if any(tail): sv['args'] = tail` | + +**ПИТФОЛЛ 63 — `dict.update()` дописывает ключи В КОНЕЦ.** Порядок ключей в YAML = порядок +вставки. Чтобы ключ был первым — вставлять его в литерал словаря **до** `update`, не после. +Alex читает YAML глазами; `id` в конце выглядит как поломка структуры. + +**ПИТФОЛЛ 64 — ветка-«число» в `set_var` перехватывает форму-«ссылка».** Обе формы имеют +`value`; различитель — **наличие `id`**: `if 'value' in sv and 'type' not in sv and 'id' not in sv`. + +**ПИТФОЛЛ 65 — порядок веток в энкодере значим для `type: var`.** `_script_value_row` умеет +собирать `var` и вернёт строку — если проверить её раньше спец-ветки, шаг потеряет ссылку на тело. + +**ПИТФОЛЛ 66 — дублирующееся имя ключа «для одной формы» всплывает у других.** `tail` я добавил +для `var`, `flag`/`kind` — для хвоста шага; оба Alex отверг. Ключ, введённый под одну форму, +надо проверять на **всех** формах того же типа (ср. питфолл 49). + +### 15.4. Состояние после круга 32 + +| Проверка | Результат | +|---|---| +| Круг по **9** конфигам (8 снапшотов + свежий) | **✅ 9/9 чисто**, потеряно 0, лишнее 0 | +| Объекты | `598→598`, `660→660`, `661→661` ×5, `749→749`, `757→757` | +| `tail:` в YAML | **0 вхождений** | +| `flag:` в YAML | **1** — законное поле 1 записи 46 (`#Z10101=46,1,…`) | +| `id` у операндов | **первым** ключом | +| Коммит | **`16ec710`** (push не делался) | + +**Файлы на диске:** `zont_config/config_local_2026-09-17_22-26-26.yml` — 84536 байт. + +### 15.5. ⏳ Осталось + +1. Alex подтверждает имя хвоста: `args: [0, 1]` у `#Z10069` — или переименовать. +2. `objcmd` (`9925`/`9929`/`9931`/`9948`) — форма вызова по-прежнему не согласована (§13 п.2). +3. Push в Gitea (`16ec710` + `375d01a`). + +--- +