yongol — Киль SaaS, написанного с помощью ИИ

200-й эндпоинт

Вы строите SaaS с вайб-кодингом. Поначалу быстро. 5 таблиц, 12 эндпоинтов — двадцать минут, и всё работает.

Но после 50 эндпоинтов начинается странное. ИИ создаёт сегодня паттерн, который противоречит вчерашнему. После 100 существующие функции тихо ломаются. После 200 добавление одной функции стоит в 10 раз дороже, чем первые десять.

Дело не в том, что модель глупая.


Решения и реализация

В исходном коде переплетены три вещи:

  • Решения пользователя — этот столбец BIGINT, этот эндпоинт только для владельца, пагинация курсорная.
  • Бизнес-логика — ценообразование, рабочие процессы, правила жизненного цикла.
  • Детали реализации — имена переменных, порядок вызовов библиотек, обёртка ошибок.

Когда ИИ читает этот код, он не может отличить, какая строка — решение, а какая — деталь. Поэтому при «рефакторинге» или «очистке» он молча перезаписывает решения, приняв их за детали. Пользователь замечает только тогда, когда поведение уже сломано.

Вот почему вайб-кодинг разваливается на 200 эндпоинтах. Более крупная модель не спасёт. Среда — сырой код — просто не сохраняет решения. Любая модель в итоге упирается в ту же стену.


Киль

Киль — первая кость, которую кладут при строительстве корабля. Он несёт вес корпуса, предотвращает бортовую качку, и все остальные конструкции строятся поверх него. Корабль без киля держится на спокойной воде, но деформируется, когда приходят волны.

SaaS, построенный вайб-кодингом, такой же. Маленький — держится. Вырастает — деформируется.

yongol — это киль SaaS, написанного с помощью ИИ.


Вынести решения из кода

Суть yongol проста. Отделить решения от кода.

Десять декларативных спецификаций (SSOT) — каждая отвечает за одну область:

SSOTОбласть
features.yamlКаталог функций — что строить
manifest.yamlКонфигурация проекта — аутентификация, middleware, инфраструктура
OpenAPIAPI-контракт — маршруты, параметры, ответы
SQL DDL + sqlcМодель данных — таблицы, столбцы, ограничения, запросы
SSaCПоток сервиса — последовательность решений внутри эндпоинта
RegoАвторизация — кто что может делать
Mermaid stateDiagramПереходы состояний — жизненные циклы сущностей
FuncSpecПользовательские функции — логика, которую нельзя выразить как CRUD
HurlТестовые сценарии — проверка во время выполнения
STMLФронтенд — структура страницы и привязка данных

Восемь из десяти — отраслевые стандарты (OpenAPI, SQL, sqlc, Rego, Mermaid, Hurl, YAML). Только SSaC и STML — DSL, созданные yongol. То, что ИИ должен выучить с нуля, сведено к минимуму.

Каждый SSOT содержит только решения. Никаких деталей реализации. ИИ редактирует SSOT; yongol generate рендерит из них код. Решения живут в SSOT постоянно; код — одноразовая проекция.


Принудительная согласованность

Решения теперь распределены по десяти файлам, и между ними могут возникнуть противоречия. DDL говорит BIGINT, а OpenAPI — string? SSaC объявляет @auth, а в Rego нет соответствующего правила? В диаграмме состояний есть переход, а в SSaC нет соответствующей функции?

Противоречивый SSOT — это повреждённое решение. Каким бы чистым ни был код, если решения противоречат друг другу, поведение будет неправильным.

yongol validate это ловит.

✓ manifest        ✓ openapi_ddl       ✓ ssac_rego
✓ openapi         ✓ openapi_ssac      ✓ ssac_authz
✓ ddl             ✓ hurl_openapi      ✓ ssac_sqlc
✓ query           ✓ hurl_statemachine ✓ ddl_statemachine
✓ ssac            ✓ hurl_manifest     ✓ ddl_rego
✓ statemachine    ✓ openapi_manifest  ✓ rego_manifest
✓ rego            ✓ ssac_ddl          ✓ stml_openapi
✓ hurl            ✓ ssac_statemachine
✓ funcspec        ✓ ssac_func

0 errors, 0 warnings

Сначала каждый SSOT проверяется отдельно, затем выполняются перекрёстные проверки между слоями. ~287 правил проверяют каждую символьную ссылку между всеми десятью SSOT. Если есть хоть одно противоречие — компиляция отклоняется.

ИИ пишет свободно. Сойдёт с рельсов — validate поймает мгновенно. Свобода на рельсах.


