# How to Implement Bounded Orchestration for Parallel Agent Work in LoopX

> Learn to implement bounded orchestration for parallel agent work in LoopX. Set max_children in your goal's orchestration contract to limit sub-agents effectively.

- Repository: [huangruiteng/loopx](https://github.com/huangruiteng/loopx)
- Tags: how-to-guide
- Published: 2026-08-07

---

**Set `max_children` in your goal's `orchestration` contract and call `apply_task_orchestration_contract()` to generate a bounded work-lane that limits parallel sub-agents.**

LoopX is an open-source agent orchestration framework that supports **task-scoped orchestration** with configurable parallelism bounds. The `max_children` field in a goal's orchestration contract directly controls how many peer lanes can execute simultaneously, ensuring resource-constrained, predictable multi-agent workflows.

---

## What Is Bounded Orchestration in LoopX?

**Bounded orchestration** is LoopX's mechanism for spawning a limited, predetermined number of parallel sub-agents (peer lanes) under a single coordinator. Unlike unbounded fan-out patterns that risk resource exhaustion, LoopX enforces limits at the contract layer—before any agents are materialized.

The orchestration system resides primarily in [`loopx/control_plane/quota/task_orchestration.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py), with visible execution handled by [`loopx/visible_multi_agent_launcher.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/visible_multi_agent_launcher.py).

Key concepts:

- **Goal boundary**: A JSON spec containing the `orchestration` object with `mode`, `spawn_allowed`, and `max_children`.
- **Task-orchestration contract**: A validated structure that selects a coordinator and eligible peer lanes (capped at `max_children`).
- **Work-lane contract**: A runtime artifact that drives execution through lanes `"task_orchestration"` → `"peer_evidence_review"`.

---

## The Orchestration Contract Schema

Every bounded orchestration begins with a goal definition. The `orchestration` object must specify `mode: "multi_subagent"` and explicitly allow spawning:

```json
{
  "goal_id": "example-123",
  "orchestration": {
    "mode": "multi_subagent",
    "spawn_allowed": true,
    "max_children": 3
  }
}

```

| Field | Type | Purpose |
|-------|------|---------|
| `mode` | string | Must be `"multi_subagent"` to trigger bounded orchestration logic |
| `spawn_allowed` | boolean | Gate that must be `true` for any child lane creation |
| `max_children` | integer | Hard upper bound on concurrent peer lanes |

This schema is validated in `apply_task_orchestration_contract()` at lines 82–108 of [`task_orchestration.py`](https://github.com/huangruiteng/loopx/blob/main/task_orchestration.py) (source: [task_orchestration.py](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py#L82-L108)).

---

## Building the Bounded Orchestration Contract

The entry point for creating a bounded orchestration is `apply_task_orchestration_contract()`. This function performs four critical operations:

1. **Validates** the goal boundary's `mode` and `spawn_allowed` fields.
2. **Extracts** `max_children` from the orchestration object.
3. **Selects** a coordinator agent via `select_peer_for_work()`.
4. **Bounds** peer lanes to `max_children` entries.

```python
from loopx.control_plane.quota.task_orchestration import apply_task_orchestration_contract

contract, work_lane = apply_task_orchestration_contract(
    fallback_work_lane_contract=None,
    goal_boundary=goal_boundary,          # dict with orchestration JSON

    agent_identity=agent_identity,        # current agent's identity

    agent_todo_summary=agent_todo_summary,
    raw_agent_todo_summary=raw_agent_todo_summary,
    raw_user_todo_summary=raw_user_todo_summary,
    agent_todo_source_items=agent_items,
    user_todo_source_items=user_items,
    available_capabilities=available_caps,
    parent_goal_id=None,
)

```

If `max_children` is set to 2, `contract["eligible_peer_lanes"]` contains **at most two entries**—the bound is enforced before any runtime spawning occurs.

---

## Peer Lane Selection and Bounding Logic

The internal function `_registered_peer_task_orchestration_contract()` (lines 81–89, 98–107, 124–129) implements the actual bounding:

```python
def _registered_peer_task_orchestration_contract(
    *, agent_id, agent_identity, raw_agent_todo_summary, max_peers
):
    # Build candidates from open advancement tasks

    candidate_lanes = [...]
    
    # Select coordinator

    assignment_key = peer_work_key(
        {"mode": "task_scoped_peer", "lanes": ...}, 
        fallback="task_orchestration"
    )
    coordinator = select_peer_for_work(candidate_agents, work_key=assignment_key)

    # **Critical: enforce max_children bound here**

    peer_lanes = [
        lane for lane in candidate_lanes 
        if lane["agent_id"] != coordinator
    ][:max_peers]  # <-- slice to enforce bound

    return {
        "mode": "task_scoped_peer",
        "coordinator_agent_id": coordinator,
        "eligible_peer_lanes": peer_lanes,
        # ...

    }

```

Source: [task_orchestration.py lines 45–54, 124–129](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py#L45-L54, L124-L129).

The `[:max_peers]` slice guarantees that even if fifty agents are available, only `max_children` (here, `max_peers`) proceed to execution.

---

## Attaching Contracts to Turn Envelopes

Once built, the orchestration contract must reach the runtime. Use `attach_task_orchestration_payload()` to embed it in the turn envelope:

```python
from loopx.control_plane.quota.task_orchestration import attach_task_orchestration_payload

payload = {"turn_id": turn_id, "goal_id": goal_id}
payload = attach_task_orchestration_payload(payload, contract)

```

Source: [task_orchestration.py lines 37–44](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py#L37-L44).

This envelope attachment ensures downstream components—particularly the launcher—receive the bounded lane list.

---

## Launching Bounded Parallel Agents

The visible multi-agent launcher materializes bounded orchestration into tmux panes. Because the contract already enforces `max_children`, the launcher simply consumes `eligible_peer_lanes` without additional checks.

### Building the Launch Payload

```python
from loopx.visible_multi_agent_launcher import build_visible_multi_agent_payload_from_spec

spec = {
    "goal_id": "example-123",
    "session_name": "demo-session",
    "roles": [
        {"agent_id": "agent-a", "role_id": "worker-a"},
        {"agent_id": "agent-b", "role_id": "worker-b"},
        {"agent_id": "agent-c", "role_id": "worker-c"},
        {"agent_id": "agent-d", "role_id": "worker-d"},
    ],
}
packet = build_visible_multi_agent_payload_from_spec(spec)

```

With `max_children: 2`, only two lanes launch despite four roles being specified.

### Executing the Launcher

```python
from loopx.visible_multi_agent_launcher import execute_visible_multi_agent_launcher
from pathlib import Path

result, chosen, workspace_mode = execute_visible_multi_agent_launcher(
    payload=packet,
    registry=Path("/path/to/registry"),
    runtime_root=Path("/tmp/loopx-runtime"),
    requested_launcher="tmux",
    tmux_bin="tmux",
    cli_bin="loopx",
    codex_bin="codex",
    attach=False,
    replace_existing=True,
    workspace=None,
    create_workspace=False,
    cwd=Path.cwd(),
)

```

Source: [visible_multi_agent_launcher.py lines 70–82](https://github.com/huangruiteng/loopx/blob/main/loopx/visible_multi_agent_launcher.py#L70-L82).

Each lane runs an isolated Codex TUI instance sharing the same goal ID, quota, and frontier. The coordinator aggregates evidence via the `peer_evidence_review` lane.

---

## Work-Lane Contract: From Orchestration to Execution

The function `_task_orchestration_work_lane_contract()` transforms the high-level orchestration contract into an executable work-lane:

```python
def _task_orchestration_work_lane_contract(
    contract, 
    lane_history, 
    agent_has_been_prompted_for_new, 
    is_eligible_child_lane
):
    return {
        "next_lane": "task_orchestration",
        "then_lane": "peer_evidence_review",
        "must_attempt_work": True,
        "reason_codes": ["eligible_child_lanes"] if is_eligible_child_lane else ["eligible_peer_lanes"],
        # ...

    }

```

Source: [task_orchestration.py lines 68–79](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py#L68-L79).

This contract signals the runtime to:
- Spawn parallel tasks in `task_orchestration` lane
- Advance to `peer_evidence_review` for evidence aggregation
- Require work attempt via `must_attempt_work: true`

---

## Complete Implementation Example

Here's a consolidated workflow implementing bounded orchestration for parallel agent work in LoopX:

```python
from loopx.control_plane.quota.task_orchestration import (
    apply_task_orchestration_contract,
    attach_task_orchestration_payload,
)
from loopx.visible_multi_agent_launcher import (
    build_visible_multi_agent_payload_from_spec,
    execute_visible_multi_agent_launcher,
)
from pathlib import Path

# Step 1: Define goal with max_children bound

goal_boundary = {
    "goal_id": "bounded-demo-001",
    "orchestration": {
        "mode": "multi_subagent",
        "spawn_allowed": True,
        "max_children": 2  # Hard limit: 2 parallel agents

    }
}

# Step 2: Build bounded orchestration contract

contract, work_lane = apply_task_orchestration_contract(
    fallback_work_lane_contract=None,
    goal_boundary=goal_boundary,
    agent_identity=current_agent,
    agent_todo_summary=agent_summary,
    raw_agent_todo_summary=raw_agent_summary,
    raw_user_todo_summary=raw_user_summary,
    agent_todo_source_items=agent_items,
    user_todo_source_items=user_items,
    available_capabilities=caps,
    parent_goal_id=None,
)

# Step 3: Attach to turn envelope

turn_payload = {"turn_id": turn_id, "goal_id": goal_id}
turn_payload = attach_task_orchestration_payload(turn_payload, contract)

# Step 4: Build and execute visible launcher

spec = {
    "goal_id": goal_id,
    "session_name": f"bounded-session-{goal_id}",
    "roles": roles_list,  # May contain many roles; bound is enforced

}
packet = build_visible_multi_agent_payload_from_spec(spec)

result, chosen, mode = execute_visible_multi_agent_launcher(
    payload=packet,
    registry=Path("./registry"),
    runtime_root=Path("/tmp/loopx"),
    requested_launcher="tmux",
    tmux_bin="tmux",
    cli_bin="loopx",
    codex_bin="codex",
    attach=False,
    replace_existing=True,
    cwd=Path.cwd(),
)

```

---

## Bounded vs. Unbounded Orchestration

| Aspect | Bounded (`max_children`) | Unbounded |
|--------|--------------------------|-----------|
| **Resource safety** | Guaranteed ceiling on concurrent agents | Risk of exhausting compute/memory |
| **Validation point** | Contract creation ([`task_orchestration.py`](https://github.com/huangruiteng/loopx/blob/main/task_orchestration.py)) | Runtime or none |
| **Coordinator selection** | Explicit via `select_peer_for_work()` | May be implicit or absent |
| **Evidence aggregation** | Structured via `peer_evidence_review` | Ad-hoc or manual |
| **Use case** | Production workflows, resource-constrained environments | Exploratory, unbounded search |

LoopX defaults to bounded behavior when `max_children` is present; omitting it or setting `mode` to other values bypasses the peer-orchestration path entirely.

---

## Key Source Files

| File | Purpose | Source Link |
|------|---------|-------------|
| [`loopx/control_plane/quota/task_orchestration.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py) | Core contract builder, validation, and work-lane generation | [View source](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/task_orchestration.py) |
| [`loopx/visible_multi_agent_launcher.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/visible_multi_agent_launcher.py) | Tmux-based multi-agent payload construction and execution | [View source](https://github.com/huangruiteng/loopx/blob/main/loopx/visible_multi_agent_launcher.py) |
| [`tests/test_task_orchestration_admission.py`](https://github.com/huangruiteng/loopx/blob/main/tests/test_task_orchestration_admission.py) | Unit tests validating contract shapes and max-peer behavior | [View source](https://github.com/huangruiteng/loopx/blob/main/tests/control_plane/test_task_orchestration_admission.py) |
| [`tests/test_turn_envelope.py`](https://github.com/huangruiteng/loopx/blob/main/tests/test_turn_envelope.py) | Envelope attachment and payload propagation tests | [View source](https://github.com/huangruiteng/loopx/blob/main/tests/test_turn_envelope.py) |

---

## Summary

- **Set `max_children`** in your goal's `orchestration` contract to bound parallel agent work.
- **Call `apply_task_orchestration_contract()`** to validate, select a coordinator, and slice peers to the limit.
- **Attach via `attach_task_orchestration_payload()`** to propagate the bound through the turn envelope.
- **Launch with `build_visible_multi_agent_payload_from_spec()`**—the bounded lane list is consumed automatically.
- **Execute via `execute_visible_multi_agent_launcher()`** to materialize up to `max_children` tmux panes with coordinated evidence review.

The bound is enforced early (contract creation), propagated explicitly (envelope attachment), and respected automatically (launcher consumption)—providing predictable, resource-safe parallel agent orchestration in LoopX.

---

## Frequently Asked Questions

### What happens if I omit `max_children` from the orchestration contract?

LoopX treats the goal as lacking bounded orchestration. The `apply_task_orchestration_contract()` function may return `None` or fall back to single-agent mode, depending on other fields. Without `max_children`, no peer-lane slicing occurs, and multi-subagent spawning is skipped.

### Where exactly is the `max_children` bound enforced in the source code?

The bound is enforced in `_registered_peer_task_orchestration_contract()` at line 124–129 of [`task_orchestration.py`](https://github.com/huangruiteng/loopx/blob/main/task_orchestration.py) via the slice `[:max_peers]`. This occurs after coordinator selection but before contract emission, ensuring downstream components receive an already-bounded lane list.

### Can I change `max_children` dynamically after goal creation?

No—the contract is immutable once built. To adjust parallelism, modify the goal boundary JSON and rebuild the orchestration contract via `apply_task_orchestration_contract()`. The new bound takes effect on the next turn envelope processing.

### Does the coordinator agent count toward the `max_children` limit?

No. The coordinator is selected separately via `select_peer_for_work()`, then excluded from the peer lane pool before the `[:max_peers]` slice. A `max_children: 3` configuration yields one coordinator plus three peer lanes—for four total agents executing concurrently.