RELAY
relay.codes
На согласовании · v0.9
Технический проект · v0.9 · 22.10.2026 · скачать .md · на согласовании

1. Краткое резюме (TL;DR)

Сегодня Claude Code, ChatGPT и Grok работают над одним проектом как три отдельных исполнителя без общего состояния. Они конфликтуют не из-за «плохих промптов», а из-за отсутствия инфраструктуры координации: нет единого источника правды, нет прав на артефакты, нет протокола передачи результата, нет журнала решений. И главное — нет механизма, который сводит их результаты в один.

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

Решение строится на четырёх механизмах:

#МеханизмЧто решает
1Контракт проекта (Project Contract) — версионируемая машинно-читаемая спецификация: цели, границы, стек, DoD, карта владенияДрейф требований, споры «о чём вообще проект»
2Доска задач с WIP-лимитами, зависимостями и зонами ответственностиДублирование работы, перегрузка агента, работа не по приоритету
3Реестр артефактов + протокол Handoff PacketПотеря контекста между агентами, приёмка «на глаз»
4Движок конфликтов (6 детекторов + авто-разрешение + эскалация)Прямо то, из-за чего сегодня всё ломается

relay.codes — это агрегатор. Центральный сценарий платформы: человек ставит одну задачу — RELAY разбирает её на три параллельных прогона (Claude Code, ChatGPT/Codex, Grok) с разными перспективами, проверяет каждый результат по DoD, сводит их в один PR и фиксирует решение в ADR. Подробно — раздел 5.

Плюс два «сшивающих» слоя: журнал решений (ADR) — чтобы спор решался фактами, а не памятью; оркестратор — чтобы задачи доходили до приёмки сами.

Предлагаемый путь: Фаза 0 (процесс, 1–2 недели, без кода) → Фаза 1 (MVP, 4–6 недель) → Фаза 2 (оркестратор и метрики, 3–4 недели) → Фаза 3 (contract-first пайплайн и авто-приёмка, 4 недели). Суммарно ~13–16 недель, состав — 2 инженера + 0.5 дизайнера + 0.5 аналитика, с человеком-владельцем на гейтах.


2. Проблема: откуда берутся конфликты

2.1. Как это выглядит сегодня

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

Типовой сценарий, который повторяется на каждом проекте:

  1. SEO-агент собирает семантику и выдаёт структуру страниц.
  2. Дизайнер-агент параллельно делает дизайн-систему под другую структуру.
  3. Инженер-агент реализует компоненты по своей версии токенов.
  4. Дизайнер обновляет токены (переименовал color.brand.primary → color.accent).
  5. Инженер узнаёт об этом через сломанный билд, переделывает 14 компонентов.
  6. Продукт-агент обнаруживает, что требования к приоритету страниц изменились после утверждения дизайна.

Итог: 3 дня потеряно, из них 2 дня — не на продукт, а на согласование того, что считать правильным.

2.2. Шесть корневых причин

КодПричинаМеханизм появления
C-1Пересечение зон ответственностиДва агента претендуют на один артефакт: «дизайн-токены» — зона дизайнера, но «цвет в теме» — это и SEO-бренд, и фронтенд
C-2Конфликт решенийРешение принято в переписке/в голове у одного агента, второй принял противоположное и не знает об этом
C-3Дрейф контекстаУ каждого агента своя копия требований; к моменту работы они уже расходятся на 2–3 итерации
C-4Нарушение порядкаРеализация начата до того, как спецификация дизайна была зафиксирована; результат — переделка
C-5ДублированиеНикто не видит, что задача «собрать страницу X» уже висит у другого агента с другим acceptance criteria
C-6Тихий сбойАгент упал или завис, handoff никто не принял, задача «в работе» неделю

2.3. Почему текущие решения не подходят

ПодходПочему не закрывает задачу
Один большой промпт / супер-агентКонфликты исчезают, но теряется специализация: один контекст на 500K токенов, деградация качества, невозможность менять одного участника
Общий чат / Telegram-группаНет прав, нет состояния, нет трассировки. История растёт, но не читается агентом. Разбор конфликта — вручную, каждый раз заново
Git + PR как система координацииРаботает для кода, но не для дизайн-токенов, семантики, структуры IA и требований. PR на токены — это merge-конфликт, который невозможно разрешить осмысленно
Один оркестратор-промптОркестратор сам становится точкой отказа и не может разрешить конфликт между двумя под-агентами, у которых нет доступа к общему состоянию
Просто «добавить больше инструкций»Инструкции не хранят состояние. Конфликт требует проверяемого арбитра, а не напоминания

2.4. Критерий успеха для платформы

> Платформа считается работающей, если конфликт между агентами обнаруживается системой до того, как он приведёт к переделке, и разрешается без участия человека в не менее чем 70% случаев, а человек вмешивается только в спорные продуктовые решения.


3. Продукт: что такое RELAY

3.1. Позиционирование

RELAY — coordination layer, слой координации. Он располагается между «мышью агента» (его LLM-контекстом) и «телом агента» (файлы, git, браузер, MCP-инструменты, внешние API).

┌──────────────────────────────────────────────────────────────┐
│  АГЕНТЫ (подменяемые)                                        │
│  Product/UX · Design · Fullstack · SEO/Research · QA/Verifier │
└───────────────┬──────────────────────────────────────────────┘
                │  через единый Agent Adapter Interface (MCP/CLI/HTTP)
┌───────────────▼──────────────────────────────────────────────┘
│  RELAY — слой координации                                     │
│  Контракт · Доска · Артефакты · Handoff · Конфликты · ADR      │
└───────────────┬──────────────────────────────────────────────┘
                │
┌───────────────▼──────────────────────────────────────────────┐
│  ИНФРАСТРУКТУРА                                                │
│  Postgres · Redis · S3 · Docker-sandbox · Git · OTel          │
└──────────────────────────────────────────────────────────────┘

Ключевое свойство: агентов можно заменять (Claude Code, Codex, Gemini CLI, MiniMax, любая модель через API) — RELAY держит протокол, а не конкретного исполнителя.

3.2. Четыре механизма

Механизм 1. Контракт проекта (Project Contract)

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

