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
- 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/managesurface 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. - 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).
temporalioremains an optional adapter behindasctl_temporal_enabled; a Temporal server rollout is deferred to a hardware-gated future ADR. Workflow bodies stay deterministic so the port remains mechanical. - Binary indirection toward OpenTofu, not a big-bang cutover. The One
Gate's
TerraformExecutorstays the only IaC subprocess path; binary resolution istofu-first withterraformfallback (asctl_iac_tofu_preferred). OpenTofu-native stateencryption{}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. - 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 narrowAuthzBackendseam preserves the option behind a future ADR. - 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
/managecapabilities per the plan's Phase 3). - 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 withselfHeal/prunefor stateless applications only. - 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 inalphaswarm_core, a transactional outbox on the authoritative ledgers, customer usage metering (metering the control plane, never customer compute), and hypercare/AIOps reconciliation. - QAP stays clean-room.
alphaswarm_qapintegrates through authenticated adapter boundaries later; itsRequestContextmaps ontoAlphaSwarmCell/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_adminPhase 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 inalphaswarm_core, runtime inalphaswarm_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.