学习指南: 应用部分 11. 与真实 API 集成:从规范到部署

模块「应用部分 11. 与真实 API 集成:从规范到部署」中第 3 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

主题: Прикладная часть 11. Интеграция с реальным API: от спецификации до деплоя

难度等级: 中等

预计学习时间: 8-12 часов (теория 3-4 ч, практика 5-8 ч)

前置要求: Прохождение частей 7-9 первого тома (цикл спецификация-план-проверка)

Часть 12 первого тома (SQLite-миграции и MVP-фаза)

Часть 16 первого тома (командное ревью кода)

Базовое владение Python 3 и командной строкой

Понимание REST API, вебхуков и формата JSON

Опыт работы с Git и базовым CI/CD

学习目标: Выполнить полную цепочку обработки инцидента: от сырого вебхука до нормализованного события, проверки готовности (readiness) и пробного прогона (dry-run) с корректными кодами возврата для разрешённых и запрещённых действий

Применить SDD-разделение фаз Specify/Plan/Tasks/Implement/Validate для инцидента high_memory_usage, обеспечив отсутствие конкретных команд ремедиации в спецификации

Оценить конвейер по 25-балльной модели готовности, выявить блокирующие условия (audit/stateful) и сформировать корректный пакет доказательств для capstone

Сформировать воспроизводимый след (audit trace) с привязкой всех артефактов к incident_id, пригодный для командного ревью без истории чата

概述: Эта глава учит строить production-ready конвейер авто-ремедиации от первого сигнала инцидента до контролируемого исполнения. В центре — учебный кейс high_memory_usage для сервиса appointments-api: нормализация вебхуков Grafana и PagerDuty, прохождение шлюза готовности по 25-балльной модели, пробный прогон заранее согласованных действий и жёсткая блокировка всего остального. Весь путь реализован в examples/real-api/ без внешних зависимостей: скрипты на стандартной библиотеке Python позволяют локально прогнать конвейер и увидеть, какие условия блокируют действие. Полный production-трек (GitOps, Kubernetes API, полный executor) отложен до накопления реплей-доказательств; в учебном минимуме достаточно доказать, что разрешённое действие проходит readiness, а запрещённое блокируется до изменения системы.

关键概念: Sdd-цикл (specify/plan/tasks/implement/validate): Структурированный процесс, где Specify фиксирует WHY/WHAT/constraints без выбора конкретной команды ремедиации, Plan выбирает стратегию, Tasks раскладывает её в исполнимые шаги, Implement применяет изменения контролируемо, Validate проверяет результат. Защищает от преждевременной реализации и обеспечивает доказуемость каждого шага.

Нормализация вебхуков: Преобразование сырых полезных нагрузок из разных источников (Grafana, PagerDuty) в единый формат incident_event с полями service, namespace, pod, severity, window_minutes, metric_context, source_refs. Устраняет дублирование и конфликт версий одного инцидента.

25-балльная модель готовности (readiness): Оценка конвейера по пяти категориям (Spec, Implementation, Verification, Process, Security) по шкале 0-5 каждая. Порог 23/25 для auto-допуска; 20-22/25 — полуручной режим. Ни одна категория не компенсирует пробел в другой. Запрещён нулевой балл по Security при любой сумме.

Блокирующие условия: Независимые от суммы readiness факторы, которые блокируют слияние: проваленная validation (Verification ≤ 2), отсутствие отката (Security ≤ 2), неопределённый радиус последствий (Implementation ≤ 2 без явного поля). Дополнительно: audit_trace_coverage < 1.0 и stateful=true без backup_verified=true.

Dry-run (пробный прогон): Проверка действия против списка заранее согласованных (pre-approved) операций без реальных изменений системы. Выполняется только после прохождения шлюза готовности. Разделяет разрешённые действия (restart_pod, scale_up_replicas_one) и запрещённые (delete_namespace).

Audit trace (журнал трассировки): Причинно-следственный след, связывающий все артефакты через incident_id: webhook_received → incident_event_normalized → /sdd:specify → spec_diff_created → commit → validate. Минимальный фрагмент воспроизводим без истории чата.