# .relay/contract.yaml (версионируется в git, как и код)
version: 7
project: "Sales Travel — платформа бронирования"
goal: "Снизить долю отказов на шаге оплаты на 30% за спринт"
non_goals: ["Рефакторинг биллинга", "Новая партнёрская интеграция"]
stack:
  frontend: "Next.js 15 / React 19 / TS"
  backend: "Node 22 / Fastify / Postgres 16"
  design_system: "Tokens v3 (design/figma-export)"
metrics:
  - { name: "LCP", target: "< 2.0s", owner: agent:fullstack }
  - { name: "SEO-трафик по семантике", target: "+25% Q", owner: agent:seo }
ownership:
  zone:design-tokens   -> agent:design
  zone:component-lib   -> agent:fullstack   # по контракту, не по факту
  zone:semantics       -> agent:seo
  zone:copy            -> agent:product
definition_of_done:
  - task_type: code
    checks: ["tsc --noEmit", "unit >= 80%", "no a11y violations", "bundle -15% vs baseline"]
  - task_type: design
    checks: ["tokens синхронизированы", "a11y contrast AA", "dark theme variant"]

Механика защиты: любой агент, предлагающий работу, обязан сослаться на zone: из контракта. Если зона не определена — работа не может быть взята в работу: сначала расширение контракта, потом реализация. Это превращает «пересечение зон» из конфликта в задачу.

Механизм 2. Доска задач с WIP-лимитами

Состояния: backlog → ready → in_progress → review → blocked → done.

Ключевые ограничения (это и есть «дисциплина экипажа»):

Механизм 3. Реестр артефактов + Handoff Packet

Каждый значимый результат работы агента — артефакт с версией, а не «сообщение в чат».

Типы артефактов: design-token, component-spec, screen-mock, api-schema, db-migration, seo-map, content-brief, adr, test-suite, analysis-report.

У каждого артефакта есть интерфейс потребления — то, что читает следующий агент:

{
  "artifact": "design-token",
  "name": "color.brand.primary",
  "version": 12,
  "contract": "alias -> {palette.600}; consumers: [Button, Link, Badge]",
  "consumed_by": ["component-lib", "marketing-site"],
  "breaking": false
}

Handoff Packet — формат передачи работы (это то, что сегодня теряется):

task: TASK-142 "Собрать страницу результатов поиска"
from: agent:design  to: agent:fullstack
status: handoff
done:
  - "Экран в 3 брейкпоинтах, токены из контракта v7"
  - "Компонент SearchResultCard — контракт props зафиксирован"
not_done:
  - "Адаптив до 360px — не успел, нужен отдельный тикет"
changed:
  - "tokens: color.brand.primary переименован (v12, non-breaking)"
risks:
  - "SEO-агент может потребовать другой H1 — проверить перед вёрсткой"
requires_from_receiver:
  - "Подтвердить контракт props SearchResultCard"
questions:
  - "Брать ли мобильную раскладку отдельной задачей или здесь?"

Приёмка — формальная. Получатель обязан прогнать DoD-проверки (для кода — tsc/тесты/a11y, для дизайна — сверка токенов и контраст) и выдать вердикт: accept / accept-with-comments / reject. Reject требует обоснования, и задача возвращается в очередь с сохранением истории.

Механизм 4. Движок конфликтов

Шесть детекторов, каждый со своим авто-разрешением или эскалацией:

IDДетекторЧто видитАвто-разрешениеИначе
D-1Пересечение claimДва агента держат claim на пересекающиеся артефактыБолее ранний claim побеждает, второй получает conflict.claim_overlapЭскалация → менеджер зоны
D-2Нарушение контрактаРабота вне своей зоны / нарушение non_goalsClaim отклоняется, задача возвращается в readyЭскалация → Product-агент
D-3Конфликт решенийНовый ADR противоречит принятому (не supersede-ит)Новое решение помечается conflict.decisionЭскалация → человек, если веса ролей равны
D-4Устаревшая зависимостьЗадача опирается на артефакт ниже текущей версииЗадача блокируется до rebase/re-acknowledgeАвтопересчёт затронутых задач
D-5Дублирование работыДве задачи с одинаковым выходом (похожий intent + зона)Вторая задача помечается duplicate_candidateЭскалация → Product-агент объединяет
D-6Тихий сбой / потерянный handoffHandoff не принят > SLA; агент молчит > N минутПереназначение на другого агента той же зоныЭскалация → оркестратор

Протокол разрешения (единый для всех типов):

DETECT → CLASSIFY → [AUTO-RESOLVE | ESCALATE] → RESOLVE → LOG → PREVENT

PREVENT — обязательный шаг: каждое разрешение конфликта порождает изменение в контракте, правиле зоны или шаблоне handoff. Иначе конфликт повторится. Это превращает платформу из «пожарной команды» в систему с обучающейся памятью.

Арбитраж по приоритету источников истины (важно, когда доходит до человека):

  1. Контракт проекта — если нарушен он, спор окончен.
  2. Журнал решений (ADR) — последнее принятое решение по теме.
  3. Зона ответственности — кто владеет зоной.
  4. Приоритет задачи — выше приоритет выигрывает.
  5. Человек — только если 1–4 не дали однозначного ответа. И получает не вопрос «кто прав», а два-три готовых варианта с последствиями (ADR-шаблон).

3.3. Сшивающие механизмы

Журнал решений (ADR). Кто, когда, что решил, почему, какие альтернативы, статус (proposed / accepted / superseded). Агенты спорят не по памяти и не по чату, а по фактам из лога. Любой новый ADR, противоречащий существующему, автоматически поднимает D-3.

Общий контекст (Context Pack). Перед началом задачи агент получает сборку: цель проекта, релевантные решения, текущие версии зависимых артефактов, критерии приёмки, ограничения зоны. Это дешёвый способ убить C-3 (дрейф контекста).

Оркестратор (Conductor). Автоматически: декомпозиция цели → граф задач с зависимостями → распределение по зонам → запуск пайплайнов → эскалация по SLA → сборка Handoff-пакетов. Он не делает предметную работу, он управляет потоком. Человек контролирует его через гейты.

