← всі звіти · federation-upgrade-plan.md

title: Federation upgrade — план переходу handoff'ів VPS↔Desktop з file-based на mTLS канал date: 2026-05-10 status: draft, чекаю ОК Сергія author: VPS Claude

Federation upgrade — план

TL;DR

Замінюємо файловий handoff (outbox-to-desktop / inbox-from-desktop) на двосторонній mTLS-канал зі structured messages. VPS-Claude (я) і Desktop-Claude бачать handoff'и миттєво, без ls outbox-to-desktop/. Кожне повідомлення підписане ed25519, не може бути підкладене третьою стороною з root-доступом до VPS.

Запозичено з ruflo Federation, але мінімалістично — без trust-scoring layer, без cross-machine swarms (це overkill для однієї пари VPS+Desktop).


Стан "як є" (baseline)

Поточний handoff flow

  1. VPS → Desktop:
    • Я роблю Write /root/.claude/projects/-/memory/outbox-to-desktop/<timestamp>-<topic>.md
    • Desktop у наступній SessionStart hook'у читає директорію + завантажує файли в additionalContext
    • Або: Desktop робить ssh root@31.131.26.203 'cat outbox-to-desktop/*.md' (вручну)
  2. Desktop → VPS:
    • Desktop пише локально + cat note.md | ssh root@31.131.26.203 'cat > inbox-from-desktop/<timestamp>-topic.md'
    • Мій SessionStart показує count + список імен файлів
  3. Після обробки: файли переносяться в processed/ ручним mv

Проблеми


Стан "як буде" (after Federation)

Архітектура

┌──────────────┐                       ┌──────────────┐
│  VPS Claude  │  ───── mTLS WSS ────  │   Federation │
│  (Telegram   │  ←──── push events ──  │   Broker      │
│   bot)       │  ───── ed25519 sig ─  │   (на VPS)    │
└──────────────┘                       └──────────────┘
                                              ↑
                                              │ mTLS WSS
                                              ↓
                                       ┌──────────────┐
                                       │Desktop Claude│
                                       │ (Windows /   │
                                       │  Cowork)     │
                                       └──────────────┘

Компоненти

  1. Broker service (/srv/services/federation-broker/, Python + websockets + sqlite)
    • WSS-сервер на 127.0.0.1:8090, прокинутий через Caddy на federation.deltamedicalservices.online (після NS-handoff)
    • Реєстрація клієнтів через mTLS-handshake (ed25519 client certs)
    • Persistence у sqlite: messages table (id, from, to, payload_json, signature, created_at, delivered_at, ack_at, status)
    • Push notifications: коли VPS пише — Desktop одразу отримує (якщо connected); коли offline — accumulates і пушить при reconnect
  2. Client SDK (federation_client.py, embedded в обох Claude-сесіях)
    • Async websocket-листенер на бекграунді
    • Hooks у SessionStart + Stop
    • API: fed.send(to, topic, payload), fed.poll(since), fed.ack(message_id)
  3. mTLS certs (/srv/passepartout/federation/)
    • Self-signed CA, ротація кожні 6 міс
    • Client certs: vps-claude.crt, desktop-claude.crt

Структура повідомлення

{
  "id": "2026-05-10T12:00:00Z-abc123",
  "from": "vps-claude",
  "to": "desktop-claude",
  "topic": "superpowers-plugin-trial",
  "priority": "normal",
  "payload": {
    "type": "task",
    "title": "Обкатати obra/superpowers",
    "body": "...markdown text...",
    "actions": ["install", "test", "report"]
  },
  "signature": "ed25519-base64-...",
  "ts": "2026-05-10T12:00:00Z"
}

Що змінюється для мене (VPS Claude)

Замість Write /root/.claude/projects/-/memory/outbox-to-desktop/...md:

fed.send(to="desktop-claude", topic="superpowers-plugin-trial",
         payload={"type": "task", "title": "...", "body": "..."})

Або через slash-команду: /fed-push desktop-claude task "Обкатати obra/superpowers"

Що змінюється для Desktop

Замість читання outbox у SessionStart:


План впровадження (3 етапи, 3 дні)

Etap 1 — Broker MVP (1 день)

Etap 2 — Client SDK (1 день)

Etap 3 — Desktop integration + migration (1 день)

Загалом: 3 дні роботи.


Що НЕ робимо в Federation MVP


Ризики

Ризик Mitigation
Broker впав → handoff'и стоять systemd auto-restart + Watchdog моніторить health endpoint + fallback на file-based
Desktop offline → повідомлення в очікуванні sqlite queue зберігає до reconnect (TTL 7 днів)
mTLS certs протухли Cron-нагадування за 30 днів до expiry + Watchdog алерт
Race condition між file-based і broker під час migration Spec: новий handoff пише ТІЛЬКИ в один з каналів, обидва listener'и відпрацьовують ідемпотентно
Хтось з root-доступом VPS впише фейкове від мого імені mTLS не врятує (root має ключ), але можна ротати ключі швидше + audit log у sqlite

Інтеграція з SPARC-upgrade'ом

Federation і SPARC незалежні. Можна робити паралельно або послідовно:

Federation НЕ впливає на PM-Agent / Dev Crew логіку. Це окремий transport layer.


Запитання до Сергія перед стартом

  1. Послідовно (SPARC → Federation, 7 днів) чи паралельно (4-5 днів, але вище ризик) — як зручніше?
  2. Domain для broker'а: federation.deltamedicalservices.online (потрібно дочекатись NS-handoff з Hostiq на Cloudflare). Поки на 31.131.26.203:8090 з self-signed CA — ОК?
  3. Як хочеш отримувати notifications про нові handoff'и: (а) тільки в Claude Code банері, (б) теж пушити у Telegram, (в) лише у логи?
  4. Залишаємо file-based outbox/inbox як fallback на 2 тижні, чи одразу deprecate після успішного migration?

Артефакти цього плану

Після ОК Сергія: