Runtime Labels and Routing
Use labels to control which runtimes can claim and execute specific tasks based on required capabilities.
Runtime labels and routing allow you to control task-to-runtime assignment based on capabilities and requirements. When you create a task, you can specify which labels (OS, toolchain, provider, custom tags) the runtime must have. The scheduler then only assigns the task to runtimes whose label set matches.
Why labels matter
Imagine you have three runtimes:
- macOS daemon — Claude provider, no Docker
- Linux daemon — Claude and Cursor, Docker support, Node.js 20
- Windows daemon — Claude provider only
If you create a task that says "this agent needs Docker and Node 20", AACWorkflow should only offer it to the Linux daemon. Without labels, the task might accidentally be assigned to the macOS daemon, which would fail at runtime.
Labels prevent these mismatches.
What is a label?
A label is a keyword describing a runtime capability or property:
| Category | Examples |
|---|---|
| OS | macos, linux, windows |
| Architecture | arm64, amd64 (x86-64) |
| Toolchain | node20, node22, python3.11, go, rust |
| Providers | claude, codex, cursor |
| Containers | docker, podman |
| Custom | ci-runner, production, gpu-enabled |
Labels are case-insensitive and use kebab-case (lowercase with hyphens).
Automatic labels from capabilities
When a daemon registers, it automatically advertises labels based on its capabilities:
- OS and architecture —
macos,linux,windows,arm64,amd64 - AI providers —
claude,codex,cursor(one per installed provider) - MCP transports —
mcp-stdio,mcp-sse,mcp-http
These are the capability labels and are automatically updated when you restart the daemon or install a new provider.
See Runtime capability registry for more details.
Custom labels
In addition to automatic capability labels, you can assign custom labels to a runtime to describe properties AACWorkflow doesn't automatically detect:
- Go to Settings → Runtimes
- Click on a runtime
- Scroll to Custom Labels
- Add labels like
node20,gpu-enabled,ci-runner,production - Click Save
Use custom labels for:
- Toolchain versions —
node20,python3.11,go1.21 - Hardware —
gpu-enabled,high-memory - Purpose —
ci-runner,local-dev,production - Location —
us-west,eu-central
Requiring labels on a task
When you create a task or assign an agent to an issue, you can specify required labels. The task will only be claimed by runtimes whose label set is a superset of the required labels.
Via the UI
- Create or edit an issue/task
- Under Runtime Requirements, click Add Label
- Select labels from the list (auto-complete, sourced from all runtimes)
- Example: select
dockerandnode20 - Save the issue/task
The task will now only run on runtimes that have both docker AND node20 labels.
Inheriting labels from issues
Issues can set default required labels that all their tasks inherit:
- Open an issue
- Go to Issue Settings → Runtime Requirements
- Add required labels
- Any agent assigned to this issue will have these requirements by default
You can override the requirements per-task if needed.
Label matching algorithm
AACWorkflow uses set matching:
- Task required labels:
[docker, node20] - Runtime labels:
[macos, arm64, claude, docker, node20, custom-tag] - Match? YES — runtime has all required labels
Another example:
- Task required labels:
[docker, gpu-enabled] - Runtime labels:
[linux, amd64, claude, docker] - Match? NO — runtime has
dockerbut notgpu-enabled
Empty required labels match any runtime (no restrictions).
Viewing runtime labels
In the UI
- Go to Settings → Runtimes
- Click on a runtime
- See both Capability Labels (auto) and Custom Labels (manual)
Via the API
The /runtimes/{id} endpoint returns both sets:
{
"id": "runtime-123",
"name": "Linux CI runner",
"capability_labels": ["linux", "amd64", "claude", "docker"],
"custom_labels": ["ci-runner", "node20", "python3.11"],
"effective_labels": ["linux", "amd64", "claude", "docker", "ci-runner", "node20", "python3.11"]
}The effective labels are what the scheduler uses for matching.
Unschedulable tasks
If a task requires labels that no runtime has, it becomes unschedulable:
- The task stays in the queue
- The issue shows a warning: "No runtime matches these requirements"
- The task waits (it doesn't fail) until a suitable runtime comes online
- After 7 days, unschedulable tasks expire and are marked incomplete
To resolve:
- Review the task's required labels
- Check which runtimes are online and what labels they have
- Either:
- Add the required label to a runtime — e.g., install Docker if the task needs it
- Remove the label requirement — if the task doesn't actually need it
- Bring online a new runtime with the required capability
Best practices
- Start simple — don't over-specify labels; rely on automatic capability labels
- Use custom labels for toolchains — tag runtimes with the language/version they support
- Document your labels — share a label vocabulary with your team
- Review unschedulable tasks — if tasks are stuck in queue, check their label requirements
Example scenarios
Scenario 1: Docker + specific Node version
Task: "Run a Docker build for my Node 20 app"
Required labels: docker, node20
Result: Only runtimes with both labels will claim it.
Scenario 2: GPU for ML inference
Task: "Run an ML inference task"
Required labels: gpu-enabled
Result: Only GPU-enabled runtimes will claim it. If no GPU runtime is available, the task waits.
Scenario 3: Production-only changes
Task: "Deploy to production"
Required labels: production
Result: Only runtimes tagged production can run it. Development runtimes are excluded.
Scenario 4: Local development
Task: "Run tests locally"
Required labels: (empty)
Result: Any runtime can run it. AACWorkflow picks the least-loaded available runtime.
Next steps
- Runtime capability registry — understand automatic capability labels
- Daemon and runtimes — learn daemon and runtime architecture