Гейты человека (Human Gate). Точки обязательного подтверждения: смена владельца зоны, конфликт равновесных ролей, изменение контракта (цели/non_goals), финальная приёмка релиза, любой шаг с превышением бюджета токенов.

Верификатор (отдельный агент). Агент-приёмщик не может быть автором проверяемой работы. Это устраняет главный источник «зелёных» но некачественных задач.


4. Роли экипажа и зоны ответственности

4.1. Состав

#РольЗона по умолчаниюЧто производитНе имеет права
1Product / UX Strategyzone:requirements, zone:copy, zone:priorityТребования, декомпозиция целей, критерии приёмки, IA-картаМенять дизайн-систему и код
2UI/UX Designzone:design-tokens, zone:components-spec, zone:mockupsДизайн-система, токены, спеки компонентов, макетыПравить production-код
3Fullstack Engineeringzone:app-code, zone:api, zone:dbКод, API, миграции, интеграции, тестыМенять токены без handoff от дизайна
4SEO / Researchzone:semantics, zone:analytics, zone:contentСемантика, карта ключей, аудит, контент-план, технические SEO-рекомендацииМенять разметку разметку/шаблоны напрямую — только через заявку
5QA / Verifierzone:acceptanceПриёмка по DoD, регрессия, отчёт о дефектахМенять артефакты в зонах других ролей
—Человек (Owner)—Гейты, спорные решения, бюджет, релизы—

4.2. Кто из инструментов какую роль играет

Пять проектных ролей распределяются между тремя физическими инструментами. Один инструмент может держать несколько ролей — но решает он их по-разному, и это отражается в профиле прогона.

Проектная рольКто играетИнструментКак именно
Реализация, рефакторинг, многофайловые измененияОсновной исполнительClaude CodeCLI headless + MCP, свой worktree
Альтернативная реализация, тесты, edge-cases, ревью диффаВторой исполнитель и ревьюерChatGPT (Codex)codex exec в отдельном worktree
Исследование, семантика, внешний контекст, проверка гипотезИсследовательGrokxAI API + web search, код не пишет
Требования, критерии приёмки, приоритетыProduct / ведущийЧеловек (или Claude Code в режиме plan)Решения фиксируются как ADR
Приёмка по DoD, регрессияВерификаторClaude Code в отдельном прогоне + проверки в CIПрогон-верификатор ≠ прогон-автор

> Практическое следствие: Judge не может быть автором. Если Claude Code написал код, судьёй этого прогона выступает отдельный запуск другого инструмента или человек. Это дешевле, чем кажется, и снимает главный источник «зелёного, но некачественного» результата.

4.3. Матрица RACI

R — исполнитель, A — ответственный (один), C — консультирует, I — информируется.

АктивProductDesignEngSEOQAЧеловек
Требования и приоритетыA/RCCCIA
Дизайн-система и токеныCA/RCICI
Компонентные спекиCA/RC—CI
Код приложения и APICIA/R—CI
Семантика и контент-планCIIA/RIA
Приёмка и регрессияCCCCA/RI
Изменение целей и non_goalsRCCCIA
РелизRIRIRA

4.4. Правило одного владельца зоны

Зона закреплена за одним агентом в контракте. Это означает:

Это превращает «конфликт» в очевидный, отслеживаемый, SLA-ограниченный поток. Конфликтующих действий просто не может произойти, если агент работает через RELAY.


5. Агрегатор: одна задача → Claude Code + ChatGPT + Grok → один результат

5.1. Постановка

relay.codes — это агрегатор. Его центральный сценарий: человек ставит одну задачу, а платформа сама разбирает её на параллельные прогоны Claude Code, ChatGPT (Codex) и Grok, проверяет каждый результат, сводит их в один артефакт и отдаёт на ревью как единый PR с историей происхождения каждой изменённой строки.

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

        одна задача от человека
                 │
        ┌────────▼─────────┐
        │  Planner (fan-out)│  задача → 3 разных подзадачи + критерии
        └────────┬─────────┘
     ┌───────────┼───────────┐
┌────▼─────┐┌────▼─────┐┌────▼─────┐
│Claude Code││ChatGPT    ││  Grok    │   изолированные worktree + контейнер
│исполнитель││(Codex)    ││исследоват.│
└────┬─────┘└────┬─────┘└────┬─────┘
     │ DoD-гейт   │ DoD-гейт   │ только факты
┌────▼─────┐┌────▼─────┐└──────────┘
│ diff ✓   ││ diff ✓   │
└────┬─────┘└────┬─────┘
     └──────┬──────┘
     ┌──────▼───────┐
     │ Сведение и    │  disjoint → merge · пересечение → Judge
     │ арбитраж      │
     └──────┬───────┘
     ┌──────▼───────┐
     │  ОДИН PR     │  + отчёт: что от кого, что отклонено и почему
     └──────────────┘

5.2. Три инструмента и их роль в прогоне

ИнструментРежим подключенияРоль в прогонеЧего не делаетЧто отдаёт
Claude CodeCLI в headless-режиме (claude -p), MCP-инструменты, потоковый JSONОсновной исполнитель: многофайловые изменения, рефакторинг, реализация по спеке, работа с репозиториемНе принимает финальные решения по чужим прогонамDiff, коммиты, артефакты, отчёт по DoD
ChatGPT (Codex)CLI codex exec (non-interactive), JSONL-событияВторой исполнитель и ревьюер: альтернативная реализация, тесты и edge-cases, разбор диффа, поиск дырНе дублирует Claude Code дословно — иначе это просто двойной расходDiff, тесты, замечания, patch-подсказки
GrokxAI API (OpenAI-совместимый endpoint) + web searchИсследователь: актуальность предметной области, рынок, конкуренты, SEO-семантика, проверка гипотез, свежая документацияКод по умолчанию не пишет — возвращает факты и рекомендацииОтчёт с фактами, ссылками, SEO-рекомендациями

Правило разведения ролей. Три агента получают не одинаковый промпт. Планировщик строит три разных подзадачи:

Если все три получают один и тот же промпт — это не агрегация, а тройной расход токенов. Это прямое требование к Planner'у.

5.3. Конвейер одной задачи

