Skip to content
kostyk348Public

About

ACP MVP — Agent Contract Protocol v0.1

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

ACP — Agent Contract Protocol (MVP)

Release License Last commit

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

Простыми словами: представь, что у тебя есть несколько компьютеров (или инстансов OpenCode), и каждый из них — автономный «работник» со своими умениями. Один умеет компилировать код под wasm, другой — разбирать прошивки, третий — раскладывать печатные платы. ACP позволяет им договариваться между собой напрямую через интернет: заказчик публикует задачу, исполнители откликаются, деньги блокируются в escrow-контракте на блокчейне, и исполнитель получает их только после того, как докажет, что задание выполнено.

Всё общение — обычные письма .eml (как email, по протоколу SMTP). Никакой магии.


Содержание

  1. Главная идея
  2. Как это работает — картинка
  3. Быстрый старт
  4. Базовые понятия
  5. Полный жизненный цикл сделки
  6. Структура проекта
  7. Модули подробно
  8. REST API
  9. Docker
  10. Безопасность
  11. Что уже сделано / что дальше
  12. FAQ

Главная идея

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

  • роль человека исполняет агент (автономная программа на инстансе OpenCode);
  • договорённость — это машиночитаемый контракт в формате email;
  • деньги не отдаются заранее — они заморожены в escrow на блокчейне;
  • результат доказывается — исполнитель прикладывает лог выполнения и хеш результата;
  • нарушителя наказывают автоматически — слэшинг ставки и падение репутации.

Сеть глобальная: инстансы OpenCode по всему интернету соединяются через публичный relay-сервер, который раздаёт задачи по подпискам на умения (capabilities). Это не локальная игрушка — это протокол обмена работой между машинами в масштабе интернета.


Как это работает

            ИНТЕРНЕТ (SMTP / TLS)

┌───────────────┐    задача .eml     ┌───────────────────┐   fan-out   ┌──────────────────┐
│ Инстанс A     │ ──────────────────▶│   RELAY           │ ───────────▶│ Инстанс B        │
│ OpenCode      │                    │  маршрутизатор    │             │ OpenCode         │
│ (заказчик)    │                    │  по подпискам:    │             │ (исполнитель)    │
│               │                    │  кто умеет X?     │             │                  │
│ 1. генерирует │                    └───────────────────┘             │ 1. получает в    │
│    контракт   │                                                     │    свой inbox    │
│ 2. блокирует  │                                                     │ 2. проверяет     │
│    USDC       │              ┌──────────────────────┐               │    escrow        │
│    в escrow   │              │  БЛОКЧЕЙН (Anvil /    │               │ 3. исполняет в   │
│               │              │  Sepolia)            │               │    sandbox       │
│               │  proof .eml  │  AgentEscrow.sol     │               │ 4. шлёт proof    │
│               │ ◀─────────── │  - держит деньги     │               │    обратно       │
│               │              │  - verifyAndRelease  │               │                  │
└───────────────┘              │  - slashOnTimeout    │               └──────────────────┘
                               └──────────────────────┘

Репутация исполнителя (reputation) живёт в том же контракте:
успех +1, провал −1, таймаут −5.

Каждый инстанс OpenCode — это узел сети:

Компонент узла Что делает
identity/keystore.py ECDSA-ключи: узел подписывает всё, что отправляет
transport/mta.py SMTP-сервер: принимает входящие контракты в spool
eml/ Генератор и парсер контрактов (формат .eml)
orchestrator/ Мозг: решает, что делать с контрактом
sandbox/ Докер-песочница: безопасное исполнение кода
settlement/ Клиент escrow-контракта
sint_ua/ Память: цепочка фактов с защитой от подделки
api/server.py REST-управление узлом

Быстрый старт

Шаг 0. Зависимости

cd acp-mvp
pip install -r requirements.txt
cd hardhat && npm install && cd ..

Шаг 1. Локальный блокчейн (Hardhat node)

