← Назад Harupa
2026-06-29RU EN UA BY PL

My Architect, частина 8: Event Storming — контроль послідовності, а не ще одна діаграма

Це восьма стаття серії про My Architect. Для тих, хто не читав попередні частини, коротко: My Architect — система, де проєкт живе між сесіями AI-агента. Одним боком вона повернена до агента — він веде проєкт через MCP; іншим до людини — візуальний інтерфейс показує, що агент уже зробив, і весь прогрес за проєктом. Ця стаття — про один конкретний механізм такого контролю.

Вітрина тут — Forklift, середній домен доставки їжі з п'яти bounded-контекстів. Усі дошки, цифри аналізатора і фрагменти DSL нижче справжні: проєкт засиджено локально і він проходить через реальний analyzeEsSequence. Нічого не вигадано.

Діаграма заради діаграми марна. Контроль послідовності — ні

У всіх нас є цей цвинтар. Тека docs/architecture, де лежать гарні PNG, намальовані пів року тому, і жоден уже не відповідає коду. Діаграма-картинка — це знімок чиїхось добрих намірів на момент часу T. Вона нічого не перевіряє. Вона не знає, що ви забули підключити гілку скасування. Вона радо покаже стрілку, якої в коді немає, і змовчить про п'ятнадцять, які є.

Тому коли я кажу «агент малює Event Storming дошку», у вас справедливо смикається око. Ще одна картинка? Ні. Різниця в одному слові: послідовність.

Event Storming — це не діаграма коробочок. Це розкладена в часі історія того, як подія породжує реакцію, реакція — команду, команда — нову подію. У доменної події («Замовлення розміщено») є причина. У команди («Розмістити замовлення») є результат. Політика («Щойно платіж авторизовано → підтвердити замовлення») — міст між чужою подією і твоєю командою. І ось ця властивість — усе має причину і наслідок — перетворюється з гарної філософії на машинно-перевірюваний інваріант.

Якщо подія висить без причини — це пролом. Якщо команда не породжує події — пролом. Якщо політика нічого не мостить — пролом. Якщо картка ізольована — хтось накидав думку і не довів. Цих проломів не видно очима на дошці з сорока стікерів. Але їх видно аналізатору, який читає граф послідовності.

Вітрина в нас апетитна — Forklift: on-demand food delivery, from tap to doorstep. П'ять bounded-контекстів: Ordering, Payments, Kitchen, Dispatch, Tracking. Рівно той клас домену, де «забув підключити гілку» коштує реальних грошей: їжу приготовано — гроші не списано; кур'єра не призначено — клієнт скаржиться.

Forklift — дошка Dispatch / Delivery Контекст Dispatch: команди (сині) → події (жовтогарячі), політики-мости (бузкові), read-models (зелені), зовнішні системи (рожеві), актори (жовті) і відкриті питання — hotspot'и (ромби) внизу.

Чому саме агенту це дає важіль

Людина дивиться на дошку і відчуває, що чогось бракує. Іноді знаходить. Частіше — ні: увага не масштабується, на тридцятій картці ви вже не пам'ятаєте, чи звели результат команди «Відхилити замовлення».

Агент не відчуває. Агент запускає детерміновану перевірку графа. analyzeEsSequence обходить причинно-наслідковий граф дошки і повертає структурований вердикт: ok, список gaps із типом (isolated, event-without-cause, command-without-effect, policy-not-bridging) і рівнем (warning / info), і окремо — openQuestions (hotspot-картки).

Це і є важіль. У агента з'являється петля зворотного зв'язку, яка не бреше і не втомлюється:

  1. Author — агент авторить дошку через create_diagram(diagramType:'event-storming', nodeId), прив'язуючи її до вузла ієрархії (епіку/ініціативі).
  2. Validate — читає через get_diagram; поле sequence показує проломи в історії.
  3. Refine — лагодить через update_diagram і валідує знову, поки gaps не схлопнеться до нуля.
  4. Re-validate during implementation — під час реалізації повторно ганяє перевірку: код розійшовся з історією → дошка знову червоніє.

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

Петля в дії: Ordering, від чорного чернетки до чистої історії

Спершу агент накидав v0 контексту Ordering — чесну чернетку, яку накидає жива людина: схопив основну нитку, помітив «сюди повернеться відповідь з Payments» — і не довів хвіст.

event-storming
# фрагмент: показана только основная нить Ordering, на доске карточек больше

group "Ordering"
  [command] "Place order"
  [event]   "Order placed"
  [policy]  "Whenever Payment authorized → Confirm order"
  [command] "Confirm order"
  [event]   "Order confirmed"
  [command] "Cancel order"

connect "Place order" -> "Order placed"
# "Whenever Payment authorized → Confirm order" — ни к чему не подключена  (isolated policy)
# "Cancel order" — ни входящего, ни исходящего                            (isolated command)
# "Order confirmed" — без входящей причины                                (event-without-cause, info)

Агент читає get_diagram, проганяє аналізатор і отримує по v0:

27 cards · 19 connections · 1 contexts — 2 sequence gap(s), 0 open question(s)
gaps:
  • "Whenever Payment authorized → Confirm order" (policy) is not connected to anything
  • "Cancel order" (command) is not connected to anything

Два проломи-warning (ізольована політика повернення з Payments і недозамкнутий хвіст скасування) плюс одна info-помітка («Order confirmed» без причини — породжувальну команду не зведено). Далі — refine: агент підключає породжувальну команду, мостить політику в команду підтвердження, замикає хвіст скасування результівною подією. Повторна валідація v1:

34 cards · 30 connections · 1 contexts — 0 sequence gap(s), 3 open question(s)

