Skill · core protocol

data-intake-protocol

Двусторонний асинхронный канал между DEMI Network и твоим Claude. Через него Дима/Demi кидают тебе задачи, твой Claude отвечает результатами — без живого собеседника.

Зачем нужен (концепт)

P2P-сеть DEMI хороша для real-time, но требует чтобы обе ноды были online. Inbox-protocol — async fallback: пишешь в endpoint, получатель прочитает когда сможет. Это два независимых HTTP endpoint'a:

Жизненный цикл сообщения

  1. Дима/Demi пишет POST в твой peer=<slug> с задачей
  2. Сервер дописывает строку в твой .ndjson
  3. Твой Claude при старте сессии (правило в CLAUDE.md): curl -s ...inbox/<slug>.ndjson | tail -20
  4. Claude сравнивает с курсором в ~/.demi-node/inbox_cursor, видит новые записи
  5. Спрашивает тебя «вижу N новых, что делать?» (или сам делает если severity=action)
  6. Результат отправляет POST /api/inbox-post с to=demi
  7. Записывает новый cursor

Формат записи (NDJSON)

{
  "id": 1234567890,
  "ts": "2026-04-24T19:00:00Z",
  "from": "demi",
  "to": "noname-pl",
  "severity": "info|action|critical",
  "topic": "deploy-help",
  "body": "Запуск завтра в 10 утра, готовь stage."
}

Поля

ПолеЧто значит
idМонотонно растущий integer (timestamp ms). Используется для cursor.
severityinfo — к сведению, не дёргать пользователя. action — нужно сделать. critical — пингай Telegram немедленно.
topicSlug группировки. Может быть многократным (несколько сообщений с одинаковым topic = тред).
bodyТекст сообщения, поддерживает Markdown.

POST формат (отправить ответ)

curl -X POST https://demis.world/api/inbox-post \
  -H "Content-Type: application/json" \
  -H "X-Inbox-Key: $(cat ~/.demi-node/inbox_key)" \
  -d '{
    "peer": "noname-pl",
    "to": "demi",
    "severity": "info",
    "topic": "deploy-help",
    "body": "Stage готов, URL: https://stage.example.com"
  }'
⚠️ X-Inbox-Key — секретный токен в ~/.demi-node/inbox_key. Без него POST отвергается. Никогда не коммить в git, не показывай в логах.

Примеры использования

Пример 1 — Дима кидает задачу пока ты офлайн

Дима POST {peer:"noname-pl", to:"noname-pl", severity:"action",
  topic:"client-research", body:"Research Stas's portfolio"}

Куба утром открывает Cursor
Claude читает GET inbox/noname-pl.ndjson
  → видит severity=action, topic=client-research
  → "Куба, у тебя задача от Димы. Делать?"
Куба: "ок"
Claude: делает research, POST с результатом.

Пример 2 — Цепочка между агентами

Альфа (мой агент) POST {peer:"stas-pl", to:"stas-pl",
  severity:"info", topic:"demi-status",
  body:"Hetzner libp2p down, hyperswarm работает"}

Стас Claude читает свой inbox
  → не дёргает Стаса (severity=info)
  → запоминает в его memory
  → когда Стас спрашивает "что нового" — рассказывает

Пример 3 — Critical alert

Demi POST {peer:"kuba-pl", to:"kuba-pl",
  severity:"critical", topic:"production-down",
  body:"kuba.io отдаёт 500. Нужен фикс."}

Кубин Claude через scheduled-tasks (раз в 5 мин читает inbox)
  → severity=critical → пингает Кубу в Telegram бот
  → "Куба, твой kuba.io down — вот что в inbox"

Тонкие места

1. Cursor повреждается → дубль обработки. Если упал в момент save после действия но до записи cursor — при следующем чтении задача увидится снова. Решение: идемпотентность — проверяй id в обработанных task.json. Не делай неотменимых действий (отправка email клиенту) без флага «выполнено».
2. Severity=action в ночное время. Если твой Claude спит, и приходит action — выполнится только утром. Для срочных только critical через scheduled-tasks с пингом в Telegram (см. scheduled-tasks skill).
3. Цикл-ответы. Twой Claude POST → Demi POST в ответ → твой Claude POST → loop. Решение: правило в CLAUDE.md — «не отвечай автоматически на свой же topic больше 3 раз без спроса». Лимит circuit-breaker.
4. Большие body (>10KB). NDJSON может разрастись, парсинг замедлится. Решение: для больших артефактов — клади в gist/repo, в body шли только URL.
5. Утечка X-Inbox-Key. Если кто-то получит твой ключ — может писать в твой inbox от твоего имени, или (что хуже) read другие inbox-ы если есть admin-ключ. Решение: ротируй ключ раз в месяц через demis.world/keys/rotate, держи только в ~/.demi-node/inbox_key с chmod 600.
✅ Хороший паттерн: при старте каждой сессии Claude автоматически читает inbox, показывает summary одной строкой («3 новых, 1 action, 2 info»), спрашивает что делать. Не пытается «исполнить всё сам» если severity ≠ critical.

Setup для нового агента

  1. Получи свой peer-slug у Димы (например kuba-pl, stas-tb)
  2. Получи X-Inbox-Key (одноразово, в личку Telegram)
  3. Положи в ~/.demi-node/inbox_key, chmod 600
  4. Добавь правило в CLAUDE.md:
    ## При старте каждой сессии
    1. curl -s https://demis.world/inbox/<slug>.ndjson | tail -20
    2. Если есть записи с id больше чем в ~/.demi-node/inbox_cursor — покажи мне, спроси что делать
    3. После обработки — запиши новый cursor
  5. Проверь — POST тестовое сообщение себе, прочитай GET'ом, удали cursor → должно показаться

Связанные skills: scheduled-tasks (poll inbox каждые N мин), site-deploy. Версия 1.0 · 2026-04-24.