Тема: Прикладная часть 1. Восстановление спецификаций из legacy
Уровень сложности: Средний (Средний)
Расчётное время изучения: 4-5 часов
Предварительные требования: Знание материала Части 13 первого тома (восстановление конституции существующего проекта).
Понимание принципов работы с облачной инфраструктурой (Kubernetes, мониторинг, алерты).
Базовые навыки работы с форматами JSON, YAML и Markdown.
Общее понимание концепции SDD (Specification-Driven Development).
Цели обучения: Научиться четко разделять фактические требования (контракты) и фоновый инфраструктурный контекст (memory bank).
Освоить сбор и нормализацию доказательств (evidence_ref) из разрозненных источников (логи, Slack, пост-мортемы) в единую временную шкалу.
Овладеть навыками извлечения неявных правил и преобразования их в проверяемые утверждения (claims) с использованием ИИ (Qwen Code).
Уметь описывать восстановленные требования на языке поведения (Given/When/Then) и проектировать для них машинно-читаемые контракты (JSON Schema).
Научиться вести реестр происхождения требований (genealogy.md) для обеспечения прозрачности и аудируемости спецификаций.
Обзор: В этом учебном модуле рассматривается процесс восстановления инженерно пригодной спецификации (SDD) из разрозненных артефактов устаревших систем (legacy), таких как неструктурированные логи, чаты операторов и пост-мортемы. На примере учебной production-модели AgentClinic вы узнаете, как превратить хаос данных в строгий, проверяемый контракт. Вы освоите методы нормализации временных шкал, использования ИИ для извлечения требований с доказательной базой и разделения бизнес-логики и инфраструктурного контекста (memory bank). Курс акцентирует внимание на том, что каждое восстановленное требование должно опираться на источники, а не на догадки.
Ключевые концепции: Spec-некромантия (восстановление спецификаций): Инженерный прием реконструкции спецификаций на основе наблюдаемых артефактов (логов, метрик, чатов). Позволяет восстановить логику системы после оттока команды, опираясь на проверяемую цепочку доказательств вместо абстрактных догадок.
Memory bank (фоновая модель): Отдельный слой инфраструктурного контекста (исторические договоренности, топология кластера, имена команд). Эта информация помогает интерпретировать факты, но сама по себе не является бизнес-требованием (контрактом) и не должна попадать в логику триажа.
Evidence ref (пометка-доказательство): Ссылка на конкретное место в исходном артефакте (например, строка в логе, сообщение в Slack), которая подтверждает истинность утверждения. Требование без evidence_ref считается лишь гипотезой.
Genealogy.md (реестр провенанса): Файл, описывающий происхождение каждого требования. В отличие от git log, показывает не только кто и когда изменил файл, но и откуда взялось правило, уровень уверенности (uncertainty), подтверждающие источники и открытые вопросы.
Утверждение-кандидат (claim): Извлеченное из данных паттерн или правило, снабженное доказательствами, контрпримерами и оценкой уверенности. Статус кандидата может быть 'approved', 'needs_clarity' или 'rejected'.
Нормализованная временная цепочка: Последовательность событий, приведенных к единому времени (UTC) и формату, очищенная от дублей. Связывает логи, алерты и действия операторов в хронологическом порядке.
Практические упражнения: Название: Разделение контракта и фонового контекста
Проблема: Вам предоставлен список выписок из пост-мортема инцидента:
- 'Сервис appointments-api начал потреблять >90% памяти за 10 минут.'
- 'Дежурный инженер Иван сообщил в Slack-канал #incidents, что это не плановый деплой.'
- 'Деплоймент происходил в canary namespace.'
- 'Команда NOC получила алерт через 15 минут.'
Задача: Разделите эти факты на две категории: 'Требования (SDD)' и 'Memory Bank'. Обоснуйте решение.
Решение: 1 и 4 — Требования (SDD). Они описывают наблюдаемое поведение системы и SLA (триггер потребления памяти и время реакции). 2 и 3 — Memory Bank. Имя дежурного инженера и факт использования canary namespace — это контекст, который помогает понять ситуацию, но не должен быть жестко зашит в бизнес-логику триаж-пайплайна как универсальное правило.
Сложность: beginner
Название: Формирование записи в genealogy.md
Проблема: На основе учебной выписки:
- grafana:HM-2026-05-17-01 cluster=prod-k8s memory_percent=92 window=10m
- postmortem:api-memory-2026-05 note='auto-resolve was rejected until stable'
Сформируйте YAML-фрагмент для файла genealogy.md. Утверждение: 'При memory_percent >= 90% за 10m для appointments-api создаётся P1'. Укажите статус 'needs_clarity', так как нет данных по условиям закрытия.
Решение: - claim: "При memory_percent >= 90% за 10m для appointments-api создаётся P1." status: needs_clarity evidence_ref:
- "grafana:HM-2026-05-17-01"
- "postmortem:api-memory-2026-05"
uncertainty: medium open_questions:
- "Подтверждён ли запрет auto-resolve без стабильных окон?"
- "Какой точный порог закрытия инцидента?"
Сложность: intermediate
Название: Двойная запись спецификации (Given/When/Then + JSON Schema)
Проблема: Переведите восстановленное требование в формат Given/When/Then и напишите минимальную JSON Schema для валидации порога срабатывания и SLA. Требование: 'Если фиксируется >=3 NodeNotReady за 10 минут на одном узле, создаётся инцидент P1 с ожидаемой реакцией в 8 минут.'
Решение: Given кластер находится в активной смене и система мониторинга фиксирует метрики; When поступает >=3 событий NodeNotReady для одного узла в течение 10 минут; Then система создает инцидент со severity=P1 и устанавливает SLA реакции 8 минут.
JSON Schema: { "$id": "urn:spec:node-not-ready:v1", "type": "object", "required": ["rule_id", "severity", "sla_minutes", "conditions"], "properties": { "rule_id": {"type": "string"}, "severity": {"type": "string", "enum": ["P0", "P1", "P2", "P3"]}, "sla_minutes": {"type": "integer", "minimum": 1, "maximum": 120}, "conditions": { "type": "object", "required": ["event_code", "count", "window_minutes"], "properties": { "event_code": {"type": "string"}, "count": {"type": "integer", "minimum": 3}, "window_minutes": {"type": "integer", "minimum": 1} } } } }
Сложность: advanced
Кейсы: Название: Восстановление логики эскалации после оттока команды SRE
Сценарий: В проекте автоматического управления инцидентами произошел отток ключевых специалистов. В наследство остались 47 страниц неочищенных логов, Slack-треды, скриншоты дашбордов и текстовые пост-мортемы. Новая команда должна построить триаж-пайплайн на основе Qwen Code, но формального документа спецификаций (SDD) не существует.
Задача: Информация хаотична: логи содержат более 1200 событий с разными часовыми поясами, в чатах смешаны реальные инциденты и обсуждения плановых работ. Существует высокий риск того, что ИИ-модель (Qwen Code) воспримет случайную фразу из чата или специфичную топологию кластера как универсальное бизнес-правило.
Решение: Команда применила метод 'Spec-некромантии':
- Инвентаризация и нормализация данных: приведение всех меток времени к UTC, фильтрация шума, создание единой временной шкалы.
- Разделение слоев: выделение проверяемых требований (триггеры, SLA, условия закрытия) и перенос всего остального в Memory Bank.
- Извлечение требований через ИИ: использование Qwen Code в режиме анализа с жестким требованием предоставлять evidence_ref для каждого утверждения.
- Ведение genealogy.md: фиксация происхождения каждого правила, чтобы отличать твердо подтвержденные пост-мортемами факты от неподтвержденных гипотез.
Результат: Вместо набора правдоподобных догадок команда получила инженерно пригодную спецификацию. Согласованный контракт был выражен в формате Given/When/Then и JSON Schema, что позволило автоматически валидировать поведение триаж-пайплайна.
Извлечённые уроки: Никогда не маскируйте спорные гипотезы под утвержденные контракты. Используйте статус needs_clarity и уровень неопределенности.
Оконный фильтр (например, [-15m,+5m] относительно алерта) критически важен для связывания ручных действий в чате с автоматическими событиями в логах.
Исключения (например, canary namespace) не должны удаляться как шум; они часто указывают на скрытые условия спецификации.
Связанные концепции: evidence_ref
memory bank
genealogy.md
Spec-некромантия
Qwen Code
Название: Анализ инцидента node_not_ready: выявление скрытых порогов
Сценарий: Анализируется конкретный исторический инцидент NR-2026-05-17-01. Grafana показывает 3 события NodeNotReady на узле worker-07 за 10 минут. Система создала эскалацию P1. В пост-мортеме указано: 'auto-resolve was rejected until two stable OK windows'.
Задача: Требуется восстановить точные правила: когда именно событие становится P1, а когда его можно закрыть автоматически. Инженерам нужно понять, является ли порог в 3 события жестким правилом или совпадением, и как именно проверять 'stable OK windows' в коде.
Решение: 1. Составление поведенческой истории в формате Given/When/Then.
- Формулирование утверждения-кандидата (Claim): 'При >=3 NodeNotReady за 10 минут создается P1'.
- Привязка доказательств (ссылка на Grafana и пост-мортем) через evidence_ref.
- Фиксация условия закрытия в JSON Schema, требующей наличия двух последовательных OK окон.
- Выделение спорного факта (canary namespace) в открытый вопрос с пометкой uncertainty: medium.
Результат: Создана проверяемая спецификация, которая восстанавливает логику триажа. Спорный момент с canary namespace не попал в финальный SDD как универсальное правило, а остался в статусе гипотезы, требующей проверки на исторических данных.
Извлечённые уроки: Гладкая текстовая формулировка требования менее полезна, чем запись, показывающая, где требование устойчиво, а где требует проверки у владельца сервиса.
Двойная запись (поведение + JSON Schema) устраняет разрыв между пониманием человека и проверкой машиной.
Связанные концепции: Утверждение-кандидат (Claim)
Нормализованная временная цепочка
JSON Schema
Given/When/Then
Советы по изучению: Начинайте с узкого фокуса: для первого практического шага выберите один claim, два источника и один открытый вопрос. Не пытайтесь восстановить всю архитектуру сразу.
Тренируйте разделение слоев: при чтении любого пост-мортема задавайте себе вопрос — это наблюдаемое поведение контракта или просто контекст ситуации?
Практикуйте работу с Qwen Code в безголовом режиме (Plan Mode): требуйте от модели возвращать не готовый текст, а структурированный JSON с полями source, counterexample и missing_context.
Обратите внимание на разницу между git blame и genealogy.md. Git покажет, кто добавил строчку в код, а genealogy.md объяснит, на основании каких логов и чатов было принято именно это бизнес-решение.
Дополнительные ресурсы: Часть 13 первого тома учебника: Базовый материал по восстановлению конституции существующего проекта. Рекомендуется к прочтению до начала данного модуля.
Часть 8 (мультиагентный арбитраж): Продвинутый материал для полного production-трека. Описывает роли Верификатора, Имплементора и Safety для разрешения спорных спецификаций.
Github spec kit: Внешний ресурс, описывающий философию SDD «спецификация как исполняемый артефакт».
Шаблон genealogy.md (book2/examples/templates/): Практический шаблон, необходимый для выполнения упражнений учебного курса.
Резюме: Восстановление спецификаций из legacy — это процесс трансформации хаоса исторических данных в строгий, валидируемый контракт. Ключ к успеху лежит в жестком разделении фактических требований (SDD) и инфраструктурного контекста (Memory Bank). Использование ИИ помогает извлечь кандидатов в требования, но каждое такое утверждение должно быть подкреплено доказательствами (evidence_ref). Двойная кодификация (человекочитаемое Given/When/Then и машинно-читаемая JSON Schema) в связке с ведением реестра происхождения (genealogy.md) гарантирует, что спецификация будет не просто набором правдоподобных догадок, а аудируемым инженерным артефактом.