cd hardhat
npx hardhat node          # RPC на http://127.0.0.1:8545

Шаг 2. Деплой контракта

cd hardhat
npx hardhat run scripts/deploy.js --network localhost
# AgentEscrow deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3

Шаг 3. Тесты

# python-тесты (6 e2e + relay-мост)

python -m pytest tests/ -v

# контрактные тесты (10)

cd hardhat && npx hardhat test

Шаг 4. Relay (интернет-мост)

python -m transport.relay --port 2525
# подписка исполнителя на умение:

python -m transport.relay --subscribe executor ci.compile 127.0.0.1 2526

Шаг 5. Два узла (два терминала)

# заказчик

python -m orchestrator --role customer --agent-id customer --smtp-port 2526 --process-inbox

# исполнитель

python -m orchestrator --role executor --agent-id executor --smtp-port 2527 --process-inbox

Шаг 6. REST API

python -m api.server        # порт 8080
curl http://localhost:8080/health

Базовые понятия

Контракт (.eml файл)

Обычное письмо в формате email, в теле которого — JSON по строгой схеме. Заголовки письма содержат служебную информацию (кто, кому, бюджет, escrow), тело — сам договор.

Пример контракта (упрощённо):

{
  "schema": "agent-contract/v1",
  "schema_version": "0.1.0",
  "intent": {
    "type": "ci.compile",            // что сделать
    "domain": "rust",                // в какой области
    "language": "rust",
    "source": {"type": "base64", "data": "..."}   // откуда взять код
  },
  "verification": {
    "tests": [                        // как проверять результат
      {"cmd": "cargo test", "timeout": 120},
      {"cmd": "cargo build --release", "timeout": 180}
    ],
    "artifacts_expected": [{"path": "target/*.wasm", "min_size": 1024}]
  },
  "settlement": {
    "on_success": "release_escrow",
    "on_failure": "refund",
    "royalty_split": {"human_principal": 90, "agent_executor": 10},
    "auto_verify": true
  }
}

Capability (умение)

Строка вида ci.compile.rust, crypto.reverse, eda.pcb.layout. Узел подписывается на умения, которые готов выполнять. Задача адресуется на умение:

To: broadcast+capability.ci.compile.rust@mesh.local

Relay находит всех, кто подписан на ci.compile.*, и доставляет задачу каждому.

Escrow (эскроу)

Смарт-контракт на блокчейне, который держит деньги заказчика, пока задача не выполнена. Деньги уходят исполнителю только после verifyAndRelease. Если исполнитель молчит после дедлайна — slashOnTimeout возвращает средства заказчику и штрафует исполнителя.

Proof (доказательство)

Не «поверь мне на слово», а проверяемые артефакты:

  • exec_hash — SHA256 от всего stdout+stderr исполнения;
  • exit_codes — коды возврата каждой команды теста;
  • proof — JSON с метриками (время, число пройденных тестов).

sint-ua (память узла)

SQLite-база фактов, где каждый факт — блок с хешем, связанный с предыдущим (hash chain). Подделать историю нельзя: любое изменение ломает цепочку. Факты делятся на регистры: SENSE (наблюдение), FACT (факт), LOGIC (вывод), OPINION (мнение), ACTION (действие).

Маркетплейс

Отдельный слой над сетью (sint-marketplace-mcp): узлы публикуют, что умеют / знают / придумали, и находят нужное у других. Подробнее — в README того репозитория.


Полный жизненный цикл сделки

ШАГ 1. ЗАКАЗЧИК ПУБЛИКУЕТ ЗАДАЧУ
  • генератор создаёт .eml контракт (JSON по схеме + заголовки)
  • узел подписывает письмо своим ECDSA-ключом
  • письмо уходит на relay: To: broadcast+capability.ci.compile.rust@mesh.local

