Допущения при поставке: стек надёжности для кода, сгенерированного ИИ

Генеративный ИИ ускоряет реализацию, но для соло-разработчика зазор между «код уже в репозитории» и «я понимаю систему» становится главным риском vibe-coding. материал @copyleftdev предлагает не наращивать поверхностное ревью, а вынести обещания системы в модели — до промпта на код.
Почему AI-assisted development ломается между компонентами
В эпоху AI-assisted development типичный сбой выглядит не как синтаксическая ошибка. Код проходит линтер, поверхностные тесты зелёные — и edge case всплывает в production. QA получает не карту системы, а реализацию с неявными решениями: границы сервисов, переходы состояний, инварианты нигде не зафиксированы.
Локально правдоподобный код скрывает глобальные риски системы. Generative AI усугубляет trade-off: правдоподобная реализация появляется раньше, чем команда (или один человек с агентом) согласует, что вообще считается системой. Без общей модели generated code становится design by default — если intent не вынесен наружу, машина решает за вас.
Чистый код ≠ связная система, когда инварианты остаются неявными.
Три слоя надёжности: карта, инварианты, атака на реализацию
@copyleftdev собирает ответ из трёх дисциплин моделирования — каждая отвечает на свой вопрос:
| Слой | Вопрос | Роль в стеке |
|---|---|---|
| C4 | Что существует и как связано? | Иерархия от context до code; для многих команд достаточно context + container — чтобы обсуждать границы до того, как QA и разработка «выведут» систему из репозитория |
| TLA+ | Что может произойти и что должно оставаться истинным? | Высокоуровневые модели (Leslie Lamport); TLC model checker ищет нарушения свойств — concurrency, ordering, retries, permissions, переходы состояний |
| DST | Реализация соответствует модели? | Deterministic Simulation Testing: время, randomness, scheduling, сети, storage и сбои — управляемые входы; seed делает запуск симуляции воспроизводимым |
Связка слоёв у автора лаконична:
C4 maps the system. TLA+ states what must remain true. DST tries to make it false.
Различие model checking и simulation иллюстрируется на TigerBeetle VOPR: проверка алгоритма в модели и проверка конкретной реализации с её assumptions — не одно и то же. Симулятор кластера на одном потоке ускоряет время и инжектирует storage faults — hostile-сценарии с сохранением seeds.
«Старые» дисциплины — architectural models, state machines, formal specifications, model checking, fault injection, deterministic simulation — исторически оставляли для систем, где сбой явно дорог. Generative AI меняет экономику: rigor перестаёт быть издержкой только для банков и авиации.
Инженерный цикл: промисы до генерации, не церемония ради галочки
Именованного CI/CD pipeline в посте нет — зато описан цикл, в который модели встроены по делу, а не как документация «на полку»:
- State the promises — до генерации кода: что система обязана сохранять и что запрещать.
- Draw the boundaries — C4: пользователи, внешние системы, контейнеры, хранилища, границы владения.
- Model the risky behavior — TLA+ на concurrency, ordering, retries, permissions, transitions.
- Generate from reviewed intent — ИИ пишет implementation и tests только после challenge структурных и поведенческих моделей людьми.
- Attack the implementation deterministically — time, randomness, scheduling, networks, storage под контролем; hostile scenarios с seeds.
- Feed reality back — наблюдения из production и падения симуляции обновляют инварианты, затем код и тесты; ловить drift, а не копить «исторический декор».
С общей моделью QA перестаёт быть финальным gate: можно оспаривать promises, проектировать hostile scenarios и возвращать находки в модель. Quality становится shared reasoning, а не последней проверкой перед релизом.
ИИ здесь не заменяет дисциплину, а снижает порог входа: черновить C4 из требований и кодовой базы, переводить обещания в инварианты TLA+, объяснять counterexample traces — retrieval наследия computer science, а не откат в «воображаемое прошлое».
Облегчённый стек для соло и малых команд
Полный формализм не обязателен. Автор называет lightweight stack:
- одна context-диаграмма;
- одна container-диаграмма;
- пять записанных инвариантов;
- небольшая модель для самого рискованного перехода;
- seeded test harness вокруг него.
Бытовой пример — не ledger и не flight control, а семейный фотоальбом, который описан как vibe-code проект для бабушки. Обещания конкретны: фото не уничтожены, private не exposed публично, подписи и хронология переживают правки, concurrent edits не затирают друг друга. Малый C4, TLA+ на concurrent edits/deletion/permissions и deterministic harness: два устройства offline, reconnect, retry uploads.
«Everything is mission-critical to someone» — критичность по последствиям для доверившегося человека, а не по масштабу инфраструктуры.
Для соло-разработчика с генеративным ИИ вывод практичен: перед очередным промптом на фичу пять инвариантов на бумаге дешевле, чем объяснять пользователю, почему его данные исчезли после «успешного» мержа агента.
Ответственность за release не передаётся генерации
Два тезиса стоит держать в голове при любом AI-assisted workflow:
- Generation does not transfer responsibility — генерация не снимает ответственность с человека.
- Humans own the promises — обещания системы принадлежат тем, кто релизит.
В конце поста есть disclosure: текст разработан с AI assistance через итеративный editorial process; аргумент и точность — у human author. Это не противоречие стеку, а его логическое продолжение: если модели видимы до кода, то и ответственность за то, что уходит в production, остаётся у автора релиза — независимо от того, кто набрал implementation.
Для ру-соло без отдельного QA-отдела правило простое: не спрашивать у модели «сделай надёжно», а сначала записать, что «надёжно» значит для вашего пользователя — и только потом открывать чат с генерацией.
Источники
- @copyleftdev — «Shipping Assumptions: A Reliability Stack for AI-Generated Code» (Dev.to, 16 августа 2026): Dev.to