From de6217e07be349e6afb01dde8b5cb4d53d6c98e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 31 Jul 2026 20:40:58 +0400 Subject: [PATCH] =?UTF-8?q?doc:=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D1=85=D1=80=D0=BE=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?polygon=20v0.2.0=20(4=20=D1=8D=D1=82=D0=B0=D0=BF=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY/2026-07-31-session.md | 160 ++++++++++++++++++++++++++++++++++ HISTORY/README.md | 2 +- 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/HISTORY/2026-07-31-session.md b/HISTORY/2026-07-31-session.md index af80166..f85e653 100644 --- a/HISTORY/2026-07-31-session.md +++ b/HISTORY/2026-07-31-session.md @@ -551,3 +551,163 @@ polygon/ - YAML не руками — через `from_stands.py` из STANDS (37 сервисов) - `site/__init__.py` ⛔ нельзя - Импорты без префикса `site.` + +--- + +## Полигон — реализация (2026-07-31, DeepSeek Pro 4) + +### Архитектура утверждена (Sonnet 4.6) + +Промпт Соннету в `polygon-docs/sonnet-polygon-prompt.md`, ответ в `polygon-docs/sonnet-response.md`. +Ссылки на генератор YAML: `polygon-docs/tf-provider-refs.md`. + +Ключевые решения Соннета (отличия от Опуса): +- subresources: `kind == "subresource"` из STANDS YAML +- dtFinish: синхронный в `/run` (sleep → apply → dtFinish) +- Лишние операции (restart, recovery): включать все, no-op +- stateOut: авто-генерация из subresource-операций +- map с sub_params → dataDescriptor для всех типов +- 11 тестов (против 5 у Опуса) +- UUID: `uuid.uuid4()` +- Mock-эндпоинты: +`/_mock/state`, `/_mock/services`, `/_mock/delay` + +Уточнения: +- Синхронный dtFinish (блокирует воркер, но MOCK_OP_DELAY ≤ 0.5s) +- Вариант Б: сгенерированные YAML коммитятся в репу (НЕ генерить на лету) +- `from_stands.py ` — без хардкода, читает все .yaml из директории + +### Сервис запущен на Nubes + +- URL: `https://polygon.pythonk8s.dev.nubes.ru/` +- Репа: `https://gitea.services.ngcloud.ru/forcloud/polygon.git` +- InstanceUid: `db9d7835-1ef8-4fee-b42f-c91e1c0783cb` +- Мониторинг: Grafana (namespace db9d7835...) + +### Этап 1 — from_stands.py (`77f12d2`) + +Создан универсальный конвертер STANDS YAML → polygon config: +- `html.unescape()` для всех строк (`>` → `>`, `"` → `"`) +- Рекурсивный `dataDescriptor` из `sub_params` (для map, map-fixed, array-map-fixed) +- Авто-генерация `state_out_template` из subresource-операций +- `stateParams` из create-операции с JSON-генерацией для map-fixed +- `cfsParamsByOp` — связка opId → список paramId +- 210 строк, 37 YAML сгенерировано, 0 ошибок +- Все YAML валидны, HTML entities раскодированы + +### Этап 2 — config_loader + mock_state + state_machine (`1956fb7`) + +**config_loader.py** (50 строк): +- Загружает все YAML из `services/`, строит `{svcId: def}` + `{opId: def}` +- 37 сервисов, 245 операций в индексе + +**mock_state.py** (150 строк): +- `MockState` синглтон: instances, operations, op_params +- `create_instance()` → UUID v4, статус "creating" +- `create_operation()` → UUID v4, dtFinish=None +- `list_instances()` с пагинацией (pageSize≤200, стоп по len` | операции сервиса | +| 5 | GET | `/api/v1/svc/instances` | пагинация (pageSize, page) | +| 6 | GET | `/api/v1/svc/instances/` | полный instance+state | +| 7 | POST | `/api/v1/svc/instances` | 201 + Location: ./{uid} | +| 8 | GET | `/api/v1/svc/instanceOperations/default/` | cfsParams с dataDescriptor | +| 9 | POST | `/api/v1/svc/instanceOperations` | 201 + Location, auto-find create opId | +| 10 | GET | `/api/v1/svc/instanceOperations/` | +cfsParams если ?fields=... | +| 11 | POST | `/api/v1/svc/instanceOperationCfsParams` | paramId → value | +| 12 | GET | `/api/v1/svc/instanceOperations//validate-cfs` | **пустое тело**, 200 | +| 13 | POST | `/api/v1/svc/instanceOperations//run` | sleep(delay) → apply_effect → dtFinish | +| 14 | POST | `/api/v1/svc/_mock/reset` | сброс состояния | +| 15 | GET | `/api/v1/svc/_mock/state` | отладка: instances + operations | +| 16 | GET | `/api/v1/svc/_mock/services` | отладка: все сервисы | +| 17 | POST | `/api/v1/svc/_mock/delay/` | изменить MOCK_OP_DELAY | + +Критические детали: +- `default/` строго ДО `` в маршрутах Flask +- `validate-cfs`: `return "", 200` (НЕ jsonify) +- `_now()`: ISO-формат с 'Z' + +### v0.1.0 → v0.2.0 (`4e136cd`) + +Bump версии после трёх этапов изменений. + +### Этап 4 — тесты (`760d16e`) + +**test_converter.py** (10 тестов): +- basic_fields, lifecycle, operations_count +- html_unescape, value_list, state_params_from_create +- data_descriptor_from_sub_params, state_out_subresources +- cfs_params_by_op, roundtrip (запись/чтение YAML) + +**test_state_machine.py** (9 тестов): +- create → running + params + state.out +- delete → инстанс удалён +- suspend → suspended +- resume → running +- modify → params мержатся +- create_user → state.out.users[name] +- delete_user → users[name] удалён +- reset → всё пусто + +**Все 19 тестов PASS.** + +### Проверка в кубере + +```bash +ssh naeel@5.172.178.213 kubectl -n db9d7835... logs deploy/pythonk8s --tail=20 +``` +- Под: `1/1 Running`, перезапущен +- Логи: все curl-запросы (201, 200), ни одной ошибки + +### Проверка curl (deployed) + +```bash +curl https://polygon.pythonk8s.dev.nubes.ru/health → OK +37 services, create flow: 201+Location → run → status=running, params=12 +``` + +### Файлы polygon-docs/ (в корне autotest) + +- `sonnet-polygon-prompt.md` — промпт для Claude Sonnet 4.6 +- `sonnet-response.md` — полный ответ Соннета (архитектура + план) +- `tf-provider-refs.md` — ссылки на генератор YAML в `~/tf_provider` + +### Итоговая структура polygon + +``` +polygon/ +├── requirements.txt +├── README.md +├── .gitignore +├── tests/ +│ ├── test_converter.py # 10 тестов +│ └── test_state_machine.py # 9 тестов +└── site/ + ├── app.py # 17 эндпоинтов + ├── mock_state.py # MockState (in-memory) + ├── state_machine.py # apply_effect() + ├── config_loader.py # загрузка YAML + ├── from_stands.py # конвертер STANDS → polygon + └── services/ # 37 сгенерированных YAML +``` + +~900 строк Python, 37 YAML-конфигов, 19 тестов PASS. +Задеплоено, проверено через curl и kubectl. +Готово к интеграции с app-autotest. diff --git a/HISTORY/README.md b/HISTORY/README.md index 7200631..bc557db 100644 --- a/HISTORY/README.md +++ b/HISTORY/README.md @@ -16,7 +16,7 @@ | `2026-07-24-session-6.md` | 24.07.2026 | Сессия 6 | | `2026-07-29-session.md` | 29.07.2026 | Сессия: CMDB delete, переписка с Георгием | | `2026-07-30-session.md` | 30.07.2026 | Сессия | -| `2026-07-31-session.md` | 31.07.2026 | **Текущая.** Аудит Codex (3 раунда), полигон (план + отдельная репа), v1.2.16→v1.2.23 | +| `2026-07-31-session.md` | 31.07.2026 | **Текущая.** Основная сессия: унификация executor (v1.2.0-v1.2.16), аудит Codex (3 раунда, v1.2.19-v1.2.23), архитектура полигона (Опус + Соннет), **реализация polygon v0.2.0** (4 этапа, 17 эндпоинтов, 19 тестов PASS) | ## Формат