Ястремський

Відкритий код · MIT · флагман

Groundwork

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

Ліцензія
MIT
Версія
v0.40.0
Працює в
Claude Code
Ціль
Laravel-бекенди
Автор
Макс Ястремський

Проблема

Правдоподібне — не те саме, що правильне

Кожен запобіжник нижче існує тому, що збій, який він відвертає, уже стався.

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

    Він вгадує щодо чужих API

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

  2. 02

    Він планує за тими файлами, які йому показали

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

  3. 03

    Він відповідає на поставлене запитання

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

  4. 04

    Він звітує про успіх

    «Воно працює» — це твердження, а твердження не є доказом. Рецензент, єдине завдання якого — спростувати твердження, отримує право подивитися до того, як у нього повірять.

Будова

Вага зростає з ризиком

Одруківка і зміна в нарахуванні ПДВ не заслуговують однакової церемонії. Застосування повного процесу до всього — це те, як процес перестають використовувати, тож рівень вирішує, що саме запускається.

Класифікація задач L0–L4
РівеньЩо охоплюєReview-агентиПогодження
L0Одруківка, коментар, документаціяНемаєНе потрібне
L1Невелике виправлення багаНемає — точкове самотрасуванняЯкщо не сказано застосувати одразу
L2Звичайна функціональністьКарта впливу, відповідністьПотрібне
L3Права доступу, міграції, публічні контракти, видимість фінансових данихУсі п’ятьПотрібне
L4Фінансові розрахунки, життєвий цикл замовлення, модель прав, руйнівні міграціїУсі п’ять і змагальна панельЛюдиною, завжди

Оберіть задачу. Подивіться, як змінюється процес.

Нуль JavaScript — radio-поля і CSS. З клавіатури: Tab у групу, далі стрілки. Працює з вимкненими скриптами.

Оберіть задачу

L0 — Дрібниця

Без специфікації. Без плану. Без review-агентів. Без погодження. Автоматичні гейти і є повне визначення готовності.

Хто перевіряє

Ніхто — і це навмисно.

Що потрібно

  • Гейти, які спрацьовують самі

L1 — Невелике виправлення

Регресійний тест, який спершу падає, потім одна жива перевірка саме того, що виправлено, — а не обхід усіх споживачів.

Хто перевіряє

Без агентів — натомість точкове самотрасування.

Що потрібно

  • Коротка вбудована специфікація
  • Регресійний тест, який падає першим
  • Жива перевірка того єдиного, що виправлено

L2 — Функціональність

Дослідження розходиться вшир ще до планування. Радіус ураження картографують, а не припускають, і нічого не пишуть до узгодження плану.

Хто перевіряє

  • impact-mapper — що це зламає
  • conformance-reviewer — чи задовольняє diff критерії

Що потрібно

  • Специфікація, план, погодження
  • До 2 раундів запитань
  • Тести, написані до коду

L3 — Високий ризик

Права доступу, міграції, публічні контракти, видимість фінансових даних. Тут під сумнів ставлять намір, а не лише код.

Хто перевіряє

  • impact-mapper
  • blind-spot-map — про що ніхто не здогадався спитати
  • grounded-researcher — що насправді робить провайдер, з посиланням
  • conformance-reviewer
  • adversarial-verifier — чи правда, що «воно працює»

Що потрібно

  • Специфікація, план, звірка вимог, нотатки до розгортання
  • До 4 раундів запитань
  • ADR, коли рішення наскрізне

L4 — Критично

Фінансові розрахунки, життєвий цикл замовлення, модель прав, руйнівні міграції. Бути приблизно правим тут означає бути неправим.

Хто перевіряє

  • Усе, що вмикає L3
  • Змагальна панель — щонайменше двоє незалежних скептиків на найризикованіших твердженнях

Що потрібно

  • Усе, що вимагає L3
  • Нотатки щодо відкату
  • Погодження людиною, завжди
Гейти — увімкнені на кожному рівні, зокрема на L0
  • форматування при редагуванні
  • статичний аналіз
  • набір тестів
  • контракт OpenAPI
  • скан дефектів
  • заявлене покриття
  • заявлена оцінка
  • намір задачі
  • контракт агента
  • примусовий runner
  • міграції заблоковано
  • правки заблоковано під час дослідження
  • незапушена робота
Вага процесу росте з ризиком. Гейти — ні, і в цьому суть.

Перевірка

П’ять спеціалістів, по одному завданню

Кожен працює у свіжому контексті, тож міркування, які призвели до помилки, не можуть тихо її відтворити.

impact-mapper

Що це зламає? Трасує назовні від кожного зачепленого символа — ті, хто викликає, події, слухачі, задачі, заплановані команди, політики, каскадні зв’язки і тести, які це покривають.

blind-spot-mapper

Про що ніхто не здогадався спитати? Передбачає пропущений вимір, а не наявний зв’язок: неочікувані наслідки, відсутні вимоги, доменний кут, у якому замовник не є експертом.

grounded-researcher

Що насправді робить провайдер? Читає офіційну документацію і повертає висновки, кожен із джерелом або позначений як невідомий. Йому не дозволено вгадувати замість перевіряти.

adversarial-verifier

Чи правдиве твердження «воно працює»? Намагається спростувати його на реальному коді, офіційній документації та результатах у пісочниці. За замовчуванням налаштований скептично.

conformance-reviewer

Чи задовольняє diff узгоджені критерії приймання? Оцінює реалізацію проти специфікації у свіжому контексті й повідомляє про прогалини, а не про стиль.

Докази

Що лишається після завершеної задачі

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

Оцінки виміряні, а не відчуті

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

Квитанція і рядок, який ніхто не підписав

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

Правило сильніше за абзац

П’ять класів дефектів, знайдених у справжніх репозиторіях — гроші у вигляді float, читання конфігурації поза шаром конфігурації, незворотна дія всередині транзакції — місяцями були записані як стандарт і все одно порушувалися. Тепер це гейт. Підвела саме проза; перевірка — друга спроба.

Спершу людською мовою

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

Використання

У щоденній роботі, а не в демо

Числа приблизні й на момент часу — саме тому вони мають дату.

7
кодових баз у продакшні
340
запусків процедур
160
написаних специфікацій
27
передач фронтенду
1 з 3
зупинено до коду

Приблизно, станом на серпень 2026

Цифра, про яку варто сперечатися

Приблизно кожна третя задача не доходить до коду. Не тому, що інструмент відмовив, а тому, що написання специфікації показало: запит неправильно окреслений, уже вирішений деінде або дешевший у розв’язанні без розробки взагалі.

Встановлення

Три рядки

`init` виводить тонкі, суто доменні контракти з самого коду й позначає все, що довелося припустити.

/plugin marketplace add YasMax91/groundwork
/plugin install groundwork@yasmax
/groundwork:init