Skip to main content

ADR 026 — Unified infrastructure control plane resolutions

  • Status: Accepted (2026-07-16) — recorded from the consolidation of the two solution-design reports against the full-estate audit
  • Authors: Platform ops
  • Related: ADR 004, ADR 005, ADR 015, ADR 016, ADR 022, ADR 023, ADR 024, ADR 025, Unified Infrastructure Control Plane Plan — relocated out of this repo (2026-07-18, "docs: relocate plans to alphaswarm_internal"); now archived at alphaswarm_internal/plans/raw/alphaswarm_docs/design/unified-infrastructure-control-plane-plan.md, Central Deployment Control — Next Steps

Context​

Two solution-design inputs proposed architectures for centralizing AlphaSwarm's infrastructure control: an industry B2B SaaS/PaaS architecture report (control/data-plane separation, Silo/Bridge/Pool tenancy, BYOC, SCIM, sagas and outboxes, automated tenant provisioning) and a concrete "Unified Infrastructure Control Plane for AlphaSwarm/QAP" design (typed service objects, Temporal sagas, kopf CRDs, ArgoCD, OpenTofu-from-Python, OpenBao, SpiceDB, PromotionRequest gates, Knight-Capital-anchored money-plane safety).

A full-estate audit (40 repositories) found the second report's architecture ~70% already decided-and-shipped under different names — the controller's One Gate, the asctl service objects/saga engine/promotions intake, the bots-operator drain machinery, and the credentials/OpenBao platform — and found the first report largely congruent with recorded decisions (ADRs 004/005/015/016/022–025, hard rules 42–45). The audit also corrected the second report's premise: the claimed stack does not live in alphaswarm_qap (a Phase-0 clean-room governance scaffold) but in the platform estate. The consolidated analysis, current-state inventory, 28-item gap register, component mapping, and the three-pillar phased delivery plan live in the companion design doc (design/unified-infrastructure-control-plane-plan.md); this ADR records the binding resolutions.

Decision​

  1. Extend, don't rebuild. The unified infrastructure control plane is an extension of the shipped One Gate + asctl substrate in alphaswarm_controller/alphaswarm_core — not a parallel stack. The controller's /manage surface remains the single sanctioned mutating path (reaffirms ADR 022); admin BFF, ops console, UI AdminConsole, and CLI are clients of the same API and gates.
  2. In-process compensating sagas, not Temporal (now). Lifecycle workflows run on the asctl typed saga engine (pure planners, idempotent steps, halt-store consultation before every mutating step). temporalio remains an optional adapter behind asctl_temporal_enabled; a Temporal server rollout is deferred to a hardware-gated future ADR. Workflow bodies stay deterministic so the port remains mechanical.
  3. Binary indirection toward OpenTofu, not a big-bang cutover. The One Gate's TerraformExecutor stays the only IaC subprocess path; binary resolution is tofu-first with terraform fallback (asctl_iac_tofu_preferred). OpenTofu-native state encryption{} renders only when the resolved binary is tofu. The shipped terraform binary is a grandfathered license-gate allowlist entry; the codified license gate blocks NEW BSL/SSPL dependencies. A funded cutover decision (including the HCP-backed edge stacks) is scheduled in the plan's Phase 3.
  4. No second authorization system. Authorization remains the Entra OIDC scope lattice + RFC 9470 step-up + four-eyes + authz_matrix.yaml-as-data (extended with a cell dimension), plus OpenFGA for fine-grained artifact ReBAC. SpiceDB is not adopted; the narrow AuthzBackend seam preserves the option behind a future ADR.
  5. PromotionRequest gates are the single approval substrate. Agents are propose-only; approval requires a distinct human approver with step-up; execution re-gates at consumption time (fresh kill-switch + plan-binding + spec-hash checks). Drift findings raise PromotionRequests and are never auto-applied to production/hard-mandatory workspaces. This posture is extended from terraform to prod-tier workload mutations (rollback, dry-run, and health-gated deploys become first-class /manage capabilities per the plan's Phase 3).
  6. One IaC estate behind One Gate. The infrastructure/ landing-zone tree and the Terragrunt tenant units are routed through the gate (registered as hash-locked stack specs); direct-OIDC GitHub Actions applies are demoted to break-glass with a mandatory postmortem trail. ArgoCD is bootstrapped live with selfHeal/prune for stateless applications only.
  7. Report 1's gap list is adopted as roadmap scope: SCIM 2.0 in alphaswarm_auth, an automated Tenant Provisioning Saga (with crypto-shredding as terminal offboarding compensation), tenant-scoped cache/blob isolation conventions in alphaswarm_core, a transactional outbox on the authoritative ledgers, customer usage metering (metering the control plane, never customer compute), and hypercare/AIOps reconciliation.
  8. QAP stays clean-room. alphaswarm_qap integrates through authenticated adapter boundaries later; its RequestContext maps onto AlphaSwarmCell/AlphaSwarmTenant. The control plane never becomes a QAP dependency and QAP keeps its own license/attestation gates.

Consequences​

  • The management surfaces converge on one contract: the controller OpenAPI (docs/reference/manage-api/) is the admin API of record; the legacy Vite admin SPA has since retired in favor of the Next.js surface (alphaswarm_admin Phase 3.11, 2026-07-16); duplicate admin broker paths collapse; the ops console remains observational with mutations deep-linking into /manage (reaffirms ADR 023).
  • Every steady-state mutation of cloud or cluster state lands a ledger row through the gate — including the previously ungoverned landing-zone tree.
  • AlphaSwarm Admins gain a complete manual control loop (propose → plan → review → approve → execute → halt/rollback → audit) with no prod mutation path that bypasses step-up.
  • Standing prohibitions are codified: no agent write credentials; no auto-applied drift; no partial rollouts without health gates; no canary/blue-green on StatefulSets; no secrets in saga state or overlays; no reuse of retired feature flags; no new BSL/SSPL dependencies.
  • Deferred items are explicit and hardware-gated (Temporal server, HA multi-node control plane, SpiceDB adapter, multi-account cell isolation).

Alternatives considered​

  • Adopt Temporal as the primary lifecycle engine (per the second report): rejected for now — zero temporalio in the estate, the recorded Celery+SecureTask decision, and the RAM-bound single-node production box.
  • Immediate OpenTofu cutover with a BSL ban: rejected — the shipped terraform v1.15 path, HCP-backed edge stacks, and committed lockfiles make a big-bang swap riskier than gated binary indirection plus a license gate on new dependencies.
  • SpiceDB ReBAC: rejected — a second authorization system alongside the scope lattice and OpenFGA is the failure mode, not the fix.
  • A new packages/asctl-* monorepo layout: rejected — modules map onto the existing repository boundaries (contracts in alphaswarm_core, runtime in alphaswarm_controller) per ADR 005.
  • Building the control plane inside alphaswarm_qap (the second report's framing): rejected — QAP is a clean-room scaffold; placing platform infrastructure there would violate its source-boundary policy and its dependency-light posture.