JavaRush /Курсы /Claude code /Changelog-driven research для миграции

Changelog-driven research для миграции

Claude code
28 уровень , 2 лекция
Открыта

1. Память ИИ в миграции — плохой штурман

Когда вы работаете с обычной задачей в знакомом коде, память ИИ часто выручает: напомнит синтаксис, подкинет шаблон теста. Миграция — другая территория: важны не общие паттерны, а точные изменения между конкретными версиями. И тут память становится не источником истины, а источником соблазна.

Проблема в том, что модель помнит усреднённую картину: смешает советы для Spring Boot 3.0, 3.1 и 3.3 в один красивый рассказ, выдаст правдоподобное «обычно это решается так» — а ваш проект как раз тот случай, где «обычно» не работает. Она не злонамеренна. Просто очень хороший собеседник, а не официальный changelog.

Поэтому в миграции действует жёсткое правило: память ИИ — это старт гипотезы, а не доказательство. Claude говорит «в Boot 3 надо заменить javax на jakarta» — не готовая работа, а повод открыть migration guide и проверить, где проект попадает под изменение.

Сравните два запроса. Первый удобен, но опасен:

Расскажи, что ломается в Spring Boot 3,
и как нам быстро починить проект.

Второй похож на инженерную постановку:

Сравни наш текущий стек Boot 2.7.18 + Java 8
с target-стеком Boot 3.x + Java 21.
Используй только official migration guide и release notes.
Для каждого вывода укажи docs section и file path в repo.
Неподтверждённые места помечай как Unknown.

Во втором варианте вы не просите модель «быть умной» — вы просите её работать как аналитик. Это совсем другой режим. И именно он нужен нам в CashFlow Dashboard, где цена ошибки — не только красный build, но и тихо сломанный расчёт подписок.

2. Авторитетный источник, а не подсказка

Фраза authoritative source звучит солидно, а смысл у неё простой: источник, которому доверяют первым. Не единственный — первым. Технология принадлежит вендору — его guide, release notes и changelog стоят выше блогов, форумов и чужих пересказов.

Для миграции CashFlow этого особенно нельзя забывать, потому что меняется сразу несколько слоёв: Spring Boot, Java, Gradle, база данных. Один блог-пост не заменит четыре независимых журнала изменений.

Источник На какой вопрос отвечает Как использовать
Файлы проекта и Migration Current State Что у нас есть сейчас Это точка старта: версии, конфиги, API, CI, кастомные адаптеры
Official migration guide Что вендор считает обязательными изменениями Читаем как карту перехода между версиями
Release notes / changelog Что именно менялось от релиза к релизу Нужны, чтобы не пропустить накопленные изменения между minor-версиями
Build/test output Что реально ломается в вашем проекте Это окончательный практический судья, но не на сегодняшнем этапе
Блоги, форумы, ответы на StackOverflow Как другие люди объясняют проблему Полезны только после официальной документации, как вторичный слой

Обратите внимание на одну деталь. Сегодня мы ещё не запускаем целевой build и не собираем runtime evidence. И даже идеальный guide не докажет совместимость вашего кастомного JsonAdapter или старого UserType: документация показывает, где искать риск, но не обещает, что проект поведёт себя по учебнику. Проекты вообще редко читают учебники. Документация отвечает на «что должно измениться по правилам технологии», код — на «где это нас заденет»; полезное исследование дают оба ответа.

3. Как выглядит нормальный changelog-driven research

Услышав «читайте release notes», вы можете воспринять это как наказание за прошлые грехи. Но в правильном порядке они из бюрократии превращаются в рабочий инструмент: не читать всё подряд, а идти от текущего состояния к целевому стеку.

Нормальный цикл выглядит так:

flowchart TD
    A[Migration Current State] --> B[Official migration guide]
    B --> C[Release notes и changelog]
    C --> D[Сопоставление с repo]
    D --> E[Статусы: confirmed / assumption / unknown]
    E --> F[Research notes по миграции]

