Multi-Agent Orchestration
| Field | Value |
|---|---|
| Document ID | ASCEND-GOV-ORCH-001 |
| Version | 2026.04 |
| Last Updated | April 2026 |
| Author | Ascend Engineering Team |
| Publisher | OW-KAI Technologies Inc. |
| Classification | Enterprise Client Documentation |
| Compliance | NIST AI RMF GOVERN-1.7, EU AI Act Art. 28, SOC 2 CC6.1/CC6.8 |
Reading Time: 10 minutes | Skill Level: Intermediate
Overview
ASCEND multi-agent orchestration (FEAT-007) lets an orchestrator agent delegate work to worker agents while preserving one audit trail, one risk roll-up, and one kill-switch target for the whole session. SDK 2.3.0 adds three optional parameters to evaluate_action that link each delegated step to its parent.
Why orchestration governance?
When one AI agent calls another, you need to answer three questions at audit time:
- Who delegated to whom? (parent → worker)
- Did the delegation stay inside one tenant, or did someone try to graft a foreign session in? (cross-tenant + session-graft protection)
- What's the total risk of the whole session, not just one step? (cumulative risk propagation)
Orchestration fields on each action record (orchestration_session_id, parent_action_id, orchestration_depth) make this queryable and enforceable.
Data model
| Field | Type | Constraint | Description |
|---|---|---|---|
orchestration_session_id | string (≤255) | Indexed | Groups related actions into one session |
parent_action_id | int | FK → agent_actions.id, nullable | Immediate parent action |
orchestration_depth | int | 0..5, default 0 | Delegation depth (0 = root) |
Columns live on every AgentAction row (migration: feat007_multi_agent_orchestration).
Security enforcement
The backend (POST /api/v1/actions/submit) enforces these rules before any action row is created:
1. Cross-tenant parent check (fail-secure 403)
If parent_action_id is supplied, the backend looks it up scoped by organization_id:
parent = db.query(AgentAction).filter(
AgentAction.id == parent_action_id,
AgentAction.organization_id == org_id,
).first()
If the parent is missing OR belongs to a different organization, the submission is rejected with:
- HTTP 403 +
"parent action not found in this organization" - Immutable audit event:
ORCHESTRATION_FIELD_REJECTED(risk_levelHIGH)
There is no 404 — rejecting off-tenant parents as 404 would leak existence of other tenants' action IDs.
2. Session-graft protection (fail-secure 403)
If both orchestration_session_id and parent_action_id are supplied, the backend requires:
parent.orchestration_session_id == submitted_session_id
Mismatch → HTTP 403 + "orchestration session id does not match parent action", logged as ORCHESTRATION_GRAFT_ATTEMPT (risk_level CRITICAL).
This blocks an attacker who, having discovered a valid parent action ID within their own tenant, tries to graft it into a different session to poison cumulative-risk math.
3. Depth cap (HTTP 422)
orchestration_depth must be in 0..5. Values outside the range produce HTTP 422 with "orchestration_depth must be between 0 and 5". The client-side SDK guardrail rejects the same values before the network call.
4. Fail-secure on validation error
Any unexpected DB or ORM error during orchestration validation produces HTTP 403 + "orchestration validation failed". The code path never silently drops the orchestration fields to succeed the request — fail-closed is mandatory.
SDK 2.3.0 usage
Root action
from ascend import AscendClient
client = AscendClient(api_key="owkai_...")
root = client.evaluate_action(
action_type="orchestrator.plan",
resource="customer-onboarding-flow",
orchestration_session_id="sess-onboard-7f3a",
orchestration_depth=0,
wait_for_decision=False,
)
Delegated child action
worker = client.evaluate_action(
action_type="database.write",
resource="customers.create",
orchestration_session_id="sess-onboard-7f3a",
parent_action_id=int(root.action_id),
orchestration_depth=1,
wait_for_decision=False,
)
Depth > 5 rejected client-side
from ascend.exceptions import ValidationError
try:
client.evaluate_action(
action_type="x", resource="y",
orchestration_depth=6,
)
except ValidationError:
# Raised before any network call
...
Cumulative risk
Each action in a session still carries its own risk score, but the backend aggregates per-session metrics that the admin UI surfaces:
- Max risk in session
- Average risk in session
- Agents involved
- Max depth observed
- Count of blocked / high-risk steps
See schemas/orchestration.py::SessionRiskResponse on the backend for the exact shape. Dashboards query these aggregates through the orchestration topology endpoints (FEAT-007B).
Topology management (FEAT-007B)
Beyond per-action linkage, administrators can register orchestrator-worker relationships explicitly to constrain delegation depth, apply broader kill-switch blast radius, and export compliance reports:
| Action | Endpoint |
|---|---|
| Register orchestrator → workers | POST /api/v1/orchestration/topology |
| Register orchestrator → MCP workers | POST /api/v1/orchestration/topology/mcp |
| Cascade kill-switch (dry-run or execute) | POST /api/v1/orchestration/topology/kill-cascade |
| List edges (with health enrichment) | GET /api/v1/orchestration/topology |
| Per-agent view | GET /api/v1/orchestration/topology/agents/{agent_id} |
| Audit trail | GET /api/v1/orchestration/topology/audit |
| Export for compliance | GET /api/v1/orchestration/topology/export |
Auth: admin (JWT or API key). Topology rows are org-scoped; cross-tenant reads and writes fail with HTTP 403.
Compliance mapping
| Concern | Standard |
|---|---|
| Recorded delegation chain | NIST AI RMF GOVERN-1.7 |
| Cross-tenant isolation | SOC 2 CC6.1 |
| Cascade kill-switch audit | NIST IR-4, SOC 2 CC6.2 |
| Transparency of multi-agent systems | EU AI Act Art. 28 |
Related docs
- Python SDK — SDK 2.3.0 section
- Kill Switch — cascade
- Security Architecture — Layer 4: Action Governance
Document Version: 2026.04 | Last Updated: April 2026