# Invest Harness ## Определения | Термин | Значение | |---|---| | Harness | Движок и обвязка агента: цикл выполнения, управление контекстом, состоянием и вызовами инструментов | | Runtime | Среда выполнения программы: например, Node.js или Python; определяется пакетом harness’а | | Plugin | Программное расширение, добавляющее инструменты, интеграции или возможности | | Skill | Инструкции и вспомогательные материалы для конкретной задачи; может содержать скрипты, но сам по себе не предоставляет доступы | | Шаблон агента | Инструкции, совместимый harness, плагины, скиллы и схема пользовательских настроек | | Экземпляр агента | Шаблон с настройками и подключениями пользователя | | Run | Логический запуск с неизменяемым снимком версий, входных данных и настроек | | Attempt | Одна попытка исполнения Run, назначенная конкретному Runner | | Runner | Заменяемый исполнитель, подготавливающий окружение и запускающий harness | | Каталог | Сервис метаданных пакетов, версий, совместимости и прав доступа с собственной БД | | Registry | API доставки OCI-образов; байты образов находятся в отдельном хранилище | | ExecutionSpec | Неизменяемое описание запуска, общее для локального и удалённого исполнения | | Capability | Проверяемая возможность исполнителя: среда, протокол, отмена, checkpoint | | Tenant | Организация или персональное пространство с отдельной границей доступа | | Lease | Ограниченное по времени назначение Attempt исполнителю | ## Концепция и статус Invest Harness — платформа агентов для инвестиций. Автор публикует шаблон и его зависимости, пользователь выбирает шаблон, настраивает его через автоматически построенную форму и запускает локально или удалённо. Оба режима используют один формат пакетов и ExecutionSpec. Документ задаёт целевую архитектуру и контракты первой версии. Реализация сервисов пока не входит в этот репозиторий. Выбранные технологии — проектные решения; численные показатели масштабирования — гипотезы до измерений. Для платформы содержимое окружения Runner — чёрный ящик. Внутри могут работать агентские цепочки, произвольные программы, разные модели и интеграции. Платформа отвечает за доставку пакетов, доступы, ресурсы, состояния и результаты. Она не задаёт инвестиционную стратегию и не гарантирует корректность финансовых выводов или внешних действий. Способность продолжить работу после сбоя должна быть явно объявлена пакетом. Локальный запуск уже загруженного публичного пакета не требует облачного аккаунта. Сеть может требоваться модели или инструментам. Публичность описания пакета не означает доступ к пользовательским данным. ## Пользовательские сценарии 1. Автор загружает версию пакета и схемы, проверяет зависимости и публикует версию. 2. Пользователь выбирает шаблон, заполняет форму и подключает разрешённые интеграции. Сохраняется ревизия экземпляра агента. 3. Пользователь запускает агента локально, в управляемом пуле или на своём Runner. 4. Платформа показывает состояние, события, файлы и итог, позволяет отменить запуск. 5. Если harness поддерживает запрос ввода и checkpoint, пользователь может ответить и продолжить выполнение отдельной попыткой. 6. Обновление шаблона создаёт новую ревизию агента после проверки настроек; текущие запуски не меняются. ## Архитектура C4 Контейнер в C4 — отдельно запускаемое приложение или хранилище, не обязательно Docker-контейнер. Диаграммы используют нотацию Mermaid с явными типами элементов C4. C3 раскрывает логические модули, а не отдельные микросервисы. ### C1 Контекст ```mermaid flowchart LR U["Пользователь / Person"] A["Автор и администратор / Person"] P["Invest Harness / Software System"] M["Модели и внешние интеграции / External System"] L["Локальное окружение пользователя / External System"] U -->|Выбор, настройка, запуск| P A -->|Публикация и управление| P P -->|Разрешённые вызовы| M P -->|Пакеты и конфигурация| L L -->|Вызовы по локальным доступам| M ``` ### C2 Контейнеры и хранилища ```mermaid flowchart TB U["Пользователь / Person"] subgraph P["Invest Harness / Software System"] G["Gateway / Container / Nginx"] W["Web UI / Container / React, TypeScript, JSON Forms"] I["Identity / Logical component of platform API / Sessions, OIDC"] B["Platform API / Container / Go, REST"] DB[("Platform DB / PostgreSQL / роли, агенты, запуски, аудит")] C["Каталог / Container / Go, REST"] CD[("Catalog DB / PostgreSQL / пакеты и версии")] PS[("Package Storage / S3 / архивы плагинов, скиллов, шаблонов")] D["Диспетчер / Container / Go"] E["Сервис исполнения / Container / Go / workflow, jobs, адаптер"] ED[("Execution DB / PostgreSQL / назначения и статусы движка")] R["Registry API / Component of execution service / Go, OCI"] RS[("Registry Storage / S3 / манифесты и слои образов")] ES[("Execution Storage / S3 / логи и технические артефакты")] X["Runner pool / Containers / стандартный адаптер или свой Runner"] J["Job / Ephemeral container / harness и зависимости"] T["Опциональный шлюз инструментов / Container / Go"] S["Secrets / Managed service / KMS-backed encryption"] F[("User Storage / S3 / вход, результат, checkpoint")] O["Наблюдаемость / OTel, Prometheus, Grafana, Loki"] end L["Local client / Container on user device / Go CLI, Docker"] M["LLM и внешние API / External Systems"] U --> G G --> W G --> B W -->|Вход| I I --> DB B -->|Проверка личности| I B --> DB B --> C C --> CD C --> PS D -->|Готовые задания| DB D -->|Зафиксировать версии| C D -->|Назначение через адаптер| E E --> ED E --> ES R -->|Метаданные| ED R -->|Байты образов| RS X -->|Runner Protocol, lease, heartbeat| D X -->|OCI pull через API| R X --> J J -->|Токен запуска| B J --> F J --> T J -->|При явно разрешённом прямом доступе| M T -->|Проверка прав и бюджета| B T --> S T --> M B --> F D --> S B -.-> O C -.-> O E -.-> O X -.-> O T -.-> O U --> L L -->|Пакеты| C L -->|Образы| R L -->|Локальные credentials| M ``` Путь X → D обозначает публичный протокол собственной реализации Runner. Стандартный исполнитель соединяется со своим движком через адаптер внутри сервиса исполнения; он не обязан нативно поддерживать этот протокол. Диспетчер остаётся единственным владельцем бизнес-решения о назначении. Нельзя одновременно выдавать один Attempt через обе системы очередей. Gateway логически обслуживает публичные HTTPS-маршруты; внутренние стрелки сокращены. Авторизация выполняется в принимающем сервисе и не заменяется наличием Gateway. Registry на схеме вынесен для наглядности, но может работать в одном процессе с сервисом исполнения. S3 buckets логически отдельны; физический сервис может быть общим. ### C3 Каталог ```mermaid flowchart LR U["Platform API / Author"] subgraph C["Каталог / Container"] A["REST API / Go"] P["Проверка прав и видимости"] V["Проверка манифеста, схем и digest"] Q["Resolver зависимостей и совместимости"] N["Публикация неизменяемой версии"] end DB[("Catalog DB / PostgreSQL")] S[("Package Storage / S3")] R["Registry API / OCI"] U --> A A --> P P --> V P --> Q V --> N V --> S V --> R N --> DB Q --> DB ``` ### C3 Исполнение и registry ```mermaid flowchart TB D["Диспетчер / Go"] X["Стандартный исполнитель или свой Runner"] OCI["OCI client / Docker Engine"] subgraph E["Сервис исполнения / Container"] A["Execution adapter API / Go"] P["Сервисная авторизация"] W["Workflow и jobs"] L["Назначения и состояния движка"] H["Приём событий, логов и завершения"] R["Registry API / OCI push и pull"] end DB[("Execution DB / PostgreSQL")] RS[("Registry Storage / S3 / image bytes")] ES[("Execution Storage / S3 / logs and artifacts")] D --> A A --> P P --> W W --> L X -->|Через соответствующий адаптер| L X --> H H --> L L --> DB H --> ES OCI --> R R --> P R -->|Метаданные| DB R -->|Манифесты и слои| RS ``` ### Технологии и границы реализации | Система | Стек | Как создаётся | |---|---|---| | Web UI | TypeScript, React, JSON Forms | Новый интерфейс | | Platform API и identity | Go, REST, OpenAPI, сессии, OIDC | Продуктовый API с адаптацией существующих механизмов аккаунтов | | Каталог | Go, PostgreSQL, S3 API | Новый отдельный сервис | | Диспетчер | Go, PostgreSQL, transactional outbox | Новый слой квот и назначений | | Сервис исполнения | Go, SQL, существующие workflow/jobs | Адаптация готового ядра; внутренние детали скрыты контрактом | | Registry | Go, OCI Distribution API, PostgreSQL, S3 | Переиспользуемый компонент ядра | | Стандартный Runner | Go, Docker Engine | Готовый исполнитель с адаптером | | Собственный Runner | Любой язык, HTTPS Runner Protocol v1 | Независимая реализация; требуется проверка совместимости | | Локальный клиент | Go CLI, Docker Engine | Общий resolver и ExecutionSpec; локальное состояние в файлах | | Хранилища | PostgreSQL; S3-совместимое хранилище | Отдельные базы, buckets и сервисные учётные записи | | Secrets | Envelope encryption, KMS; локально OS keychain | Провайдер выбирается при развёртывании | | Шлюз инструментов | Go, HTTPS | Опциональный новый сервис | | Наблюдаемость | OpenTelemetry, Prometheus, Grafana, Loki | Интеграция; без payload и секретов по умолчанию | | Начальное развёртывание | Linux, Docker Compose, Nginx | Управление и исполнители на разных машинах | Runtime внутри harness’а не ограничен языком платформы. Kubernetes — будущая реализация Runner, не зависимость MVP. Kafka и отдельный координатор кластера в MVP не требуются. ## Публикация пакета ```mermaid sequenceDiagram participant A as Автор participant C as Каталог participant S as Package Storage / Registry participant D as Catalog DB A->>C: Создать draft и запросить upload C-->>A: Ограниченный адрес загрузки A->>S: Загрузить архив или OCI-образ A->>C: Publish с digest и манифестом C->>S: Проверить наличие, размер и digest C->>C: Проверить схему и зависимости C->>D: Зафиксировать immutable version C-->>A: Published version ``` Метаданные опубликованы только после проверки объекта. Незавершённые загрузки убирает сборщик мусора после grace period. Каталог хранит четыре типа пакетов: harness, plugin, skill, template. Версии неизменяемы; блокировка — изменяемая политика доступа поверх версии. Детали: [каталог](catalog.md). ## Настройка через JSON Schema Автор шаблона задаёт config.schema.json, config.defaults.json и необязательную ui.schema.json. Схемы настроек harness’а и плагинов подключаются шаблоном в отдельные пространства имён. Пользователь меняет значения, не схему автора. Secret-поля содержат ссылки на подключения, а не значения credentials. ```mermaid sequenceDiagram participant U as Пользователь participant W as Web / локальная форма participant C as Каталог participant B as Platform API / локальный валидатор W->>C: Загрузить закреплённую схему и defaults C-->>W: JSON Schema и UI Schema W-->>U: Форма настроек U->>W: Значения и ссылки на подключения W->>B: Сохранить конфигурацию B->>B: Проверить схему, права и policy B-->>W: Новая immutable revision ``` Сервер повторно валидирует данные. Скрытое поле формы не является защитой. Defaults применяются отдельным шагом: JSON Schema default не заполняет данные автоматически. [Конфигурация и UI](configuration-ui.md). ## Локальный запуск ```mermaid sequenceDiagram participant U as Пользователь participant L as Local client participant C as Каталог / локальный кеш participant R as Local Runner participant H as Harness U->>L: Запустить экземпляр агента L->>C: Resolve и проверить digest L->>L: Валидировать config, собрать ExecutionSpec L->>R: Spec и локальные secret bindings R->>H: Запустить в ограниченном окружении H-->>R: События и результат R-->>L: Итог и локальные файлы ``` ## Удалённый запуск ```mermaid sequenceDiagram participant U as Пользователь participant B as Platform API participant C as Каталог participant D as Диспетчер participant R as Runner / адаптер participant S as Хранилища U->>B: Создать Run с Idempotency-Key B->>C: Resolve точных версий B->>B: Сохранить Run и outbox в одной транзакции D->>B: Обработать готовый Run R->>D: Claim с capabilities D-->>R: Attempt, lease, ExecutionSpec R->>S: Загрузить пакеты по digest R->>D: Heartbeat и события R->>S: Загрузить результаты R->>D: Complete с lease epoch и manifest результатов D->>B: Финализировать Run B-->>U: Статус и доступ к файлам ``` Обработка допускает повторную доставку; exactly-once внешних действий не обещается. Отзыв lease блокирует поздние записи в платформу, но не может отменить уже отправленный запрос во внешний сервис. [Исполнение](execution.md). ## Авторизация ```mermaid sequenceDiagram participant U as Пользователь participant I as Identity participant B as API participant R as Runner participant T as Tool gateway participant S as Secrets U->>I: Вход I-->>U: Сессия U->>B: Создать запуск B->>B: Tenant, роль, пакет, подключения, квоты B-->>R: Токен только назначенного Attempt R->>T: Разрешённая операция T->>B: Проверить права и актуальность Attempt T->>S: Получить нужный credential T-->>R: Результат без долгоживущего ключа ``` Прямые интеграции разрешаются явно: секрет может потребоваться внутри окружения. В таком режиме runner-owner становится частью границы доверия, а стоимость внешних вызовов нельзя ограничить только платформенным счётчиком. [Доступы и изоляция](security.md). ## Состояния запуска ```mermaid stateDiagram-v2 [*] --> queued queued --> preparing: назначение preparing --> running: окружение готово running --> waiting_input: checkpoint и запрос ввода waiting_input --> queued: подтверждённое продолжение running --> succeeded: результат принят preparing --> failed: ошибка подготовки running --> failed: ошибка preparing --> interrupted: потеря lease running --> interrupted: потеря lease interrupted --> queued: разрешённый повтор interrupted --> failed: повтор запрещён queued --> cancelled: отмена waiting_input --> cancelled: отмена preparing --> cancelling: запрос отмены running --> cancelling: запрос отмены cancelling --> cancelled: остановка подтверждена cancelling --> interrupted: остановка не подтверждена succeeded --> [*] failed --> [*] cancelled --> [*] ``` Переход в waiting_input освобождает исполнителя только после durable checkpoint. Для harness без checkpoint этот режим не предоставляется. При потере lease от собственного Runner результат внешних действий может остаться неизвестным. ## Замена исполнителей ```mermaid flowchart TB D["Диспетчер / tenant policy, capabilities, quotas"] P["Runner Protocol v1 / HTTPS"] A["Адаптер стандартного движка"] R["Собственный Runner"] K["Kubernetes Runner / после MVP"] L["Local Runner"] D --> P P --> A P --> R P --> K P --> L ``` Нативный Runner и адаптер не создают две независимые аренды одного Attempt: платформа хранит lease, адаптер сопоставляет его с executionId движка и подавляет дубликаты. Локальный автономный режим использует тот же ExecutionSpec, но не обязан регистрироваться в облаке. [Протокол Runner](api/executor-api.md). ## Масштабирование ```mermaid flowchart LR API["API replicas"] --> DB[("PostgreSQL / runs + outbox")] D["Dispatcher replicas / atomic claims"] --> DB D --> Q["Логические очереди tenants / fair scheduling"] Q --> A["Управляемый пул"] Q --> B["Собственные пулы tenants"] A --> S[("S3 + локальные кеши образов")] B --> S A --> M["Внешние API / rate limits"] B --> M ``` Ёмкость определяется активными запусками, длительностью и ресурсами; добавление исполнителей ограничено квотами внешних API. Реализации движка с одной активной репликой не масштабируются простым дублированием процесса: сначала проверяются ограничения ядра, затем шардирование по пулам. Формулы, отказы, SLO и retention: [масштабирование](scaling.md). ## MVP и развитие MVP: четыре типа пакетов; immutable versions; конфигурация через формы; экземпляры агентов; ручной и регулярный запуск; стандартный и локальный Runner; документированный протокол своей реализации; отмена, события и результаты; tenant isolation; registry и buckets; аудит. Следующий этап: возобновление через checkpoint, пользовательский ввод, автоматическая миграция конфигураций, Kubernetes Runner, автоматическое масштабирование и коммерческий биллинг. Протокол заранее резервирует эти возможности, но UI не предлагает их без подтверждённой capability. Открытые решения: провайдер KMS и S3, конкретные версии зависимостей, политика модерации публичных пакетов, целевые SLO после нагрузочных измерений, перечень лицензий распространяемых runtime и пакетов. Публичный доступ к этому проекту сам по себе не задаёт лицензию его дальнейшего использования. ## Подробные спецификации - [Каталог и версии](catalog.md) - [JSON Schema Driven UI](configuration-ui.md) - [Исполнение](execution.md) - [Авторизация и изоляция](security.md) - [Масштабирование](scaling.md) - [Общие правила API](api/conventions.md) - [API каталога](api/catalog-api.md) - [API агентов](api/agents-api.md) - [API запусков](api/runs-api.md) - [Runner Protocol](api/executor-api.md) - [Модель данных и JSON Schema](contracts/domain-model.md)