Skip to main content
Home Server Domain Controllers

Domain Controllers

The business intelligence layer of the Weblisk architecture. Domain controllers sit between the orchestrator and work agents — receiving business-level tasks, decomposing them into discrete work units, dispatching those units to specialised agents, aggregating results, and feeding outcomes back into the continuous optimisation lifecycle.

Nothing enters or leaves a business function without the domain controller's knowledge and approval. It is the director: it understands the process, the rules, the data contracts, and the quality gates that make each business function operate correctly.

Architecture

Relationship to other components
┌──────────────────────────────────────────────────────┐
│                   Orchestrator                       │
│    Registration · Routing · Security · Discovery     │
└────────────┬────────────────────┬────────────────────┘
             │ task               │ task
             ▼                    ▼
 ┌─────────────────┐  ┌─────────────────┐
 │  SEO Domain      │  │  Ops Domain      │
 │  (controller)    │  │  (controller)    │
 └──┬──────┬───────┘  └──┬──────┬───────┘
    │      │              │      │
    ▼      ▼              ▼      ▼
 ┌─────┐┌─────┐       ┌─────┐┌─────┐
 │ seo ││a11y │       │ cron││email│
 │ anlz││chkr │       │ agnt││agnt │
 └─────┘└─────┘       └─────┘└─────┘
  work     work        infra   infra
  agents   agents      agents  agents
ComponentRole
OrchestratorCoordinates between domains. Manages registration, discovery, security, and audit for the entire system.
Domain controllerDirects a business function. Owns one or more workflows, dispatches to agents, aggregates results, enforces quality gates. A domain IS an agent (implements the same 5 protocol endpoints) but with additional responsibilities.
Work agentsPerform specific tasks dispatched by a domain. They have no independent initiative — they receive input, execute, return output.
Infrastructure agentsSystem-level utilities (sync, cron, webhook, email). Any domain or the orchestrator can use them. They are not owned by a specific domain.

Domain Manifest

A domain controller registers with the orchestrator using the standard POST /v1/register flow. Its manifest uses the same AgentManifest structure with domain-specific fields:

SEO domain manifest
{
  "name": "seo",
  "type": "domain",
  "version": "1.0.0",
  "description": "SEO optimization — audits, recommendations, and automated fixes",
  "url": "http://localhost:9700",
  "public_key": "<hex Ed25519 public key>",
  "capabilities": [
    {"name": "agent:message", "resources": []},
    {"name": "workflow:execute", "resources": []}
  ],
  "inputs": [
    {"name": "target_files", "type": "file_list", "description": "Files to optimize"}
  ],
  "outputs": [
    {"name": "domain_report", "type": "json", "description": "Aggregated results with recommendations"}
  ],
  "approval": "required",
  "required_agents": ["seo-analyzer", "a11y-checker"],
  "workflows": ["seo-audit", "seo-optimize"]
}

Domain-Specific Fields

FieldTypeRequiredDescription
typestringYesMUST be "domain" (vs "agent" or "infrastructure")
required_agents[]stringYesAgent names this domain dispatches to
workflows[]stringYesWorkflow names this domain supports

The type field tells the orchestrator how to route tasks and track dependencies.

Registration & Dependency Verification

Domain registration follows the standard protocol with additional orchestrator behaviour:

  1. Domain sends RegisterRequest (same as any agent)
  2. Orchestrator verifies signature and identity (standard flow)
  3. Orchestrator reads manifest.type = "domain"
  4. Orchestrator reads manifest.required_agents
  5. For each required agent: check if present in the registry
    • If ALL present → domain status = "online"
    • If ANY missing → domain status = "degraded" (log warning with missing agents)
  6. Issue token and respond (standard flow)
  7. Broadcast service directory (standard flow)

Late agent registration: when a missing agent registers later, the orchestrator checks if any domain requires it. If the domain was degraded and all required agents are now present, the domain is promoted to "online". This allows agents and domains to start in any order.

Workflow Specification

