JavaRush /Курси /Claude code /Діагностика середовища

Діагностика середовища

Claude code
Рівень 21 , Лекція 1
Відкрита

1. «Усе зламалося, допоможи» — це не задача

Коли проєкт не стартує, особливо ввечері, особливо після третьої чашки кави, дуже хочеться написати щось у дусі: «Claude, усе зламалося, допоможи». Фраза повідомляє про ваш настрій, але майже нічого — про стан проєкту. Claude не екстрасенс. Він не бачить ваш shell, не вгадує версію Java за вібраціями термінала і не читає лог силою волі. Йому потрібні спостережувані сигнали.

У контурі постачання це і є контракт: явний вхід, вузька задача, перевірювана відповідь. Ламається він там, де замість даних ви віддаєте чисту емоцію.

Порівняйте:

Погано:
«Проєкт не запускається. Полагодь».

Краще:
«Commerce OS не стартує локально.
OS: macOS 15, shell: zsh.
Версії Java і Node нижчі.
Команда запуску: docker compose up.
Нижче — останні 40 рядків логу backend.
Код поки не змінюй: спочатку назви ймовірну причину і команду для перевірки гіпотези».

У другому варіанті ви мислите як інженер: відокремлюєте симптом від здогадки, ставите межу — спочатку діагноз, потім правки. Факти замість туману — і Claude різко корисніший. Майже магія, тільки без магії.

2. Відтворюване середовище: «той самий результат», а не «приблизно»

У відтворюваного локального середовища дуже простий сенс: інша людина бере чисту копію репозиторію, запускає ті самі команди й отримує той самий результат. Не «приблизно так само». Не «ну в мене ж працює». Не «якщо спочатку перезавантажити Docker, потім вимкнути VPN, потім відкрити IDE з лівої ноги». Саме той самий — на тій самій послідовності кроків.

Для Commerce OS це особливо важливо, тому що стек у проєкту не іграшковий — Java 25, Spring Boot, Next.js, Node.js, PostgreSQL, Gradle плюс контейнерний baseline. Опишіть хоча б один шар розмито — і отримаєте не setup, а домашню тварину «працює тільки в автора».

Нижче корисно тримати просту карту того, що взагалі має збігатися.

Що має бути визначено Приклад для Commerce OS Як зрозуміти, що все гаразд
Версії середовища Java 25, Node 24, Docker, Gradle wrapper Команди версій дають очікуваний результат
Стан залежностей lockfile, wrapper, package manager Немає «випадково оновлених» залежностей
Конфігурація .env.example, profiles, порти Усі обов’язкові змінні перелічено
Команда запуску
docker compose up
як baseline
Проєкт стартує однією й тією самою командою
Мінімальна перевірка health endpoint, старт UI Після запуску є smoke-сигнал «живий»

Дуже корисно починати не з міркувань, а з короткого набору команд, який фіксує середовище на папері:

pwd                         # /projects/commerce-os
git status --short          # робоче дерево чисте
./gradlew --version         # Gradle 9.5.1, Java 25
node -v                     # v24.x.x
docker compose ps           # видно сервіси postgres / backend / frontend

Якщо у вас Windows і PowerShell, конкретні команди можуть відрізнятися. Але суть та сама: зафіксувати середовище так, щоб його обговорювали без «ну в мене начебто все нормально».

3. Зберіть evidence до запиту — коротко й по суті

Хороша діагностика майже завжди починається не з правок, а зі збору evidence. І цього evidence не має бути занадто багато: не потрібно кидати в Claude три тисячі рядків логу в надії, що він із любовʼю все перечитає. Краще короткий, але якісний набір сигналів. Зазвичай для локальної діагностики вистачає ось такої карти:

Сигнал Звідки взяти Навіщо він потрібен
OS і shell uname, echo $SHELL, властивості системи Деякі проблеми привʼязані до середовища, а не до коду
Git state git status, git diff --stat Щоб не лікувати проблему в уже зіпсованому дереві
Версії Java / Node / Docker java -version, node -v, docker --version Часте джерело несумісності
Команда відтворення точна команда запуску Без неї немає відтворюваного бага
Фрагмент логу останні 30–50 рядків навколо помилки Дає симптом і точку входу
Lockfile / wrapper state package-lock.json, pnpm-lock.yaml, gradle-wrapper.properties Допомагає побачити дрейф залежностей
.env.example сам файл Показує, які змінні взагалі очікуються

