Когда PR вроде нормальный, но всё равно кажется неправильным

Если вы уже несколько недель выпускаете код с AI, это ощущение вам, скорее всего, знакомо.

Открываете pull request. Код достаточно чистый. Имена нормальные. Тесты есть. Ничего явно не сломано. И всё же что-то в нём не так.

Возможно, граница ответственности слегка размыта. Возможно, contract подразумевается, но не сформулирован явно. Возможно, happy path покрыт, а настоящее бизнес-правило по-прежнему живёт у кого-то в голове. Риск ощущается, даже если вы не можете указать на одну катастрофическую строку.

Вот в чём теперь новая проблема ревью.

Большинство команд до сих пор прогоняют AI-assisted coding через старый workflow: написать prompt, сгенерировать diff, открыть PR и попросить старшего инженера настолько внимательно просмотреть код, чтобы поймать сломанные invariants, пропущенные edge cases, архитектурный дрейф и скрытые риски.

Эта модель имела смысл, когда люди сами писали почти всю реализацию. Она имеет куда меньше смысла теперь, когда модель за один проход может сгенерировать реализацию, первый набор тестов, схему и даже заготовки для contract.

В этот момент построчное ревью кода перестаёт быть местом, где внимание старшего инженера даёт максимальный рычаг.

Настоящий вопрос больше не звучит как: “Эта функция выглядит разумно?”

Настоящий вопрос теперь такой: “Мы вообще правильно определили поведение, границу и invariant до того, как эта функция появилась?”

В этом и состоит инверсия workflow, которую создаёт AI. Code review не исчезает. Но центр тяжести смещается выше по цепочке. В эпоху AI ревью кода превращается в ревью спецификаций.

Почему этот сдвиг ощущается настолько непривычно

Долгое время большинство инженерных команд считали спецификации вспомогательным материалом.

Код был настоящим продуктом. Doc comment был лишь подсказкой. ADR давал контекст, если вообще находилось время его прочитать. Схема считалась “просто валидацией”. Файл Gherkin считался приятным дополнением, если кто-то вообще поддерживал его в актуальном состоянии.

Эта иерархия распадается.

Если LLM может быстро и многократно превращать спецификацию в артефакты реализации, спецификация перестаёт быть вторичной. Она становится исходным объектом, из которого выводится остальная система.

И это меняет место, где ошибки дешевле всего ловить.

Если спецификация расплывчатая, модель может выдать красиво структурированную реализацию неправильной вещи. Она даст вам чистый код, правдоподобные тесты и ложное чувство уверенности. Даже сильное ревью кода может не заметить настоящую проблему, потому что баг не в синтаксисе. Баг в замысле.

Именно поэтому этот момент одновременно такой коварный и такой важный. AI упрощает выпуск убедительно выглядящего результата. И одновременно делает куда опаснее небрежность в том, что именно вы попросили.

Если спецификация точная, ограниченная и проверяемая, всё становится проще. Реализацию делать проще. Валидацию делать проще. Ревью делать проще. CI становится сильнее.

Поэтому лучшая человеческая работа по ревью смещается от ручного аудита каждой ветки выполнения к тому, чтобы ужесточать артефакт, который вообще определяет поведение этих веток.

Спецификация не обязана быть гигантским документом с требованиями

Когда люди слышат слово “спецификация”, они часто представляют раздутый документ, который никто не хочет писать и которому никто не верит уже через шесть недель.

Но важно не это.

В практическом AI-assisted workflow спецификацией является любой артефакт, который достаточно точно задаёт ожидаемое поведение, чтобы по нему можно было делать генерацию и enforcement.

Это может быть:

  • Markdown ADR с описанием boundary rule
  • Zod-схема, задающая форму внешнего ввода
  • сигнатура функции с чётким doc comment
  • сценарий Gherkin, который фиксирует наблюдаемое поведение
  • блок contract с предусловиями и постусловиями
  • модель reducer или таблица переходов состояния

