orchestrata_ultimate.cxp.router
Reference › orchestrata_ultimate › cxp › router
CXPRouter decides where a CXP packet may go and whether it is allowed to go there. dispatcher is its caller, and the optional prolog_bridge supplies governance. It returns the RoutingResult and RoutingDecision types from types. See cxp.
The router holds a routing table mapping each sender alias to a set of allowed recipients. _seed_default_routes fills it from the known volk aliases: every volk may send to Postman (U:PS) and the Orchestrator (U:Ox), and those two may send to every other volk. register_route and unregister_route change the table; is_valid_route, get_routes_for and get_all_routes read it.
route first raises RoutingError if the packet lacks a sender or recipient, then NoRouteError if the sender has no route to the recipient. If a Prolog bridge was supplied, _check_governance asks it to validate the route, and a refusal produces a REJECT result with the reason. An error while consulting the bridge is logged and also counts as a refusal. Otherwise the result is DELIVER with the recipient as the single target.
At a glance
| Source | src/orchestrata_ultimate/cxp/router.py |
| Lines of code | 245 |
| Classes | 1 |
| Functions | 0 |
| Imports (internal) | orchestrata_ultimate.core.base.traces, orchestrata_ultimate.core.packet, orchestrata_ultimate.cxp.exceptions, orchestrata_ultimate.cxp.prolog_bridge, orchestrata_ultimate.cxp.types |
| Imported by | orchestrata_ultimate.cxp, orchestrata_ultimate.cxp.dispatcher |
| Tests that import it | tests/cxp/test_router.py |
Class diagram
Dependency diagram
API
Constants
| Name | Type | Value |
|---|---|---|
_HUB_AGENTS |
frozenset |
frozenset({VOLK_ALIASES['Orchestrator'], VOLK_ALIASES['Postman']}) |
_DEFAULT_DESTINATIONS |
frozenset |
frozenset({VOLK_ALIASES['Postman'], VOLK_ALIASES['Orchestrator']}) |
Classes
CXPRouter
Line 52
CXP-level packet router.
| Method | Signature | Summary |
|---|---|---|
__init__ |
__init__(prolog_bridge: PrologBridge | None = None) -> None |
|
route |
async route(packet: CXPPacket) -> RoutingResult |
Determine routing for a CXP packet. |
register_route |
register_route(from_agent: str, to_agent: str) -> None |
Register an allowed route between two agents. |
unregister_route |
unregister_route(from_agent: str, to_agent: str) -> None |
Remove a previously registered route. |
is_valid_route |
is_valid_route(from_agent: str, to_agent: str) -> bool |
Check whether a route from from_agent to to_agent exists. |
get_routes_for |
get_routes_for(agent: str) -> list[str] |
Return all agents reachable from agent. |
get_all_routes |
get_all_routes() -> dict[str, list[str]] |
Return the full routing table. |
_seed_default_routes |
_seed_default_routes() -> None |
Populate the routing table with default routes. |
_check_governance |
async _check_governance(packet: CXPPacket) -> bool |
Validate routing against governance rules via the Prolog bridge. |
Source
# mypy: ignore-errors
"""
CXP Packet Router.
Determines WHERE a CXP packet goes based on the routing table
and governance rules. Each Volk has a set of allowed destinations;
the router resolves the correct target(s) for a given packet.
Spec: 004-cxp
Author: Mohamed
"""
import logging
from typing import TYPE_CHECKING
from orchestrata_ultimate.core.base.traces import traces
from orchestrata_ultimate.core.packet import CXPPacket
from orchestrata_ultimate.cxp.exceptions import NoRouteError, RoutingError
from orchestrata_ultimate.cxp.types import (
VOLK_ALIASES,
RoutingDecision,
RoutingResult,
)
if TYPE_CHECKING:
from orchestrata_ultimate.cxp.prolog_bridge import PrologBridge
logger = logging.getLogger(__name__)
__all__ = [
"CXPRouter",
]
# Agents that act as global hubs: they can send to anyone.
_HUB_AGENTS: frozenset = frozenset(
{
VOLK_ALIASES["Orchestrator"], # U:Ox
VOLK_ALIASES["Postman"], # U:PS
}
)
# Default destinations available to every non-hub agent.
_DEFAULT_DESTINATIONS: frozenset = frozenset(
{
VOLK_ALIASES["Postman"], # U:PS
VOLK_ALIASES["Orchestrator"], # U:Ox
}
)
class CXPRouter:
"""CXP-level packet router.
Maintains a routing table that maps each ``from_agent`` to a set of
allowed ``to_agent`` destinations. The table is pre-populated with
default routes:
* Every Volk can send to Postman (U:PS) and Orchestrator (U:Ox).
* Orchestrator and Postman can send to any registered Volk.
An optional *prolog_bridge* can be supplied for governance-level
validation (e.g. PAM++ ownership checks).
Args:
prolog_bridge: Optional bridge to a Prolog governance engine.
"""
def __init__(self, prolog_bridge: PrologBridge | None = None) -> None:
self._routes: dict[str, set[str]] = {}
self._prolog_bridge = prolog_bridge
# Seed the routing table with defaults.
self._seed_default_routes()
# ------------------------------------------------------------------
# Public API
# ------------------------------------------------------------------
@traces(spec="001", story="US-002", reqs=["REQ-001-US-002-001"])
async def route(self, packet: CXPPacket) -> RoutingResult:
"""Determine routing for a CXP packet.
Resolution order:
1. Validate that *from_agent* has a route to *to_agent*.
2. If a prolog_bridge is present, perform governance validation.
3. Return a :class:`RoutingResult` with decision DELIVER (or REJECT
when no valid route exists).
Args:
packet: The CXP packet to route.
Returns:
A RoutingResult describing where the packet goes.
Raises:
NoRouteError: If no route exists from the sender to the
intended recipient.
RoutingError: If governance validation fails.
"""
from_agent: str = packet.from_agent
to_agent: str = packet.to_agent
if not from_agent or not to_agent:
raise RoutingError(
message="Packet missing from_agent or to_agent",
packet_id=packet.message_id,
)
# Check the routing table.
if not self.is_valid_route(from_agent, to_agent):
raise NoRouteError(
destination=to_agent,
message=f"No route from {from_agent} to {to_agent}",
details={"from_agent": from_agent, "to_agent": to_agent},
)
# Governance check via Prolog bridge (if available).
if self._prolog_bridge is not None:
governance_ok = await self._check_governance(packet)
if not governance_ok:
return RoutingResult(
decision=RoutingDecision.REJECT,
targets=[to_agent],
reason=f"Governance rejected route {from_agent} -> {to_agent}",
)
return RoutingResult(
decision=RoutingDecision.DELIVER,
targets=[to_agent],
reason=f"Routed {from_agent} -> {to_agent}",
)
def register_route(self, from_agent: str, to_agent: str) -> None:
"""Register an allowed route between two agents.
Args:
from_agent: Sender Volk alias (e.g. ``"U:Cd"``).
to_agent: Receiver Volk alias (e.g. ``"U:Qa"``).
"""
if from_agent not in self._routes:
self._routes[from_agent] = set()
self._routes[from_agent].add(to_agent)
def unregister_route(self, from_agent: str, to_agent: str) -> None:
"""Remove a previously registered route.
Args:
from_agent: Sender Volk alias.
to_agent: Receiver Volk alias.
"""
if from_agent in self._routes:
self._routes[from_agent].discard(to_agent)
@traces(spec="001", story="US-002", reqs=["REQ-001-US-002-009"])
def is_valid_route(self, from_agent: str, to_agent: str) -> bool:
"""Check whether a route from *from_agent* to *to_agent* exists.
Args:
from_agent: Sender Volk alias.
to_agent: Receiver Volk alias.
Returns:
True if the route is registered, False otherwise.
"""
destinations = self._routes.get(from_agent, set())
return to_agent in destinations
def get_routes_for(self, agent: str) -> list[str]:
"""Return all agents reachable from *agent*.
Args:
agent: The source Volk alias.
Returns:
Sorted list of destination aliases.
"""
return sorted(self._routes.get(agent, set()))
def get_all_routes(self) -> dict[str, list[str]]:
"""Return the full routing table.
Returns:
Dictionary mapping each source agent to its sorted list of
allowed destinations.
"""
return {
agent: sorted(destinations)
for agent, destinations in sorted(self._routes.items())
}
# ------------------------------------------------------------------
# Internal helpers
# ------------------------------------------------------------------
def _seed_default_routes(self) -> None:
"""Populate the routing table with default routes.
Default policy:
* All Volks can reach Postman (U:PS) and Orchestrator (U:Ox).
* Orchestrator and Postman can reach every Volk.
"""
all_aliases: list[str] = list(VOLK_ALIASES.values())
for alias in all_aliases:
if alias not in self._routes:
self._routes[alias] = set()
if alias in _HUB_AGENTS:
# Hub agents can reach everyone.
self._routes[alias] = set(all_aliases) - {alias}
else:
# Non-hub agents get the default destinations.
self._routes[alias].update(_DEFAULT_DESTINATIONS - {alias})
@traces(spec="001", story="US-003", reqs=["REQ-001-US-003-001"])
async def _check_governance(self, packet: CXPPacket) -> bool:
"""Validate routing against governance rules via the Prolog bridge.
Args:
packet: The packet whose routing is being validated.
Returns:
True if governance permits the route, False otherwise.
"""
try:
if self._prolog_bridge is None:
# Only called (route()) when a bridge is configured; guard
# narrows the type for the call below without changing
# behavior for the one real caller.
return True
result = self._prolog_bridge.validate_route_via_prolog(
from_agent=packet.from_agent,
to_agent=packet.to_agent,
)
return bool(result)
except Exception as exc:
# Governance bridge failure is treated as rejection.
logger.warning(
"Prolog route validation failed for %s->%s: %s — rejecting route",
packet.from_agent,
packet.to_agent,
exc,
)
return False