Dependencies point downward only. The orchestration layer knows the messaging and state layers exist; neither of those knows anything about orchestration, which is what allows Service Bus to be replaced by another broker without touching the DAG logic.
Execution is a peer of orchestration, not a child of it. Workers are reached only through the messaging layer, so a worker deployment can be restarted, replaced or scaled with no control-plane coordination.
The Task Handler SDK is a deliberate seam. A new task type is a plugin implementing execute(context), registered by configuration — the promise made in the requirement that new task types do not change the orchestrator.
The red arrow
Workers fetch task definitions from the Workflow API, which is the execution layer calling the API layer. It is drawn rather than hidden.
It is contained: read-only, version-pinned to the execution's bound version, cached for the pod's lifetime, and served from a read replica. A Workflow API outage degrades new task types, not running tasks.
The clean fix is to inline the resolved task definition into the dispatch message, at the cost of message size. It is tracked as debt with a decision point at the 500-task workflow ceiling.
Assumptions
Azure SQL is present for reporting only. No runtime path reads it, so it can be down without affecting execution.
Redis is a cache and a coordination aid, never a system of record. View 31 states that concurrency leases fail open at a reduced limit when it is unavailable.
Seven task types are assumed at launch. The plugin model is what makes that number uninteresting.