Ничего из этого не обязано быть тяжеловесным. Нужно лишь, чтобы всё было достаточно ясно и чтобы инструменты могли извлечь из этого реальную пользу.

Вот какой порог действительно важен. Полезная спецификация не просто читаема для людей. Она должна быть такой, чтобы система вокруг codebase могла с ней работать.

Как теперь выглядит сильное ревью

В старой модели старший инженер тратит энергию на вопросы вроде:

  • эта реализация чистая?
  • не пропустил ли автор edge case?
  • достаточно ли сильны эти тесты?
  • нарушает ли этот import границу?

Эти вопросы по-прежнему важны. Просто это уже не самые ценные первые вопросы.

В workflow, где спецификация первична, более ценные вопросы выглядят так:

  • этот contract вообще корректен?
  • задаёт ли схема настоящую границу?
  • полны ли бизнес-правила?
  • достаточно ли точен ADR для enforcement?
  • выражают ли перечисленные свойства реальную семантику?

Это лучшие вопросы для ревью, потому что один хороший ответ сразу улучшает несколько артефактов.

Если вы делаете расплывчатый ADR точнее, вы одним движением улучшаете архитектурное правило, ориентиры для реализации и enforcement в CI.

Если вы чините слабую схему, вы одним движением улучшаете runtime-валидацию, type inference и качество генерации кода.

Если вы уточняете contract, вы одним движением улучшаете реализацию, тесты и устойчивость к проверке через mutation testing.

В этом и разница в рычаге. Вы больше не проверяете выходы по одному. Вы ревьюите то, что вообще формирует эти выходы.

Почему традиционное ревью кода начинает трещать

Традиционное ревью кода исходит из того, что главные авторы - люди, а ревьюер по готовому коду проверяет качество человеческого мыслительного процесса.

С AI это предположение слабеет каждую неделю.

Модель может за секунды выдать пятьдесят правдоподобных строк. И ещё пятьдесят так же быстро. И ещё пятьдесят после этого. Если весь ваш процесс держится на том, что ревьюер вручную заметит семантический дрейф, спрятанный внутри этого потока, поверхность ревью растёт быстрее, чем когда-либо сможет расти человеческое внимание.

Из этого складывается плохое равновесие:

  • генерация кода ускоряется
  • diff становятся больше или идут чаще
  • усталость ревьюеров растёт
  • уверенность в семантике падает
  • команды начинают компенсировать это vibes, интуицией и “looks good to me”

Это не стратегия масштабирования. Это накопленный риск с хорошим форматированием.

Гораздо разумнее сначала уменьшить сам объём субъективного ревью, который вам вообще нужен. Вкладывайте больше смысла в детерминированные, пригодные для ревью спецификации. А затем дайте машине проверять, что код по-прежнему соответствует этому смыслу.

CI делает это реальным

Такая инверсия workflow работает только тогда, когда спецификация привязана к enforcement.

Иначе вы просто переименовываете документацию и надеетесь, что теперь к ней будут относиться серьёзнее.

Смысл в том, чтобы сделать спецификацию операционной.

Это значит, что:

  • архитектурные решения компилируются в правила зависимостей
  • схемы определяют runtime-safe и type-safe границы
  • contracts порождают исполняемые проверки
  • списки свойств управляют генерацией тестов
  • критическая семантика превращается в merge gates

Когда это происходит, CI перестаёт быть пассивной системой сборки и становится механизмом, который удерживает реализацию в соответствии с замыслом.

Поэтому живые спецификации наконец становятся реалистичными и для обычных команд. Исторически документация сгнивала просто потому, что ни у кого не было времени вручную держать текст и код в синхроне.

AI меняет экономику написания и обновления этих артефактов. CI меняет экономику их enforcement.

Нужны оба. AI без enforcement даёт вам отполированный дрейф. Enforcement без хороших спецификаций даёт вам жёсткую путаницу.

Жёсткие проверки, мягкое ревью

И именно эта часть философии Autotomy кажется мне всё более правильной.