#ШагЧто делает RELAYПровалится, если
1IntakeПринимает задачу от человека, требует acceptance criteria и зонуНет критериев приёмки → задача не создаётся
2DecomposePlanner строит 3 разных подзадачи, схему зависимостей, DoD-чек-листПодзадачи дублируют друг друга → возврат планировщику
3PrepareСоздаёт 3 изолированных окружения: git worktree + ветка + контейнер + лимиты (время, токены)Нет свободного worktree или превышен лимит стоимости
4RunЗапускает 3 прогона параллельно, пишет heartbeat, следит за leaseАгент молчит → детектор D-6, переназначение или эскалация
5VerifyПрогоняет DoD-гейт на каждом прогоне: тесты, типы, линт, a11y, перф-бюджетПровал гейта → прогон не идёт в сведение, а помечается rejected_by_gates
6Diff-arbitrationСравнивает диффы трёх прогонов: пересечение по файлам, хункам и строкамСемантический конфликт → Judge
7MergeСводит прогоны по политике сведения (§5.4)Все три разошлись и Judge не разрешил → человеку
8PublishОтдаёт один PR: сводный дифф, отчёт о происхождении строк, ADR решения, журнал проверок—

5.4. Политика сведения (merge arbitration)

Сведение идёт по правилам, а не по вкусу. Каждая ситуация имеет однозначное поведение:

СитуацияРешениеАвтоматически
Диффы не пересекаются (разные файлы)git merge обоих в сводную веткуДа
Один файл, разные хунки3-way merge, конфликтные маркеры не возникаютДа
Один файл, одни и те же строки, разный смыслСемантический конфликт → Judge получает оба варианта + критерииНет
Grok вернул только факты и рекомендацииФакты → в отчёт и ADR, код не трогаемДа
Все три пришли к одинаковому результатуConsensus: доверие высокое, берётся вариант Claude Code как основной, остальные подтверждаютДа
Ровно два сошлись, третий расходитсяБерётся consensus-вариант, расхождение → в отчёт как «предложено к пересмотру»Да
Все три разошлисьJudge → 3 готовых варианта человекуНет
Прогон не прошёл DoD-гейтИсключается из сведения, причина в отчётеДа

Правило приоритета при равных условиях: Claude Code — основной исполнитель (его дифф базовый), ChatGPT/Codex — дополнения поверх (тесты, edge-cases), Grok — только информация. Это дефолт, который переопределяется решениями в ADR.

5.5. Контракт результата прогона (RunResult)

Все три инструмента приводятся к общему контракту — именно это делает их взаимозаменяемыми и сопоставимыми:

run_id: RUN-4471
task: TASK-201
agent: claude-code
role: implementer
branch: relay/TASK-201/claude-code
context_pack_ref: CP-889            # что агент видел на входе
files_touched: [src/features/search/SearchCard.tsx, src/features/search/page.tsx]
diff:
  insertions: 18
  deletions: 4
  files: 2
