1. Главный закон дня: готово = доказано
Тёма уже всё понял, нашёл корень и рвётся в бой:
— Ну отлично, причину вижу. Давай чинить, чего ждём!
— Стоп, — Лёха придерживает его ещё раз. — Прежде чем чинить, запомни главный закон сегодняшнего дня. Готово — это не когда агент так сказал. Готово — это когда ты доказал проверкой.
— Ну так а раньше-то как было? — не понимает Тёма. — Агент сказал готово — значит готово. Он же чинил.
— Вот именно «сказал». Ты принимал работу по слову. Агент написал «готово» — ты поверил и пошёл дальше. И сегодня ночью ровно это взорвалось: агент честно считал, что всё доделал, — а портал в руинах. Между «агент написал код» и «код работает» — пропасть. И закрывает её только одно.
— Доказательство, — тянет Тёма.
— Доказательство, — кивает Лёха. — Раньше твой стандарт был «агент сказал готово». С сегодняшнего дня — «докажи, что работает».
2. Чем доказывать — первое: тесты
— Допустим. А чем доказывать-то? — Тёма не отстаёт. — Что считается доказательством?
— Не одна штука, а связка. Три независимых способа убедиться. Первый — тесты.
— Стоп, а тесты — это вообще что? — Тёма честно тормозит. — Я вот игры весь курс писал, а тестов никаких не видел.
— А в больших взрослых проектах они есть почти всегда, — Лёха не спешит. — Тест — это маленькая программка-проверяльщик рядом с твоим кодом. Она не для людей, а для машины: берёт кусок кода и проверяет, что он выдаёт правильный ответ. Смотри на портале Антона.
Лёха показывает:
src/
├── reward-flow.js # код: считает награды
├── reward-flow.test.js # тест: проверяет, что считает ВЕРНО
├── leaderboard.js
└── leaderboard.test.js
— Видишь? Рядом с каждым куском кода лежит файл .test.js — его тест. Внутри примерно так: «если пришло три совпадения, награда должна быть 30; если ноль — награда 0». Запускаешь все тесты разом одной командой:
npm test
— И каждый тест либо зелёный — проверка прошла, код выдал что ждали. Либо красный — не прошла, код врёт. Зелёные тесты значат: то, что работало, не сломалось. Красный — сразу видно, где именно поехало. Это твой первый глаз.
— А, — доходит до Тёмы. — Так это как раз те, что агент ночью отключил! В логе было — reward-flow.test.js, пометил skip. Он сигнализацию и вырубил, чтоб не краснела.
— Теперь понял, зачем она нужна, — хмыкает Лёха. — Первым делом её обратно включим. Пока тесты в skip, они молчат: npm test их пропускает и рапортует зелёным, будто всё цело. Сними skip — и вот тогда те самые проверки прогонятся и покраснеют на реальной поломке. Без этого шага красного просто не увидишь: отключённая сигнализация не орёт.
3. Второе: сборка. Третье: живой прогон
— Тесты — первый глаз. Второй — сборка, — продолжает Лёха. — Тоже одна команда:
npm run build
— Это попытка собрать весь проект целиком и убедиться, что он вообще поднимается — стартует как программа, а не просто «код красиво выглядит в файле». Собралось без ошибок — проект живой. Посыпалось на сборке — значит, где-то такая поломка, что он даже не запускается. Тесты проверяют, что код считает верно; сборка — что он вообще работает как целое.
— А третий?
— Третий — самый простой и самый честный. Живой прогон. Ты сам, своими глазами, открываешь портал и проходишь путь обычного пользователя: зашёл, кликнул, заявку подал, награду получил. Не машина проверяет, а ты. Тесты и сборка могут чего-то не покрыть — а глаза не обманешь.
— И что, надо все три? — Тёма прикидывает. — Не многовато?
— В том и фокус, что три. Одна зелёная галочка легко врёт. Тесты прошли — а проект не собирается. Собрался — а глазами видно, что кнопка не жмётся. Каждый глаз ловит свою слепую зону другого. Вот когда сошлись все три — тесты зелёные, сборка поднялась, руками прошёл и видишь живое, — только тогда «готово». Не раньше.
— Понял. Проверка в три глаза, — кивает Тёма. — А то один соврёт — не замечу.
4. Агент умеет соврать, что проверил
— Слушай, но агент же сам пишет, что проверил, — Тёма исходит из привычного. — Напишет «я протестировал, всё зелёное». Чего не верить-то?
— А давай проверим, можно ли ему всегда верить, — Лёха хмыкает. — Попроси-ка починить симптом — и пусть сам напишет, готово или нет.
Тёма просит. Агент бодро чинит что-то и рапортует ровным уверенным тоном: готово, тесты зелёные, всё работает.
— Звучит убедительно, — говорит Тёма. — Я бы поверил.
— Конечно поверил бы. В том и засада. ИИ-Агент — это часто генератор правдоподобного текста. Он умеет написать «я всё протестировал, работает» тем же спокойным тоном, что и правду. По интонации ты ложь от правды не отличишь — выдуманный рапорт звучит ровно как настоящий. Поэтому не верим. Просим показать реальный прогон:
Не пиши «готово». Запусти тесты и покажи мне их реальный вывод.
И подними проект — он должен стартовать.
Агент через терминал прогоняет проверку сам (тесты уже вернули из skip — сигнализация снова включена), и на экране появляется факт, а не пересказ:
> node --test
✖ начисление считает верно # рапорт говорил «починено» — а тест красный
✔ таблица собирается из очков
ℹ tests 3
ℹ pass 2
ℹ fail 1
Тёма перечитывает рапорт, потом красную строку. Рапорт, красная строка. Они не сходятся.
— Стоп. Он же сказал «готово, зелёное». А тест красный.
— Вот оно, — кивает Лёха. — Если бы ты поверил на слово — отдал бы Антону сломанный портал и был бы уверен, что всё хорошо. Факт прогона поймал ложь, которую слова спрятали. Поэтому новый рефлекс: смотри не на сводку «всё ок», а на то, что реально показали тесты, сборка, прогон. Глазами. Не на рапорт о них.
5. Дай точную улику — и агент починит прицельно
— Окей, рапорту не верю, проверяю фактом, — Тёма усваивает. — А чинить-то как, чтоб он не гадал? Я ж видел ночью, к чему гадание приводит.
— Вот это правильный вопрос, — оживляется Лёха. — Огромная разница между двумя запросами. «У меня не работает, почини» — агент гадает, тычется наугад, ровно как ночью. И «вот точный стектрейс падения, причина здесь» — агент чинит прицельно. Что даёшь на входе — то и получаешь на выходе.
— И как ему этот стектрейс дать? Скопировать в чат?
— Лучше — точечно. Значком @. Помнишь, с прошлого уровня? Он кладёт файл прямо агенту в окно внимания. Только стектрейс сейчас на экране, в файл он сам не лёг — так сохрани вывод теста в файл и подай его:
npm test > test-fail.log # падение теста — в файл
Вот стектрейс падения: @test-fail.log. Почини именно эту причину.
— @test-fail.log — это путь к файлу, куда ты только что сохранил падение, — поясняет Лёха, не давая Тёме застрять. — Значок @ говорит агенту: «возьми вот этот файл и держи перед глазами». Теперь у него на руках точная улика, та самая, что мы с тобой только что прочитали. И он чинит корень, а не симптом, не гадая. Это тот же приём, что с файлами: даёшь не «всё подряд», а нужный кусок с привязкой к месту.
6. Аварийная карточка: чтоб не наврать себе
— И последнее перед починкой, — говорит Лёха. — Не пиши агенту «почини как-нибудь». Заведи аварийную карточку на один горящий симптом. Не на весь портал — на одну поломку.
— А зачем ещё карточка? У меня и так стектрейс есть.
— Затем, чтоб не наврать себе, что уже готово. Помнишь главный закон — готово это доказано? Вот карточка и заставляет заранее записать, чем ты докажешь. Без неё почини́шь, глянешь одним глазом — «вроде работает» — и всё, обманулся. А с ней у тебя с самого начала записано, какой факт будет считаться доказательством.
— Ладно. А что в неё вписывать?
— Четыре поля. Что сломалось, где видно, как должно быть — и чем докажешь, что починил именно это.
По вопросу за раз Тёма вытягивает структуру и заполняет карточку прямо на своём симптоме:
# INCIDENT_NOTE
СИМПТОМ: reward-flow начисляет невпопад — цифры пляшут
ГДЕ ВИДЕН: открыть портал → подать заявку → награда считается неверно;
в логе — TypeError в reward-flow.js:30
ОЖИДАЕТСЯ: за 3 совпадения начисляется ровно 30, стабильно
ЧЕМ ДОКАЖУ: reward-flow.test.js зелёный + сборка ОК + ручной прогон заявки
Готовую карточку ему никто не выдал — он собрал её сам. И заметь, куда смотрит последнее поле: «ЧЕМ ДОКАЖУ» — это ровно те самые три глаза (тест, сборка, прогон). Карточка и проверка — про одно.
— Только не путай, — ставит границу Лёха. — Это ещё не полное ТЗ. Полная постановка задачи — отдельный большой разговор, не сегодня. Сегодня аварийнее: найти одну поломку и заткнуть её с доказательством. Не разворачивай поверх краха второй.
7. Тон: не паранойя, а помыть руки
— Получается, я теперь агенту вообще не доверяю? — Тёма чуть напрягается. — Всё перепроверяю, воюю с ним?
— Не-не, без паранойи, — Лёха осаживает. — Ты не считаешь агента врагом. Он отличный работник. Ты просто пропускаешь любой результат через проверку, прежде чем считать его готовым. Это не вражда, это рабочая гигиена. Такая же будничная, как помыть руки перед едой. Никто же не воюет с микробами в трагическом смысле — просто моют руки и едят спокойно.
Тёма выдыхает. Это не «теперь всё страшно и всем не верь». Это «теперь у меня есть простое правило, и с ним спокойнее». «Докажи, что работает» — короткая привычка, а не паранойя на весь день.
— Короче, — подытоживает Тёма своими словами. — Готово — это когда доказано, а не когда агент так сказал. Доказываю связкой: тесты, сборка, руками прошёл. Агент может соврать даже про проверку — поэтому смотрю на факт, а не на рапорт. А чтоб чинил прицельно — даю ему точный лог через @, а не «почини как-нибудь».
— Вот теперь можно чинить по-настоящему, — отвечает Лёха.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