Проломи схлопнулися. Але — і це важливо — дошка не стала порожньою і не стала брехати «все вирішено». Лишилося рівно три картки, які агент свідомо лишив червоними. Про них — нижче.

Та сама петля на Payments: де чернетка особливо небезпечна

Payments — контекст, де недопроведена стрілка означає «їжу приготовлено, гроші не знято» або «гроші знято двічі». Тут v0 був дірявим, і це нормально: саме тому перевірка і потрібна.

Forklift — дошка Payments

Вердикт аналізатора по v0 Payments:

25 cards · 15 connections · 1 contexts — 3 sequence gap(s), 0 open question(s)
gaps:
  • "Issue refund" (command) is not connected to anything        — путь возврата нарисован наполовину
  • "Chargeback opened" (event) is not connected to anything     — забытая ветка отказа
  • "On decline cancel order" (policy) missing outgoing command  — мост к отмене брошен на шве

Після refine агент замикає шлях повернення (Evaluate refund → Issue refund → Refund issued), зводить обробку чарджбеку і добудовує міст політики decline у Cancel order. Вердикт по v1:

39 cards · 27 connections · 1 contexts — 0 sequence gap(s), 3 open question(s)

І знову — три картки лишаються червоними навмисне (capture-vs-reject race, атрибуція провини при поверненні, власник liability по чарджбеку).

Решта три контексти: той самий патерн

Петля скрізь одна й та сама. Що спіймав аналізатор у v0 — і до чого схлопнулося в v1:

Контекстv0 (проломи)v1Що було зламано в v0
Ordering2 →0ізольована політика повернення; недозамкнутий хвіст скасування
Payments3 →0обірваний шлях повернення; забутий чарджбек; міст decline на шві
Kitchen5 →0Reject order/Order rejected осиротіли; політика оцінки часу без тригера; Start cooking без події; Cooking started ізольований
Dispatch4 →0Notify ops без результату; політика трекінгу-сирота; Courier arrived/Delivery failed без причини
Tracking3 →0політика нотифікації без тригера; Recalculate ETA ізольована; політика запиту рейтингу не зведена

Разом по проєкту: 17 механічних проломів спіймано і закрито, 15 відкритих питань свідомо лишено на видноті. Жодної вигаданої цифри — це вивід реального analyzeEsSequence по засиджених дошках.

Що лишається відкритими питаннями — і чому це фіча, а не баг

Ось головна думка. Коли gaps схлопнулися до нуля, у наївної системи виникла б спокуса сказати «архітектура готова». Це була б брехня. Різниця між проломом і відкритим питанням фундаментальна:

Тому hotspot'и — повноправні громадяни дошки. Вони проходять валідацію (ok=true), але лишаються на видноті як openQuestions. Дошка чесно каже: «механічно я зв'язна, але ось ці розвилки чекають на людину».

І найкрасивіше: одне бізнес-питання спливає hotspot'ом з різних боків шва — одне й те саме питання видно з кількох контекстів одразу. Це не дублювання, а карта того, кого зачепить рішення, коли продакт його нарешті прийме:

Зелений аналізатор не означає «рішення прийнято». Він означає «історія механічно зв'язна, і всі невирішені розвилки явно піднято на поверхню, а не втоплено в мовчанні». Це рівно та межа, яку ви хочете між тим, що агент має право добудувати сам, і тим, де він зобов'язаний покликати людину.

Артефакт: це не картинки, це працюючий проєкт

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

Forklift — дошка Ordering

Як спробувати самому — уже можна

Це не «колись зарелізимо». Увесь тулчейн оновлено і доступний прямо зараз:

Встановлення в Claude Code:

  1. Заведи акаунт на my-architect.app, візьми токен на сторінці API Keys і експортуй його в тій самій сесії, де запускаєш Claude Code:

``bash export MCP_API_KEY=mcp_ВАШ_ТОКЕН ``

  1. Додай маркетплейс і постав плагін (MCP-сервер підключиться сам — npx -y @my-architect/mcp@latest, MA_API_URL=https://my-architect.app):

`` /plugin marketplace add d7561985/my-architect-marketplace /plugin install my-architect@my-architect-marketplace ``

  1. Дай агенту епік чи ініціативу і попроси розкласти Event Storming — він сам пройде петлю create_diagram → get_diagram (sequence) → update_diagram до зеленого, лишивши відкриті питання hotspot'ами.

Уже стоїть плагін? Онови до свіжих інструментів і правила: /plugin marketplace update my-architect-marketplace/plugin update my-architect.

Висновок: практика для команд

Якщо прибрати весь Forklift і лишити суть — робочий рецепт:

  1. Перестаньте ставитися до діаграм як до картинок. Беріть формат із перевірюваним інваріантом. У Event Storming він вбудований: усе має причину і наслідок.
  2. Зробіть перевірку послідовності дешевою і детермінованою. analyzeEsSequence поверх дошки — це лінтер для архітектури. Проломи (isolated, event-without-cause, command-without-effect, policy-not-bridging) — це помилки компіляції вашої історії.
  3. Дайте петлю агенту, а не разовий прогін. create_diagramget_diagram (validate) → update_diagram (refine) → re-validate під час реалізації. Агент ітерує до зеленого так само, як до зелених тестів — без утоми і без «начебто все підключив».
  4. Жорстко розділяйте пролом і відкрите питання. Пролом лагодить агент. Відкрите питання тримається hotspot'ом на видноті і чекає на людину. Система, що маскує друге під перше, мовчки приймає бізнес-рішення за вас — найгірший вид техборгу.
  5. Прив'язуйте дошку до вузла ієрархії (епіку/ініціативі), а не до повітря.

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