Compare commits

...

2 Commits

5 changed files with 95 additions and 38 deletions

View File

@@ -1,35 +1,34 @@
--- ---
_last_updated_: 2026-08-18T19:20:00Z _last_updated_: 2026-08-18T23:00:00Z
session_id: 2026-08-18-pi-sched-openapi-client-fnf session_id: 2026-08-18-pi-sched-openapi-round2-retest
--- ---
# Next session handoff # Next session handoff
## Recent commits ## Recent commits
- (this commit) handoff: openapi-client F&F закрыт — репорт sched отправлен 19:15Z, коммит e89e868 (sched repo) - d658ff0 (sched repo) feat(examples): admin-client retest vs 0.2.0/0.3.5 — raw_ops deleted, typed-only suite 24/24, smoke 19/19 (пуш в sched разрешён таской)
- e89e868 (sched repo) feat(examples): python admin client from spec — 15 путей/21 операция, 24/24, smoke 19/19 - e24b100 (sched repo, их) fix(admin-api): openapi F&F round — wrapped shapes, open health, flat schedule
- b56da997 handoff: паблиш-волна sched принята (ретест Node 24 зелёный, 18-29Z)
## Что сделано в этой сессии (openapi-client F&F, таска от sched 18-55Z) ## Что сделано в этой сессии (F&F round 2 retest, письмо sched 19:35Z)
- Спеку взял из verdaccio `@sched/admin-api@0.1.2` (tarball = идентична репо, 15 путей/12 схем). - Ретест против **@sched/admin-api@0.2.0** (tarball spec byte-identical pinned) + **@sched/daemon@0.3.5** (глобальный npm-пакет обновлён, стенд :8127 перезапущен, no auth, scratch db).
- Клиент: **Python, openapi-generator 7.24.0** (JDK 25; системная Java 8 не годится — JAVA_HOME обязателен) — «одной командой» из спеки. - **Все 5 находок F-1..F-5 подтверждены закрытыми** (спека+сервер). Главный итог: **raw_ops.py удалён, 11/11 ранее-сырых операций идут через типизированный клиент** (0 на обходе). Сьют переписан typed-only: **24/24** (3 прогона), **smoke 19/19**.
- TDD: сьют до клиента (RED) → после генерации **24/24 GREEN** (3 прогона стабильно), **smoke 19/19**. - F-1/F-5 проверены живьём на keyed-инстансе 0.3.5 (:8128): health 200 open, /tasks 401 без ключа, 400 на неизвестные поля schedule body/patch.
- Код: `sched/examples/admin-client-python/` (README+F&F-таблица, generate.ps1, openapi.json pinned, sched_admin_client/ checked-in, tests/, smoke.py, raw_ops.py). - Репорт: `sched/.agents/inbox/2026-08-18T22-55-00Z-admin-openapi-fixes-round2-retest.md`.
- **Репорт**: `sched/.agents/inbox/2026-08-18T19-15-43Z-admin-fnf-openapi-client-report.md` — находки F-1..F-5, НЕ чинил (их импл). - Нюанс среды (для будущих регенераций): openapi-generator CLI дёргает `java` из **PATH**, не из JAVA_HOME — нужен `$env:Path = "$env:JAVA_HOME\bin;" + $env:Path` (записал в generate.ps1).
## Open треки ## Open треки
| Трек | Готовность | Entry-point | | Трек | Готовность | Entry-point |
|---|---|---| |---|---|---|
| **sched openapi-client F&F — находки F-1..F-5** | 🔵 жду их импла: F-1 /health auth-контрадикция (спека security:[], daemon с ключом 401-ит даже health); F-2 mutation-ответы {} вместо {task/run/schedule:…} (главный, ломает генераторы); F-3 const:true→строковый enum; F-4 Schedule oneOf не десериализуется; F-5 top-level dedupKey молча игнорится. По фиксам — ретест. | письмо sched 19:15Z | | **sched openapi-client F&F round 2** | 🟢 ретест отправлен 22:55Z; жду их приёмки/след. письма | письмо sched 22:55Z |
| sched CLI-F&F раунд | ✅ ЗАКРЫТ | — | | sched CLI-F&F раунд | ✅ ЗАКРЫТ | — |
| books-sched-integration (Phase 3) | ⚪ их работа; приёмка только по их пингу | — | | books-sched-integration (Phase 3) | ⚪ их работа; приёмка только по их пингу | — |
## Стенды (все живы на конец сессии) ## Стенды
- **:8127** — МОЙ scratch-стенд openapi-client F&F: published daemon 0.3.4, NO AUTH, db `/tmp/sched-acpy-stand/acpy.db`. Гасить можно. - **:8127** — sched daemon **0.3.5**, no auth, db `/tmp/sched-acpy-stand/acpy.db` (перезапущен мной в этой сессии). ЖИВ — sched может юзать для ретеста; можно гасить.
- **:8080** — sched CLI-F&F стенд (0.3.4, `SCHED_ADMIN_KEY=dev-key` — ключ НАШЁЛ в старом handoff, для F&F он был нужен, но я обошёлся :8127). - :8128 — keyed 0.3.5 (F-1 проверки) — **погашен**.
- **:8123** — dev-билд, **СТЕЙЛ** (health 0.1.8): нет POST /tasks, /schedules в легаси-формате. Для контракта не годен. - :8080 — sched CLI-F&F стенд (0.3.4, SCHED_ADMIN_KEY=dev-key), не трогал.
## Заметки на будущее ## Заметки на будущее
- openapi-generator + 3.1-спека: const:true → строковый enum; ответы {} → wrapped-тело валит десериализацию; oneOf+discriminator → actual_instance=None. Обход: raw-транспорт + model_validate. (Кандидат в .wiki-концепт.) - В спеке `info.version` = 0.1.0 и в 0.1.2, и в 0.2.0 (версия только в package.json) — предложил sched поднять, «на усмотрение».
- Windows: порты 8090/8091 в excluded range (Hyper-V) — EACCES. `netsh interface ipv4 show excludedportrange`. - Wrapped-формы объявлены инлайн в components.responses → имена InlineObject..InlineObject4; если sched назовёт их в components.schemas — станет красивее (предложил).
- Триггер долгого process-раннера (POST run) синхронный — ответ приходит после завершения процесса; для cancel-теста дёргать в фоновом треде. - Не стал добавлять F-1/F-5 тесты в сьют (нужен keyed-стенд) — предложил sched, «на усмотрение».