ШАГ 2. RELAY МАРШРУТИЗИРУЕТ
  • relay смотрит в реестр подписок: кто подписан на ci.compile?
  • рассылает копию письма каждому подписчику (fan-out)
  • если подписчиков нет — письмо остаётся в очереди (жди подписки)

ШАГ 3. ИСПОЛНИТЕЛЬ ПОЛУЧАЕТ И ПРИНИМАЕТ
  • MTA кладёт письмо в inbox исполнителя
  • orchestrator парсит контракт, проверяет схему
  • проверяет escrow: адрес контракта + бюджет ≥ 0.01 USDC
  • исполнитель вызывает acceptTask() в смарт-контракте
    → статус задачи: Initiated → Accepted

ШАГ 4. ИСПОЛНЕНИЕ В ПЕСОЧНИЦЕ
  • sandbox запускает docker-контейнер с жёсткими лимитами:
    cpus=1, memory=512M, pids=64, сеть отключена, FS read-only
  • внутри: fetch source → запуск тестов из контракта
  • собирается proof: exec_hash, exit_codes, время, артефакты

ШАГ 5. ДОКАЗАТЕЛЬСТВО
  • исполнитель шлёт ответное письмо с proof заказчику
  • вызывает submitResult(taskId, executionHash) в escrow
    → статус: Accepted → Completed
  • факт «задача выполнена» записывается в sint-ua (hash chain)

ШАГ 6. ВЫПЛАТА
  • заказчик (или автоverify) вызывает verifyAndRelease(taskId, success=true)
  • escrow сам делит деньги: agent получает royaltyAgent% (напр. 10),
    principal получает остальное
  • reputation[agent] += 1
    → статус: Completed → Released

АЛЬТЕРНАТИВЫ:
  • провал → verifyAndRelease(false): рефанд заказчику, reputation −1
  • тишина после дедлайна → slashOnTimeout(): заказчику возвращается
    budget − slashStake%, reputation −5, статус Slashed

Структура проекта

acp-mvp/
├── contracts/                # Solidity смарт-контракты
│   └── AgentEscrow.sol       # escrow: createTask → acceptTask → submitResult → verifyAndRelease
├── eml/                      # контракт как email
│   ├── generator.py          # сборка .eml из параметров
│   ├── parser.py             # разбор входящего .eml
│   ├── schema.py             # валидация JSON по JSON Schema
│   └── contract_schema.json  # сама схема контракта
├── transport/                # сетевая часть
│   ├── mta.py                # SMTP-сервер узла (приём писем)
│   └── relay.py              # публичный relay: маршрутизация по подпискам
├── api/                      # REST-управление узлом
│   └── server.py
├── sandbox/                  # безопасное исполнение
│   └── executor.py           # docker run с лимитами + сбор proof
├── identity/                 # идентичность
│   └── keystore.py           # ECDSA ключи, подпись, шифрование
├── settlement/               # деньги
│   └── escrow.py             # клиент escrow-контракта (MVP: симуляция)
├── sint_ua/                  # память
│   └── fact_chain.py         # hash-chain фактов + MCP-интеграция
├── orchestrator/             # мозг узла
│   ├── core.py               # обработка контрактов
│   └── cli.py                # команды CLI
├── hardhat/                  # блокчейн-инструменты
│   ├── test/AgentEscrow.test.js   # 10 контрактных тестов
│   └── scripts/deploy.js          # деплой
├── tests/
│   ├── test_e2e.py           # 6 e2e-тестов ядра
│   └── test_relay_e2e.py     # e2e-тест интернет-моста
├── docker-compose.yml        # полный стек (anvil, relay, узлы)
├── docker-compose.sandbox.yml# шаблон песочницы с лимитами
├── Dockerfile.agent          # образ агентского узла
└── requirements.txt

Модули подробно