Радиус последствий: Явно указанный уровень вмешательства (pod, deployment, namespace). Защищает от непреднамеренного расширения масштаба операции. Должен быть зафиксирован до implement, не описан текстом.

Human-in-the-loop (ручное подтверждение): Обязательный элемент авто-ремедиации: человек остаётся в контуре при неопределённости, расширении радиуса последствий или повторном провале. Полностью автоматизированная ремедиация без human-review остаётся фронтир-сценарием.

Идемпотентность: Свойство задач, при котором повторный запуск не ломает состояние системы. Обязательное требование для Implementation на максимальный балл.

Gitops-фиксация: Фиксация всех изменений через Git с последующей синхронизацией (например, через ArgoCD). В учебном минимуме — справочное понятие; в полном треке — обязательный шаг перед production-переключением.

练习题: 名称: Нормализация и верификация вебхука

问题: Запустите скрипт нормализации для фикстур Grafana и PagerDuty. Убедитесь, что выход совпадает с эталоном поле-в-поле. Затем модифицируйте webhook_grafana.json: измените memory_percent с 93 на 87 и window с 10m на 5m. Снова запустите нормализатор и объясните, почему выход всё ещё валиден, но эталон не совпадает. Какие поля критичны для идентификации инцидента, а какие — для контекста метрики?

解决方案: 1. cd book2/examples/real-api

  1. python3 scripts/normalize_webhook.py --grafana fixtures/webhook_grafana.json --pagerduty fixtures/webhook_pagerduty.json --expected fixtures/incident_event.expected.json → ожидаем код 0.
  2. Копируем фикстуру: cp fixtures/webhook_grafana.json fixtures/webhook_grafana_modified.json
  3. Меняем memory_percent на 87 и window на 5m в копии.
  4. Запускаем с модифицированной фикстурой: скрипт вернёт код 1, так как выход не совпадает с incident_event.expected.json.
  5. Анализ: incident_key, service, namespace, pod — критичны для идентификации (должны совпадать у обоих источников). memory_percent, window_minutes — контекст метрики, они влияют на specify, но не ломают нормализацию как процесс. Несовпадение с эталоном ожидаемо: эталон фиксирован для конкретного инцидента, а модификация создаёт другое событие.

难度: beginner

名称: Прогон шлюза готовности с анализом блокеров

问题: Последовательно прогоните три фикстуры readiness: readiness_pass.json, readiness_block_audit.json, readiness_block_stateful.json. Для каждой зафиксируйте код возврата, итоговую сумму и конкретную причину блокировки. Затем вручную создайте четвёртую фикстуру readiness_block_implementation.json с суммой 24/25, но явным radius_of_impact: 'cluster' без поля dry_run_verified: true. Предскажите и проверьте поведение шлюза.

解决方案: 1. python3 scripts/check_readiness.py --readiness fixtures/readiness_pass.json → код 0, PASS incident=HM-2026-05-17-01 score=24/25.

  1. python3 scripts/check_readiness.py --readiness fixtures/readiness_block_audit.json → код 1, BLOCK с причинами: score=22/25 below threshold 23 и audit_trace_coverage=0.7 < 1.0.
  2. python3 scripts/check_readiness.py --readiness fixtures/readiness_block_stateful.json → код 1, BLOCK с причиной: stateful workload without verified backup (сумма 24/25 не спасает).
  3. Создаём fixtures/readiness_block_implementation.json на базе readiness_pass.json, меняем radius_of_impact на 'cluster' и убираем dry_run_verified.
  4. Предсказание: код 1, блокировка по Implementation ≤ 2 (неопределённый радиус последствий без dry-run) — это блокирующее условие независимо от суммы.
  5. Проверка запуском подтверждает предсказание.

难度: intermediate

名称: Полный цикл specify → dry-run с запрещённым действием

问题: Прочитайте specs/high_memory_usage/specify.md. Убедитесь, что он содержит WHY/WHAT/constraints и pre-approved actions, но не конкретную команду kubectl. Запустите dry_run.py для restart_pod (PASS) и delete_namespace (BLOCK). Затем добавьте в spec третье действие scale_up_replicas_one с условием requires: ['stateless', 'hpa_enabled'] и создайте фикстуру, где stateless: false. Проверьте, что новое действие блокируется условием, а не только отсутствием в списке.