View File

@@ -8,12 +8,38 @@ updated: 2026-08-18
# openapi-generator + OpenAPI 3.1 — gotchas # openapi-generator + OpenAPI 3.1 — gotchas
Проверено вживую на F&F-раунде sched «клиент на любом ЯП одной командой» Проверено вживую на F&F-раундах sched «клиент на любом ЯП одной командой»
(2026-08-18): Python-клиент из `@sched/admin-api@0.1.2` спеки (3.1.0, 15 путей) (2026-08-18): Python-клиент из спеки `@sched/admin-api` через
через `openapi-generator` **7.24.0** (`-g python`, pydantic v2). Спеку НЕ чинили `openapi-generator` **7.24.0** (`-g python`, pydantic v2). Спеку НЕ чинили —
(их импл, TDD) — обходили. Находки F-1..F-5 полные — в обходили (round 1, 0.1.2). Round 2 (0.2.0): все гочи 1–4 **закрыты фиксами
`sched/.agents/inbox/2026-08-18T19-15-43Z-admin-fnf-openapi-client-report.md`; спеки/сервера**, raw-обход удалён — см. «Статус после round 2» ниже.
здесь — переиспользуемая суть.
## Статус после round 2 (0.2.0 / daemon 0.3.5)
Все 5 находок round 1 подтверждены закрытыми (ретест 2026-08-18, отчёт
`sched/.agents/inbox/2026-08-18T22-55-00Z-admin-openapi-fixes-round2-retest.md`):
- **Гоча 1 (wrapped-ответы) — FIXED (спека).** Мутации теперь объявляют
`{task}/{run}/{schedule}` (response-компоненты TaskMutation/RunMutation/
ScheduleMutation), `GET /runs/{id}?logFromOffset` — RunLogChunk (allOf
RunRecord + logChunk/logTotalLength). Генератор выдаёт **InlineObjectN**-
модели (поля task/run/schedule/ok), десериализация нативная. `raw_ops.py`
из примера **удалён**.
- **Гоча 2 (const:true) — FIXED.** `const` убран из спеки; `Health200Response.ok`
= обычный `StrictBool`.
- **Гоча 3 (oneOf+discriminator) — FIXED.** `Schedule` стал плоской схемой
(`kind` + опциональные `cron/timezone/ms/at`); `rec.schedule.cron` читается
с типизированной модели. Normalization живьём: `once`→`{kind:once, at:ISO}`,
`interval`→`{kind:interval, ms}`.
- **F-1 (health auth) — FIXED (сервер).** `/health` всегда открыт, auth —
после health-роута; прочие роуты с ключом 401.
- **F-5 (dedupKey fail-fast) — FIXED (сервер).** POST/PATCH /schedules с
неизвестным top-level полем → 400 с именем поля.
- Итог ретеста: **11/11 ранее-сырых операций идут через типизированный клиент,
сьют 24/24, smoke 19/19** (коммит sched `d658ff0`).
Гочи 1–3 ниже — описание сломанного состояния round 1 (0.1.2) + паттерн обхода
(потребительский escape-hatch, если спека где-то ещё сырая).
## Гоча 1 — ответы `{}` в спеке ломают десериализацию (главная) ## Гоча 1 — ответы `{}` в спеке ломают десериализацию (главная)
@@ -47,20 +73,35 @@ updated: 2026-08-18
модели приходит с `actual_instance=None` — правило (`cron`) недостижимо через модели приходит с `actual_instance=None` — правило (`cron`) недостижимо через
модель, только через raw JSON: `raw["schedule"]["schedule"]["cron"]`. модель, только через raw JSON: `raw["schedule"]["schedule"]["cron"]`.
Касается любого oneOf+discriminator на этой версии генератора (3.1-ветка). Касается любого oneOf+discriminator на этой версии генератора (3.1-ветка).
Фикс (round 2): плоская output-схема вместо oneOf — `kind` + опциональные
поля; per-kind валидация на сервере (parseScheduleEntry).
## Окружение (Windows) ## Окружение (Windows)
- `openapi-generator` 7.x требует **Java 11+**: системная Java 8 падает на - `openapi-generator` 7.x требует **Java 11+**: системная Java 8 падает на
class-load; ставь `JAVA_HOME` на новый JDK (Temurin 25 работает). class-load; ставь `JAVA_HOME` на новый JDK (Temurin 25 работает).
**Важно (round-2 уточнение):** CLI-обёртка (`@openapitools/openapi-generator-cli`)
спавнит `java` из **PATH**, не из `JAVA_HOME` — одного JAVA_HOME мало:
`$env:Path = "$env:JAVA_HOME\bin;" + $env:Path` до запуска, иначе
UnsupportedClassVersionError (class file 55.0 vs JRE 52.0 = Java 8 в PATH).
Запуск: `npx --yes @openapitools/openapi-generator-cli generate -i spec.json -g python -o out --additional-properties=packageName=...` Запуск: `npx --yes @openapitools/openapi-generator-cli generate -i spec.json -g python -o out --additional-properties=packageName=...`
- Wrapped-ответы, объявленные **инлайн в `components.responses`**, дают имена
`InlineObject..InlineObjectN` и доступ `resp.schedule.schedule.cron` (двойной
`.schedule`). Работает; красивее — именованные схемы в `components.schemas`.
- `info.version` спеки НЕ бьётся вместе с версией пакета (в 0.1.2 и 0.2.0 —
`0.1.0`); версия живёт только в package.json / dist-tags.
- Windows excluded port ranges (Hyper-V/WinNAT) резервируют порты (напр. 8090/8091): - Windows excluded port ranges (Hyper-V/WinNAT) резервируют порты (напр. 8090/8091):
`EACCES` на listen. Проверка: `netsh interface ipv4 show excludedportrange protocol=tcp`. `EACCES` на listen. Проверка: `netsh interface ipv4 show excludedportrange protocol=tcp`.
- Консоль cp1251: не печатай `→`/`«»` в скриптах — `'charmap' codec can't encode`; ASCII-only. - Консоль cp1251: не печатай `→`/`«»` в скриптах — `'charmap' codec can't encode`; ASCII-only.
## Паттерн обхода (потребитель, клиент не трогаем) ## Паттерн обхода (потребитель, клиент не трогаем) — исторический
Тонкий raw-слой рядом с сгенерированным пакетом (в примере — `raw_ops.py`): Тонкий raw-слой рядом с сгенерированным пакетом (в примере был `raw_ops.py`):
только операции, где спека `{}`, через `call_api`; остальное — через типизированный только операции, где спека `{}`, через `call_api`; остальное — через типизированный
клиент. Сгенерированный пакет остаётся перегенерируемым. клиент. Сгенерированный пакет остаётся перегенерируемым.
Пример целиком: `sched/examples/admin-client-python/` (24/24 сьют, 19/19 smoke). > **Статус:** после round 2 (0.2.0) обход не нужен — `raw_ops.py` удалён из
> примера. Паттерн остаётся escape-hatch'ем для сырых спек в других проектах.
Пример целиком: `sched/examples/admin-client-python/` (24/24 сьют, 19/19 smoke,
typed-only).

