docs(opus): полная запись диалога 2026-09-30 — промпт + отчёт Opus по архитектуре и модификаторам
Дословно, без сокращений: задание пользователя, разведка агента, содержимое промпта, сырой лог сессии Opus и его отчёт (расхождения спека↔код S1–S5, риски R1–R6), открытый вопрос Opus. Статус: диалог не завершён.
This commit is contained in:
@@ -0,0 +1,412 @@
|
||||
# Диалог: Opus 4.8 — анализ архитектуры провайдера и ресурсов-модификаторов (2026-09-30)
|
||||
|
||||
> **Что это.** Полная, без сокращений, запись диалога: постановка задачи пользователем,
|
||||
> ход работы агента (GitHub Copilot) до создания файла-промпта, содержимое промпта,
|
||||
> ответ Opus 4.8 (приведён дословно в том виде, как получен) и открытый вопрос Opus.
|
||||
> **Формат.** Хронология ходов. Реплики пользователя и ответ Opus — дословно, включая опечатки.
|
||||
> **Статус.** Диалог НЕ завершён: Opus задал вопрос, ответ ему ещё не передан.
|
||||
|
||||
---
|
||||
|
||||
## Ход 1 — Задание пользователя (дословно)
|
||||
|
||||
```
|
||||
составь промпт в файл для Опус 4.8
|
||||
пусть проанализирует архитектуру провайдера ... с дополнительными ресурсами-модификаторами
|
||||
ограничь зону его доступносьти - пусть НИЧЕГО не читает из хистори, только файл с архитектурой
|
||||
и точно выдай ему список файлов которые надо изучить, более пусть никуда не лезет
|
||||
если что непончятно - пусть напишет тебе вопрос, я тебе передам
|
||||
взаимодейтвуйте в редиме диалога, НО НЕ НАДО злоупотреблять !
|
||||
ответы от него - МАКСИМАЛЬНО СЖАТО, без лирики и воды, лишь бы ты сам как агент понял
|
||||
```
|
||||
|
||||
Контекст задания: активный файл — `DEV_STAND/FullPipe/shturval.tf1`; активное выделение — строка 117
|
||||
(`suspend_on_destroy`).
|
||||
|
||||
---
|
||||
|
||||
## Ход 2 — Работа агента до создания файла (разведка, только чтение)
|
||||
|
||||
Поиск архитектурных документов и существующих промптов для Opus:
|
||||
|
||||
- `NOTES/20_prompts/` — 20 файлов промптов; среди них `prompt_for_opus_modifier_architecture_full.md`,
|
||||
`prompt_for_opus_modifiers_review.md`, `prompt_for_opus_review_modify_resources_2026-09-24.md`,
|
||||
`prompt_for_opus_modifier_global_architecture.md`. Часть помечена баннером ⛔ «ЛОЖНЫЙ ПУТЬ — ОТМЕНЕНО».
|
||||
- `HISTORY/OPUS/` — 16 файлов диалогов с Opus (напр. `2026-09-22_modifier_architecture_project.md`).
|
||||
- Кандидаты на «файл архитектуры»: `TOOLS/ARCHITECTURE.md`, `NOTES/30_analysis/ARCHITECTURE_NEW.md`,
|
||||
`docs/60_strategy/provider_philosophy.md`, `docs/60_strategy/modifier_resources_ideology_and_specification.md`.
|
||||
|
||||
Прочитано:
|
||||
|
||||
- `TOOLS/ARCHITECTURE.md` (246 строк) — в первых строках помечен «PRIMARY SOURCE OF TRUTH»,
|
||||
«THIS FILE IS THE FOUNDATION».
|
||||
- `NOTES/30_analysis/ARCHITECTURE_NEW.md` — «Universal Rebuild — Архитектура и рабочая цепочка»
|
||||
(внутри — ссылки на пути `/home/naeel/terra/universal_rebuild`, т.е. иная раскладка репозитория).
|
||||
- `NOTES/20_prompts/prompt_for_opus_modifier_architecture_full.md`, `…_modifiers_review.md`,
|
||||
`…_review_modify_resources_2026-09-24.md`.
|
||||
- `NOTES/40_chat_summaries/CHAT_RESUME_IAC_2026-09-24.md` — карта файлов, разделение «актуально / LEGACY».
|
||||
|
||||
Проверка актуальности через git:
|
||||
|
||||
```
|
||||
git log -3 -- TOOLS/ARCHITECTURE.md
|
||||
cbd559d 2026-09-30 docs(tools): канонический пайплайн + история ужесточения генерации YAML
|
||||
78f9dfb 2026-09-22 refactor(build): эфемерные generated-копии …
|
||||
c14f7de 2026-09-22 docs: раздел «Реестр исключений» + диалог код-ревью opus/astra
|
||||
```
|
||||
|
||||
Установленная фактическая реализация модификаторов (на 2026-09-30):
|
||||
|
||||
- База: YAML на сервис — «чистая выгрузка» из API, без доменных меток. В `TOOLS/yaml-generator/main.go`
|
||||
(комментарий перед `CollectOperations`) прямо сказано: реестр `serviceSpecificModifiers`, ранее
|
||||
помечавший `modify` как `kind=modifier`, удалён при рефакторинге 2026-09-23; модификаторы теперь —
|
||||
«отдельный оверлей (см. `modifiers.yaml` + второй проход)», базовый YAML о них не знает.
|
||||
- Реальные модификаторы — РУЧНЫЕ Go-ресурсы:
|
||||
- `provider/internal/resources_core/org_ip_allocation_resource.go` —
|
||||
`nubes_vc_org_ip_allocation` (сервис 19, `modify`, `vIPConfigure` id 662);
|
||||
- `provider/internal/resources_core/nsxt_snat_resource.go` —
|
||||
`nubes_vc_nsxt_snat` (сервис 22, `modify`, `ipSpaceName` id 372; канон-значение `no-needed`).
|
||||
- Регистрация: `provider/internal/provider/provider.go`, функция `Resources()` (строки 182–190) —
|
||||
`append(resources, resources_core.NewOrgIpAllocationResource, resources_core.NewNsxtSnatResource)`.
|
||||
- Вызываемые методы ядра: `RunInstanceOperationUniversalByCode` (`provider/internal/core/operation_run_bycode.go`),
|
||||
`GetInstanceStateParams` (`provider/internal/core/instance_params.go`),
|
||||
`LockInstance`/`UniversalClient` (`provider/internal/core/client.go`),
|
||||
`ResolveRefSvcParamValue` (`provider/internal/core/refsvc_resolve.go`),
|
||||
`ShouldRemoveFromState` (`provider/internal/resources_core/resource_diagnostics.go`).
|
||||
- Спеки операций/параметров: `generated/dev/resources_yaml/19_vc_org.yaml`, `22_vc_nsxt.yaml`.
|
||||
- Пример применения цепочки: `DEV_STAND/FullPipe/modifiers.tf`.
|
||||
|
||||
Агент задал пользователю 3 уточняющих вопроса (какой файл считать «архитектурой»; что именно должен
|
||||
выдать Opus; имя файла промпта) — **пользователь вызов отклонил (cancelled)**.
|
||||
|
||||
---
|
||||
|
||||
## Ход 3 — Ответ пользователя (дословно)
|
||||
|
||||
```
|
||||
думай сам ! возможно несколько файлов ему дать
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ход 4 — Решение агента и создание файла
|
||||
|
||||
Агентом принято самостоятельно (без дополнительных вопросов):
|
||||
|
||||
- «Файл с архитектурой» — единственный: `TOOLS/ARCHITECTURE.md`.
|
||||
- Формат выхода Opus — архитектурный разбор: устройство по слоям, спека ↔ код, жизненный цикл
|
||||
модификаторов, риски с указанием `файл:строка`.
|
||||
- Путь промпта — `NOTES/20_prompts/prompt_for_opus_provider_architecture_modifiers.md`
|
||||
(соответствует конвенции папки `NOTES/20_prompts/`).
|
||||
|
||||
Проверка существования всех 22 путей из списка (скрипт `test -f` по каждому) — результат:
|
||||
`ALL FILES PRESENT`. Отсутствующих путей нет.
|
||||
|
||||
Коммит: `752244f` —
|
||||
`docs(prompt): промпт для Opus 4.8 — анализ архитектуры провайдера + ресурсов-модификаторов`.
|
||||
|
||||
### Содержимое созданного файла `NOTES/20_prompts/prompt_for_opus_provider_architecture_modifiers.md` (дословно)
|
||||
|
||||
```markdown
|
||||
# Промпт для Opus 4.8 — анализ архитектуры провайдера + ресурсов-модификаторов
|
||||
|
||||
**Репо:** `/home/naeel/TF/tf_provider` — `terraform-provider-nubes` (Go, Terraform Plugin Framework).
|
||||
**Дата:** 2026-09-30. **Стенд-источник фактов:** `dev`.
|
||||
|
||||
---
|
||||
|
||||
## Роль и режим работы
|
||||
|
||||
- Ты — архитектор/ревьюер универсального Terraform-провайдера.
|
||||
- Работаем **в диалоге**: я (агент) передаю твои вопросы пользователю и возвращаю его ответы.
|
||||
- Вопрос задавай ТОЛЬКО если без него ответить нельзя. Максимум 1–2 вопроса за раз, предельно коротко.
|
||||
- Не догадываться. Нет данных — вопрос, а не допущение.
|
||||
- Область не расширять: отвечать ровно на поставленную задачу.
|
||||
|
||||
## Задача
|
||||
|
||||
Проанализировать архитектуру универсального провайдера Nubes и встроенный в неё слой
|
||||
**ресурсов-модификаторов** — отдельных ресурсов, которые вызывают операцию `modify`
|
||||
у родительского инстанса (когда нужного параметра нет в операции `create`).
|
||||
|
||||
Оценить:
|
||||
|
||||
1. Как устроена архитектура по слоям и как течёт поток данных (API → YAML → код → API).
|
||||
2. Соответствие заявленной спеки (`TOOLS/ARCHITECTURE.md`) фактической реализации — все
|
||||
расхождения, с указанием `файл:строка`.
|
||||
3. Корректность жизненного цикла модификаторов: `Create` / `Read` / `Update` / `Delete`,
|
||||
идемпотентность, дрейф (drift), поведение при `replace` / повторном `apply`, импорт.
|
||||
4. Место модификаторов в универсальном ядре: где и как нарушается принцип
|
||||
«ядро универсально, доменные знания — только данные». Насколько оправдано текущее
|
||||
решение (ручные Go-ресурсы, зарегистрированные поверх генерируемых).
|
||||
5. Границы ответственности: что модификатор делает сам, что отдаёт платформе; как
|
||||
выражается обратная операция (откат при `destroy`, значение «выключено»).
|
||||
6. Риски и топ-проблемы — по убыванию критичности, каждое с `файл:строка`.
|
||||
|
||||
## Границы доступа (ЖЁСТКО)
|
||||
|
||||
Читать РАЗРЕШЕНО **только** файлы из списка ниже. Всё остальное — ЗАПРЕЩЕНО, в частности:
|
||||
|
||||
- `HISTORY/**`, `NOTES/**`, `TMP/**`, `HAR/**`, `docs/**`, `site/**`, `site_test/**`,
|
||||
`apps/**`, `charts/**`, `FIYR_MGU/**`, `gateway/**`, `scripts/**`, `secrets/**`,
|
||||
`tfflaskcrud/**`, `tfluceecrud/**`, `tfnodejscrud/**`, `DEV_STAND/**` (кроме одного файла
|
||||
из списка), `TEST_STAND/**`, `PROD_STAND/**`, `provider/artifacts/**`, `provider/bin/**`;
|
||||
- история git (`git log`, `git show`, `git diff` с коммитами), коммиты, теги, ветки;
|
||||
- любой файл репозитория, которого нет в списке ниже.
|
||||
|
||||
Нужен файл вне списка → НЕ читать, а задать мне вопрос.
|
||||
|
||||
## Файлы к изучению (исчерпывающий список)
|
||||
|
||||
### Группа 1. Архитектура (спека)
|
||||
- `TOOLS/ARCHITECTURE.md`
|
||||
|
||||
### Группа 2. Ресурсы-модификаторы и их регистрация
|
||||
- `provider/internal/provider/provider.go`
|
||||
- `provider/internal/resources_core/org_ip_allocation_resource.go`
|
||||
- `provider/internal/resources_core/nsxt_snat_resource.go`
|
||||
- `provider/internal/resources_core/org_ip_allocation_test.go`
|
||||
|
||||
### Группа 3. Рантайм-зависимости модификаторов (ядро)
|
||||
- `provider/internal/core/client.go`
|
||||
- `provider/internal/core/operation_run_bycode.go`
|
||||
- `provider/internal/core/instance_params.go`
|
||||
- `provider/internal/core/refsvc_resolve.go`
|
||||
- `provider/internal/resources_core/resource_diagnostics.go`
|
||||
- `provider/internal/resources_core/crud.go`
|
||||
|
||||
### Группа 4. Генератор (как рождается «универсальная» часть)
|
||||
- `TOOLS/yaml-generator/main.go`
|
||||
- `TOOLS/resource-generator/internal/loader/loader.go`
|
||||
|
||||
### Группа 5. Факты API (спеки операций/параметров)
|
||||
- `generated/dev/resources_yaml/19_vc_org.yaml`
|
||||
- `generated/dev/resources_yaml/22_vc_nsxt.yaml`
|
||||
|
||||
### Группа 6. Применение модификаторов (композиция цепочки)
|
||||
- `DEV_STAND/FullPipe/modifiers.tf`
|
||||
|
||||
### Группа 7. Только если без них нельзя ответить (иначе не открывать)
|
||||
- `provider/internal/resources_core/state_refresh.go`
|
||||
- `provider/internal/resources_core/params_compare.go`
|
||||
- `provider/internal/resources_core/helpers.go`
|
||||
- `TOOLS/resource-generator/main.go`
|
||||
- `TOOLS/resource-generator/internal/templates/instance.go`
|
||||
|
||||
## Что нужно на выходе
|
||||
|
||||
Структурированный отчёт, разделы строго в этом порядке:
|
||||
|
||||
1. **Устройство архитектуры** — слои и поток данных, 5–10 строк.
|
||||
2. **Спека ↔ код** — список расхождений `ARCHITECTURE.md` с реализацией (`файл:строка`).
|
||||
3. **Дефекты и риски модификаторов** — по убыванию критичности. По каждому:
|
||||
суть → место (`файл:строка`) → последствие → предлагаемое направление (одна строка).
|
||||
4. **Открытые вопросы** — списком, если есть.
|
||||
|
||||
## Формат ответа
|
||||
|
||||
- Максимально сжато: тезисы, без вступлений, воды и «лирики».
|
||||
- Каждое утверждение проверяемо: ссылка `файл:строка`.
|
||||
- Код — только короткие фрагменты, и лишь если без них тезис не понятен.
|
||||
- Никаких «а ещё могу», никаких предложений расширить работу.
|
||||
|
||||
## Правило «стоп»
|
||||
|
||||
Если задание неоднозначно или данных не хватает — **остановиться и задать один короткий
|
||||
вопрос**. Не достраивать смысл и не действовать по догадке.
|
||||
```
|
||||
|
||||
### Итоговое сообщение агента пользователю (дословно)
|
||||
|
||||
```
|
||||
Готово.
|
||||
|
||||
`NOTES/20_prompts/prompt_for_opus_provider_architecture_modifiers.md` (коммит `752244f`).
|
||||
|
||||
Что внутри:
|
||||
- **Задача** — анализ архитектуры провайдера + слоя модификаторов (`Create/Read/Update/Delete`, идемпотентность, drift, спека↔код, место в универсальном ядре, границы/откат, топ-рисков с `файл:строка`).
|
||||
- **Границы (жёстко)** — запрет на `HISTORY/**`, `NOTES/**`, `TMP/**`, `HAR/**`, `docs/**`, стенды, git-историю; нужен файл вне списка → вопрос мне, не чтение.
|
||||
- **Список файлов** — 22 шт., исчерпывающий, 7 групп: спека (`TOOLS/ARCHITECTURE.md`) → модификаторы + регистрация → рантайм-ядро → генератор → YAML-спеки 19/22 → пример (`DEV_STAND/FullPipe/modifiers.tf`) → «только при необходимости».
|
||||
- **Формат ответа** — сжато, тезисы, каждое утверждение с `файл:строка`, без «лирики».
|
||||
- **Режим** — диалог, но без злоупотребления; при неясности один короткий вопрос и стоп.
|
||||
|
||||
Все 22 пути проверены — существуют.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ход 5 — Ответ Opus 4.8 (дословно, как получен от пользователя)
|
||||
|
||||
Ниже — полный сырой лог сессии Opus (включая служебные строки о чтениях и неудачных поисках),
|
||||
затем его отчёт.
|
||||
|
||||
```
|
||||
Read
|
||||
|
||||
Прочитаю файлы строго по разрешённому списку. Начну с групп 1–3.
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Прочитаю группу 2 (модификаторы) и группу 3 (ядро).
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Прочитаю группу 3 (ядро) и тест.
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Прочитаю `client.go` (ядро) и группу 4 (генератор).
|
||||
|
||||
Read
|
||||
|
||||
Прочитаю группу 4 (генератор), группу 6 (modifiers.tf) и начну группу 5.
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Прочитаю группу 5 (API YAML). Сначала проверю размер.
|
||||
|
||||
No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files.
|
||||
If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]).
|
||||
Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true.
|
||||
|
||||
No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files.
|
||||
If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]).
|
||||
Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true.
|
||||
|
||||
Searched for files matching `**/generated/dev/resources_yaml/*vc_org*.yaml`, no matches
|
||||
|
||||
Searched for files matching `**/generated/dev/resources_yaml/*nsxt*.yaml`, no matches
|
||||
|
||||
Searched for files matching `**/generated/dev/**/19_*.yaml`, no matches
|
||||
|
||||
Read
|
||||
|
||||
Searched for files matching `**/generated/dev/resources_yaml/*.yaml`, no matches
|
||||
|
||||
Read
|
||||
|
||||
Файлы существуют; grep не сработал по паттерну. Прочитаю их напрямую.
|
||||
|
||||
No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files.
|
||||
If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]).
|
||||
Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true.
|
||||
|
||||
No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files.
|
||||
If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]).
|
||||
Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true.
|
||||
|
||||
Read
|
||||
|
||||
Read
|
||||
|
||||
Проанализировал все файлы из разрешённого списка (группы 1–6; группа 7 не понадобилась). Отчёт ниже.
|
||||
```
|
||||
|
||||
### Отчёт Opus (дословно)
|
||||
|
||||
```markdown
|
||||
## 1. Устройство архитектуры
|
||||
|
||||
Поток данных: **API → YAML → Go-код → API**.
|
||||
- Генератор YAML (`main.go`) делает **чистую выгрузку** операций сервиса из API (`create/delete/modify/suspend/...`) без доменных знаний — один файл на сервис (`19_vc_org.yaml`, `22_vc_nsxt.yaml`).
|
||||
- Генератор кода (`loader.go`) читает YAML, классифицирует операции на `instance/subresource/action/modifier`, строит `GenResource/...` и рендерит универсальные ресурсы.
|
||||
- Ядро (`core`) — универсальный HTTP-клиент: запуск операций, ожидание, резолв ref-параметров, досылка дефолтов.
|
||||
- **Модификаторы** — это НЕ генерируемый слой: два ручных Go-ресурса (`org_ip_allocation_resource.go`, `nsxt_snat_resource.go`), зарегистрированных вручную в `provider.go:199-204`. Каждый дёргает `modify` родителя через `RunInstanceOperationUniversalByCode`.
|
||||
|
||||
## 2. Спека ↔ код (расхождения)
|
||||
|
||||
**S1. Реестр `serviceSpecificModifiers` в спеке указан не там, где он есть (его нет).**
|
||||
`ARCHITECTURE.md` (таблица «Exception Registry») утверждает, что `serviceSpecificModifiers` живёт в `main.go`. Фактически этот реестр **удалён** (рефакторинг 2026-09-23) — прямо задокументировано в `main.go:70-90`. Названного реестра нет; модификаторы стали ручными ресурсами. Таблица-спека устарела.
|
||||
|
||||
**S2. «Service-specific Go code is fully generated… No manual edits» / «Core is universal» — нарушено.**
|
||||
`ARCHITECTURE.md` (Core Principles 2, 3; «Provider Model»). Но `org_ip_allocation_resource.go` и `nsxt_snat_resource.go` — ручной сервис-специфичный Go с зашитыми `service_id`, именами параметров и канон-значениями, лежащий в слое `resources_core`. Это доменная логика внутри «ядра».
|
||||
|
||||
**S3. Заявленные «ровно ДВА реестра исключений» — по факту есть третье место.**
|
||||
`ARCHITECTURE.md` («The ONLY allowed deviations… MUST live in exactly two named registries»). Третье место доменных данных/логики — `provider.go:199-204` + два файла модификаторов. Оно не покрыто правилом реестра и не отражается в его диффе.
|
||||
|
||||
**S4. «modify всегда через WithDefaults» — модификаторы идут через ByCode.**
|
||||
`ARCHITECTURE.md` («modify всегда через WithDefaults / `RunInstanceOperationUniversalWithDefaults`»). Модификаторы намеренно используют `RunInstanceOperationUniversalByCode` (`operation_run_bycode.go:10-13`) с причиной в комментарии `nsxt_snat_resource.go:240-250`. Досылка дефолтов там своя (live → paramValue формы → default, `operation_run_bycode.go:105-150`). Буквальное утверждение спеки не выполняется.
|
||||
|
||||
**S5. Полноценный генерируемый слой модификаторов существует, но не задействован.**
|
||||
`loader.go:55-90` полностью поддерживает `kind: modifier` с `delete_strategy` (`noop_warn/inverse/error`), `idempotency` (`none/check_before_run`), `delete_params`, валидацией (validateModifierOperation). Ядро под это имеет `RunInstanceOperationUniversalByIdempotent` (`operation_run_bycode.go:15-19`) и `RunOperationByCodeIdempotent` (`crud.go`). Но оба реальных модификатора — ручные и это всё **не используют**, переизобретая delete-стратегию вручную (`keep_on_destroy` + inverse). Базовые YAML (19, 22) `kind: modifier` не содержат — оверлей `modifiers.yaml`, упомянутый в `main.go:84-90`, в разрешённом списке отсутствует и в базовых спеках не проявлен.
|
||||
|
||||
## 3. Дефекты и риски модификаторов (по убыванию критичности)
|
||||
|
||||
**R1. Двойное владение одним и тем же параметром API.**
|
||||
Суть: `vIPConfigure` (id 662) есть в `modify` генерируемого `nubes_vc_org` (`19_vc_org.yaml`, op modify), а `ipSpaceName` (id 372) — в `modify` генерируемого `nubes_vc_nsxt` (`22_vc_nsxt.yaml`). Те же поля пишет и модификатор.
|
||||
Место: `org_ip_allocation_resource.go:316-340` / `nsxt_snat_resource.go:240-253`.
|
||||
Последствие: если пользователь заводит и инстанс-ресурс, и модификатор — «война дрейфов»: два ресурса по очереди перезаписывают поле каждым apply.
|
||||
Направление: явно исключать пересекающиеся коды из схемы генерируемого ресурса, если поле отдано модификатору (или запретить одновременное использование).
|
||||
|
||||
**R2. Зашитые сервис-специфичные данные обходят страж `check_hardcoded_service_ids.sh`.**
|
||||
Суть: id 19/22, имена `vIPConfigure`/`ipSpaceName`, значение `"no-needed"` зашиты как литералы-аргументы, а не как `svc.ID == N`.
|
||||
Место: `org_ip_allocation_resource.go:296-314` (`ResolveRefSvcParamValue(ctx, 19, …)`), `nsxt_snat_resource.go:43`.
|
||||
Последствие: правило «никаких hardcoded service id вне реестров» формально соблюдено, фактически — нет; страж это не ловит.
|
||||
Направление: вынести id/коды/каноны в один явный реестр-данные, покрытый чекером, либо расширить паттерн чекера.
|
||||
|
||||
**R3. Порядок «edge → аллокация» не гарантируется провайдером.**
|
||||
Суть: платформа требует существующий vDC+Edge до `modify` орги, иначе «Can't cast Complex Object Type Struct to String».
|
||||
Место: описано в `modifiers.tf:6-16`; в коде порядок не выражен — держится только на пользовательском `depends_on`.
|
||||
Последствие: забытый `depends_on` → непонятная ошибка платформы на apply.
|
||||
Направление: либо документировать как жёсткое требование в схеме/описании ресурса, либо проверять готовность edge в `Create` до modify.
|
||||
|
||||
**R4. Нельзя снять аллокацию через атрибут — только `destroy`.**
|
||||
Суть: пустой массив запрещён (`org_ip_allocation_resource.go:328-331` `len==0 → error`), а Delete шлёт `count=0`, но `[]` не отправляется (`org_ip_allocation_resource.go:246-266`).
|
||||
Последствие: «выключено» выражается двумя разными способами (count=0 при destroy vs невозможность `[]` при update) — асимметрия семантики.
|
||||
Направление: определить единый канон «ноль аллокаций» и разрешить его через атрибут, либо явно задокументировать ограничение как намеренное.
|
||||
|
||||
**R5. Модификаторы не идемпотентны на уровне API (modify выполняется всегда).**
|
||||
Суть: `ByCode` без pre-check — `Create`/`Update` всегда POST-ят modify, даже если live уже совпадает. Причина осознанная (комментарий applyAllocation).
|
||||
Последствие: лишние операции modify при повторных apply/после ручных правок state; на больших инстансах — время и нагрузка. Корректности не нарушает (дрейф гасится в `Read`).
|
||||
Направление: если появится надёжное сравнение desired↔live (не с paramValue формы) — переключить на idempotent-путь, уже имеющийся в ядре.
|
||||
|
||||
**R6. Импорт оставляет Required-атрибуты неинициализированными.**
|
||||
Суть: `ImportState` ставит только `id` и `organization`/`nsxt_uid` (`org_ip_allocation_resource.go:288-292`, `nsxt_snat_resource.go:222-226`). `vip_configure`/`ip_space_name` (Required) наполняются лишь в `Read`, и то по условию (nsxt — только если live непустой `nsxt_snat_resource.go:160-166`).
|
||||
Последствие: при импорте эджа с невыставленным SNAT `ip_space_name` останется null → требуется совпадение с конфигом на следующем плане; для пользователя неочевидно.
|
||||
Направление: в `ImportState`/`Read` заполнять атрибут каноном (`no-needed`) при отсутствии значения.
|
||||
|
||||
## 4. Открытые вопросы
|
||||
|
||||
1. Оверлей `modifiers.yaml` и генерируемый слой `kind: modifier` (см. R5/S5) — в разрешённый список не входил. Нужно ли оценивать его как «мёртвый/параллельный» код к удалению, или он планируется как целевая замена ручных модификаторов? (файл вне списка — не читал).
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ход 6 — Указание пользователя (дословно)
|
||||
|
||||
```
|
||||
сначала документируй ВЕСЬ диалог, без сокращений
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Открытый вопрос Opus (ожидает ответа пользователя)
|
||||
|
||||
1. Оверлей `modifiers.yaml` и генерируемый слой `kind: modifier` — «мёртвый/параллельный» код
|
||||
к удалению, или планируемая целевая замена ручных модификаторов?
|
||||
|
||||
## Статус
|
||||
|
||||
- Диалог с Opus не завершён: его вопрос ещё не передан и ответ не получен.
|
||||
- Настоящий документ создан по прямому указанию пользователя «сначала документируй ВЕСЬ диалог,
|
||||
без сокращений».
|
||||
- Артефакты хода 4: файл `NOTES/20_prompts/prompt_for_opus_provider_architecture_modifiers.md`,
|
||||
коммит `752244f`.
|
||||
Reference in New Issue
Block a user