operationId — замковый камень

Как связать десять слоёв? Одним PascalCase-идентификатором.

Введите operationId ExecuteWorkflow:

── Feature Chain: ExecuteWorkflow ──

  OpenAPI    api/openapi.yaml                POST /workflows/{id}/execute
  SSaC       service/workflow/execute_workflow.ssac   @get @empty @auth @state @call @publish @response
  DDL        db/workflows.sql                CREATE TABLE workflows
  DDL        db/execution_logs.sql           CREATE TABLE execution_logs
  Rego       policy/authz.rego               resource: workflow
  StateDiag  states/workflow.md              diagram: workflow → ExecuteWorkflow
  FuncSpec   func/billing/check_credits.go   @func billing.CheckCredits
  FuncSpec   func/billing/deduct_credit.go   @func billing.DeductCredit
  FuncSpec   func/worker/process_actions.go  @func worker.ProcessActions
  FuncSpec   func/webhook/deliver.go         @func webhook.Deliver
  Hurl       tests/scenario-happy-path.hurl  scenario: scenario-happy-path.hurl

От спецификации API до схемы базы данных, от политик авторизации до переходов состояний, от реализаций функций до тестовых сценариев — полная топология одной функции на одном экране. Десятки grep заменены одной командой.

operationId — замковый камень, потому что в full-stack приложении единица функциональности — это API-эндпоинт. Пользователь нажимает кнопку, вызывается API, и этот API пронизывает все остальные слои. Одно имя физически связывает десять слоёв.


Бенчмарк: ZenFlow

ZenFlow — мультитенантный SaaS для автоматизации рабочих процессов. Claude Sonnet 4.6 писал SSOT; yongol их валидировал.

ЭтапОписаниеВремяНакопительно
Начальная сборкамультитенант, аутентификация, конечный автомат, 6 таблиц, 10 эндпоинтов23 мин23 мин
+ Версионированиеклон воркфлоу, список версий, INSERT…SELECT копирование действий16 мин39 мин
+ Вебхукипубликация событий, CRUD вебхуков, бэкенд очередей8 мин47 мин
+ Маркетплейс шаблоновкурсорная пагинация, кросс-орг клон, публичные эндпоинты7 мин54 мин
+ Вложения файловотчёты выполнения, файловый бэкенд7 мин61 мин
+ Планированиеcron на сессиях, TTL10 мин71 мин
+ Аудит-логибэкенд кэша, пагинация, фильтры6 мин77 мин
+ Дашбордагрегирующий API, реляционные соединения, детальные виды14 мин91 мин
+ Пакетные операциимассовое сохранение действий, JSON-сериализация10 мин101 мин
+ Внешний APIимпорт API геокодирования, хранение координат14 мин115 мин
+ Условное обновлениеавтоназначение, оценка уверенности, условное ветвление16 мин131 мин

Итого: 30 эндпоинтов, 12 таблиц, 64 тестовых запроса. Всё зелёное.

Десять функций добавлены последовательно. Добавление функций никогда не замедлялось. Существующие тесты никогда не ломались. Стены 200 эндпоинтов не существовало.

Запуск той же спецификации с Opus: 30 эндпоинтов, 73 тестовых запроса, ~76 мин. Модель меняется, рельсы остаются.


Почему более крупная модель — не ответ

«GPT-6 это решит.»

Не решит. Проблема не в интеллекте модели — а в среде.

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

yongol меняет среду. Переносит то, что редактирует ИИ, с кода на декларативные спецификации. Поскольку спецификации содержат только решения без деталей реализации, ИИ никогда не спутает решение с деталью. Выживание решений становится независимым от размера модели.

Маленькая LLM, редактирующая только SSOT, с validate, дающим точную обратную связь при каждой ошибке, может поддерживать ту же целостность решений, что и гораздо более крупная модель, редактирующая сырой код. yongol закрывает этот разрыв.


Начало работы

npx skills add park-jun-woo/yongol

Установите skill yongol в ваш ИИ-агент (Claude Code, Cursor, Copilot и другие). Агент автоматически изучает рабочий процесс при установке.

Для прямого использования CLI:

go install github.com/park-jun-woo/yongol/cmd/yongol@latest

git clone https://github.com/park-jun-woo/yongol && cd yongol
yongol validate examples/zenflow

0 errors, 0 warnings.

Направьте ИИ на эти спецификации и попросите добавить функцию. validate кладёт рельсы; ИИ бежит по ним. Стены нет.


Связанные статьи

Код: github.com/park-jun-woo/yongol