Сначала вы берёте уже собранный Migration Current State и фиксируете, откуда и куда идёте: для нас это Boot 2.7.18 → Boot 3.x и Java 8 → Java 21. Открываете guide именно для этого перехода. Читаете release notes промежуточных релизов — изменения размазаны по цепочке 3.0 → 3.1 → 3.2 → 3.3, а не собраны на одной странице.

Только затем начинается сопоставление с кодом. Не наоборот. Сначала понимание, что именно вы ищете, иначе grep выдаст классику: двадцать импортов, десять конфигов, пять тревожных мест и ноль понимания, какие из них важны.

Запрос здесь нужен не креативный, а дисциплинированный:

Используй official migration guide и release notes
для Boot 3.x и Java 21.
Сравни их с файлами build.gradle, application.yml,
gradle-wrapper.properties и src/main/java.
Верни только релевантные breaking changes,
затронутые файлы и места для ручной проверки.
Для каждого пункта укажи docs section и file path.
Не предлагай правки кода и не запускай build.

Обратите внимание на две вещи: вы ограничили набор файлов и запретили ранние действия — иначе исследование сползёт в «я уже всё понял, давайте сразу чинить». Нет, не давайте. Сегодня мы собираем доказательства. Код ещё успеет пострадать без нас.

4. Привязка breaking changes к коду CashFlow

Вот где начинается настоящая инженерная работа: построить мост между внешним источником и кодом CashFlow. Пока вы не показали пальцем — «этот пункт guide касается вот этого файла» — документация остаётся красивой пачкой слов.

Начинать удобно с формальных мест — с build.gradle:

plugins {
    id 'org.springframework.boot' version '2.7.18'
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
}

Это маленький фрагмент, но он уже многое говорит: эти две строки фиксируют стартовую площадку. Guide требует Java 17+ — вы уже знаете, где первое прямое несоответствие.

Дальше — кодовые сигналы. Классический маркер миграции на современный Spring — старые javax.* импорты:

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Subscription {
    @Id
    private Long id;
}

Есть в документации раздел про переход на jakarta.* — и этот код становится подтверждённой точкой соприкосновения guide и проекта. Не гипотеза. Факт: изменение касается этого файла.

Так же работает старый security-конфиг:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
    }
}

Даже если вы ещё не знаете новый стиль конфигурации, риск вы уже видите. Не потому, что «Claude где-то слышал», а потому, что guide говорит про изменения в Spring Security, а код использует устаревший подход.

Такие соответствия удобно держать в компактной таблице:

Что нашли в официальных docs Что ищем в проекте Где это видно в CashFlow
Переход javax.*jakarta.* Импорты javax.persistence, javax.validation Файлы: Subscription.java, BillingHistory.java
Новый baseline Java sourceCompatibility, CI-образ, toolchain Файлы: build.gradle, CI workflow
Изменения в Spring Security WebSecurityConfigurerAdapter, старые DSL-цепочки Файл: SecurityConfig.java
Конфигурационные изменения Старые ключи в application.yml Файл: src/main/resources/application.yml
Возможные проблемы с кастомными типами Самописные адаптеры и ORM-расширения Типы: JsonAdapter, MoneyUserType

Последняя строка особенно интересна. Она показывает, что не всё в исследовании обязано сразу стать подтверждённым фактом. Кастомный MoneyUserType может не иметь прямого описания в guide. Значит, он не превращается магически в «всё будет хорошо». Он уходит в зону Unknown и ждёт ручной проверки. Это как раз зрелое поведение, а не слабость. Слабость — это закрыть его фразой «наверное, совместимо».

5. Accelerators: docs lookup без режима оракула

Когда исследование становится длинным, появляется естественное желание ускориться. И это нормальное желание. В конце концов, мы пришли на курс по Claude Code не для того, чтобы вручную листать сто страниц документации, изображая монаха-схоласта. Но ускорение должно быть управляемым. Иначе вы просто замените слепую веру в память ИИ слепой верой в красивый инструмент.