Every domain defines one or more workflows — multi-step, multi-agent processes that accomplish a business function. Workflows are defined in the domain's blueprint file (in domains/), not in the runtime manifest (which only lists workflow names).

seo-audit workflow
workflow: seo-audit
description: Full SEO audit — scan, analyze, check accessibility, report
trigger: action = "audit"

phases:
  - name: scan
    agent: seo-analyzer
    action: scan_html
    input:
      html_files: $task.payload.files
    output: scan_results
    timeout: 60

  - name: analyze
    agent: seo-analyzer
    action: analyze_metadata
    input:
      metadata: $phases.scan.output.metadata
    output: analysis_results
    timeout: 120
    depends_on: [scan]

  - name: accessibility
    agent: a11y-checker
    action: check_images
    input:
      images: $phases.scan.output.images
    output: a11y_results
    timeout: 60
    depends_on: [scan]

  - name: synthesize
    agent: self
    action: aggregate_results
    input:
      analysis: $phases.analyze.output
      a11y: $phases.accessibility.output
    output: final_report
    depends_on: [analyze, accessibility]
    approval: required

Phase Fields

FieldRequiredDescription
nameYesUnique identifier within this workflow
agentYesTarget agent name, or "self" for domain-internal logic
actionYesHandleMessage action to invoke on target
inputYesReference expressions binding data from task, phases, entity, or config
outputYesKey name for phase result — used in $phases.<output> references
depends_onNoPhases that must complete first; drives execution order
timeoutNoPhase timeout in seconds (default: 300)
approvalNo"required" or "auto" (default: "auto")
on_errorNo"fail" (default), "skip", or "retry"
max_retriesNoRetry count when on_error = "retry" (default: 0)
conditionNoExpression that must be truthy to execute phase

Execution Order

  1. Phases with no depends_on run first (in parallel if multiple)
  2. A phase starts only after ALL of its depends_on phases complete
  3. If a phase fails and on_error = "fail", the entire workflow fails
  4. If on_error = "skip", the phase is marked skipped and dependents proceed without its output
  5. If on_error = "retry", the phase retries up to max_retries with 1s, 2s, 4s backoff
  6. Phases with agent: "self" execute within the domain controller itself (for aggregation, validation, decisions)
  7. If approval: "required", execution pauses until approval is received before exposing results

Reference Expressions

Phase inputs use reference expressions to bind data from the task, previous phase outputs, entity context, or domain configuration:

RootResolves To
$task.payload.<key>Field from the original TaskRequest.payload
$task.context.<key>Field from the TaskContext
$phases.<name>.outputFull output map of a completed phase
$phases.<name>.output.<key>Specific key from a phase's output map
$entity.<key>Field from EntityContext (injected via task context)
$config.<key>Domain-specific configuration value (set at startup)

Syntax

Resolution Rules

  1. Expressions MUST start with $ — literals without $ are passed through
  2. Unresolvable references resolve to null (not an error)
  3. If a required input resolves to null, the domain controller fails the phase with "unresolved reference"
  4. No type coercion — the resolved JSON value is passed as-is
  5. Circular references are impossible by construction (depends_on creates a DAG)

Workflow Execution Flow

When a domain controller receives a task via POST /v1/execute:

Execution phases
Phase 1 — Select workflow
  Match task.action against workflow triggers
  If no match → return failed result: "unknown action"

Phase 2 — Initialize execution
  Create WorkflowExecution record:
    id, workflow_name, domain_name, task_id
    status: "running", started_at: now()

Phase 3 — Resolve execution order
  Topological sort of phases by depends_on
  Group into levels: L0 (no deps), L1 (depend on L0), etc.
  Verify no cycles (fail if circular dependency)

Phase 4 — Execute levels
  For each level (L0, L1, L2, ...):
    For each phase in this level (concurrently):
      a. Check condition (if set) — skip if falsy
      b. Resolve input references from task + previous outputs
      c. If agent = "self":
           Execute domain's own HandleMessage
         Else:
           Look up agent in service directory
           Build AgentMessage (from, to, action, payload)
           Sign with domain's private key
           POST to agent_url + /v1/message
           Wait for response (with timeout)
      d. Store phase result
      e. If failed: apply on_error strategy

