diff --git a/NOTES/30_analysis/OPUS_QA_MODIFIER_DESIGN_2026-09-24.md b/NOTES/30_analysis/OPUS_QA_MODIFIER_DESIGN_2026-09-24.md index 711ce99..7becfde 100644 --- a/NOTES/30_analysis/OPUS_QA_MODIFIER_DESIGN_2026-09-24.md +++ b/NOTES/30_analysis/OPUS_QA_MODIFIER_DESIGN_2026-09-24.md @@ -69,7 +69,60 @@ TF не видит. Цепочка: `vdc → org → org-IP → edge → SNAT (по `ip_space_name`), то два ресурса на разные ipSpace возможны; если всем массивом — нет. `count=0` как inverse предполагает поэлементную модель, но в ответах это не зафиксировано. -## Что дальше (после решения пользователя) +--- -- Проверить по коду п.2 и п.4 замечаний (чтение, без правок). -- Дописать план реализации 2 ресурсов с учётом п.3 и п.5. +# Раунд 2 (те же сутки): ответы Opus на 5 уточняющих вопросов + +### Про противоречие в п.3 (раунд 1) +Opus признал: это были две несовместимые опции. +- **Канон (цель):** modify-only параметра в схеме instance быть не должно — владелец отдельный modifier-ресурс. +- **«Всегда Optional»** — только переходный вариант, если параметр временно оставлен в instance. +- Одновременно оба тезиса не действуют. + +### 1. Два владельца 372/662 +Один владелец. Instance **перестаёт слать** 372/662: убрать из `ModifyParams` генератора +(не эмитить в `params` map в `instance.go:478`, Update). Незаданные параметры при этом не сбросятся — +досылаются из live `state.params` (см. п.2 раунда 1). Поле в instance остаётся максимум как read-back +(Computed) либо убирается вовсе. + +### 2. Массив vs элемент +`vIPConfigure` — `array-map-fixed` с **replace-семантикой всего массива**: отправка `[{name,count}]` +перезаписывает массив целиком. +- **Один ресурс = весь массив** — просто и безопасно. +- Два ресурса на разные ipSpace — только с read→merge→send-full-array; без merge last-write-wins. +- **Рекомендация MVP Opus: один ресурс = весь массив.** Мультиресурс по имени — отдельная фича. + +### 3. Destroy, когда родитель не наш +Флаг `keep_on_destroy` (bool, Optional): +- родитель жив и `keep_on_destroy=false` (дефолт) → inverse (`count=0`); +- родитель 404 / вне нашего контроля → пропустить + Warning (не падать); +- `keep_on_destroy=true` → всегда no-op + Warning. + +### 4. Вывод атрибута из instance-схемы (не breaking) +Два шага: +- **сейчас**: `Deprecated: "..."` + **Optional+Computed** + прекратить отправку в modify (read-back остаётся); +- **следующий major**: удалить атрибут. + +### 5. Тип атрибута в новом ресурсе +**String + JSON + `JsonNormalize()`** (как сейчас `v_ip_configure`), потому что: +- wire-формат `array-map-fixed` — JSON-строка; +- `json_planmodifier.go` — `planmodifier.String` (на list/nested не встанет); +- `RefreshResourceState` читает input-поля только как scalar string/bool/int. +Nested list даёт лучший UX, но требует нового кода в `state_refresh.go`. Для MVP — String+JsonNormalize. + +## Мои замечания к раунду 2 + +1. **П.2 меняет интерфейс заявленного ресурса.** Мы планировали `nubes_vc_org_ip_allocation` + с `ip_space_name` + `count` (по элементу). Opus рекомендует «один ресурс = весь массив» + (list `{name,count}`). Это разные ресурсы по UX и по семантике Delete — требует решения пользователя. +2. **Проверяемость.** Утверждение про `instance.go:478` и про приоритет live при дозаполнении я не + проверял по коду — числовой якорь может быть неточным (в прошлом ответе он ссылался на + `modifier.go` отменённой ветки). +3. **`Deprecated` + `Optional+Computed`** — единственный вариант, который проходит без breaking, согласен; + но это правка сгенерированной схемы → правится в генераторе, не в `resources_gen/*.go`. + +## Что дальше + +- Решение пользователя по п.2 замечаний (элемент vs весь массив). +- Проверка по коду приоритета live-дозаполнения и строки `instance.go:478` (чтение, без правок). +- После решения — план реализации 2 ресурсов.