Хороший docs lookup работает как хороший библиотекарь: быстро приносит нужную полку. Плохой — как знакомый, вбегающий с криком: «Я всё понял, давайте срочно переписывать!» В миграции второй тип особенно опасен.

Если у команды есть read-only MCP-сервер для поиска по документации, его конфиг может выглядеть примерно так:

mcpServers:
  spring-docs:
    command: npx
    args: ["-y", "@example/spring-docs-mcp"]
    permissions: read-only

Важна не марка пакета — имя сервера, плагина или утилиты у вас может быть другим. Стабильный принцип один: доступ только на чтение. Инструмент ищет и цитирует, а не меняет код, запускает recipe и «завершает миграцию за вас».

Хорошо, если границы зафиксированы и в CLAUDE.md migration-сессии:

## Режим исследования миграции
- source of truth: official docs + repo files
- каждый вывод = docs section + file path
- неподтверждённое помечать Unknown
- не предлагать edit, build и version bump без запроса

Это очень полезная маленькая дисциплина: она не даёт сессии уплыть в «ну я и так уже всё понял» — уплывает она ровно тогда, когда вы расслабились и решили, что проверять больше не нужно.

Если у вас есть Context7-like workflow, docs plugin или свой migration-assistant из Workflow Kit — относитесь к ним так же. Они ускоряют путь к разделу, собирают выжимку, подсвечивают файлы. Но вердикт «это confirmed» вы выносите, только увидев docs section и file path рядом, в одном кадре. Остальное — красивые рассказы.

6. Фиксация выводов: confirmed, assumption, unknown

Самое взрослое сегодня — даже не источники, а язык, которым вы фиксируете результат. Нет этого языка — команда путает факт, догадку и надежду. А в миграции надежда — плохой dependency manager.

Поэтому удобно использовать три статуса:

Статус Что означает Как с ним обращаться
confirmed Есть подтверждение и в docs, и в repo Можно включать в рабочие решения
assumption Есть сильная гипотеза, но не хватает части доказательств Нельзя считать завершённым выводом
unknown Ни docs, ни код не дают честного ответа без проверки Явно выносится в ручную верификацию

Здесь важно не смешивать этот словарь со словарём COMPATIBILITY_MATRIX.md. confirmed / assumption / unknown описывают качество знания на этапе research notes. Чуть дальше появятся статусы решений вроде needs code changes или needs manual validation. Если assumption или unknown так и не получили подтверждения, они не исчезают: в матрице становятся needs manual validation, а в плане доживают до Open risks.

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

## Миграция Jakarta
- confirmed: `javax.persistence` используется в `Subscription.java`
  и `BillingHistory.java`; см. раздел migration guide про Jakarta.
- assumption: автоматическая массовая замена импортов не затронет
  кастомные аннотации в модуле billing.
- unknown: совместимость `MoneyUserType` с новым стеком ORM.

Здесь всё устроено правильно: третий пункт нельзя «закрыть оптимизмом» — он честно висит незавершённым вопросом. И это хорошо: Unknown не признак слабости, а признак того, что вы ещё не начали играть в рулетку.

Если вынесете из лекции одну привычку — пусть будет эта: не заполнять пробелы уверенным тоном. В миграции тон голоса не доказывает ничего; доказывают официальная документация, конкретный файл в репозитории и честная пометка, где знание заканчивается. В тот момент, когда вы спокойно пишете Unknown вместо «наверное, нормально», исследование перестаёт быть гаданием и становится инженерной работой.

1
Задача
Claude code, 28 уровень, 2 лекция
Недоступна
Research notes через Claude Code
Research notes через Claude Code
1
Задача
Claude code, 28 уровень, 2 лекция
Недоступна
Конфигурация read-only docs lookup через MCP
Конфигурация read-only docs lookup через MCP
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