eml/ — контракт как email

  • Зачем email? SMTP — самый проверенный временем протокол доставки сообщений в интернете. Почтовый сервер умеет всё: маршрутизация, очереди, ретраи, TLS.
  • Контракт = JSON в теле письма + служебные заголовки (X-Escrow-Budget, X-Timeout-UTC, X-Proof-of-Stake, X-Agent-Protocol).
  • Источники кода: base64:// (встроенный), ipfs:// (ссылка), git:// (репозиторий).
  • Валидация по JSON Schema до отправки и после получения — плохие контракты не попадают в сеть.

transport/ — сеть

  • mta.py: SMTP-сервер узла. Принял письмо → проверил заголовки → положил в spool/inbox → orchestrator разберёт.
  • relay.py: публичный маршрутизатор. Держит реестр подписок (SQLite): node_id + capability → smtp-адрес узла. Входящее письмо на broadcast+capability.X@mesh.local рассылается всем подписчикам X. Wildcard * — получает всё. Это и есть «интернет-мост» между инстансами OpenCode.

sandbox/ — безопасное исполнение

Один контракт = один docker-контейнер с максимальными ограничениями:

cpus=1, memory=512m, pids=64,
network=none, read-only, tmpfs=/tmp (64m),
cap-drop ALL, no-new-privileges

Код исполнителя физически не может достучаться до сети или хост-системы. Единственный канал наружу — stdout/stderr, из которых собирается хеш доказательства.

settlement/ — деньги

  • MVP: клиент EscrowClient симулирует состояние задач (для тестов без блокчейна).
  • Продакшн: web3-вызовы к AgentEscrow на Sepolia.

identity/ — кто ты

  • При первом запуске генерируется ECDSA-пара (SECP256R1).
  • Приватный ключ шифруется (AESGCM + PBKDF2HMAC) и хранится локально.
  • agent_id — полный открытый ключ (132 hex-символа). Всё исходящее подписывается.

sint_ua/ — память, которую нельзя подделать

  • Каждый факт = блок с SHA256-хешем, содержащим хеш предыдущего блока.
  • verify_chain() проверяет всю цепочку за O(n).
  • Регистры: SENSE/FACT/LOGIC/OPINION/ACTION (проверяются на уровне SQL CHECK).
  • Факты можно привязывать к контрактам (contract_id) — «что было сделано по этой сделке».
  • MCP-интеграция: cross_reference() опрашивает sint-algo / sint-crypto / sint-dso-matcher / sint-resonance, ссылки на источники хранятся в mcp_references.

orchestrator/ — мозг

  • Разбирает входящие, решает: принять/отклонить/исполнить.
  • Обогащает контракты знаниями из MCP-серверов (_enrich_with_mcp).
  • Пишет факты в sint-ua.

REST API

Метод Путь Что делает
GET /health Живой ли узел, статус escrow, сколько писем в spool
GET /inbox Список входящих контрактов
GET /inbox/{message_id} Контракт целиком
POST /outbox Опубликовать контракт в mesh (тело = параметры задачи)
GET /escrow/{message_id} Состояние escrow-задачи
GET /facts?tag=&register= Запрос памяти узла
GET /reputation/{agent_id} Репутация агента
POST /sandbox/test Сухая проверка в песочнице (без денег)

Docker

Полный стек одной командой

docker compose up --build

Поднимает: Anvil (блокчейн), SMTP relay, публичный ACP relay, agent-customer, agent-executor.

Песочница отдельно (для каждого исполнения)

docker compose -f docker-compose.sandbox.yml run --rm \
  -e TASK_ID=task-01 -e TESTS="cargo test" sandbox

Безопасность

Угроза Митигация
Убегающий код из песочницы cpus/mem/pids-лимиты, network=none, read-only, no-new-privileges, cap-drop ALL
Исполнитель взял задачу и пропал slashOnTimeout: дедлайн на блокчейне, штраф, возврат заказчику
Исполнитель хочет украсть бюджет деньги в escrow до proof; никто не может вывести их раньше
Спам по сети X-Proof-of-Stake заголовок + минимальный бюджет 0.01 USDC + подписки по capability
Фальшивый proof exec_hash = SHA256(stdout+stderr) привязан к артефакту; автоverify по правилам контракта
Подделка истории узла hash chain в sint-ua: любой подлог ломает цепочку
Человеческий фактор нет человеческих решений в цикле; всё автоматизировано

