My Architect, частина 11: вісімсот комітів, які писав не я
Другого серпня зранку я порахував коміти у своєму відеогенераторі. Вийшло 795. Поки я писав цю статтю, лічильник дійшов до 802. Коду за цей час я не написав ані рядка — відповідав на питання й дивився, що виходить.
Десять частин цієї серії я розповідав, як влаштований my_architect: пам'ять, сховище, модель планування, робочий цикл, Event Storming, код-граф. Увесь цей час був справедливий докір: красиво, але покажи на справжньому проєкті. Показую.
Усі числа нижче зняті з живого проєкту 2 серпня 2026 року. Де число міряє не те, що здається на перший погляд, — я так і пишу.
Проєкт, який не вміщується в голову
Відеогенератор — він же Vini Studio — почався 16 травня 2026 року комітом із повідомленням init. На друге серпня це 802 коміти за 78 діб, 920 файлів під гітом, 85 тисяч рядків коду і ще 70 тисяч рядків документації та конфігів.
Різнорідність там непристойна для однієї людини. Фронт: React 18 поверх litegraph, нодове полотно на 25 типів нод. Бек: Node без фреймворка, 2771 рядок в одному роутері, SQLite на 16 таблиць. Рендер іде через Remotion, а той піднімає Chrome Headless Shell. Поруч живуть два пітонівські сайдкари на Flask: перший обгорнутий довкола ffmpeg і тримає 17 ендпоінтів, другий розділяє доріжки через Demucs на торчі. Моделей п'ять вендорів — fal.ai, Anthropic, OpenAI, Groq, ElevenLabs, і два реєстри по шість моделей у кожному, для відео і для картинок. Є ще дослідницький шар: дев'ятнадцять research-документів, тришарові евали поведінок, сліпа крос-вендорна оцінка сценаристів і п'ять A/B-замірів, де рішення ухвалювалося за числами.
А 24 липня проєкт узагалі змінив архітектуру цілком. Перший шлях складання, телеграм-бот на n8n, пішов в архів рішенням RFC-055, канонічним стало нодове полотно. Дев'ятнадцять n8n-воркфлоу лишилися в гіті тільки як історія.
Про заголовок одразу, щоб не було спекуляцій. Автором усіх 802 комітів гіт вважає мене, і тисну коміт теж я. Формальний слід агентського співавторства — трейлер Co-Authored-By, він стоїть у 256 комітах, це 31,9%, і там п'ять різних версій моделей. Це нижня межа, бо трейлер ставиться не завжди.
Зате режим роботи по репозиторію видно добре. Сім робочих дерев, три з них агентські і створені 19 липня з різницею в сім хвилин. А четвертого липня є серія з 43 комітів за 33 хвилини: механічна міграція тестів на спільний стенд, по коміту на файл. Руками я так не вмію.
Я не пам'ятаю цей проєкт. Я пам'ятаю напрямок. Усе інше лежить в архітекторі.
Що там насправді лежить
Дамп проєкту з my_architect на друге серпня — 650 вузлів. Тридцять один епік верхнього рівня, 237 фіч, 33 історії, 324 задачі і 25 багів заведені окремим типом. З них 527 закриті — це 81%. Чотири рівні ієрархії, шість релізних кошиків, найстаріший — MVP, закритий цілком, 38 із 38.
Вимог — 296. Не тільки функціональних: 241 FR, 26 NFR, 20 обмежень, п'ять архітектурно значущих, три системні й одне відкрите питання — те саме, яке я підкинув в обговоренні і яке заведене саме для того, щоб не загубитися. Документів на вузлах — 29, діаграм — чотири, включно з дошкою Event Storming.
Масштаб найпростіше відчути так. Коли я попросив вивантажити контекст проєкту одним викликом, відповідь зайняла 258 тисяч символів — і це ще урізаний вигляд, без описів вузлів. А список вимог цілком не вліз узагалі: інструмент повернув помилку «385 тисяч символів, перевищено ліміт» і поклав відповідь на диск.
Це і є відповідь на питання, навіщо зовнішня пам'ять. Не тому що агент дурний. Тому що проєкт фізично більший за будь-яке контекстне вікно — і за моє теж.
Вимога, коміт і тест тримаються за руки
У корені проєкту лежить CLAUDE.md на 488 рядків з одинадцятьма жорсткими правилами. Одне з них влаштоване так:
Будь-яке архітектурне рішення, decision, status-change або scope-shift ОБОВ'ЯЗКОВО відображається у ДВОХ місцях: RFC у
docs/rfc/RFC-NNN-*.mdі my_architect MCP. Якщо зміну не відображено в обох — вона загубиться при /compact або новій сесії. Не роби роботу не записавши. Не записуй роботу не зробивши.
Остання фраза не мій переказ, а дослівний рядок із репозиторію. І вона працює: 456 комітів з 802, тобто 56,9%, несуть у темі або тілі посилання на конкретний FR чи RFC. RFC-файлів у проєкті 63, від першого до шістдесят четвертого, з однією дірою на сорок шостому.
Але сама лише дисципліна посилань нічого не варта без другого кінця. Другий кінець — тести. Правило звучить так: кожне полагодження регресії приїжджає з постійним тестом, поміченим // covers: FR-NNN проти вимоги в архітекторі, а якщо вимоги ще немає, її спершу заводять.
Далі починається механіка. Скрипт витягає вимоги з архітектора і звіряє їх із тегами в тестах. Другий скрипт роняє збірку, якщо в якоїсь вимоги знайшлося нуль покривних тестів. Я запустив його просто зараз: ALL 203 requirements covered. Тегів // covers: у тестовій теці — 290 штук на 221 унікальний ідентифікатор. Ідентифікатори вимог живуть і в продуктовому коді теж: 145 різних FR трапляються у вихідниках полотна.
Як це виглядає в конкретному ланцюжку. Є RFC-052 про видалення проєкту. У його шапці — вузол feature-211-adwcry в архітекторі. У вузла п'ять вимог. За ними два коміти від 23 липня, за комітами — функції deleteProject і renameProject у сторі, а за функціями — три тести з тегами. І тіло першого коміту закінчується рядком Architect: feature-211-adwcry → done; NFR-122/FR-143/FR-144/FR-145 → approved. Ланцюжок замкнутий в обидва боки, і пройти його можна з будь-якого кінця.
До коду — картинка, а не текст
Є техніка, яку я недооцінював, поки не почав користуватися нею постійно: перед тим як щось будувати, намалювати це і дати собі вибрати.
З 28 червня по 3 липня агент намалював мені чотирнадцять інтерактивних HTML-вайрфреймів у шести брейншторм-сесіях — приблизно 94 кілобайти рукописної верстки. Не картинки: локальний сервер піднімав їх у браузері по одному, а я клікав варіант. Розкладка оболонки — рейка з доком проти всього у верхній панелі. Три варіанти статус-бара. Куди вішати іконки над нодою і скільки їх. Який вигляд мають стани індикатора збереження. Панель історії.
Перевірити порядок «спершу картинка, потім код» просто. Вайрфрейм концепту полотна датований 28 червня, перший коміт самого полотна — 29-м. Спека від 1 липня каже дослівно: «варіанти нижче відображають реальний вибір користувача в браузері, а не припущення». Спека від 3 липня вказує, що взято макет C, а макет B відхилено.
Найцінніший випадок — коли мокап привів до рішення нічого не будувати: порівняли варіанти й побачили, що провід і так читається, проміжна нода не потрібна.
У моїх нотатках це правило записане жорсткіше, ніж я зазвичай собі дозволяю: поки брейншторм не проведений і не пропрацьований — робити нічого не треба, буде тільки гірше.
Вайрфрейми, до речі, лежать у gitignore. За самим лише гітом цю практику не побачити — що само по собі непогана ілюстрація, чому роботу треба записувати не тільки комітами.
Про ніч
Я віддаю задачу о десятій вечора, а зранку приходжу до готового результату. Останніми місяцями — до великого: не «поправ відступ», а зібраний шматок системи.
Спершу я вирішив перевірити це за комітами і мало не зробив хибний висновок. У вікно з десятої вечора до восьмої ранку потрапляють 75 комітів із 802, а з першої ночі до шостої ранку — рівно нуль. Виглядає як спростування.
Тільки коміт фіксує не момент, коли робота йшла, а момент, коли її прийняли. О третій ночі її ніхто не приймає. За таймстемпами тривалість автономного прогону не міряється в принципі — ні довести, ні спростувати.
Зате форма доби міряється, і вона каже рівно те, що я й описую. У дня два горби, і ніч лежить між ними. Дев'ята вечора — друга за завантаженістю година за весь час проєкту, 75 комітів. Дев'ята ранку — третя, 70. На вечірню здачу з дев'ятої до півночі припадають 122 коміти, на ранковий розбір із сьомої до десятої — 115.
І ранкові коміти найбільші за добу: у середньому 361 вставлений рядок проти 179 удень, удвічі. Удень іде дрібна ітерація. Уранці до репозиторію приїжджає великий шматок, зроблений цілком.
Тож фраза не про години. Вона про те, звідки береться впевненість віддати великий шматок і не сидіти над ним, — і ось це міряється напряму.
Упевненість дає не модель. Її дає те, що агентові нікуди збрехати: у вимоги є номер, у номера є тест, у тесту є гейт, який роняє збірку.
Як виглядає перевірка на міцність цього механізму, видно з історії першого серпня. У полотні було 63 зелені браузерні тести, що створювали зв'язки між нодами викликом внутрішнього API. Одночасно з цим жили два баги, відтворювані руками стовідсотково. Один тест узагалі підробляв подію, якої в проді не буває, і був зеленим саме тому, що лагодив собою рівно ту умову, яка зламана.
Висновок із цього став ще одним жорстким правилом: баги вводу перевіряються справжнім вводом браузера — через реальні події миші, зі справжнім захопленням вказівника. Тег // covers: на вимозі про взаємодію без справжнього вводу — це хибна впевненість, бо гейт звіряє рядок у коментарі, а не шар, який тест насправді чіпає.
І раз уже я обіцяв чесність, ось друга половина картини. Машинного примусу до синхронізації в мене немає: хуків немає, CI проганяє тільки деплой, тести й гейт покриття я ганяю руками. Дисципліна тримається текстом правил і тим, що агент їх читає щосесії. Працює — але це не те саме, що «неможливо порушити».
Що я на цьому виграю
Роль у мене через це інша. Я не переказую агентові контекст і не пам'ятаю, в якому стані двадцять восьмий епік. Я займаюся продуктом: дивлюся ролики, ловлю, що дратує, вирішую, яку модель викидаємо з реєстру, і скільки це коштує в секундах відео.
За останній тиждень липня і перші дні серпня в студії з'явився редактор оформлення, де прев'ю фізично не може розійтися з рендером, бо це буквально та сама композиція. З'явилася студія монтажу: з ревізії від 2 серпня вона збирає ролик просто у вкладці браузера. І за два дні приїхав увесь голосовий контур: клон голосу, озвучення, ізоляція, дубляж, ліпсинк. Три RFC поспіль закриті за троє діб.
Заодно там стався інцидент, який у звіт про перемоги зазвичай не потрапляє: 20 липня необмежений рендер поклав по пам'яті весь спільний сервер, load дійшов до одинадцяти на чотирьох ядрах. Лікується це нудно — стелею пам'яті й процесорів у контейнера, щоб падав тільки свій рендер, а не хост. Коментар з описом інциденту я лишив просто в конфізі, щоб ніхто потім не зняв ліміти «за непотрібністю».
Далі — команда
Скажу прямо, щоб мене не зрозуміли навпаки. Це не історія про те, що одна людина замінює команду. Посадити одного на великий командний проєкт і сподіватися, що злетить, сьогодні не можна, і я такого не пропоную.
Історія про те, куди переїхало вузьке місце. Раніше моїм обмеженням були руки. Тепер обмеження — наскільки виразно сформульовано, що має вийти, і наскільки машина здатна перевірити, що вийшло саме воно.
І ось тут для команди найцікавіше. Уся дисципліна, через яку агентові можна віддати великий шматок, — це рівно ті артефакти, які команді потрібні й без жодних агентів. Одне джерело правди про стан роботи замість треду в месенджері. Вимога з номером, до якої дотягуєшся з коду, і гейт, який роняє збірку, якщо ця вимога лишилася без тесту. Наодинці без такого ще можна жити, в команді — ні.
Раніше такі артефакти доводилося продавати команді як накладні витрати: пишемо вимоги, бо так правильно. Тепер у них з'явився другий споживач, який читає їх щосесії і працює за ними буквально. Один і той самий документ обслуговує і людину, і агента. Я такого раніше не бачив, і множник саме в цьому.
Що я на команді ще не міряв і чесно називаю відкритим: як розходиться трекер, коли в нього пишуть п'ять людей і десять агентів; хто затверджує вимогу, якщо її автор — агент; скільки треба рев'ю, коли обсяг коду за тиждень зростає кратно. Це наступна задача, а не розв'язана.
Двері я відчиняю, а не зачиняю.
Факти і посилання
Замір зроблено 2 серпня 2026 року. Репозиторій відеогенератора: 802 коміти, перший 16 травня 2026, останній на момент заміру — a2cc612 о 12:50. Дані архітектора — живий проєкт ai-video-generator на my-architect.app: 650 вузлів, 296 вимог, 29 документів, 4 діаграми. Гейт покриття — node test/check-coverage.mjs, вивід «ALL 203 requirements covered». Розподіл комітів за годинами — git log --format='%ad' --date=format:'%H'; середній розмір коміту за вікнами доби — за git log --shortstat. Вайрфрейми лежать у .superpowers/ і в гіт не потрапляють, дати взяті за файловою системою і звірені з датами спек.
Сам інструмент — my-architect.app, ставиться в Claude Code двома командами. Як влаштована студія, про яку тут мова, я розбирав у статті «Від полотна до студії».
Якщо ви ведете схожий проєкт з агентами і у вас вийшло інакше — напишіть мені. Особливо цікаві випадки, коли така дисципліна не злетіла: вони корисніші за історії успіху.