Architecture: How should the SandboxPlacementRouter be architected to supp...

Documentation for Sessions

🏗️ Architecture: How should the SandboxPlacementRouter be architected to supp...

Date: 2026-03-23
Time: 15:39:09 UTC
Session: gspace1-260.3
Agent: backend
Confidence: 94%
Status: ✅ Documented


📋 Decision Context

Question:

How should the SandboxPlacementRouter be architected to support concurrent multi-server VM routing with role-based workload placement?

Task: S260: Multi-server sandbox infrastructure with concurrent workload routing


🎯 Decision Made

Chosen:

Placement Router pattern (inspired by K8s scheduler + Nomad affinity model): SandboxPlacementRouter implements SandboxProvider interface (zero consumer changes). Config-driven server registry via SANDBOX_SERVERS_JSON with per-server id, url, apiKey, roles[], priority, maxContainers. Filter→Score placement: filter by health+capacity+role, score by priority. Placement map (vmId→serverId) for sticky routing. Per-server health monitor with circuit breaker (healthy→degraded→down). Server IDs: {hardware-class}-{sequence} (ax102-01, ax42-01) — roles as metadata. Git operations moved to ax102-01 (more powerful). ax42-01 kept as sandbox.gograb.space (legacy DNS preserved).

Options Considered:

  1. Modify SelfHostedProvider to accept multiple URLs (breaks single-responsibility)
  2. Two separate SelfHostedProviders in factory (doesn't scale, hacky)
  3. HAProxy/NGINX load balancer in front of both servers (no workload-type routing)
  4. SandboxPlacementRouter with filter-score-place pattern (chosen — clean, extensible, zero consumer changes)

💭 Reasoning

Research across 3 dimensions: (1) Codebase — SelfHostedProvider is single-URL, SandboxProviderFactory selects ONE provider at startup, SandboxHandle has no server affinity. (2) External — K8s filter→score is the gold standard but overkill at 2-3 servers; simplified to priority+capacity. Nomad's constraint+affinity model maps directly (hard: role match, soft: priority preference). Registry-based stickiness beats hash-based for stateful VMs. (3) MCP history — S178.13 documented the missing fallback as known gap. S244 IDS spec identified executive/customer VM mixing as dangerous. S240 snapshot model is current correct approach. The Placement Router wraps multiple SelfHostedProvider-like HTTP clients behind the same SandboxProvider interface, achieving multi-server without touching any consumer code.


📁 Files Involved


🔗 Related


Auto-generated by MCP Smart Consolidation