Skip to main content

Multi-Agent Orchestration

FieldValue
Document IDASCEND-GOV-ORCH-001
Version2026.04
Last UpdatedApril 2026
AuthorAscend Engineering Team
PublisherOW-KAI Technologies Inc.
ClassificationEnterprise Client Documentation
ComplianceNIST 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:

  1. Who delegated to whom? (parent → worker)
  2. Did the delegation stay inside one tenant, or did someone try to graft a foreign session in? (cross-tenant + session-graft protection)
  3. 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

FieldTypeConstraintDescription
orchestration_session_idstring (≤255)IndexedGroups related actions into one session
parent_action_idintFK → agent_actions.id, nullableImmediate parent action
orchestration_depthint0..5, default 0Delegation 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_level HIGH)

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:

ActionEndpoint
Register orchestrator → workersPOST /api/v1/orchestration/topology
Register orchestrator → MCP workersPOST /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 viewGET /api/v1/orchestration/topology/agents/{agent_id}
Audit trailGET /api/v1/orchestration/topology/audit
Export for complianceGET /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

ConcernStandard
Recorded delegation chainNIST AI RMF GOVERN-1.7
Cross-tenant isolationSOC 2 CC6.1
Cascade kill-switch auditNIST IR-4, SOC 2 CC6.2
Transparency of multi-agent systemsEU AI Act Art. 28

Document Version: 2026.04 | Last Updated: April 2026