На практиці це виглядає приблизно так:

java -version
node -v
docker --version
docker compose logs backend --tail=40
grep -n "SPRING_PROFILES_ACTIVE" .env.example

Великий лог без контексту — важкий спосіб сказати «подивись сам». А останні 40 рядків навколо падіння — реальний діагностичний артефакт.

4. EVIDENCE_LOG.md — один журнал замість хаосу

Коли setup вередує, evidence розповзається: один лог у терміналі, другий на скриншоті, третя думка в голові, четверта в повідомленні Claude, загубленому після /clear. Рятує старий добрий EVIDENCE_LOG.md, який ви почали вести раніше в курсі. Сьогодні він потрібен не для debugging runtime-логіки, а для setup-evidence.

Хороша практика — не заводити новий файл із красивою назвою на кшталт SETUP_EVIDENCE.md, а додати блок у вже знайомий журнал. Тоді у вас зберігається одне джерело правди, і свіжу сесію Claude можна відкрити без танців із переказом минулого життя:

## Setup / докази відтворюваності
- ОС і shell: macOS 15 / zsh
- Git state: clean working tree
- Версії: Java 25, Node 24, Docker 28
- Команда запуску: docker compose up
- Спостережувана помилка: backend завершує роботу з кодом 1
- Фрагмент логу: Missing required property PAYMENT_PROVIDER_MODE
- README і `.env.example` перевірено: так

Такий блок розвʼязує одразу кілька проблем: він дисциплінує вас — ви не перескакуєте до правок раніше часу, — а Claude отримує структурований контекст замість потоку свідомості. А повернетеся завтра чи передасте задачу — залишиться не «здається, щось було з Docker», а нормальний слід розслідування.

5. Diagnostic request: спочатку діагноз, потім рішення

Одна з найкращих звичок у роботі з AI — вголос називати, яка зараз фаза. Потрібен діагноз — так і просіть діагноз, а не рішення. Інакше Claude кинеться «рятувати» проєкт, переписуючи конфіг, README і пів скрипта запуску, хоча справа може бути в одній пропущеній змінній або версії Node.

Корисний шаблон запиту:

Проаналізуй проблему локального запуску Commerce OS.
Код поки не змінюй.
Використовуй лише факти з логів, README, `.env.example` і версій середовища.

Поверни:
1. ймовірну першопричину;
2. які файли або команди це підтверджують;
3. мінімальні команди для перевірки гіпотези.

Запит залишає рішення за вами. Claude не грає в шамана, а працює як акуратний діагност.

Сам цикл у цьому місці дуже корисно тримати в голові як послідовність, а не як один «магічний» prompt:

flowchart TD
A[Зібрали сигнали] --> B[Записали setup-evidence в EVIDENCE_LOG.md]
B --> C[Попросили Claude пояснити причину]
C --> D[Перевірили одну гіпотезу]
D --> E{Підтвердилася?}
E -- так --> F[Виправили мінімальним diff]
E -- ні --> C

Зверніть увагу, що в цій схемі немає кроку «одразу попросили Claude полагодити все»: його немає не тому, що не можна, а тому, що це занадто дорогий шлях до випадкових змін.

6. Три джерела правди про запуск

Чимало setup-проблем народжуються не в коді, а в розсинхронізації документів і конфігурації: README обіцяє одне, package.json робить інше, docker-compose.yml живе власним життям. Ви чесно виконуєте інструкцію, отримуєте помилку — і підозрюєте Spring, Next.js, Gradle, ретроградний Меркурій і все інше.

Корисно дивитися на три джерела як на три версії однієї й тієї самої істини:

Джерело Що воно має повідомляти Що найчастіше не відповідає дійсності
README.md як установити й запустити проєкт команди застаріли, нові змінні не описано
package scripts / Gradle tasks що реально запускається назва команди змінилася, а README залишився старим
Dockerfile / docker-compose.yml як проєкт стартує в контейнерному baseline інший порт, інший env, інший entrypoint

Команди продубльовано ще й у CLAUDE.md? Це не четверте джерело правди, а привід перевірити узгодженість: CLAUDE.md не має сперечатися з README і scripts — інакше спочатку плутається Claude, потім решта.

Для такої перевірки можна дати Claude дуже конкретну задачу:

Порівняй README, package scripts і Docker/compose.
Знайди розбіжності в командах запуску, портах, змінних середовища
та очікуваних версіях Java і Node.
Поверни коротку таблицю: джерело | що обіцяно | що реально використовується.

Це якраз той випадок, коли Claude корисний не як «виправляч», а як помічник із звіряння: він бачить невідповідності між файлами, які ви легко пропустите, втомившись і читаючи README так, ніби там усе написано правильно.

7. .env.example замість секрету в чаті

Змінні середовища — класичне джерело setup-болю та випадкових витоків, коли в пориві відвертості ви вставляєте в чат половину свого .env. Так робити не треба. Узагалі. Ніколи. Навіть коли дуже хочеться «швиденько розібратися».

Правильний підхід тут простий: Claude майже завжди достатньо імен змінних і факту їх наявності або відсутності. Значення секретів не потрібні — важливо, що змінна очікується застосунком, але не згадана в .env.example.

Хороший безпечний приклад:

SPRING_PROFILES_ACTIVE=dev
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
PAYMENT_PROVIDER_MODE=sandbox
# PAYMENT_PROVIDER_API_KEY=заповнюється локально, не комітиться

Якщо лог випадково надрукував секрет, перед передачею його потрібно відредагувати: залиште структуру, замініть значення на ***. І ще: .env.example — частина reproducible setup. Обовʼязкової змінної там немає — проблема не лише у вас, а в усього проєкту, просто поки не всі про це знають.

8. Commerce OS не підіймається локально

Давайте зберемо все разом на одному реалістичному епізоді. Уявіть, що ви клонували Commerce OS і запускаєте baseline-команду docker compose up. База стартує, frontend чекає backend, а backend падає. Найшкідливіше зараз — попросити Claude «полагодити Spring Boot». Найкорисніше — зібрати мінімальне evidence:

docker compose up
docker compose logs backend --tail=40   # Missing required property 'PAYMENT_PROVIDER_MODE'
grep -n "PAYMENT_PROVIDER_MODE" README.md .env.example   # збігів немає
git status --short                      # робоче дерево чисте

Після цього ви фіксуєте setup-evidence в EVIDENCE_LOG.md, а потім надсилаєте Claude diagnostic request. Він побачить: проблема не в Java-коді й не в контейнері, а в config drift — застосунок вимагає PAYMENT_PROVIDER_MODE, але вона не задокументована й не потрапляє до локального середовища.

Далі важливий наступний крок: не бігти одразу комітити все підряд, а перевірити гіпотезу мінімальною командою — додайте локально безпечне dev-значення і повторіть запуск:

docker compose down
echo "PAYMENT_PROVIDER_MODE=sandbox" >> .env
docker compose up -d
curl -s http://localhost:8080/actuator/health   # {"status":"UP"}

Якщо smoke-перевірка проходить, у вас не «ніби допомогло», а ланцюжок доказів. Тепер доречний мінімальний diff: оновити .env.example, підправити README.md, за потреби синхронізувати CLAUDE.md. Невеликою читабельною зміною, а не генеральним прибиранням усього репозиторію під музику героїзму.

9. Ознаки завершеної діагностики

Дуже важливо вміти зупинитися в правильний момент. Діагностика завершена не тоді, коли ви втомилися і не тоді, коли Claude написав «root cause found». Вона завершена, коли ви можете назвати першопричину, показати evidence, дати команду перевірки та пояснити, як інша людина відтворить виправлений setup без усних заклинань.

По суті, хороший фінал такої задачі виглядає так: у EVIDENCE_LOG.md є блок setup-evidence, README і приклад env-конфігу синхронізовано, baseline-команда відпрацьовує однаково, smoke-сигнал підтверджує, що сервіс живий. Тут Claude перестає грати в вгадування, а ви — жити в режимі «тільки нічого не чіпайте, воно заведено».

І ось це вже дуже хороша база для будь-якої подальшої інженерної роботи: локальний setup перестає бути особистим ритуалом і стає відтворюваним контрактом — таким, що переноситься в CI job без переосмислення правил.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