View File

@@ -6,14 +6,28 @@ related: [[openapi-generator-3-1-spec-gotchas]], [[sched-fnf-r8-verification-sta
updated: 2026-08-18 updated: 2026-08-18
--- ---
# sched admin-client openapi — F&F раунд # sched admin-client openapi — F&F раунды
Живая проверка claim'а sched openapi-spec: **«клиент на любом ЯП одной Живая проверка claim'а sched openapi-spec: **«клиент на любом ЯП одной
командой»**. Вердикт: **claim подтверждён с оговорками** — генерация одной командой»**. Вердикт round 1: **claim подтверждён с оговорками** (8 операций
командой работает, но 3.1-спека до «любого ЯП без правок» не дотягивает требуют raw-обхода). Вердикт round 2 (0.2.0/0.3.5): **claim подтверждён
(8 операций требуют raw-обхода). полностью** — все находки F-1..F-5 закрыты, raw-обход удалён, клиент
типизированный end-to-end.
## Что делал / ожидал / получил ## Round 2 — ретест фиксов (0.2.0 / daemon 0.3.5), 2026-08-18
| | |
|---|---|
| Что | `generate.ps1` заново против `@sched/admin-api@0.2.0` (tarball spec byte-identical pinned), сьют+smoke против `@sched/daemon@0.3.5` (:8127, no auth) |
| Ожидал | все 5 находок закрыты, `raw_ops.py` не нужен |
| Получил | **все 5 закрыты**; сьют **24/24** (3 прогона), smoke **19/19** — **полностью через типизированный клиент, 0 операций на обходе**; `raw_ops.py` **удалён**; F-1/F-5 подтверждены живьём на keyed-инстансе (:8128): health 200 open, /tasks 401 без ключа, 400 на неизвестные поля schedule body/patch |
Deliverables round 2: коммит sched `d658ff0` (пример обновлён: openapi.json
0.2.0, tests/smoke typed-only, raw_ops удалён, README+generate.ps1); репорт
`sched/.agents/inbox/2026-08-18T22-55-00Z-admin-openapi-fixes-round2-retest.md`.
Механика фиксов и генераторные грабли — [[openapi-generator-3-1-spec-gotchas]].
## Round 1 — 2026-08-18 (0.1.2 / daemon 0.3.4)
| | | | | |
|---|---| |---|---|
@@ -45,12 +59,14 @@ updated: 2026-08-18
```powershell ```powershell
cd sched/examples/admin-client-python cd sched/examples/admin-client-python
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot" $env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot"
$env:Path = "$env:JAVA_HOME\bin;" + $env:Path # генератор спавнит java из PATH, не из JAVA_HOME
.\generate.ps1 .\generate.ps1
pip install -r requirements.txt pytest pip install -r requirements.txt pytest
SCHED_ADMIN_URL=http://127.0.0.1:8127/api python -m pytest tests/ -v SCHED_ADMIN_URL=http://127.0.0.1:8127/api python -m pytest tests/ -v
python smoke.py --url http://127.0.0.1:8127/api python smoke.py --url http://127.0.0.1:8127/api
``` ```
Стенд раунда: published `@sched/daemon` 0.3.4, `--admin-port 8127`, NO AUTH, Стенд round 2: published `@sched/daemon` 0.3.5, `--admin-port 8127`, NO AUTH,
scratch sqlite (`/tmp/sched-acpy-stand/acpy.db`). Письменный `:8080` — под ключом scratch sqlite (`/tmp/sched-acpy-stand/acpy.db`). Round 1 стоял на 0.3.4.
(`SCHED_ADMIN_KEY=dev-key`), `:8123` — стейл-билд (health 0.1.8, нет POST /tasks). Письменный `:8080` — под ключом (`SCHED_ADMIN_KEY=dev-key`), `:8123` — стейл-билд
(health 0.1.8, нет POST /tasks).

View File

@@ -21,8 +21,8 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
- [windows-recovery-host](entities/windows-recovery-host.md) — Windows Recovery Host (рабочий PC пользователя) - [windows-recovery-host](entities/windows-recovery-host.md) — Windows Recovery Host (рабочий PC пользователя)
## Concepts ## Concepts
- [sched-admin-client-openapi](concepts/sched-admin-client-openapi.md) — F&F раунд 2026-08-18: Python-клиент одной командой из спеки (openapi-generator 7.24.0), 24/24 + smoke 19/19, вердикт «claim подтверждён с оговорками», находки F-1..F-5 - [sched-admin-client-openapi](concepts/sched-admin-client-openapi.md) — F&F раунды 2026-08-18: Python-клиент одной командой из спеки (openapi-generator 7.24.0); r1 0.1.2 — 24/24+smoke 19/19, находки F-1..F-5 (8 операций на raw-обходе); r2 0.2.0/0.3.5 — все 5 закрыты, raw_ops удалён, 11/11 typed-only, вердикт «claim подтверждён полностью»
- [openapi-generator-3-1-spec-gotchas](concepts/openapi-generator-3-1-spec-gotchas.md) — генерация клиентов из 3.1-спеки (openapi-generator 7.24.0, python): ответы `{}` + wrapped-тело → ValidationError (raw-обход + by_alias), `const:true` → строковый enum, oneOf+discriminator → actual_instance=None, Java 11+, Windows excluded-порты - [openapi-generator-3-1-spec-gotchas](concepts/openapi-generator-3-1-spec-gotchas.md) — генерация клиентов из 3.1-спеки (openapi-generator 7.24.0, python): wrapped-ответы {} → ValidationError (raw-обход историчен: r2 спека фикснута), const:true → строковый enum, oneOf+discriminator → actual_instance=None (r2: плоская схема), java из PATH а не JAVA_HOME, InlineObjectN-имена, info.version не бьётся
- [nvm-junction-ismain-gate-gotcha](concepts/nvm-junction-ismain-gate-gotcha.md) — ESM isMain-гейт молча не выполняется под junction'нутым npm-рутом (nvm/mise/volta); realpath-фикс; диагностика за 30 сек - [nvm-junction-ismain-gate-gotcha](concepts/nvm-junction-ismain-gate-gotcha.md) — ESM isMain-гейт молча не выполняется под junction'нутым npm-рутом (nvm/mise/volta); realpath-фикс; диагностика за 30 сек
- [nvm-windows-node-switch](concepts/nvm-windows-node-switch.md) — смена версии Node на nvm-windows: junction, per-version глобалы, PATH-кэш, npm 11 allow-scripts; Node 22→24 evidence - [nvm-windows-node-switch](concepts/nvm-windows-node-switch.md) — смена версии Node на nvm-windows: junction, per-version глобалы, PATH-кэш, npm 11 allow-scripts; Node 22→24 evidence
- [sched-fnf-r8-verification-stand](concepts/sched-fnf-r8-verification-stand.md) — стенд верификации F&F r8 (schedule-as-entity): путь, версии core 0.40.2/ui 0.2.0, карта репро-скриптов (миграции/движок/политики/API 52/UI 13), подтверждённый контракт (ceiling, retryCount, snapshot, pause AND, tz-hoist, PATCH-merge), находки №5 (U1 форма-tz, U2 вёрстка), как закрыть раунд - [sched-fnf-r8-verification-stand](concepts/sched-fnf-r8-verification-stand.md) — стенд верификации F&F r8 (schedule-as-entity): путь, версии core 0.40.2/ui 0.2.0, карта репро-скриптов (миграции/движок/политики/API 52/UI 13), подтверждённый контракт (ceiling, retryCount, snapshot, pause AND, tz-hoist, PATCH-merge), находки №5 (U1 форма-tz, U2 вёрстка), как закрыть раунд

View File

@@ -137,3 +137,4 @@ Append-only log of wiki operations (ingests, promotions, lints, migrations).
## [2026-08-18] ingest | NEW concepts/nvm-junction-ismain-gate-gotcha.md — ESM isMain-гейт молча no-op под junction-префиксом npm-рута (C:\nvm4w\nodejs → realpath …\nvm\v22.22.0): import.meta.url резолвится в realpath, argv[1] держит литеральный → main() не выполняется, exit 0. Бьёт global-install под любым version-manager'ом (nvm/mise/volta). Фикс realpath-сравнения (sched bd38aab, daemon 0.3.2). NEW concepts/nvm-windows-node-switch.md — Node 22→24.19.0 рецепт: junction-свап, per-version глобалы, PATH-кэш shell'а, npm 11 allow-scripts. Оба из сессии CLI-F&F sched 2026-08-18. index.md updated (+2). ## [2026-08-18] ingest | NEW concepts/nvm-junction-ismain-gate-gotcha.md — ESM isMain-гейт молча no-op под junction-префиксом npm-рута (C:\nvm4w\nodejs → realpath …\nvm\v22.22.0): import.meta.url резолвится в realpath, argv[1] держит литеральный → main() не выполняется, exit 0. Бьёт global-install под любым version-manager'ом (nvm/mise/volta). Фикс realpath-сравнения (sched bd38aab, daemon 0.3.2). NEW concepts/nvm-windows-node-switch.md — Node 22→24.19.0 рецепт: junction-свап, per-version глобалы, PATH-кэш shell'а, npm 11 allow-scripts. Оба из сессии CLI-F&F sched 2026-08-18. index.md updated (+2).
## [2026-08-18] ingest | NEW concepts/openapi-generator-3-1-spec-gotchas.md — из F&F openapi-client sched (2026-08-18): генерация Python-клиента из 3.1-спеки openapi-generator 7.24.0. Гочи: (1) ответы `{}` в спеке + wrapped-тело ({task/run/schedule:…}) → pydantic ValidationError, фикс — реальные схемы ответов, обход raw-транспорт + by_alias=True; (2) `const:true` → строковый enum ('true') ломает boolean; (3) oneOf+discriminator → actual_instance=None, контент только через raw JSON; Java 11+ обязателен (системная 8 падает), Windows excluded-порты 8090/8091 (EACCES), консоль cp1251 без →/«». Полные находки F-1..F-5: sched/.agents/inbox репорт 19:15Z; пример sched/examples/admin-client-python (24/24). index.md updated. ## [2026-08-18] ingest | NEW concepts/openapi-generator-3-1-spec-gotchas.md — из F&F openapi-client sched (2026-08-18): генерация Python-клиента из 3.1-спеки openapi-generator 7.24.0. Гочи: (1) ответы `{}` в спеке + wrapped-тело ({task/run/schedule:…}) → pydantic ValidationError, фикс — реальные схемы ответов, обход raw-транспорт + by_alias=True; (2) `const:true` → строковый enum ('true') ломает boolean; (3) oneOf+discriminator → actual_instance=None, контент только через raw JSON; Java 11+ обязателен (системная 8 падает), Windows excluded-порты 8090/8091 (EACCES), консоль cp1251 без →/«». Полные находки F-1..F-5: sched/.agents/inbox репорт 19:15Z; пример sched/examples/admin-client-python (24/24). index.md updated.
## [2026-08-18] ingest | NEW concepts/sched-admin-client-openapi.md — F&F раунд openapi-claim sched (по предписанию таски): Python-клиент одной командой (openapi-generator 7.24.0 из спеки verdaccio 0.1.2), сьют 24/24 + smoke 19/19 против published daemon 0.3.4 (:8127), вердикт «claim подтверждён с оговорками» (8 операций требуют raw-обхода). Код sched/examples/admin-client-python (e89e868), репорт — sched инбокс 19:15Z, находки F-1..F-5 (спеку не чинил). Таска [sched-admin-client-openapi] 🟢. Гочи генерации — concepts/openapi-generator-3-1-spec-gotchas.md. index.md updated. ## [2026-08-18] ingest | NEW concepts/sched-admin-client-openapi.md — F&F раунд openapi-claim sched (по предписанию таски): Python-клиент одной командой (openapi-generator 7.24.0 из спеки verdaccio 0.1.2), сьют 24/24 + smoke 19/19 против published daemon 0.3.4 (:8127), вердикт «claim подтверждён с оговорками» (8 операций требуют raw-обхода). Код sched/examples/admin-client-python (e89e868), репорт — sched инбокс 19:15Z, находки F-1..F-5 (спеку не чинил). Таска [sched-admin-client-openapi] 🟢. Гочи генерации — concepts/openapi-generator-3-1-spec-gotchas.md. index.md updated.
## [2026-08-18] ingest | UPDATE concepts/openapi-generator-3-1-spec-gotchas.md + concepts/sched-admin-client-openapi.md — round 2 ретест (0.2.0/daemon 0.3.5): все 5 находок F-1..F-5 закрыты, raw_ops.py удалён, 11/11 ранее-сырых операций typed-only, сьют 24/24 + smoke 19/19 (коммит sched d658ff0, репорт sched инбокс 22:55Z). Новые грабли в окружение: CLI спавнит java из PATH а не JAVA_HOME; wrapped-ответы в components.responses → InlineObjectN; info.version не бьётся с версией пакета. index.md hooks обновлены.