解决方案: 1. Читаем specs/high_memory_usage/specify.md: проверяем наличие WHY, WHAT, constraints, списка pre-approved actions: [restart_pod, scale_up_replicas_one].

  1. Убеждаемся, что нет строки вида kubectl delete pod или конкретного API-вызова.
  2. python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action restart_pod → код 0, PASS.
  3. python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action delete_namespace → код 1, BLOCK: action not in pre-approved list.
  4. Редактируем spec: добавляем scale_up_replicas_one с requires: ['stateless', 'hpa_enabled'].
  5. Создаём тестовую фикстуру или передаём контекст через аргументы скрипта, где stateless=false.
  6. Запускаем dry_run.py --action scale_up_replicas_one с контекстом stateless=false → ожидаем BLOCK: precondition 'stateless' not met.
  7. Вывод: dry-run проверяет не только членство в списке, но и runtime-условия, что делает его более надёжным, чем простой whitelist.

难度: intermediate

名称: Заполнение 25-балльной рубрики для собственного кейса

问题: Возьмите инцидент из вашей практики (или используйте high_memory_usage). Заполните таблицу из раздела «Практика» главы: для каждой из пяти категорий укажите балл, конкретный артефакт-доказательство (файл, лог, схема) и причину снижения. Подсчитайте итог, проверьте блокирующие условия. Если итог ниже 23 или есть блокеры — сформулируйте конкретные изменения для каждой ячейки, а не общие «улучшить процесс».

解决方案: Пример заполнения для high_memory_usage:

КатегорияБаллАртефакт-доказательствоПричина снижения
Spec5specs/high_memory_usage/specify.md с WHY/WHAT/constraints и GWTНет
Implementation4tasks.md с идемпотентными шагами, но scale_up без отдельного dry-runОдна задача меняет состояние без предварительной проверки
Verification5validation.md с GWT, JSON Schema, стресс-спекой, пост-метрики в двух окнахНет
Process5Лог webhook → CLI → diff → commit с incident_id=HM-2026-05-17-01Нет
Security4specify.md с ограждениями stateful, откатом, аварийным стопомЭскалация описана текстом без формального триггера
Итог23/25Блокирующие: нетЧто менять: добавить dry_run_verified для ветки scale-up в tasks.md; формализовать триггер эскалации в security_policy.md

Проверка: 23 ≥ порог, блокеры отсутствуют → production-ready с двумя полуручными ветками.

难度: advanced

名称: Создание воспроизводимого следа для capstone

问题: Выполните минимальный runnable-цикл (шаги 1-8 из главы). Зафиксируйте результат в capstone/readiness.md в формате YAML из главы. Убедитесь, что файл читается без истории чата: каждая строка должна указывать на конкретный прогон, а не на «я обсуждал это с ассистентом». Добавьте одну реально запущенную команду в capstone/validation.md.

解决方案: 1. Выполняем шаги 1-8 из раздела «Минимальный учебный сценарий».

  1. Создаём capstone/readiness.md:
readiness:
  pass_fixture: "readiness_pass.json -> 24/25"
  blockers:
    - "audit_trace_coverage=0.7 blocks auto mode (fixture: readiness_block_audit.json)"
    - "stateful=true without backup_verified blocks action (fixture: readiness_block_stateful.json)"
  dry_run: "restart_pod PASS; delete_namespace BLOCK (scripts/dry_run.py --spec specs/high_memory_usage/specify.md)"
  1. Создаём capstone/validation.md:
# Валидация readiness-шлюза

Команды, реально запущенные:
- `python3 scripts/check_readiness.py --readiness fixtures/readiness_pass.json` → код 0
- `python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action restart_pod` → код 0
  1. Проверяем: файл читается без контекста чата, содержит конкретные фикстуры, коды возврата, команды. Нет ссылок на «ассистент сказал» или «в чате обсудили».

难度: intermediate

