Runtime control and data plane separation¶
Historical — archived
This page is kept for provenance. Its dates, targets and technology statements are not current direction. See the linked replacement page.
Merged page (2026-10-09)
Replaces factory/runtime/00-overview.md and factory/runtime/control-plane.md (2025 generation). Their control-plane / data-plane split remains a valid design pattern and is restated below in the plane vocabulary; their run states (Requested → Validated → Queued → Running → Succeeded/Failed/Cancelled), "idempotent jobs", "automatic retry with exponential backoff" and "resume from the last successful step" were design intent, not implemented behaviour. The authoritative run vocabulary is now the one proposed in ADR-0014.
The pattern¶
Orchestration, scheduling, run-state ownership, validation, policy enforcement, audit and the API surface belong to the Control plane: long-running, highly available services over a durable run-state store and a messaging profile. Execution of work units belongs to the Execution and Agent & Orchestration runtime planes: stateless, autoscaled worker pools that consume dispatched attempts, execute them in isolated workspaces and report receipts back to the owner.
flowchart LR
subgraph CP["Control plane (authority)"]
API["Factory API"]
RC["Run Control"]
Store["('Run state + outbox')"]
Audit["Audit sink (Trust & Ops)"]
end
subgraph RT["Agent runtime + Execution (workers)"]
W1["Agent runtime worker"]
W2["Delivery worker"]
W3["Generation worker"]
SBX["Sandboxes / workspaces"]
end
Client["Console · CLI · API · IDE · CI"] --> API --> RC
RC --> Store
RC --> Audit
Store -- "dispatch via messaging profile" --> W1
Store --> W2
Store --> W3
W1 --> SBX
W1 -- "attempt receipts" --> RC
W2 -- receipts --> RC
W3 -- receipts --> RC
Workers never write Control plane tables directly; they submit commands or receipts through the owner's contracts. Workers can be isolated by job type, tenant or security requirement (namespace, node pool, cluster, network policy).
Mapping the 2025 vocabulary to the current design¶
| 2025 term | Current meaning |
|---|---|
| Run | Run (BC-03): one persisted execution with pinned release, policy and model profile |
| Job | Step and attempt: a unit of work and each try of it |
| Requested / Validated / Queued | Phases of acceptance; in the proposed vocabulary a run is Pending until a worker acquires a lease |
| Running / Succeeded / Failed / Cancelled | Running / Completed / Failed / Cancelled (now a first-class terminal state) |
| Repo Generator, Pipeline Generator, SaaS Scaffolder workers | Software Factory pack workloads executed by Execution-plane workers under governed tools |
| Run State DB | Owned relational store of Run Control; transition and outbox in one transaction |
| Job Queue / Bus | Messaging profile (ADR-0012) |
| Automatic retry, idempotent jobs, resume, compensation | Requirements, not guarantees: retry only operations whose side-effect semantics are known; uncertain outcomes are reconciled before retry; resume from a compatible checkpoint or record a new attempt |
Benefits the pattern still provides¶
Independent scaling of control and execution; failure isolation (a lost worker does not lose state); separate security postures (administrative access to the control plane, limited access for workers); independent deployment cadence; scale-to-zero workers against an always-on control plane.
Current implementation¶
None of the above exists for the Factory. The Factory lifecycle library runs in-process in the agent host; there is no run store, queue dispatch, lease, worker pool or audit sink bound to runs. DerechHaLev operates a comparable control/worker split for its own domain using Orleans and Hangfire from the templates, which is evidence that the template estate can host such a design, not that the Factory has one.