# Invest Harness ## Определения | Термин | Значение | |---|---| | Harness | Движок и обвязка агента: цикл выполнения, управление контекстом, состоянием и вызовами инструментов | | DSH | DeepSeek Harness — исходная база стандартного agent runtime Invest Harness | | Connection | Подключение к провайдеру: способ входа, права, место хранения credentials и их состояние | | AttemptContext | Deadline и данные продолжения конкретной попытки, отдельно от ExecutionSpec | | 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. Стандартный агент строится на DSH с собственным интерфейсом и исправленным разделением ядра, конфигурации, credentials и исполнения. Плагины сохраняют совместимость с публичным API DSH в проверенном профиле; другие harness также допускаются. Документ задаёт целевую архитектуру и контракты первой версии. Реализация сервисов пока не входит в этот репозиторий. Выбранные технологии — проектные решения; численные показатели масштабирования — гипотезы до измерений. Для платформы содержимое окружения 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 / роли, агенты, Run, Attempt, расписания, аудит")] C["Каталог / Container / Go, REST"] CD[("Catalog DB / PostgreSQL / пакеты и версии")] PS[("Package Storage / S3 / архивы плагинов, скиллов, шаблонов")] D["Диспетчер / Container / Go"] E["Сервис исполнения / Container / Go / workflow, jobs, адаптер"] ED[("Execution DB / PostgreSQL / executionId mapping и технические статусы")] 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 B --> 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 ``` ### Технологии и границы реализации | Система | Стек | Как создаётся | |---|---|---| | DSH adapter / plugin host | TypeScript, Node.js, DSH / Cordis | Переработанные границы ядра; публичный plugin API сохраняется | | Standalone app | TypeScript, React; Electron / Capacitor | Общие формы, desktop sidecar; mobile управляет Runner | | Provider broker | Go API + изолированные TypeScript provider plugins | Вход, хранение bindings, обновление и отзыв credentials | | 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: подтверждённое продолжение waiting_input --> failed: INPUT_EXPIRED или deadline preparing --> failed: deadline и остановка подтверждена running --> failed: deadline и остановка подтверждена 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; аудит. Полный MVP достигается поэтапно (P0–P5 ниже), а не одним релизом. Следующий этап: возобновление через checkpoint, пользовательский ввод, автоматическая миграция конфигураций, Kubernetes Runner, автоматическое масштабирование и коммерческий биллинг. Протокол заранее резервирует эти возможности, но UI не предлагает их без подтверждённой capability. Открытые решения: провайдер KMS и S3, конкретные версии зависимостей, политика модерации публичных пакетов, целевые SLO после нагрузочных измерений, перечень лицензий распространяемых runtime и пакетов. Публичный доступ к этому проекту сам по себе не задаёт лицензию его дальнейшего использования. ## DSH: интерфейс и внутренняя архитектура Свой UI показывает шаблоны, настройки, подключения, расписания и результаты. Внутри DSH сохраняются публичные точки подключения плагинов; platform adapter изолирует конфигурацию, credentials, запуск и состояния сессий. Runner остаётся заменяемым, а внутренний agent loop — чёрным ящиком для диспетчера. ```mermaid flowchart LR UI["UI / React + JSON Forms"] --> API["Platform API / Go"] API --> SPEC["Immutable ExecutionSpec + AttemptContext"] SPEC --> RUN["Runner / Go adapter или своя реализация"] subgraph JOB["Job / изолированное окружение"] AD["Invest Harness adapter / TypeScript"] CORE["DSH core / Node.js, Cordis"] PL["DSH-compatible plugins / TypeScript"] SK["Skills / инструкции и ресурсы"] AD --> CORE CORE --> PL CORE --> SK end RUN --> AD PL --> BROKER["Provider broker / изолированный plugin host"] BROKER --> STORE["KMS vault или локальное secret storage"] BROKER --> EXT["LLM / официальный клиент / API"] ``` Совместимость подтверждается для конкретных версий DSH, runtime и плагина. Непроверенные пакеты не получают отметку совместимости; зависимость от платформенного API объявляется явно. Детали и исходные источники: [DSH foundation](dsh-foundation.md). ## Плагины и авторизация провайдеров Первая линейка: provider-claude, provider-codex, provider-xai, provider-generic, recurring-tasks и package-discovery. Provider plugins поддерживают API keys и отдельно разрешённые способы входа в аккаунт. Наличие подписки само по себе не делает её доступной стороннему приложению; неподтверждённые режимы не включаются. Плагин расписаний обращается к единому Scheduler, а discovery ищет пакеты и показывает зависимости/разрешения до установки. ```mermaid sequenceDiagram participant U as Пользователь participant UI as Web / Desktop / Mobile participant B as Provider broker / сервер или sidecar participant P as Провайдер / официальный клиент participant S as Разрешённое secret storage U->>UI: Выбрать провайдера и способ входа UI->>B: Создать AuthFlow B->>B: Проверить deployment mode и права B-->>UI: URL / device code / official client action U->>P: Подтвердить вход P-->>B: Результат поддержанного auth flow B->>S: Сохранить credentials или локальный binding B-->>UI: ConnectionSummary без секретов ``` Для official_client авторизация завершается внутри неизменённого клиента; broker получает только статус/binding, не извлекает его tokens. Для API key используется отдельная защищённая передача. Полная матрица и правила: [плагины](plugins.md), [Provider API](api/provider-api.md), [API edge cases](provider-edge-cases.md). ## Режимы приложения и развёртывания ```mermaid flowchart TB WEB["Web / PWA / React"] --> CLOUD["Облачный control plane / Go, PostgreSQL, S3"] MOBILE["Mobile / Capacitor + React"] --> CLOUD MOBILE --> ONPREM["On-prem control plane / тот же стек"] DESKTOP["Desktop / Electron + React"] --> SIDE["Локальный sidecar / Go"] DESKTOP --> CLOUD SIDE --> LOCAL["Local Runner / DSH Node.js или OCI"] CLOUD --> MANAGED["Managed Runner"] CLOUD --> OWN["Свой Runner"] ONPREM --> PRIVATE["Runner внутри инфраструктуры клиента"] ``` Desktop выполняет локально через sidecar; mobile/PWA управляют Runner. On-prem означает размещение всей платформы у клиента; свой Runner при облачном API — отдельный режим. Local CLI остаётся самостоятельным способом запуска без обязательной облачной учётки. ## Roadmap и готовность | Этап | Результат | |---|---| | P0 | DSH spike, фиксация версий, plugin compatibility и контракты | | P1 | JSON Schema Driven компоненты и редактор конфигураций | | P2 | Реестры harness/plugin/skill/template и discovery | | P3 | Локальный и on-premise запуск | | P4 | Managed и собственные Runner, регулярные задачи | | P5 | Provider plugins и допущенные account modes | | P6 | Standalone JS: desktop, mobile, PWA | | P7 | Расширение API edge cases, нагрузка и эксплуатация | Проверки ошибок и изоляции входят в каждый этап, а не откладываются до P7. [Roadmap с критериями выхода](roadmap.md). Начинать можно с P0–P2; [результат проверки дизайна](review.md) разделяет принятые решения и оставшиеся проверки реализации. ## Подробные спецификации - [Каталог и версии](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) - [База DSH](dsh-foundation.md) - [Плагины](plugins.md) - [Provider API](api/provider-api.md) - [API edge cases](provider-edge-cases.md) - [Roadmap](roadmap.md) - [Проверка готовности](review.md)