Mac → gateway-web
browser- Abrir gateway-web en el navegador
- Conectar al workspace remoto
- Seleccionar provider + channels ON
Playbook · UC5 · Workspace E2E
El use case definitivo: todo en el workspace container remoto. Sesión via gateway-web, channels activos, spawn de segunda sesión desde el workspace, mensajería bidireccional realtime entre peers remotos y Mac. Si esto pasa, el ecosistema a2a está completo.
El playbook de victoria. Todo el ecosistema a2a funcionando en el workspace container remoto: gateway-web conectado al workspace, sesión con channels, spawn de una segunda sesión desde el workspace, mensajería bidireccional realtime entre peers remotos y el Mac de waxin. Si este playbook pasa, la fase 0.18 está completa.
curl -s https://lab1-helsinki.api.mks2508.systems/health → 200 OK Gateway-server del workspace respondecurl -s https://broker.gateway.mks2508.systems/healthz → 200 OK Broker público respondewhich a2a-mcp → /usr/local/bin/a2a-mcp a2a-mcp wrapper existeenv | grep GATEWAY_BROKER_URL → broker público Env var configuradaenv | grep OIDC_CLIENT_ID → valor presente Credenciales OIDC inyectadassupervisorctl status gateway → RUNNING Servicio gateway corriendohttps://lab1-helsinki.api.mks2508.systems Conectado al workspace remotops aux | grep claude → proceso corriendo El CLI de Claude está vivo dentro del container# Desde gateway-web o vía curl: $ curl -s -X POST https://lab1-helsinki.api.mks2508.systems/api/sessions \ -H "Content-Type: application/json" \ -d '{ "providerMode": "minimax", "cwd": "/workspace", "channels": true }' | jq . → { → "session": { → "sessionId": "ws-a-abc123...", → "state": "running", → "model": "claude-sonnet-4-20250514", → "channels": true → } → } # Verificar en el workspace: $ ssh developer@lab1-helsinki.api.mks2508.systems $ cat ~/.mks-harness/sessions/ws-a-abc123/.claude.json | jq '.mcpServers' → { → "agent2agent": { → "command": "a2a-mcp", → "env": { → "GATEWAY_BASE_URL": "https://broker.gateway.mks2508.systems", → "A2A_PEER_ID": "ws-a-abc123...", → "A2A_CHANNEL_PUSH": "1" → } → } → }
cl minimax --proxy --channels Claude Code en Mac con channels apuntando al broker públicoListPeers → muestra peer del Mac + peer del workspace (sesión A) Ambos peers visibles desde el MacGetPeer ws-a-abc123... → card de la sesión A en el workspace El Mac puede ver el peer del workspaceSendPeerMessage to=ws-a-abc123... content='hola desde Mac' Mensaje enviado al peer en el workspace<channel> block con 'hola desde Mac' El mensaje llegó en tiempo real al workspace<channel> block con la respuesta del workspace Bidireccional confirmado — Mac ↔ Workspace realtime# En el chat de gateway-web, después de que Mac envía un mensaje: <channel source="agent2agent" from_id="mac-peer-xyz..." kind="request" priority="normal"> hola desde Mac </channel> # La sesión A en el workspace puede responder: > SendPeerMessage to=mac-peer-xyz... content="hola desde workspace, recibido!" # Y en el Mac, Claude Code muestra: <channel source="agent2agent" from_id="ws-a-abc123..." kind="request" priority="normal"> hola desde workspace, recibido! </channel>
SpawnPeer name='ws-session-B' provider='minimax' host='lab1-helsinki' Spawn de una segunda sesión gestionada por el gateway-server del workspaceListPeers → 4+ peers (Mac, sesión A, sesión B, gateway-server como runner) La sesión B aparece registrada en el brokerSendPeerMessage to=<peerId-B> content='hola a la spawneada' El Mac puede enviar mensajes a la sesión spawneadaSendPeerMessage to=<peerId-B> content='hola desde A' La sesión A también puede comunicarse con la spawneadaEn el workspace, el gateway-server en modo server (no runner) actúa como
runner implícito para spawns internos. Cuando el broker recibe un POST /api/spawn
con host='lab1-helsinki', enruta el spawn_order al gateway-server del workspace
(que está registrado como runner en el broker).
Esto es diferente a UC4 (runner independiente en Mac). Aquí el gateway-server del workspace es tanto servidor de sesiones como runner de spawns — unifica ambos roles en el mismo proceso.
Si el gateway-server del workspace NO está registrado como runner en el broker,
el spawn fallará con RUNNER_OFFLINE. Hay que verificar que el gateway-server
del workspace se registra como runner al iniciar (el código en runner.ts vs
server.ts — verificar cuál entrypoint se usa en el workspace).
ListPeers desde cualquier peer muestra todos los peers (4+) Peer discovery completoCheckInbox de cada peer → mensajes también en inbox (durable) Los mensajes se persisten en el inbox del broker (SQLite)StopPeer de la sesión B → peer removido Lifecycle completo: spawn → communicate → stop$ ssh developer@lab1-helsinki.api.mks2508.systems # Log del gateway-server (cli-launcher): $ tail -50 /var/log/supervisor/gateway.log → Spawning CLI for session ws-a-abc123... → Peer registered with remote broker: ws-a-abc123 (depth=1) → Spawning CLI for session ws-b-def456... → Peer registered with remote broker: ws-b-def456 (depth=1) # Procesos Claude Code corriendo: $ ps aux | grep claude → developer 1234 ... claude --sdk-url http://127.0.0.1:4105/ws/cli/ws-a-abc123 ... → developer 5678 ... claude --sdk-url http://127.0.0.1:4105/ws/cli/ws-b-def456 ... # Directorios de sesión: $ ls ~/.mks-harness/sessions/ → ws-a-abc123/ ws-b-def456/
Desde el Mac, ejecutar ListPeers después de crear la sesión en el workspace
SendPeerMessage de Mac a workspace → verificar gateway-web
SpawnPeer desde sesión A del workspace → ¿peer B aparece?
UC5 es el criterio de cierre definitivo para la fase 0.18 (broker reliability + flip público + spawn-plane).
Con UC5 verde:
Siguiente fase: 0.19 — polish + test harness automatizado basado en estos playbooks.