1. Legacy — це зона невизначеності
Коли люди вперше чують слово legacy, їм майже завжди хочеться уявити стародавній моноліт кольору мамонтового лайна, який компілюється тільки в повний місяць. Насправді це не про вік і не про мову: legacy починається там, де поведінка системи погано зафіксована, ownership розмитий, а ціна невдалого зміщення неприємно висока.
CashFlow Dashboard чудово підходить під це визначення — і підходить не через старий стек (Java 8, Spring Boot 2.7.18, PostgreSQL 12, Gradle 7.6.4). Сам по собі старий стек ще не робить проєкт legacy. Legacy тут робить інше: Commerce OS уже залежить від обчислень дашборда, MRR роз’їхався на 8%, частина правил живе в коді, частина — в застарілій документації, тести покривають проєкт нерівномірно. Ви поки не знаєте, яке зміщення безпечне, а яке тихо завалить довіру до цифр у звітах.
На практиці change risk зростає не сам по собі, а коли сходяться одразу три фактори:
- потік важливий для бізнесу — гроші, підписки, звіти, повернення;
- поведінка погано зафіксована — мало тестів, документація суперечлива, припущення неясні;
- область зміни розповзається по кількох модулях, конфігах, інтеграціях.
Склалися всі три — перед вами вже не «шматок старого коду», а потенційна міна.
Гарна аналогія тут — старий будинок. Якщо ви зайшли в нього, перше завдання не в тому, щоб обирати колір стін: ви шукаєте несівні конструкції, дивитеся, куди підведено електрику, і чому одні двері відчиняються тільки ногою та з молитвою. У legacy так само: перш ніж рухати меблі, знайдіть несівні стіни.
У legacy-системі перше питання звучить не «як тут усе влаштовано?», а «що тут небезпечно чіпати без доказів?».
2. Від «поясни проєкт» до «що небезпечно чіпати»
На ранніх рівнях ви вже робили codebase discovery: будували карту проєкту — мови, фреймворки, каталоги, entry points, команди запуску, модулі. Для legacy цього вже мало: гарний огляд структури не відповідає на головне практичне питання — де змінювати код спокійно, а де спершу зняти взуття, каску і, можливо, гордість. І різницю тут корисно побачити не як теорію, а як зміну кута зору:
| Звичайний codebase discovery | Legacy discovery |
|---|---|
| Головне питання: як влаштований проєкт? | Головне питання: що небезпечно змінювати? |
| Корисний результат: карта модулів і entry points | Корисний результат: критичні потоки, risky areas, test gaps, unknowns |
| Невизначеності вважаються тимчасовим шумом | Невизначеності фіксуються як артефакт |
| Після огляду можна швидко перейти до реалізації | Після огляду спершу будується картина ризиків |
| Вихід: CODEBASE_INVENTORY.md | Вихід: discovery-note, чорновик RISK_MAP.md, current-state notes |
Це важливий зсув. Якщо раніше хороша відповідь Claude звучала як «проєкт складається з модулів subscriptions, billing, payments, reporting», то тепер хороша відповідь має звучати інакше: «mrr-engine впливає на гроші і звіти, тестів мало, правила pause/resume неочевидні, обчислення дати використовує різні timezone-гілки — область поки не можна змінювати без додаткової фіксації поведінки».
Зверніть увагу, структура проєкту при цьому нікуди не поділася — вона все ще потрібна: CODEBASE_INVENTORY.md залишається базовою картою. Але в legacy поверх неї лягає другий шар — risky areas, unknowns, current-state observations, — і з нього виростає рішення, що безпечно змінювати. Тому я прошу Claude не «пояснити репозиторій», а повернути критичні runtime-потоки, зони change risk, наявні тести і список незрозумілого.
3. Evidence anchor перетворює слова на знання
На цьому етапі в багатьох з’являється дуже людське бажання: отримати від Claude красиве, впевнене зведення, кивнути і піти далі. Ось тут і спрацьовує класична пастка legacy. Впевнений тон ще не знання. Знання починається там, де в кожного важливого висновку є evidence anchor: прив’язка до коду, тесту, конфіга, логу або команди.
Уявіть, що Claude каже: «Paused subscriptions залишаються в active MRR». Тут ви не відповідаєте «ага, переконливо». Ви запитуєте: у якому файлі, у якій функції, чи є тест, що каже job, який запускає розрахунок, і чи немає документа, який цьому суперечить. Головне — перевірюваність без телепатії.
Ось так може виглядати маленький фрагмент нормального discovery-звіту:
## Підсистема: mrr-engine
**Призначення:** щоденний розрахунок MRR-знімка.
**Докази:**
- `mrr-engine/MrrCalculator.java:42` — вхідна точка `computeDailySnapshot`
- `jobs/MrrSnapshotJob.java:55` — плановий запуск за розкладом
- `tests/integration/MrrSnapshotIT.java` — всього 3 інтеграційні сценарії
**Неясно:**
- як враховується pause/resume підписки
- чи всюди використовується UTC під час обчислення дати знімка
Сила такого фрагмента не в красі, а в чесності: підтверджене і незрозуміле стоять поруч, і незрозуміле не сховане. У legacy невідоме не ганьба, а результат роботи — значно гірше, коли через бажання «виглядати впевнено» сумніви стирають.
Корисно тримати в голові ще одну фразу: README — хороший свідок, але не суддя. Source of truth — у коді, тестах, конфігу та поведінці. Якщо BILLING_RULES.md говорить одне, а MrrFormulas.java робить інше — вірте не красивому файлу, а тому, що легше перевірити.
4. Discovery-сесія без шкоди проєкту
Дуже спокусливо відкрити legacy-репозиторій і через п’ять хвилин попросити Claude «заодно підчистити пару дивних місць». Не треба. У discovery-сесії ваше завдання — бачити, а не лагодити. Тому вона починається в режимі лише читання — plan mode або його еквівалент, якщо у вашій версії Claude Code режим називається інакше. Команди змінюються, навичка залишається: спершу дослідження без правок.
Перед початком корисно зробити кілька дуже нудних, але рятівних речей:
git status # переконуємося, що випадкових правок немає
./gradlew tasks # дивимося, які команди проєкт взагалі вміє виконувати
git log --oneline -5 # швидко перевіряємо, чим проєкт жив у останніх комітах
Так, це не найкінематографічніший набір команд. Зате він заземлює. Для CashFlow Dashboard це особливо корисно: частина болю тут не в бізнес-логіці, а в тому, що половина документації не збігається з реальним способом запуску.
Якщо ви використовуєте Workflow Kit, хороша допомога тут — окремий read-only subagent, наприклад discovery-explorer. Його сенс не в тому, щоб «магічно все дізнатися», а в тому, щоб винести важке читання файлів в окреме вікно контексту і повернути перевірюване зведення:
---
name: discovery-explorer
description: Read-only агент для legacy-discovery. Шукає підсистеми, потоки, тести й неясні зони. Для кожного висновку дає докази.
tools: Read, Grep, Glob, Bash(git log:*), Bash(./gradlew tasks:*)
---
Зверніть увагу на дві речі. Тут немає Edit і Write. І навіть Bash обмежений read-only сценаріями. Це і є правильна архітектура довіри: discovery-agent не «допоможе» правкою коду. Його справа — шукати, а не лікувати. А змішування дослідження з реалізацією найчастіше і змушує людей лагодити симптом до того, як зрозуміло систему.
5. Запит до Claude, який дає карту ризику
Якість discovery сильно залежить від формулювання запиту. Поганий запит зазвичай звучить так: «Поясни цей проєкт» — Claude у відповідь видасть щось гладке, а ви потім довго з’ясовуватимете, де там факти, а де просто стилістика. Запит має одразу вимагати структуру, evidence і чесне поводження з невідомим.
Гарна базова формулювання може виглядати так:
Проаналізуй цей репозиторій як legacy-систему.
Поверни:
1. ключові підсистеми;
2. критичні runtime-потоки;
3. зони підвищеного change risk;
4. наявні тести;
5. неясні припущення;
6. докази для кожного висновку.
Зміни в код не пропонуй і файли не редагуй.
Такий запит робить одразу кілька корисних речей: задає контекст саме як legacy discovery, фіксує формат, змушує виділити unclear assumptions і явно забороняє правки.
Якщо після цієї відповіді ви бачите красиві фрази без опор, заходьте другим, жорсткішим колом: «Які файли це підтверджують?», «Де саме видно цей runtime flow?», «Чи є тест, який покриває цю поведінку?», «Що у твоїй відповіді — гіпотеза, а що факт?». Звучить трохи менш дружньо — зате дуже дружньо до вашого майбутнього часу і нервів.
Тут корисно пам’ятати ще одну тонку, але важливу річ: discovery-відповідь не зобов’язана бути довгою — вона зобов’язана бути структурованою. Коротке зведення з п’ятьма сильними висновками і трьома чесно зафіксованими unknowns майже завжди цінніше за три сторінки архітектурної прози — якщо за кожним висновком можна відкрити файл.
6. Перший discovery-звіт по CashFlow Dashboard
Коли первинні відповіді вже зібрані, не потрібно одразу стрибати у велику документацію. Корисніше невеликий discovery-note: сирий робочий чорновик із підтвердженими знахідками, unknowns і першими натяками на ризик. З нього пізніше виростуть ARCHITECTURE_CURRENT.md, RISK_MAP.md і інвентар поведінки — і не доведеться витягувати все заново. Не ідеально. Зате чесно і перевірювано.
Наочно це можна представити так:
flowchart TD
A[Legacy-репозиторій] --> B[Читання коду, тестів, конфігів, логів]
B --> C[Підтверджені факти]
B --> D[Неясні припущення]
C --> E[Discovery-note]
D --> E
E --> F[Черновик RISK_MAP.md]
Для CashFlow Dashboard розумний перший прохід зазвичай починається не з усіх папок одразу, а з кількох гарячих зон:
- mrr-engine — там спливло розходження по MRR;
- payments і retry-логіка — проблеми з платежем майже завжди б’ють в active/churn стан підписки;
- конфіги та feature flags — крихка конфігурація любить ламати систему тихо і буденно;
- папка legacy/, якщо вона є і виглядає як місце, звідки проєкт давно хотів, але так і не зміг з’їхати.
Невеликий стартовий шаблон discovery-note може бути таким:
# Заметка legacy-discovery
## Підсистема
mrr-engine
## Що підтверджено
...
## Які тести є
...
## Що неясно
...
## Чому це ризик
...
Тут не потрібно намагатися бути письменником — потрібно бути людиною, якій завтра доведеться пояснювати команді, чому саме ця зона потребує обережності. Якщо для mrr-engine у вас уже є вхідна точка, scheduled job, число тестів і чесний список неясностей про pause/resume та timezone — ви вже не «дивитеся у старий репозиторій». Ви проводите legacy discovery як інженер.
І ось у цей момент змінюється оптика. Репозиторій перестає бути абстрактним набором папок — стає картою зон довіри і недовіри. Десь є опора: зрозумілий flow, виразний test surface, узгоджена поведінка. Десь туман: висока бізнес-важливість, мало перевірок, дивні правила, суперечності між кодом і документами. Із цього туману й народжується справжня робота з legacy — не «зробити красиво», а зрозуміти, що тут взагалі безпечно робити.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