案例研究: 名称: Инцидент high_memory_usage в учебном контуре: от вебхука до блокировки запрещённого действия

场景: Сервис appointments-api, построенный в части 12 первого тома на SQLite, столкнулся с пиком потребления памяти. Grafana зафиксировала memory_percent=93 за окно 10 минут для пода api-7b4 в неймспейсе appointments-api. PagerDuty подтвердила критичность и привязку к сервису. Команда разворачивает конвейер авто-ремедиации на основе материалов главы 11.

挑战: Три ключевых проблемы: (1) разные источники оповещений (Grafana и PagerDuty) дают разные версии одного инцидента, что создаёт риск двойной обработки; (2) предыдущие попытки specify сразу указывали kubectl delete pod, блокируя альтернативные стратегии и мешая Plan; (3) команда не могла отличить допустимый auto-ремедиации инцидент от требующего ручного вмешательства, что приводило к перезапуску stateful-подов без бэкапа.

解决方案: Команда внедрила четырёхступенчатый конвейер из главы 11: (1) normalize_webhook.py свёл Grafana и PagerDuty к единому incident_event с incident_id=HM-2026-05-17-01, удалив чувствительные поля; (2) specify был переписан в формате WHY/WHAT/constraints с pre-approved actions (restart_pod, scale_up_replicas_one), без конкретных команд; (3) шлюз готовности на 25-балльной модели с порогом 23/25 блокировал инциденты с неполным аудитом (audit_trace_coverage=0.7) и stateful без бэкапа; (4) dry_run.py проверял действия против списка заранее согласованных, блокируя delete_namespace и другие вне списка.

结果: Локальный прогон показал: readiness_pass.json (24/25) проходит с кодом 0, restart_pod получает PASS. readiness_block_audit.json (22/25) и readiness_block_stateful.json (24/25, но без бэкапа) блокируются с конкретными причинами в stderr. delete_namespace получает BLOCK как не входящий в pre-approved. Пакет доказательств был зафиксирован в capstone/readiness.md и прошёл командное ревью в духе части 16.

经验教训: Specify не должен выбирать конкретную команду ремедиации — это блокирует Plan и лишает гибкости

Шлюз готовности должен проверяться до dry-run, а не после: последовательность гарантирует известный радиус последствий до проверки списка действий

Блокирующие условия (audit, stateful) работают независимо от суммы баллов — 24/25 не спасёт от блокировки stateful без бэкапа

Воспроизводимый след с привязкой к incident_id важнее истории чата: ревьюер должен проверить файл, а не верить на слово

相关概念: Нормализация вебхуков

25-балльная модель готовности

SDD-цикл

Dry-run

Audit trace

Блокирующие условия

名称: Опасный антипаттерн: запуск dry-run до шлюза готовности в production-команде

场景: Команда с 2-летним опытом работы с SDD попыталась ускорить конвейер, запуская dry_run.py параллельно с check_readiness.py, чтобы «не терять время на ожидание». В инциденте с memory_percent=91 действие restart_pod было формально разрешено спецификацией, но audit_trace_coverage оказался 0.8 из-за пропущенного шага /sdd:specify в чате, а не в файле.

挑战: Параллельный запуск создал race condition: dry-run вернул PASS за 200 мс, readiness вернул BLOCK через 500 мс, но оркестратор уже начал подготовку к исполнению. Отсутствие полного audit trace означало, что причинно-следственная связь между вебхуком и спецификацией не была доказуема — критично для пост-инцидентного разбора и регуляторной проверки.

解决方案: Инцидент был остановлен вручную оператором, который заметил расхождение в логах. Команда ввела жёсткое правило: dry_run.py запускается только при коде возврата 0 от check_readiness.py, последовательно, с явной проверкой в скрипте-обёртке. Добавили guardrail: если audit_trace_coverage < 1.0, readiness возвращает BLOCK до любого другого анализа. Пересмотрели рубрику Process: максимальный балл 5 теперь требует не просто наличия журнала, а воспроизводимого реплея по incident_id.

