Control Plane — Aggregate Roots¶
The Control Plane domain comprises 20 aggregate roots, grouped by bounded context. Each aggregate is a consistency boundary: invariants are enforced within it, it is loaded and saved atomically through its repository, and it emits domain events in the canonical envelope. All aggregates carry the cross-cutting metadata fields (tenantId, traceId, createdAt, etc.), persisted as first-class columns. Persistence is NHibernate on Azure SQL / PostgreSQL with ConnectSoft.Extensions.Saas.NHibernate tenant filters.
Target Architecture — Final-State Design
Naming follows the conventions: aggregates and entities are singular PascalCase nouns; repositories are {AggregateRoot}Repository. Fields below show the essential domain state, not every column.
Tenant & Edition Context¶
Tenant¶
- Purpose: The top-level isolation boundary — an isolated customer of the factory. Root of all tenant-scoped data.
- Fields:
tenantId(slug, identity),displayName,region,status(Provisioning/Active/Suspended/Retired),editionId,provisionedAt. - Entities:
TenantContact,TenantSetting. - Value Objects:
TenantSlug,Region,IsolationModel(shared/dedicated). - Invariants: slug is globally unique and immutable; a tenant must reference exactly one active edition; cannot transition to
Activeuntil provisioning completes. - Domain Events:
TenantProvisioned,TenantSuspended,TenantRetired. - Repository:
TenantRepository. - Persistence: Azure SQL (
TenantServiceDB); slug uniquely indexed.
Edition¶
- Purpose: A packaged capability tier — the bundle of feature flags and quota templates a tenant subscribes to.
- Fields:
editionId,name,version,status(Draft/Published/Retired),featureSet,quotaTemplate. - Entities:
EditionFeature,EditionQuota. - Value Objects:
FeatureKey,QuotaLimit,SemVer. - Invariants: a published edition is immutable (new tier = new version); quota template values are non-negative; cannot retire an edition with active subscriptions.
- Domain Events:
EditionPublished,EditionRetired. - Repository:
EditionRepository. - Persistence: Azure SQL (
EditionServiceDB).
Subscription¶
- Purpose: The relationship between a tenant and an edition over time, with lifecycle status.
- Fields:
subscriptionId,tenantId,editionId,status(Trial/Active/PastDue/Cancelled),startedAt,renewsAt,cancelledAt. - Entities:
SubscriptionTerm,BillingAnchor. - Value Objects:
BillingPeriod,Money. - Invariants: at most one active subscription per tenant; cannot activate against a retired edition; cancellation is terminal.
- Domain Events:
SubscriptionActivated,SubscriptionRenewed,SubscriptionCancelled. - Repository:
SubscriptionRepository. - Persistence: Azure SQL (
SubscriptionServiceDB).
Project Management Context¶
Project¶
- Purpose: A factory project — the SaaS product being produced. Owns environments and modules.
- Fields:
projectId(proj-prefixed),tenantId,name,slug,description,status(Active/Paused/Archived),createdAt. - Entities:
ProjectMember,ProjectTag. - Value Objects:
ProjectSlug,IntentSummary. - Invariants: slug unique per tenant; cannot archive a project with running workflow instances; must have at least one environment.
- Domain Events:
ProjectCreated,ProjectPaused,ProjectArchived. - Repository:
ProjectRepository. - Persistence: Azure SQL (
ProjectServiceDB).
Environment¶
- Purpose: A deployment/config scope of a project (
dev/test/staging/prod). - Fields:
environmentId,projectId,name(enum),status(Provisioning/Active/Decommissioned),configScopeRef. - Entities:
EnvironmentVariable,EnvironmentEndpoint. - Value Objects:
EnvironmentName,ConfigScope. - Invariants: environment name unique within a project;
prodrequires an approved release gate before promotion; cannot decommission while referenced by an active deployment. - Domain Events:
EnvironmentProvisioned,EnvironmentDecommissioned. - Repository:
EnvironmentRepository. - Persistence: Azure SQL (
EnvironmentServiceDB).
Module¶
- Purpose: A unit the factory builds (microservice, UI, worker, library, gateway), tracked in the catalogue.
- Fields:
moduleId(module-prefixed),projectId,name,type(Microservice/UI/Worker/Library/Gateway),status,currentBlueprintVersionId. - Entities:
ModuleEndpoint,ModuleArtifactRef. - Value Objects:
ModuleType,ModuleName. - Invariants: module name unique within project; type is immutable after creation; must reference a valid blueprint version once assembled.
- Domain Events:
ModuleRegistered,ModuleRetired. - Repository:
ModuleRepository. - Persistence: PostgreSQL (
ModuleCatalogServiceDB).
ModuleDependency¶
- Purpose: A directed dependency edge between two modules; the basis of the project dependency graph.
- Fields:
dependencyId,projectId,fromModuleId,toModuleId,kind(Build/Runtime/Contract),status(Declared/Resolved/Broken). - Entities: (none — edge aggregate).
- Value Objects:
DependencyKind,VersionConstraint. - Invariants: no self-dependency; the graph must remain acyclic (cycles raise
DependencyCycleDetected); both endpoints must exist in the catalogue. - Domain Events:
DependencyDeclared,DependencyResolved,DependencyCycleDetected. - Repository:
ModuleDependencyRepository. - Persistence: PostgreSQL (
DependencyServiceDB); graph-friendly indexing.
Blueprint Management Context¶
Blueprint¶
- Purpose: A declarative specification of what the factory will build for a module/service, owning its version history.
- Fields:
blueprintId(bp-prefixed),projectId,name,kind(Service/Domain/ContextMap/Solution),status(Draft/Published/Deprecated),currentVersionId. - Entities:
BlueprintVersion(see below),BlueprintParameter. - Value Objects:
BlueprintKind,SpecRef. - Invariants: name unique per project; a published blueprint must have at least one validated version; current version always points to an existing version.
- Domain Events:
BlueprintCreated,BlueprintPublished,BlueprintDeprecated. - Repository:
BlueprintRepository. - Persistence: Azure SQL (
BlueprintServiceDB).
BlueprintVersion¶
- Purpose: An immutable, validated version of a blueprint; the unit referenced by workflows and modules.
- Fields:
blueprintVersionId(bpv-prefixed),blueprintId,version(SemVer),specHash,validationStatus(Pending/Validated/Failed),validatedAt. - Entities:
ValidationViolation,ParsedArtifactRef. - Value Objects:
SemVer,SpecHash,RuleSetVersion. - Invariants: a version is immutable once
Validated;specHashuniquely identifies content; cannot be referenced by a workflow untilValidated. - Domain Events:
BlueprintVersionSubmitted,BlueprintValidated,BlueprintValidationFailed. - Repository:
BlueprintVersionRepository(often accessed viaBlueprintRepository). - Persistence: Azure SQL (
BlueprintServiceDB); validation results may project to PostgreSQL.
Workflow Orchestration Context (core)¶
WorkflowDefinition¶
- Purpose: A reusable, versioned process template (e.g. Project Bootstrap, Sprint Execution, Milestone Lifecycle, Microservice Assembly, Release) seeded from the platform registry.
- Fields:
workflowDefinitionId,name,version(SemVer),status(Draft/Published/Deprecated),steps,gates,timeouts. - Entities:
WorkflowStepDefinition,ApprovalGateDefinition,CompensationDefinition. - Value Objects:
StepKind,RoleRequirement,SkillRequirement,TimeoutPolicy,RetryPolicy. - Invariants: a published definition is immutable; step graph is acyclic with a single start; every gate references a valid role/policy.
- Domain Events:
WorkflowDefinitionPublished,WorkflowDefinitionDeprecated. - Repository:
WorkflowDefinitionRepository. - Persistence: Azure SQL (
WorkflowDefinitionServiceDB). Grounded in orchestration domain and coordinators.
WorkflowInstance¶
- Purpose: A running, event-sourced execution of a workflow definition for one project — the heart of orchestration.
- Fields:
workflowInstanceId(wf-prefixed),workflowDefinitionId+version,projectId,state(see state machine),currentStep,correlationId,startedAt,completedAt. - Entities:
StepExecution,OpenApprovalRef,CompensationRecord. - Value Objects:
WorkflowState,StepStatus,Deadline. - Invariants: state transitions follow the definition's allowed graph; an instance cannot complete with open approvals or pending steps; the event history is append-only and immutable (enables replay).
- Domain Events:
WorkflowInstanceStarted,WorkflowStepCompleted,WorkflowStepTimedOut,WorkflowInstanceCompleted,WorkflowInstanceFailed. - Repository:
WorkflowInstanceRepository(MassTransit saga repository + event store). - Persistence: Azure SQL (
WorkflowOrchestratorDB) — saga state + append-only event store; projection inProcessStateService.
AgentTask¶
- Purpose: The unit of work the Control Plane assigns to the Agent Mesh for a workflow step (contract).
- Fields:
taskId(task-prefixed),workflowInstanceId,agentRole,requestedSkill,inputs,constraints(modelPolicyId, maxCorrectionAttempts, deadline),status(Assigned/ContextLoading/Executing/Validating/Correcting/Completed/Failed),outputArtifacts. - Entities:
TaskInput,TaskConstraint,TaskOutputRef. - Value Objects:
AgentRole,SkillReference,RetryPolicy,Deadline. - Invariants: idempotent assignment (same
taskIdnever duplicates execution); cannot complete without validated output; correction attempts cannot exceedmaxCorrectionAttempts. - Domain Events:
AgentTaskAssigned,AgentTaskReassigned,AgentTaskCompleted,AgentTaskFailed. - Repository:
AgentTaskRepository. - Persistence: Azure SQL (
TaskAssignmentServiceDB).
Agent Management Context¶
AgentDefinition¶
- Purpose: A registered, versioned agent — its role, capabilities, and the task contract it satisfies. Governs (not runs) Agent Mesh agents.
- Fields:
agentId(ConnectSoft.Agent.*),role,version(SemVer),status(Active/Deprecated),capabilities,supportedSkills,defaultModelPolicyId. - Entities:
AgentCapability,AgentVersionRecord. - Value Objects:
AgentRole,Capability,SemVer. - Invariants: role+version unique; a deprecated agent cannot be assigned new tasks; supported skills must exist in the skill registry.
- Domain Events:
AgentDefinitionRegistered,AgentDefinitionDeprecated. - Repository:
AgentDefinitionRepository. - Persistence: Azure SQL (
AgentRegistryServiceDB).
SkillDefinition¶
- Purpose: A registered, versioned skill with its input/output contract — the capability an agent invokes.
- Fields:
skillId(ConnectSoft.Skill.*),name,version(SemVer),status,inputSchema,outputSchema,requiredCapabilities. - Entities:
SkillParameter,SkillVersionRecord. - Value Objects:
SkillReference,IoSchema,SemVer. - Invariants: name+version unique; I/O schemas are immutable per version; a skill cannot be retired while referenced by an active agent definition.
- Domain Events:
SkillDefinitionRegistered,SkillDefinitionRetired. - Repository:
SkillDefinitionRepository. - Persistence: Azure SQL (
SkillRegistryServiceDB).
Governance Context¶
PolicyDefinition¶
- Purpose: A declarative rule governing a sensitive action (e.g. production release, model usage, blueprint publish).
- Fields:
policyId(pol-prefixed),name,version,status(Draft/Active/Retired),target(action+resource matcher),effect(Allow/Deny/RequireApproval),obligations. - Entities:
PolicyRule,PolicyObligation. - Value Objects:
ActionMatcher,ResourceMatcher,Effect. - Invariants: an active policy is immutable (changes create a new version); deny takes precedence over allow on conflict; obligations reference valid roles.
- Domain Events:
PolicyDefinitionActivated,PolicyDefinitionRetired. - Repository:
PolicyDefinitionRepository. - Persistence: Azure SQL (
PolicyEngineServiceDB).
PolicyDecision¶
- Purpose: An immutable record of a single policy evaluation outcome — the audit anchor for governance.
- Fields:
policyDecisionId(pd-prefixed),subject,action,resource,effect,matchedPolicyId+version,obligations,decidedAt,workflowInstanceId. - Entities: (none — value record).
- Value Objects:
Subject,Effect,Obligation. - Invariants: immutable once recorded; must reference the policy version that produced it; every
RequireApprovaldecision links to anApprovalRequest. - Domain Events:
PolicyDecisionRecorded. - Repository:
PolicyDecisionRepository. - Persistence: Azure SQL (
PolicyEngineServiceDB), append-only.
ApprovalRequest¶
- Purpose: A human approval gate within a workflow that must be resolved before proceeding.
- Fields:
approvalId(apr-prefixed),workflowInstanceId,policyDecisionId,requiredRole,status(Pending/Granted/Rejected/Expired),requestedAt,decidedBy,decidedAt,comment. - Entities:
ApprovalDecisionRecord. - Value Objects:
ApprovalStatus,RoleRequirement,Deadline. - Invariants: terminal once
Granted/Rejected/Expired; decider must holdrequiredRole; expiry escalates or fails the workflow step. - Domain Events:
ApprovalRequested,ApprovalGranted,ApprovalRejected,ApprovalExpired. - Repository:
ApprovalRequestRepository. - Persistence: Azure SQL (
ApprovalServiceDB).
AuditEntry¶
- Purpose: An immutable record of a governed action — the tamper-evident audit trail.
- Fields:
auditEntryId(aud-prefixed),tenantId,projectId,actor,action,resource,outcome,correlationId,occurredAt,hashChainPrev. - Entities: (none — append-only record).
- Value Objects:
Actor,Outcome,HashChainLink. - Invariants: append-only and immutable; each entry chains to the previous via
hashChainPrevfor tamper evidence; never deleted (only exported/retained). - Domain Events:
AuditEntryRecorded,AuditExported. - Repository:
AuditEntryRepository. - Persistence: PostgreSQL (
AuditServiceDB), append-only; exported by theAuditExportWorker.
Cost & Usage Context¶
UsageRecord¶
- Purpose: A metered consumption fact (tokens, compute minutes, agent tasks) attributed to a tenant/project for billing and quota.
- Fields:
usageRecordId,tenantId,projectId,metric(Tokens/ComputeMinutes/AgentTasks),quantity,source(taskId/modelInvocationId),occurredAt,period. - Entities: (none — fact record).
- Value Objects:
Metric,Quantity,BillingPeriod. - Invariants: quantity is non-negative; records are immutable; idempotent per
(source, metric)to prevent double counting. - Domain Events:
UsageRecorded,UsageRolledUp. - Repository:
UsageRecordRepository. - Persistence: PostgreSQL time-series (
CostUsageServiceDB); rolled up byUsageRollupWorker.
Integration Context¶
IntegrationConnection¶
- Purpose: A managed connection to an external system (Git provider, identity provider, cloud, billing); the anti-corruption boundary.
- Fields:
integrationConnectionId(int-prefixed),tenantId,type(GitProvider/IdentityProvider/Cloud/Billing),provider,status(Connected/Degraded/Disconnected),configRef(Key Vault),lastCheckedAt. - Entities:
IntegrationCredentialRef,IntegrationHealthCheck. - Value Objects:
IntegrationType,ProviderName,SecretRef. - Invariants: secrets are never stored in the aggregate (only
configRefto Key Vault); a connection must pass a health check beforeConnected; one active connection per(type, provider)per tenant unless multi-connect is enabled. - Domain Events:
IntegrationConnected,IntegrationDegraded,IntegrationDisconnected. - Repository:
IntegrationConnectionRepository. - Persistence: Azure SQL (
IntegrationServiceDB); secrets in Azure Key Vault.
Aggregate-to-Context Summary¶
| Context | Aggregate Roots |
|---|---|
| Tenant & Edition | Tenant, Edition, Subscription |
| Project Management | Project, Environment, Module, ModuleDependency |
| Blueprint Management | Blueprint, BlueprintVersion |
| Workflow Orchestration | WorkflowDefinition, WorkflowInstance, AgentTask |
| Agent Management | AgentDefinition, SkillDefinition |
| Governance | PolicyDefinition, PolicyDecision, ApprovalRequest, AuditEntry |
| Cost & Usage | UsageRecord |
| Integration | IntegrationConnection |
Related¶
- Bounded Contexts · Microservices · Storage · Events · Workflows
- Reference: Naming Conventions · Metadata Schema · Agent Task Contract