diff --git a/prompt_for_opus_modifier_architecture_q3.md b/prompt_for_opus_modifier_architecture_q3.md new file mode 100644 index 0000000..fea4a2d --- /dev/null +++ b/prompt_for_opus_modifier_architecture_q3.md @@ -0,0 +1,64 @@ +# Уточнения к архитектуре модификаторов — расхождения с фактическим кодом + +Не принимаю предыдущие ответы за истину. Сверка с реальным кодом выявила расхождения. +Прошу пересмотреть/уточнить. + +## Факт №1: `OperationSpec` — это алиас `lib.OperationSpec`, не локальный тип + +В `TOOLS/resource-generator/internal/types/types.go`: +```go +type OperationSpec = lib.OperationSpec +type ParamSpec = lib.ParamSpec +``` +Канонический YAML-контракт лежит в `TOOLS/lib/types.go` (пакет `tf-tools/lib`), +где уже определены `OperationSpec` (Name/ID/Kind/Action/Modifier/Subresource/Man/Params) +и `ParamSpec`. + +Ошибка в прошлом ответе: «добавить в types.go:39» — НЕ указано, что это `lib`. +Новые поля `delete_strategy` / `idempotency` / `delete_params` должны быть +в `TOOLS/lib/types.go`, иначе yaml-generator (который тоже импортирует lib) +и resource-generator разойдутся. + +Вопрос: подтверждаешь, что новый контракт добавляется в `lib/types.go\` (OperationSpec), +а `resource-generator` получает его через алиас? Или нужно отдельное +resource-generator-специфичное поле (не в lib, а в GenModifier)? Где граница: +что в lib, что локально в GenModifier? + +## Факт №2: `normalizeUniversalValueV6` — приватная, живёт в core, принимает core-структуру + +Прошлый ответ: «сравнивать desired vs current после normalizeUniversalValueV6». +Но: +- `normalizeUniversalValueV6(val string, param universalCfsParam)` — **приватная** (маленькая буква); +- принимает `universalCfsParam` (структуру пакета `core`); +- сравнение pre-check «desired == current» предполагалось в `resources_core` + (там `RunOperationByCodeWithTimeout`) или в шаблоне модификатора. + +Вопрос: ГДЕ правильно делать pre-check и нормализованное сравнение? +- вариант A: в `core` (там доступны и cfsParams, и normalize), экспортировать сравнение; +- вариант B: в `resources_core` — тогда нужен экспортированный компаратор + (`JSONStringsEquivalent` там уже есть), но `universalCfsParam` недоступен; +- вариант C: сравнение только через `JSONStringsEquivalent` по JSON-строкам, + без `normalizeUniversalValueV6`? (но тогда `" 5"` vs `"5"`, `true` vs `1` дадут ложный diff). + +Как совместить нормализацию типов (bool→"true", int→"5") с местом, где сравнение +происходит? Конкретный файл+функция. + +## Дополнительные сомнения (прошу подтвердить/опровергнуть) + +1. **Idempotency pre-check и «полный payload» конфликтуют?** Если desired==current → skip. + Но при этом «полный payload» не шлётся вообще (skip). Это согласуется? Или при + расхождении одного поля всё равно слать полный payload (и это нормализует всё)? + +2. **`delete_strategy: inverse` + параметр, у которого НЕЛЬЗЯ обнулить** (напр. + `virtualServicesCount` integer>0): прошлый ответ — «inverse недопустим, fail-fast». + Но что если inverse-стратегия нужна только для ЧАСТИ полей, а не для всех? + Т.е. `delete_params` покрывает `needEnableAVI:false`, а `virtualServicesCount` + просто остаётся как есть. Допустимо ли «частичный inverse» (обратить только + обратимое, остальное не трогать)? Или inverse обязан покрывать все поля? + +3. **`noop_warn` (дефолт) — всегда ли безопасен?** Удаление модификатора из state + при оставшемся эффекте на платформе — это drift. Допустимо ли вообще иметь + `noop_warn` как ДЕФОЛТ, или для необратимых (ip_space) правильнее дефолт `error` + (запретить destroy, пока не разберутся)? Что каноничнее? + +Ответ — кратко, по пунктам.