docs: промпт Opus раунд 4 + журнал правок ядра/модификаторов
- NOTES/20_prompts/prompt_for_opus_remediation_round4.md — 5 коротких вопросов (retry POST, осиротевшая операция, zero-value по подстроке, единый словарь жизненного цикла, что упущено в ядре); ответ ≤ 25 строк. - HISTORY/2026-09-30_core_and_modifiers_remediation.md — журнал: 6 коммитов, что отклонено (A3/A4/A5) и почему, что отложено (A2/B8/B9).
This commit is contained in:
@@ -0,0 +1,59 @@
|
|||||||
|
# Правки ядра и модификаторов по итогам анализа 2026-09-30 (раунд Flash)
|
||||||
|
|
||||||
|
**Репо:** `/home/naeel/TF/tf_provider`. **Дата:** 2026-09-30.
|
||||||
|
**Источник заданий:** `NOTES/20_prompts/prompt_for_deepseek_pro_remediation_plan.md`
|
||||||
|
(гипотезы A1–A5, B1–B9) + диалог с Opus `HISTORY/OPUS/2026-09-30_provider_architecture_modifiers_dialog.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что сделано (6 коммитов)
|
||||||
|
|
||||||
|
| Коммит | Пункт | Файлы | Суть |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `047d53a` | C | `TOOLS/ARCHITECTURE.md` | Спека приведена к коду: ручные ресурсы, 401, удалённый `serviceSpecificModifiers`, раздел «Lifecycle Vocabulary». |
|
||||||
|
| `c5a4499` | B3 | `TOOLS/scripts/check_hardcoded_service_ids.sh`, `org_ip_allocation_resource.go` | Страж сканирует `TOOLS/` + `provider/internal/` (кроме `resources_gen/`), второй паттерн — литеральный ref-svc id. `ResolveRefSvcParamValue(ctx, 19, …)` → константа `svcIDVcOrg`. |
|
||||||
|
| `383f8ea` | A1 | `core/http.go`, `core/client_test.go`, `ARCHITECTURE.md` | 401 добавлен в `isRetryable` (действует для GET). Тест `TestIsRetryable`. |
|
||||||
|
| `ea75cac` | B6 | `core/modifier_compare.go`, `operation_run_bycode.go`, `nsxt_snat_resource.go` | Idempotency pre-check сравнивает с **live** (`state.params`), а не с `paramValue` формы. `setSnat` → `ByIdempotent`. Тест `TestModifierDesiredEqualsLive`. |
|
||||||
|
| `8519ba0` | B7 | `org_ip_allocation_resource.go`, `nsxt_snat_resource.go`, `org_ip_allocation_test.go` | `ImportState` заполняет Required (`vip_configure` из live/`[]`; `ip_space_name` из live/`no-needed`). Тесты на чистые хелперы. |
|
||||||
|
| `0e26e98` | — | `core/refsvc.go`, `docs/60_strategy/terraform_case_sensitivity_fix.md` | Убран устаревший комментарий про несуществующий блок «Restore user-provided casing»; §4 помечен как исторический. |
|
||||||
|
|
||||||
|
**Проверка после каждого коммита:** `go build ./...` OK, `go test ./internal/... -short` PASS,
|
||||||
|
`bash TOOLS/scripts/check_hardcoded_service_ids.sh` → OK.
|
||||||
|
|
||||||
|
**Бэкапы:** `TMP/backup_2026-09-30/` (исходные версии всех правимых файлов).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что ОТКЛОНЕНО после проверки по коду (важно)
|
||||||
|
|
||||||
|
- **A5 (нормализация регистра в `Read`) — был бы РЕГРЕССОМ.**
|
||||||
|
Принятое решение (проверено): state хранит регистр **пользователя**; ref_svc-атрибуты **исключены
|
||||||
|
из read-back** (шаблон `instance.go` добавляет `InputField` только при `eq .RefSvcId 0`); UUID
|
||||||
|
внутри JSON нормализуются при **отправке** (`resources_core.BuildJSON` →
|
||||||
|
`jsonutil.LowercaseUUIDsInText`). См. `docs/60_strategy/terraform_case_sensitivity_fix.md` §4 (пометка),
|
||||||
|
§10–§11. Нормализация state к lowercase сломала бы соответствие plan=config.
|
||||||
|
- **A3 (не обрывать modify при сбое live) — осознанная защита, а не дефект.**
|
||||||
|
`instanceLiveParams` намеренно возвращает ошибку: тихий fallback на `paramValue` (дефолт ФОРМЫ)
|
||||||
|
возвращает reset-баг (затирание параметров инстанса, HAR/edge_.har: `needEnableAVI`). Требуется
|
||||||
|
отдельное решение (см. Q2 промпта раунда 4).
|
||||||
|
- **A4 (угадывание типа по подстроке имени) — нужен замер.**
|
||||||
|
Fallback применяется только к required-параметру без `paramValue`/`defaultValue`
|
||||||
|
(`instance_create.go:105-113`) и при досылке modify. Гарантированного улучшения нет, риск сломать
|
||||||
|
больше, чем починить. Оставлено как есть.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Отложено
|
||||||
|
|
||||||
|
- **A2 — retry POST.** Слепой ретрай создающего `POST /instanceOperations` опаснее обрыва
|
||||||
|
(дубликат операции). Решение — за владельцем (варианты в промпте раунда 4, Q1).
|
||||||
|
- **B8** — создавать ли оверлей `modifiers.yaml` или узаконить ручные модификаторы категорией в спеке.
|
||||||
|
- **B9** — единый словарь жизненного цикла (в спеку внесён как незакрытый вопрос; решение — Q4 промпта).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Артефакты
|
||||||
|
|
||||||
|
- Промпт раунда 4 для Opus: `NOTES/20_prompts/prompt_for_opus_remediation_round4.md`
|
||||||
|
(5 коротких вопросов, лимит ответа ≤ 25 строк).
|
||||||
|
- Ограничение сессии: чат с Opus по раундам 1–3 исчерпан по токенам → раунд 4 в новом чате.
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Opus — раунд 4: короткие решения (2026-09-30)
|
||||||
|
|
||||||
|
**Репо:** `/home/naeel/TF/tf_provider` — `terraform-provider-nubes` (Go, Terraform Plugin Framework).
|
||||||
|
|
||||||
|
## Формат ответа (ЖЁСТКО)
|
||||||
|
|
||||||
|
- На каждый вопрос — **1–3 строки**, с `файл:строка`.
|
||||||
|
- **Весь ответ ≤ 25 строк.** Без вступлений, пересказа, «а ещё могу», без повторения вопросов.
|
||||||
|
- Не хватает данных — одна короткая строка-вопрос, не догадка.
|
||||||
|
|
||||||
|
## Уже сделано — не обсуждать
|
||||||
|
|
||||||
|
401 в `isRetryable`; страж хардкодов покрыл `provider/`; idempotency pre-check переведён на live
|
||||||
|
(`core/modifier_compare.go`); `ImportState` модификаторов заполняет Required.
|
||||||
|
|
||||||
|
## Вопросы
|
||||||
|
|
||||||
|
**Q1. Retry POST.** `core/http.go:87-108` ретраит только GET. Слепой retry создающего
|
||||||
|
`POST /instanceOperations` рискует дубликатом операции. Как правильно: (а) не ретраить +
|
||||||
|
задокументировать; (б) ретраить только безопасный POST (`validate-cfs`); (в) иное?
|
||||||
|
|
||||||
|
**Q2. Осиротевшая операция.** `core/operation_run.go:150`, `core/operation_run_bycode.go:108`: при
|
||||||
|
сбое `instanceLiveParams` уже созданная операция остаётся невыполненной. Продолжение с fallback
|
||||||
|
вернёт reset-баг (защита поставлена сознательно). Есть ли безопасный третий путь (cancel/delete
|
||||||
|
операции через API) или оставить как есть? Нужен API-метод — назови его.
|
||||||
|
|
||||||
|
**Q3. Zero-value по подстроке имени.** `core/params.go:47-59`: при пустом `dataType` тип угадывается
|
||||||
|
по `name/code/label`. Пути применения: `instance_create.go:105-113` (required без значения), досылка
|
||||||
|
modify. Менять (убрать угадывание) или оставить?
|
||||||
|
|
||||||
|
**Q4. Словарь жизненного цикла.** Три несогласованных контракта: `suspend_on_destroy`/`keep_on_destroy`
|
||||||
|
(генерируемые ресурсы), `delete_strategy` (генерируемые модификаторы), `keep_on_destroy` (ручные).
|
||||||
|
Какой единый контракт зафиксировать в `TOOLS/ARCHITECTURE.md`?
|
||||||
|
|
||||||
|
**Q5. Что упущено.** Назови **один** самый критичный для устойчивости/корректности **ядра** дефект,
|
||||||
|
не упомянутый выше: 1 строка — суть → `файл:строка`.
|
||||||
|
|
||||||
|
## Границы доступа
|
||||||
|
|
||||||
|
Читать: `provider/internal/**`, `TOOLS/ARCHITECTURE.md`,
|
||||||
|
`TOOLS/resource-generator/internal/{templates,loader,params,helpers}/**`.
|
||||||
|
|
||||||
|
Не читать: `HISTORY/**`, `NOTES/**`, `docs/**`, `HAR/**`, стенды, git-историю. Нужен файл вне списка → вопрос.
|
||||||
Reference in New Issue
Block a user