Phase 5 — Aggregate
  Collect all phase results
  Build final TaskResult:
    status: "success" | "failed" | "pending_approval"
    summary, changes, observations, recommendations
    metrics: {phases_total, completed, failed, duration_ms}
  Sign result with domain's private key

Phase 6 — Record
  Store WorkflowExecution with all phase results
  Emit observations and recommendations (for lifecycle)
  Return TaskResult

Agent Dispatch

When a domain dispatches work to an agent, it uses direct messaging (POST /v1/message), not the orchestrator's task endpoint. This keeps the orchestrator as a coordinator and the domain as the executor.

  1. Look up agent in service directory (populated during registration and updated via /v1/services broadcasts)
  2. Build AgentMessage: from, to, type: "request", action, payload
  3. Sign: JSON.stringify({from, to, action, payload})
  4. POST to agent_url + /v1/message
  5. Parse response AgentMessage
  6. Extract response.payload as phase output
  7. If agent unreachable:
    1. Check if channel exists → use channel
    2. Request new channel from orchestrator → retry
    3. If still unreachable → fail phase
No bypass: business tasks MUST flow through domain controllers. Work agents do not accept tasks from arbitrary sources — only from their owning domain. Infrastructure agents accept tasks from any authenticated source.

Result Aggregation

The domain controller merges results from multiple agents into a coherent outcome:

  1. Collect all phase outputs
  2. Merge observations: concatenate, deduplicate by target + element
  3. Merge recommendations: concatenate, sort by priority, deduplicate
  4. Merge proposed changes: group by file path, apply in order
  5. Compute summary metrics: total observations, recommendations by priority, changes by action type, workflow duration
  6. Apply domain-specific validation: reject conflicting recommendations, enforce business constraints, apply quality gates
  7. Set overall status:
    • "success" if all phases completed and no approval needed
    • "pending_approval" if any phase or the workflow requires approval
    • "failed" if any critical phase failed

Standard Actions

Every domain controller MUST implement these actions:

ActionDescription
execute_workflowPrimary entry point. Invoked by the orchestrator via POST /v1/execute. Runs a named workflow and returns aggregated results.
get_statusReturns domain state: online/degraded, required agent availability, active and completed workflow counts.
get_workflowsReturns full workflow definitions. Runtime introspection endpoint for the orchestrator, CLI, and external tools.
workflow_historyReturns recent workflow executions with results.

Custom actions are domain-specific and defined in each domain's blueprint file.

Entity Context

Domains operate within the context of a business entity. The EntityContext provides:

Every domain SHOULD use entity context to ground its decisions in business reality. For example, an SEO domain uses keywords and audiences to evaluate whether page titles target the right terms. Entity context is injected via TaskContext.entity on every task execution.

Configuration

Domains accept configuration at startup via environment variables (prefix WL_DOMAIN_) or configuration files. Values are accessible in workflow reference expressions as $config.<key>:

Environment variables
WL_DOMAIN_MAX_ISSUES_PER_FILE=50
WL_DOMAIN_SCORE_THRESHOLD=70
WL_DOMAIN_MEASUREMENT_WINDOW=86400

Domain configuration is NOT part of the manifest or wire protocol — it is local to the domain process.

Port Convention

RangeAssigned To
9700–9709Domain controllers (SEO = 9700, future domains = 9701+)
9710+Work agents
9750+Infrastructure agents
9800Orchestrator

Reference Domains

Three reference domains ship with the specification:

SEO

Audits, recommendations, and automated fixes for search engine optimisation. Dispatches to seo-analyzer and a11y-checker. Workflows: seo-audit, seo-optimize.

Content

Content analysis, metadata validation, and quality assessment. Dispatches to content-analyzer and meta-checker.

Health

Uptime monitoring, performance auditing, and availability tracking. Dispatches to uptime-checker and perf-auditor.

Implementation Notes

Verification Checklist