Идея проста: вынесите неоспоримые правила в жёсткие ограничения, а человеческому ревью оставьте те части, где действительно требуется суждение.

Это значит, что типы, схемы, contracts, правила зависимостей и deterministic checks берут на себя известные режимы отказа. Они запускаются каждый раз. Они не устают. Их не отвлекает красиво отформатированный diff. Им всё равно, написал код ведущий инженер или языковая модель.

После этого слой ревью становится меньше и лучше.

Вместо того чтобы тратить внимание старших инженеров на то, что система могла бы отклонить автоматически, вы тратите его на компромиссы, семантику, interface и архитектуру. Вы спрашиваете, правильна ли граница, честен ли contract, действительно ли замена удовлетворяет interface, становится ли систему легче менять или, наоборот, труднее.

Именно эта последняя часть особенно важна.

Один из самых полезных побочных эффектов подхода, где спецификация идёт первой, в том, что он толкает вас к более чистым точкам разреза. Если module можно заменить, пока он удовлетворяет contract и проходит проверки, вы перестаёте относиться к каждой реализации как к святыне. Вы начинаете проектировать под безопасную замену, а не под мучительное сохранение любой ценой.

Сдвиг тонкий, но он меняет то, как команды переживают рост. codebase перестаёт ощущаться как нечто, что можно только осторожно латать изнутри. Вместо этого codebase начинает ощущаться как система с явными стыками.

На самом деле это хорошие новости для старших инженеров

Этот сдвиг не делает суждение старших инженеров менее ценным. Он делает его более сфокусированным и более важным.

Старший инженер теперь наиболее ценен не как человек, механически прогоняющий синтаксический diff. Он наиболее ценен там, где снимается неоднозначность, выбираются invariants, проектируется interface и явно проговариваются tradeoffs.

Это означает, что больше времени уходит на:

  • написание точных ADR
  • определение contracts и схем
  • ревью семантических изменений вместо стилистических
  • решение, какие свойства заслуживают enforcement
  • превращение архитектуры в правила, которые можно проверять при merge

Это гораздо лучшее применение дорогого внимания.

Машина очень хороша в том, чтобы достраивать детали реализации. Но старшие инженеры по-прежнему намного лучше решают, что должно оставаться истинным, когда система испытывает нагрузку, меняется и масштабируется.

Вам не нужен гигантский rewrite процесса

Всё это может звучать масштабнее, чем есть на самом деле.

Вам не нужно запускать инициативу по формальным методам. Вам не нужно переставать выпускать изменения. Вам не нужно закапывать команду в процессах.

Начните с одного узкого сдвига: выберите один класс спецификаций и относитесь к нему как к первоклассному артефакту для ревью.

Практическая последовательность выглядит так:

  1. требуйте точных doc comments и схем на критических границах
  2. относитесь к изменениям в ADR как к предмету ревью старших инженеров
  3. генерируйте тесты и contracts из этих артефактов
  4. включайте enforcement архитектуры и дрейфа contract в CI
  5. понижайте вес комментариев только про стиль в пользу семантического ревью

Этого уже достаточно, чтобы изменить культуру.

Как только команда чувствует, что более качественные спецификации уменьшают дальнейшую турбулентность в ревью, этот цикл начинает усиливать сам себя. Ревью становятся точнее. Diff перестают пугать. Доверие растёт.

Настоящий стратегический сдвиг

Команды, которые выиграют с AI, будут не теми, кто просто быстрее генерирует код.

Ими будут команды, которые переносят человеческое внимание в самую узкую часть workflow, где отдача максимальна.

Эта часть и есть спецификация.

Когда спецификация становится первичным артефактом, код перестаёт быть единственным, что стоит ревьюить построчно. Он становится одним из выходов более дисциплинированной системы.

Вот в чём настоящий сдвиг.

Реализация по-прежнему важна. И очень. Но всё чаще самое важное решение в ревью принимается ещё до того, как реализация вообще появляется.

Именно поэтому в эпоху AI ревью кода превращается в ревью спецификаций.