
200-й эндпоинт
Вы строите SaaS с вайб-кодингом. Поначалу быстро. 5 таблиц, 12 эндпоинтов — двадцать минут, и всё работает.
Но после 50 эндпоинтов начинается странное. ИИ создаёт сегодня паттерн, который противоречит вчерашнему. После 100 существующие функции тихо ломаются. После 200 добавление одной функции стоит в 10 раз дороже, чем первые десять.
Дело не в том, что модель глупая.
Решения и реализация
В исходном коде переплетены три вещи:
- Решения пользователя — этот столбец
BIGINT, этот эндпоинт только для владельца, пагинация курсорная. - Бизнес-логика — ценообразование, рабочие процессы, правила жизненного цикла.
- Детали реализации — имена переменных, порядок вызовов библиотек, обёртка ошибок.
Когда ИИ читает этот код, он не может отличить, какая строка — решение, а какая — деталь. Поэтому при «рефакторинге» или «очистке» он молча перезаписывает решения, приняв их за детали. Пользователь замечает только тогда, когда поведение уже сломано.
Вот почему вайб-кодинг разваливается на 200 эндпоинтах. Более крупная модель не спасёт. Среда — сырой код — просто не сохраняет решения. Любая модель в итоге упирается в ту же стену.
Киль
Киль — первая кость, которую кладут при строительстве корабля. Он несёт вес корпуса, предотвращает бортовую качку, и все остальные конструкции строятся поверх него. Корабль без киля держится на спокойной воде, но деформируется, когда приходят волны.
SaaS, построенный вайб-кодингом, такой же. Маленький — держится. Вырастает — деформируется.
yongol — это киль SaaS, написанного с помощью ИИ.
Вынести решения из кода
Суть yongol проста. Отделить решения от кода.
Десять декларативных спецификаций (SSOT) — каждая отвечает за одну область:
| SSOT | Область |
|---|---|
| features.yaml | Каталог функций — что строить |
| manifest.yaml | Конфигурация проекта — аутентификация, middleware, инфраструктура |
| OpenAPI | API-контракт — маршруты, параметры, ответы |
| 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 на сессиях, TTL | 10 мин | 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 кладёт рельсы; ИИ бежит по ним. Стены нет.
Связанные статьи
- SSaC — Service Sequences as Code — Замковый DSL yongol. Объявляет решения внутри эндпоинтов.
- Feature Chain — Отследить Full Stack по одному operationId — Трассировка всех восьми слоёв через один operationId.
- Ratchet Pattern — Как заставить агента довести дело до конца — Теоретическая основа обратной связи validate с агентами.