# Extension routing Version 0.1 — SAND-WP-0006. Select backend when a profile lists multiple extensions. ## Profile route block ```yaml extension: ext.compose-ssh # default / explicit fallback route: strategy: prefer-self-hosted extensions: - ext.compose-ssh - ext.e2b - ext.modal - ext.saas-stub max_cost_per_hour_usd: 1.0 ``` ## Strategies | Strategy | Behavior | |----------|----------| | `explicit` | Use `profile.extension` (default when no route) | | `prefer-self-hosted` | Self-hosted if host available; else credentialed E2B/Modal; else stub | | `lowest-cost` | Self-hosted if available; else cheapest `estimate_cost` | | `lowest-latency` | Self-hosted if available; else last candidate (v0) | ## Testing SaaS fallback ```bash # Skip self-hosted when host unavailable: unset SANDBOXER_HOST SANDBOXER_FORCE_SAAS=1 sandboxer create --profile profile.burst-sandbox # Or use metered-only profile: sandboxer create --profile profile.saas-stub ``` ## Reference profiles | Profile | Route | |---------|-------| | `profile.burst-sandbox` | compose-ssh → e2b → modal → saas-stub | | `profile.e2b-burst` | explicit `ext.e2b` | | `profile.modal-gpu` | explicit `ext.modal` | | `profile.saas-stub` | explicit `ext.saas-stub` | Cloud adapters require provider credentials (`E2B_API_KEY`, `MODAL_TOKEN_ID`). See `docs/cloud-adapters.md`. Resolver: `sandboxer.routing.resolver.resolve_extension`.