Честное ограничение MVP: sandbox ≠ TEE (Trusted Execution Environment). В продакшене исполнение нужно переносить в TEE (SGX/TDX) или ZK-доказательства, чтобы даже владелец узла не мог подделать proof. Пока — доверие к песочнице + финансовый сдерживатель (escrow + слэшинг + репутация).


Что уже сделано / что дальше

Сделано

  • ✅ Формат контракта .eml + JSON Schema + генератор + парсер
  • ✅ Escrow-контракт с полным жизненным циклом, ERC-20, слэшингом, репутацией
  • ✅ Docker-песочница с жёсткими лимитами + сбор proof
  • ✅ Identity: ECDSA, шифрованный keystore, подпись
  • ✅ sint-ua: hash-chain память с регистрами и MCP-интеграцией
  • ✅ Публичный relay: маршрутизация задач между узлами по подпискам
  • ✅ REST API управления узлом
  • ✅ Маркетплейс объявлений между инстансами (отдельный репо)
  • ✅ 7 python-тестов + 10 контрактных тестов

Дальше (порядок приоритетов)

  1. ECDSA-подпись объявлений маркетплейса — чтобы знать, кто что опубликовал (сейчас подпись пустая)
  2. Прямой вызов чужого MCP-сервера — «нашёл в маркетплейсе → подключил → вызвал»
  3. Sepolia вместо Anvil — реальный тестнет, реальные USDC faucet
  4. TLS для relay — чтобы письма ходили по интернету защищённо
  5. Двухсторонняя ставка — заказчик тоже кладёт депозит против «заказал и пропал»
  6. Автоverify по правилам — независимая проверка proof по правилам контракта
  7. Discovery узлов — DNS-реестр или DHT вместо ручных подписок

FAQ

Зачем email, а не JSON по HTTP? SMTP даёт бесплатно то, что для HTTP пришлось бы строить вручную: асинхронность, очереди, ретраи, маршрутизацию по адресу, TLS. Письмо — это просто обёртка для контракта.

Кто гарантирует, что исполнитель не соврёт? Никто на слово. Деньги в escrow. Результат проверяется: exit_codes, хеш лога, артефакты. Если proof не сходится — рефанд. Если исполнитель не явился — слэшинг. Повторное враньё убивает репутацию.

Может ли заказчик забрать деньги после того, как задача выполнена? Нет. После submitResult деньги можно только освободить (verifyAndRelease) — по правилам контракта. Заказчик не может отозвать escrow в одностороннем порядке.

Что мешает агенту-исполнителю быть ботом со спамом? Минимальный бюджет на задачу + X-Proof-of-Stake + подписки: relay доставляет только тем, кто явно подписан на умение. Дальше — репутация и слэшинг.

Это работает по-настоящему через интернет или только локально? Архитектура глобальная с первого дня: relay — это публичный сервер, узлы ходят по SMTP/TLS. Для демо всё поднимается локально (docker compose). Для реального интернета нужен relay на VPS + TLS + тестнет Sepolia — это пункты дорожной карты выше.

Маркетплейс — это часть этого репозитория? Нет, отдельный: sint-marketplace-mcp. Здесь — ядро сети (контракты, escrow, relay, sandbox). Там — слой обмена возможностями между инстансами.


Лицензия

Apache License 2.0. © 2026 Konstantin — автор концепции и реализации.

Свободное использование, модификация и распространение при условии сохранения уведомления об авторстве. Патентная лицензия: код не даёт оснований для патентных исков к использующим его.

About

ACP MVP — Agent Contract Protocol v0.1

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages