Самый опасный результат репетиции миграции — не ошибка, а уверенная запись «всё прошло». Без инвентаря, границы трафика, состояния данных и именованного триггера эта фраза не сообщает, что наблюдалось и как остановить переход. Цена — завышенная готовность: следующий участник воспринимает заметку как разрешение, хотя автор мог видеть лишь один удачный фрагмент. При первом отклонении приходится заново восстанавливать условия и ответственность.
Field note должна делать обратное: превращать наблюдение в маленькую цепочку input → criterion → evidence → counterexample → decision. Здесь каждый элемент — fixed synthetic literal. Есть только два допустимых финала: точный stop-… или synthetic-migration-review-hand-off с effect: no-system-change. Ни один из них не разрешает переводить routes, переносить records, запускать rehearsal или менять инфраструктуру.
Репетиция начинается с вопроса, а не с сценария
Фраза «отрепетировать миграцию» слишком велика. В поле полезнее спросить: какой один переход мы способны описать без скрытых предположений? Fixed case выбирает route-ledger-read, record-ledger-entry и named transition. Он не делает вид, что ими покрыт портфель приложений. Такое сужение не мешает глубине: оно заставляет показать, какой owner знает route, какой writer связан с record и какая dependency отделяет один шаг от другого.
Если любой из этих ответов отсутствует, evidence loop не должен переходить к метрикам. Иначе review внезапно начинает рассуждать о качестве candidate, не зная, чему принадлежат наблюдения. Статус stop-missing-inventory корректен даже при заполненной целевой диаграмме. Диаграмма отвечает на другой вопрос. Полевой review защищает переход от того, чтобы текущая неизвестность была спрятана за будущим желаемым состоянием.
| Поле | Что зафиксировать | Пример fixed literal | Запрещённая подмена |
|---|---|---|---|
| input | объект и граница | route-ledger-read | «вся система» |
| criterion | условие перехода | control и recovery state | «выглядит готовым» |
| evidence | узкое наблюдение | window с двумя metric ids | реальная телеметрия |
| counterexample | что отменяет вывод | missing control boundary | «бывает по-разному» |
| decision | stop или hand-off | effect no-system-change | разрешение на cutover |
Evidence должно связывать четыре плоскости
Для миграции недостаточно одного успешного check. Evidence связывает inventory с route, traffic boundary с тем же route, data state с record и rollback trigger с обоими return states. Если связь порвана, текст не имеет права говорить «переход контролируемый». Он может назвать только отсутствие конкретного звена. Эта строгость выглядит медленной до первого спорного момента; затем она экономит часы, потому что reviewer не ищет в общем документе, к какой части относится наблюдение.
В fixed case evidence не хранит значения ошибок, время или реальные traces. Он хранит id окна и два metric ids. Поэтому корректная фраза: «в record названы поля наблюдения». Некорректная: «ошибок не было». Разница кажется стилистической, но она защищает решение. Первая фраза следует из literal. Вторая требует системы измерений, интервала и выборки, которых package принципиально не имеет. M9-голос выигрывает от такой краткости: меньше эффектных слов, больше проверяемых границ.
Контрпример — часть успеха, не примечание к нему
Accepted branch полезен только если рядом виден случай, который его отменяет. Для traffic это candidate без control; для data — copy без restore state; для rollback — trigger без condition. Контрпример не утверждает, что переход опасен. Он доказывает более скромное: текущий вывод нельзя получить из текущего input. Такой stop не наказание автору. Это короткое описание следующего факта, который нужен, чтобы продолжить review без изменения модальности текста.
Особенно важен контрпример с данными. Возвращение трафика на прежний endpoint часто воспринимают как полный rollback, хотя у модели есть отдельное поле rollback.dataState. Если оно пусто, функция возвращает data-migration-has-no-named-recovery-state. Это не предписание о стратегии восстановления. Это запрет назвать обратимой операцию, для которой не описано, как связать новые данные с предыдущим write state.
Буквальный stop decision
import { createFixedMigrationRecord, reviewFixedMigrationPlaybook } from './upgrade-2026-07.mjs';
const record = createFixedMigrationRecord('rollback-without-trigger-v1');
const result = reviewFixedMigrationPlaybook(record);
console.log({ status: result.status, reason: result.reasons[0], next: result.nextAction });
// { status: 'stop-unnamed-rollback-trigger', reason: 'rollback-trigger-is-not-named', next: 'name-trigger-condition-owner-and-traffic-data-return-state' }
Пример выполняется буквально и останавливается до любого действия. Он не создаёт incident, не открывает dashboard и не выбирает fix-forward. При этом он делает decision review пригодным для передачи: есть status, причина и точное следующее действие над моделью. Важно не смягчать output до «нужно подумать об откате». Такой совет не хранит границу и через день потребует устного пересказа. Named reason переносится вместе с literal.
Стоп лучше постановочного green
Green status опасен, когда его нельзя воспроизвести. В этой карточке hand-off появляется только после трёх независимых проверок: inventory complete, transition state complete и allowed positive next action. Даже тогда итог формулируется скромно: fixed record можно передать на synthetic migration review. В нём остаётся boundary и поле no-system-change. Это не эстетическая перестраховка. Это контракт с будущим читателем, который может не знать контекста автора.
Такой подход согласуется с узкой границей rollback у Kubernetes Deployment documentation. Если даже controller rollback имеет определённый объект — Pod template, то в инженерском тексте нельзя расширять слово «rollback» без названия объекта. Для полевой заметки достаточно спросить: что возвращает traffic state, что возвращает data state и по какому наблюдению это вообще обсуждается? Пока нет всех ответов, review должен остановиться, а не компенсировать пробел опытом рецензента.
Пять шагов evidence loop
- Зафиксировать один synthetic input и назвать его границу: route, record, owner и dependency.
- Выбрать критерий, который проверяет структура: comparable traffic и reversible data, а не обещание результата.
- Сохранить evidence как id окна и named fields; не приписывать им фактические значения или эффект.
- Добавить контрпример с конкретным stop reason и проверить его public export так же буквально, как accepted case.
- Выпустить только stop или synthetic hand-off, сохранив open question, boundary и effect no-system-change.
Ответственность держится на имени, а не на роли «команда»
Decision owner в fixed record — fixed-transition-reviewer. Это не реальный человек и не организационная рекомендация. Его функция — показать, что решение нельзя спрятать в безличное «мы откатим». Рядом есть условие trigger и два состояния возврата. Вместе они образуют предмет review. Если owner отсутствует, модель должна бы остановиться так же, как при пустом trigger; в текущем case этот дефект проверяется в одной ветке, чтобы не делать учебный пример притворной системой управления.
Слово cutover легко разрастается до обещания, которое input не поддерживает. Наш package не берёт его как доказательство, что route можно переключить. Он использует более строгую внутреннюю форму: route set является literal, а не вызовом к DNS или load balancer. Поэтому нельзя переносить название этапа в status. Решение определяется только тем, что явно лежит в input и что функция умеет вернуть.
Как вычитывать текст перед hand-off
Сначала заменить в выводе все крупные слова полями literal. «Готовы к cutover» не выживает: такого поля нет. «Есть synthetic hand-off при complete record» выживает. Затем проверить, не утекло ли реальное время: у record нет clock, значит «в течение пятнадцати минут» будет ложным claim. Наконец, проверить глаголы: «перевели», «восстановили», «проверили сервис» запрещены. Package ничего не делает за пределами памяти Node.
RFC 2119 особенно полезен на этом проходе. MUST можно применить к обязательному полю review card; MAY — к следующему synthetic counterexample. Но слова не должны маскировать власть над окружением. Если правило нельзя проверить через public export на named literal, оно не должно звучать как gate. Эта редактура делает полевую заметку короче и надёжнее: читатель видит, где заканчивается наблюдение и начинается задача для другого, отдельно определённого процесса.
Ограничения и следующий шаг
Evidence loop не заменяет репетицию с реальными системами, не подтверждает recovery procedure и не доказывает, что metrics достаточно. Он также не говорит, что выбранный trigger хороший, а route — важный. Google SRE Book, используемая здесь только для понятия положительной обратной связи, не превращает fixed mismatch в предсказание каскада. Модель учит остановиться на неизвестном, но не учит устранять неизвестное без дополнительных данных.
Следующий шаг — создать новый named literal с одним изменённым условием и выполнить тот же review. Например, сохранить control/candidate boundary, но удалить reconciliation, чтобы убедиться, что output остаётся fail-closed. Это расширяет библиотеку контрпримеров и делает language точнее. Не следует на основании accepted case начать миграцию, обещать rollback или публиковать real inventory: любой из этих актов требует иных входов, полномочий и evidence, которых в P101 нет.
Проверяемые источники
- Kubernetes Documentation: Deployments — версия: Kubernetes v1.33 versioned documentation snapshot, 23 April 2025. Источник ограничивает смысл rollback Deployment его Pod template; это поддерживает требование называть объект rollback отдельно. Граница: Не поддерживает claims о traffic, data, кластере или завершённой миграции.
- Google SRE Book: Addressing Cascading Failures — версия: Wayback immutable capture, 23 January 2025 16:42:19 UTC. Источник используется только для понятия каскадной положительной обратной связи и пользы раннего stop condition. Граница: Не устанавливает реальные условия инцидента или пороги evidence.
- RFC 2119: Key words for use in RFCs to Indicate Requirement Levels — версия: RFC 2119, March 1997, immutable RFC text. Источник определяет requirement keywords, применённые лишь к проверяемой структуре synthetic review card. Граница: Не делает текст операционным распоряжением.