结果: Конвейер замедлился на 300 мс среднем, но нулевой инцидентов с необоснованной авто-ремедиацией в течение 6 месяцев. Рубрика Process стала самой строгой в оценках: команды с 4 баллами (требующими ручной подстановки переменной для реплея) не допускались к auto-контуру. Урок был интегрирован в учебный материал главы 11 как явное предупреждение «Плохо/Хорошо».

经验教训: Производительность конвейера никогда не должна жертвовать доказуемостью: 300 мс ожидания — ничтожная цена за предотвращение необоснованного вмешательства

Максимальный балл по Process требует воспроизводимого реплея, а не просто наличия логов

Human-in-the-loop — не баг, а фича: даже опытные команды удерживают человека в контуре на критическом пути

Guardrails должны быть независимы от основного потока: audit проверяется первым, до любого анализа рисков

相关概念: Audit trace

Блокирующие условия

Process

Human-in-the-loop

Guardrails

学习建议: Проходите главу последовательно, не перепрыгивая на полный production-трек: учебный минимум (шаги 1-8) даёт 80% понимания за 20% времени

Запускайте каждый скрипт вручную и фиксируйте код возврата в заметках, а не полагайтесь на память: ревьюер capstone проверяет конкретные команды

Создавайте собственные «сломанные» фикстуры (как в упражнении 2) — это лучший способ понять, почему блокирующие условия работают независимо от суммы баллов

Читайте specs/high_memory_usage/specify.md до запуска скриптов: найдите WHY, WHAT, constraints и убедитесь, что нет конкретных команд — это ключевое отличие хорошего specify

Используйте qwen -p с флагом --approval-mode plan для необязательного шага анализа (шаг из главы), но не смешивайте его вывод с обязательным пакетом readiness: план — для ревью, скрипты — для доказательств

Параллельно с главой перечитывайте части 7-9 и 16 первого тома: конвейер главы 11 — это обёртка вокруг уже известного цикла, а не его замена

Для визуального стиля: нарисуйте на бумаге цепочку вебхук → нормализация → readiness → dry-run и отметьте, где стрелка прерывается при каждом блокере

附加资源: Github spec kit: https://github.com/github/spec-kit — практическая рамка фаз Specify → Plan → Tasks → Implement, на которую ссылается глава

Github spec kit quickstart: https://github.github.io/spec-kit/quickstart.html — краткое руководство по внедрению SDD-цикла

Примеры к главе (examples/real-api/): Локальный конвейер на stdlib Python без внешних зависимостей; скрипты normalize_webhook.py, check_readiness.py, dry_run.py

Часть 12 первого тома (book/part-12-mvp.md): MVP-фаза и SQLite-миграции — контекст для инцидента high_memory_usage

Часть 7 первого тома (book/part-07-feature-specification.md): Цикл спецификации — основа для /sdd:specify

Часть 16 первого тома (book/part-16-team-code-review.md): Командное ревью — куда попадает пакет readiness

Приложение d, раздел d.5 (appendix-d-threshold-calibration.md#d5-production-готовность-глава-11): Калибровка порогов readiness для разных риск-профилей

摘要: Глава 11 учит строить воспроизводимый конвейер авто-ремедиации от вебхука до контролируемого исполнения. Учебный минимум — четырёхступенчатая цепочка вебхук → нормализация → readiness → dry-run для кейса high_memory_usage, реализованная локально без внешних зависимостей. Ключевые принципы: SDD-разделение фаз защищает от преждевременной реализации; 25-балльная модель готовности с порогом 23/25 и независимыми блокирующими условиями (audit, stateful, откат, verification) определяет допуск к auto-контуру; dry-run проверяет действия только после прохождения шлюза; human-review остаётся обязательным элементом, а не препятствием скорости. Полный production-трек (GitOps, Kubernetes, полный executor) — фронтир, требующий накопления реплей-доказательств. Практический результат первого прохода — не оркестратор, а доказательство: разрешённое действие проходит, запрещённое блокируется, след воспроизводим по incident_id.

我的笔记
0 / 10000

笔记保存在当前浏览器中。在其他设备上将不会显示。

课程菜单

课程

Production SDD for Qwen Code CLI. Part 2
进度 0 / 100