artifacts: [artifact/component-spec#v7]
checks:
  - { name: "tsc --noEmit", result: pass }
  - { name: "unit >= 80%", result: pass, value: "86%" }
  - { name: "a11y violations", result: pass, value: 0 }
cost: { tokens: 84_200, duration_s: 411, usd: 1.42 }
verdict: eligible                 # eligible | rejected_by_gates | failed
notes: "..."

5.6. Judge — агент-судья

Отдельный агент, который не был автором ни одного из трёх прогонов:

Судья — это узкое место, поэтому он включается только на семантических конфликтах, а не на каждой задаче.

5.7. Что это даёт в числах

Метрика агрегатораОдин агентТри агента через RELAY
Вероятность, что задача закрыта с первого PRбазовая+25–35 п.п. за счёт тестов второго исполнителя и edge-cases
Доля задач, требующих переделкибазовая−30–40% за счёт слияния на уровне диффов
Стоимость одной задачи (токены)1×2,5–3× (платим за параллельность)
Время цикла задачи1×≈ 0,8× (параллельность компенсирует тройной расход)

Плата за параллельность — тройной расход токенов. Экономика работает только потому, что переделки и отказы на ревью сегодня стоят дороже: в агрегаторе выигрыш приходит из меньшего числа итераций, а не из меньшего числа вызовов. Бюджет ограничивается лимитом на задачу в cost ledger.

5.8. Специфичные риски агрегации

РискМера
Три одинаковых промпта → тройной расход без выигрышаPlanner обязан давать разные перспективы; детектор дублирования подзадач блокирует запуск
Разный стиль кода у трёх авторовФормат и линтер-гейт до сведения; слияние только по пройденным гейтам
«Лучший из трёх» не выбираетсяJudge по критериям, а не по вкусу; при равенстве — человеку с тремя готовыми вариантами
Тройной расход токеновЛимиты на задачу и на проект в cost ledger, предупреждение на 80%, пауза на 100%
Промпт-инъекция из веба (особенно Grok)Внешние выдержки идут в отдельный канал «данные», не в инструкции; агенту запрещено выполнять команды из источников
Один агент «плохо спит» и портит общий результатИзоляция worktree + DoD-гейт + автоматическое исключение провалившегося из сведения

6. Архитектура

6.1. Слои

СлойКомпонентыОтветственность
InterfaceWeb App (доска, артефакты, решения, метрики), Agent CLI (relay task claim), MCP-сервер RELAY, WebSocket/SSE-стрим событийТочка входа для человека и агентов
CoordinationTask Service, Artifact Service, Handoff Service, Conflict Engine, Decision Service, Contract Service, Gate Service, OrchestratorЯдро: состояние, правила, переходы
IntelligenceContext Pack Builder, Impact Analyzer, Similarity/Duplicate Detector, Verifier Runner, Cost/Ledger AnalyzerПроизводные вычисления и автоматизация
IntegrationAgent Adapters (Claude Code / Codex / Gemini CLI / MiniMax / OpenAI API), Git Provider, Browser/MCP tools, SEO tools, Sandbox RunnerСвязь с внешним миром
InfrastructurePostgres 16 + pgvector, Redis 7, BullMQ, S3/MinIO, Docker sandbox, OpenTelemetry, GitХранение, очереди, изоляция, наблюдаемость

6.2. Ключевые технические решения

РешениеОбоснование
Событийная модель (event log)Каждый переход состояния — событие в events. Это даёт: аудит, воспроизведение, повторную обработку, построение метрик без отдельного пайплайна
Claim = lease с TTLClaim не бессрочен. Истёкший TTL освобождает артефакт — «забытый» артефакт не блокирует проект навсегда (и это отдельный детектор D-6)
Версионирование артефактов + impact-графПри bump версии артефакта RELAY считает потребителей и автоматически помечает их задачи как требующие re-acknowledge. Это механическая защита от C-4
Contract-first для дизайн→кодТокены и пропсы компонентов публикуются как схемы (JSON Schema). Инженер генерирует типы и стабы из схемы, а не из скриншота. Пропс-дрифт становится ошибкой компиляции, а не сюрпризом на ревью
Sandbox исполненияКод, сгенерированный агентом, исполняется в изолированном контейнере без доступа к сети и секретам (кроме allowlist)
Один оркестратор, но решения — за людьмиОркестратор оптимизирует поток, но не имеет права менять цели. Гейты — единственный путь изменения контракта
Полный аудит и cost ledgerКаждый запуск агента фиксируется: токены, стоимость, время, что сделано. Это делает «почему мы потратили 40k токенов» вопросом с ответом

6.3. Интеграция с агентами

Единый Agent Adapter Interface — агенты подключаются как «исполнители с входом и выходом», а не как «чат-боты»:

interface AgentAdapter {
  capabilities(): Capability[]          // design | code | research | verify | plan
  run(task: TaskEnvelope): RunHandle    // получает Context Pack + Task
  report(run: RunHandle): RunReport     // что сделано / не сделано / риски
}

TaskEnvelope = { contract_snapshot, context_pack, task, acceptance_checks, zone, deadline, budget }.

Поддерживаемые адаптеры по приоритету: CLI-адаптеры (Claude Code, Codex, Gemini CLI — самые зрелые, умеют работать с файлами и MCP), API-адаптеры (любая модель через OpenAI-совместимый API), MCP-адаптер (агент сам ходит в RELAY за задачами — pull-модель).

Pull-модель рекомендуется для основного потока: агент сам забирает доступные ему задачи (relay pull --agent design --zone design-tokens). Это снимает проблему «оркестратор не знает, что агент умеет» и позволяет масштабировать экипаж горизонтально.


7. Модель данных

7.1. Основные сущности

projects ──1:N── contracts ──1:N── contract_versions
   │                                   │
   ├──1:N── tasks ──1:N── task_deps     │  (zones, ownership, DoD)
   │        │  └──N:1── agents
   │        └──1:N── handoffs ──1:N── handoff_events (verdicts)
   │        └──1:N── claims (lease+TTL)
   ├──1:N── artifacts ──1:N── artifact_versions ──1:N── artifact_deps
   ├──1:N── decisions (ADR) ──1:N── decision_links
   ├──1:N── conflicts ──1:N── conflict_events ──N:1── resolution
   ├──1:N── gates (human approvals)
   ├──1:N── agent_runs ──1:N── cost_entries
   └──1:N── events (append-only audit log)

7.2. Ключевые таблицы (DDL-схема, сокращённо)

CREATE TABLE tasks (
  id              uuid PRIMARY KEY,
  project_id      uuid NOT NULL REFERENCES projects(id),
  title           text NOT NULL,
  intent          text NOT NULL,              -- для детекта дубликатов (D-5)
  task_type       text NOT NULL,              -- design | code | seo | content | plan | verify
  zone            text NOT NULL,              -- зона по контракту
  owner_agent_id  uuid REFERENCES agents(id),
  state           text NOT NULL,              -- backlog|ready|in_progress|review|blocked|done
  priority        int  NOT NULL DEFAULT 100, -- меньше = выше
  acceptance      jsonb NOT NULL,             -- acceptance criteria (DoD-ссылка + чеклист)
  contract_version int NOT NULL,              -- снимок контракта на момент взятия
  blocked_by      uuid REFERENCES conflicts(id),
  created_at      timestamptz NOT NULL DEFAULT now(),
  updated_at      timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT tasks_need_acceptance CHECK (jsonb_array_length(acceptance) > 0)
);

CREATE TABLE claims (
  id          uuid PRIMARY KEY,
  task_id     uuid NOT NULL REFERENCES tasks(id),
  agent_id    uuid NOT NULL REFERENCES agents(id),
  artifact_id uuid REFERENCES artifacts(id),
  lease_until timestamptz NOT NULL,          -- TTL; истечение → авто-освобождение
  acquired_at timestamptz NOT NULL DEFAULT now(),
  UNIQUE (artifact_id, agent_id) WHERE artifact_id IS NOT NULL
);

CREATE TABLE artifacts (
  id           uuid PRIMARY KEY,
  project_id   uuid NOT NULL REFERENCES projects(id),
  kind         text NOT NULL,                -- design-token|component-spec|api-schema|seo-map|...
  key          text NOT NULL,                -- человекочитаемый путь, напр. color.brand.primary
  owner_agent_id uuid REFERENCES agents(id),
  zone         text NOT NULL,
  current_version int NOT NULL DEFAULT 1,
  consumer_contract jsonb,                   -- схема потребления (JSON Schema)
  UNIQUE (project_id, key)
);

CREATE TABLE artifact_versions (
  id          uuid PRIMARY KEY,
  artifact_id uuid NOT NULL REFERENCES artifacts(id),
  version     int  NOT NULL,
  payload     jsonb NOT NULL,
  breaking    boolean NOT NULL DEFAULT false,
  author_agent_id uuid NOT NULL REFERENCES agents(id),
  reason      text NOT NULL,
  created_at  timestamptz NOT NULL DEFAULT now(),
  UNIQUE (artifact_id, version)
);

CREATE TABLE handoffs (
  id            uuid PRIMARY KEY,
  task_id       uuid NOT NULL REFERENCES tasks(id),
  from_agent_id uuid NOT NULL,
  to_agent_id   uuid NOT NULL,
  packet        jsonb NOT NULL,              -- Handoff Packet
  state         text NOT NULL,               -- proposed|accepted|rejected|superseded
  verdict       text,                        -- accept|accept_with_comments|reject
  verdict_notes text,
  sla_until     timestamptz NOT NULL,
  created_at    timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE decisions (
  id           uuid PRIMARY KEY,
  project_id   uuid NOT NULL REFERENCES projects(id),
  title        text NOT NULL,
  context      text NOT NULL,
  decision     text NOT NULL,
  alternatives jsonb NOT NULL,
  status       text NOT NULL,                -- proposed|accepted|superseded|rejected
  supersedes   uuid REFERENCES decisions(id),
  author_agent_id uuid NOT NULL,
  decided_by   uuid REFERENCES agents(id),   -- человек, если эскалация
  created_at   timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE conflicts (
  id         uuid PRIMARY KEY,
  project_id uuid NOT NULL REFERENCES projects(id),
  type       text NOT NULL,                  -- claim_overlap|contract_violation|decision_conflict|stale_dep|duplicate|silent_failure
  severity   text NOT NULL,                  -- blocker|major|minor
  state      text NOT NULL,                  -- open|auto_resolved|escalated|resolved
  subject    jsonb NOT NULL,                 -- что именно конфликтует
  options    jsonb,                          -- готовые варианты для человека
  resolution jsonb,
  detected_at timestamptz NOT NULL DEFAULT now()
);

Полная схема (+ events, gates, agent_runs, cost_entries, context_packs, task_deps, artifact_deps) — в Приложении B.

7.3. Индексы и производительность


8. API (поверхностность)

REST + WebSocket. REST — для команд и чтения; WS — для живого обновления доски и событий.

Проекты и контракт

POST   /api/projects                       создать проект
GET    /api/projects/:id                   сводка: состояние, здоровье, метрики
GET    /api/projects/:id/contract          текущая версия контракта
POST   /api/projects/:id/contract/versions предложить новую версию (→ gate)
GET    /api/projects/:id/contract/diff     дифф между версиями

Задачи

GET    /api/tasks?project=&state=&zone=&owner=&blocked=
POST   /api/tasks                          создать (валидация зоны + acceptance)
GET    /api/tasks/:id
PATCH  /api/tasks/:id                      title/intent/priority/acceptance
POST   /api/tasks/:id/claim                взять с lease (WIP-check → 409 при превышении)
POST   /api/tasks/:id/release              освободить claim
POST   /api/tasks/:id/state                переход состояния (валидация переходов)
GET    /api/tasks/:id/context-pack         сборка контекста для агента

Артефакты и handoff

GET    /api/artifacts?project=&zone=&kind=
POST   /api/artifacts                      создать артефакт
GET    /api/artifacts/:id/versions
POST   /api/artifacts/:id/versions         bump версии → impact-анализ
GET    /api/artifacts/:id/impact           кто затронут, что заблокировано
POST   /api/tasks/:id/handoff              сформировать Handoff Packet
POST   /api/handoffs/:id/verdict           accept | accept_with_comments | reject

Решения и конфликты

GET    /api/decisions?project=&status=&topic=
POST   /api/decisions                      предложить ADR
POST   /api/decisions/:id/accept|supersede
GET    /api/conflicts?project=&state=&type=
POST   /api/conflicts/:id/resolve          ручное разрешение
POST   /api/conflicts/:id/escalate         → гейт человеку

Гейты и наблюдаемость

GET    /api/gates?project=&state=          очередь на решения человека
POST   /api/gates/:id/approve|reject
GET    /api/agents?project=&state=         статус агентов, текущая нагрузка
GET    /api/agents/:id/runs                запуски, стоимость, результат
GET    /api/metrics/project/:id            KPI дашборда
GET    /api/events?project=&since=         append-only лента (audit + replay)

WebSocket /stream

События: task.created, task.claimed, task.state_changed, handoff.proposed, handoff.verdict, conflict.detected, conflict.resolved, artifact.version_bumped, gate.raised, agent.run_finished, metric.updated.

Agent-facing (CLI / MCP)

relay pull --agent <id> --zone <zone>      взять доступную задачу (pull-модель)
relay report --task <id> --packet <file>   сдать Handoff Packet
relay heartbeat --task <id>                продлить lease
relay ask-context --task <id>              получить Context Pack

9. Протоколы (то, что нужно согласовать как «правила игры»)

9.1. Жизненный цикл задачи

backlog ──(product/plan)──► ready ──(claim)──► in_progress ──(self-check)──► review
                                   │                                            │
                                   │◄──────(blocked: конфликт/зависимость)──────┤
                                   │                                            │
                                   │                                            ▼
                                   └────────(reject + обоснование)────────── done

Правила переходов:

9.2. Правила handoff

  1. Handoff требует заполненного пакета; пустой not_done при отсутствии рисков — норма, но done без единого пункта — ошибка валидации.
  2. Получатель обязан ответить вердиктом за SLA (по умолчанию 4 часа / 1 час для блокирующих).
  3. Вердикт reject без ссылок на нарушенные критерии не принимается системой.
  4. Handoff версионируется: повторная передача той же задачи создаёт новую запись, старая помечается superseded, но остаётся в истории.

9.3. Правила версионирования артефактов

9.4. Правила бюджета


10. Пример сквозного сценария

Цель: «Падение конверсии на шаге оплаты, нужно понять и починить».

ШагКтоЧто происходит в RELAY
1ProductДекомпозирует цель → 5 задач с зависимостями, acceptance criteria, зонами. Задача «Собрать воронку платежа» → ready
2SEOБерёт задачу «аудит аналитики воронки». Claim на артефакт analytics/pay-funnel (lease 2 ч). В конце — Handoff: «воронка теряет 22% на шаге ввода карты; поле требует 6 цифр на десктопе, 4 на мобиле»
3DesignБерёт задачу «редизайн поля карты». Читает Handoff, берёт claim на design/pay-form + token/form-field. Делает макет, публикует версию артефакта с consumer_contract (props, states, токены)
4—Версия токена бампается: RELAY считает impact → 9 компонентов зависят от token/form-field, 2 задачи в review → помечаются requires_reacknowledge, в чат агентов уходит уведомление
5EngБерёт задачу «реализация поля карты». Context Pack содержит: контракт v7, ADR-014 (формат поля), схема props из шага 3, DoD. Код генерируется из схемы, типы — из JSON Schema
6QAЗадача «проверка формы». Запускает DoD-чеки в sandbox: unit-тесты, a11y (contrast/focus/labels), bundle-размер, визуальная регрессия по токенам
7EngОтдаёт Handoff: сделано / не сделано (3D Secure — отдельная задача) / изменено (высота поля +4px) / риски
8QAВердикт: accept_with_comments — 1 замечание (фокус-кольцо), 1 мелкий баг. Задача → done с 1 комментарием, замечание → отдельная задача
9ProductЗадача закрыта. ADR-015: «поле карты принимает 16 цифр с автопробелами» — принято. Всё зафиксировано

Что предотвратил RELAY на этом сценарии: дизайн не пошёл в код без спецификации (шаг 4→5), код не был написан по устаревшим токенам (impact-анализ), SEO не потерял выводы (Handoff вместо «посмотрел и забыл»), приёмка не была на глаз (DoD-чеки в sandbox).


11. План реализации

11.1. Фаза 0 — Процесс без кода (1–2 недели)

Цель: снизить конфликты до появления системы. Даёт эффект немедленно и снижает риск Фазы 1 (платформа будет строить под реальный процесс, а не под выдуманный).

Результат фазы: измеримый baseline и работающий процесс, который RELAY затем автоматизирует.

11.2. Фаза 1 — MVP (4–6 недель)

Цель: закрыть 4 из 6 корневых причин.

#ПодсистемаСодержаниеНеделя
1.1Contract ServiceВерсионирование контракта, зоны, DoD, проверка задач на соответствие1–2
1.2Task Service + Board UIЗадачи, состояния, зависимости, WIP-лимиты, claim/lease2–3
1.3Artifact RegistryАртефакты, версии, impact-граф, consumer_contract3–4
1.4Handoff ServiceПакеты, SLA, вердикты, приёмка по DoD4
1.5Decision Service (ADR)Создание, принятие, supersede, детект D-34–5
1.6Conflict Engine (D-1, D-2, D-4, D-5)Детекторы + авто-разрешение + эскалация5–6
1.7Agent CLI (pull/report)Минимальный клиент для агентов5–6
1.8Adapters инструментовClaude Code (headless CLI), ChatGPT/Codex (codex exec), Grok (xAI API + web search) → единый контракт RunResult3–5
1.9Fan-out PlannerОдна задача → 3 разные подзадачи + DoD-чек-лист; детектор дублирования подзадач4–6
1.10Изоляция прогоновGit worktree + ветка + контейнер на каждый прогон, лимиты времени и токенов4–5
1.11Diff-arbitration + сведениеСравнение диффов (файл / хунк / строка), merge-политика, Judge, единый PR с отчётом о происхождении строк5–7
1.12Базовый дашбордДоска, артефакты, решения, конфликты, активность, экран агрегации6–7

Критерии готовности Фазы 1 — раздел 12. Фаза 1 в агрегаторном виде = одна задача → 3 параллельных прогона (Claude Code, ChatGPT/Codex, Grok) → один PR.

11.3. Фаза 2 — Оркестратор и наблюдаемость (3–4 недели)

11.4. Фаза 3 — Contract-first пайплайн (4 недели)

11.5. Команда и ресурсы

РольЗагрузкаПериод
Backend/Platform engineer1.0 FTEФазы 1–3
Fullstack engineer1.0 FTEФазы 1–2, 0.5 — Фаза 3
Product designer0.5 FTEФаза 1 (Board UI + дизайн-система RELAY), далее по 0.25
Tech lead / архитектор0.3 FTEвсе фазы + human gate
QA0.25 FTEс Фазы 1.6

Инфраструктура (оценка, на 1 проект): Postgres + Redis на существующем VPS ≈ $60–90/мес; объектное хранилище ≈ $10–20/мес; sandbox-раннеры ≈ $80–150/мес (спотовые); LLM-бюджет агентов — считается отдельно по ledger'у (ожидаемое снижение переделок компенсирует 15–25% роста прямых вызовов).

Итого: 13–16 недель, ≈ 24–28 человеко-недель, инфраструктура ~$150–260/мес.


12. Критерии приёмки MVP

MVP считается готовым, если одновременно:

  1. Агент может взять задачу одной командой (relay pull) и сдать результат Handoff-пакетом (relay report), не участвуя в чате.
  2. Задача не может быть взята без acceptance criteria, без соответствия зоне контракту и при превышенном WIP-лимите — система возвращает ошибку с объяснением.
  3. Claim имеет TTL: истёкший claim освобождает артефакт и порождает событие; «забытый» артефакт не блокирует работу.
  4. Bump версии артефакта автоматически помечает зависимые задачи и handoff-пакеты как требующие пересмотра, с визуальным impact-списком.
  5. Приёмка возможна только вердиктом; reject без ссылки на нарушенный критерий отклоняется валидатором.
  6. Детекторы D-1, D-2, D-4, D-5 срабатывают на тестовых сценариях: пересечение claim, работа вне зоны, устаревшая зависимость, дубликат задачи.
  7. Каждый конфликт, разрешённый автоматически, попадает в журнал, и из него генерируется предложение по изменению контракта/правил (шаг PREVENT).
  8. Вся история задачи восстанавливается по ленте событий (replay) — видно, кто, что и когда менял.
  9. Метрики MVP считаются без ручных правок: First-Pass Acceptance, MTTR конфликта, Rework Rate, стоимость задачи.
  10. Экипаж из 3 агентов проходит один полный спринт на RELAY, включая минимум 5 handoff'ов и 2 спровоцированных конфликта, без вмешательства человека в рутину.
  11. Одна задача запускает три параллельных прогона (Claude Code, ChatGPT/Codex, Grok) в изолированных worktree, все три приводятся к единому контракту RunResult.
  12. Планировщик выдаёт три разные подзадачи; при попытке выдать одинаковые — прогон блокируется детектором дублирования.
  13. Сведение работает по правилам: непересекающиеся диффы мержатся автоматически, пересечение по одним и тем же строкам уходит Judge'у, провалившийший DoD-гейт исключается.
  14. На выходе — один PR с отчётом: какая строка от какого агента, что отклонено и по какой причине, решения — в ADR.

13. Метрики и целевые значения

МетрикаСейчас (baseline, Фаза 0)MVPЦелевое (Фаза 3)
Конфликты, закрытые без человека—≥ 60%≥ 85%
MTTR конфликта—< 30 мин< 15 мин
First-Pass Acceptance (handoff без reject)—≥ 65%≥ 80%
Rework Rate (переделки из-за рассинхрона)baseline−25%−50%
Задачи, взятые вне зоны—0 (блокируется)0
Стоимость задачи (токены)baselineвизуализация−20% при росте объёма
Lead time goal → donebaseline−15%−35%
Доля знаний, найденных в Decision Log за < 2 мин——90%

Baseline обязателен до старта Фазы 1 — иначе эффект платформы невозможно доказать.


14. Риски и меры

#РискВероятностьВлияниеМера
R-1Агенты продолжат работать «мимо платформы» (в обход CLI)высокаявысокоеPull-модель: агент берёт задачи только из RELAY; интеграция в MCP/промпт по умолчанию; метрика «% задач из RELAY»
R-2Порог входа (нужно описывать контракт, зоны, DoD) окажется слишком высокимсредняявысокоеШаблоны под 3 типа проектов; автогенерация контракта из существующей документации; Фаза 0 как «процессный» пилот
R-3RELAY станет новым бутылочным горлышком (очередь решений человека)средняявысокоеАвто-разрешение по правилам; человек видит только 2–3 варианта; SLA на гейты
R-4Формализация слишком жёсткая, скорость упадётсредняясреднее«Мягкие» артефакты: контракт может быть частично неформальным; приоритет — не блокировать, а ускорять; метрика lead time как guardrail
R-5Плохая интеграция с конкретными агентами (CLI/API дрейф)средняясреднееАдаптерный слой + контрактные тесты адаптеров; поддержка ≥ 3 агентов на старте
R-6Ложные срабатывания детекторов (особенно D-5 дубликаты)высокаясреднееПорог близости для D-5 настраиваемый; каждый авто-resolve пишет причину; регулярный тюнинг по логу
R-7Команда не перейдёт на новый процесссредняявысокоеRELAY = минимальное усилие: агент сам подтягивает контекст; человек не переписывает задачи, а подтверждает
R-8Безопасность: выполнение сгенерированного кода, секретынизкаявысокоеSandbox без сети по умолчанию, allowlist инструментов, секреты только через MCP-broker с аудитом, redacting логов

15. Что нужно от вас для старта (решения на согласование)

#ВопросРекомендацияВлияние
1Где живёт репозиторий платформы — отдельный сервис или монорепо рядом с продуктом?Отдельный сервис (self-hosted, Docker Compose) + тонкий CLIОпределяет эксплуатацию
2Кто владелец продукта RELAY — вы лично или отдельный техлид?Вы как владелец, техлид — исполнитель решенийОпределяет, кто закрывает гейты
3Область первого пилота: один реальный проект (например, sales.travel) или синтетический?Реальный проект, ограниченный по объёму (1 фича-спринт)Определяет риск и качество baseline
4Человек в контуре: только гейты или также ежедневное участие в приёмке?Только гейты + 1 разбор в деньВлияет на вашу нагрузку
5Бюджет LLM на MVPОтдельный лимит на RELAY-пилот: $300–500/мес на пилотный проектОпределяет, сколько задач прогоняем
6Агенты-пилоты (какие подключаем первыми)Product + Design + Fullstack; SEO подключаем в Фазе 2Определяет объём интеграций
7Формат хранения артефактовGit-репозиторий артефактов (дизайн-токены как JSON в репо) + RELAY как индексВлияет на аудит и diff
8Горизонт: делаем MVP за 4–6 недель или сначала 2-недельный срез2-недельный срез (доска + контракт + handoff + ADR) → показ → полный MVPСнижает риск большого проекта
9Провайдеры и доступ: где лежат ключи к Claude Code, ChatGPT/Codex и Grok — у вас, у платформы или у команды?Ключи платформы в secret-хранилище, доступ по проекту и лимиту; в репозитории — только идентификаторыОпределяет, как агрегатор запускает прогоны
10Что делает Grok в коде: только исследование или тоже пишет кодПо умолчанию не пишет: возвращает факты, SEO-семантику и рекомендации. Код — только по явному флагуСнижает риск «трёх авторов одного файла»
11Правило сведения по умолчанию: чей дифф базовыйClaude Code — базовый, ChatGPT/Codex — дополнения (тесты, edge-cases), Grok — информация. Переопределяется ADRОпределяет, как выглядит 90% слияний
12Домен и эксплуатация: relay.codes уже зарегистрирован, но обслуживается сторонним парковщикомПеревести NS на Cloudflare, привязать домен к платформе, TLS — через платформуОпределяет, кто отвечает за доступность

16. Приложения

Приложение A. Глоссарий

ТерминЗначение
Контракт проектаВерсионируемая спецификация проекта: цели, границы, стек, зоны владения, DoD
Зона (zone)Именованная область ответственности, закреплённая за одним агентом
АртефактВерсионируемый результат работы агента с интерфейсом потребления
Handoff PacketФормализованная передача результата от агента к агенту
ClaimLease на задачу/артефакт с TTL, защищающий от двойной работы
ADRArchitecture/Product Decision Record — запись о принятом решении
Impact-графСвязи «артефакт → потребители → задачи → handoff-пакеты»
WIP-лимитМаксимум одновременных задач у агента
ГейтТочка обязательного человеческого подтверждения
PREVENTОбязательный шаг разрешения конфликта: изменение правил, чтобы не повторилось

Приложение B. Полная схема БД

Дополняет раздел 7.2: events, task_deps, artifact_deps, gates, agent_runs, cost_entries, context_packs, decision_links, artifact_consumers, notifications.

Приложение C. OpenAPI-спецификация и event-схемы

Готовится в Фазе 1; контракт зафиксирован в разделе 8.


Конец документа. Согласование: раздел 15.

RELAY · агрегатор ИИ-агентов · технический проект v0.9 relay.codes
Created by MiniMax Agent
×