postman package
Reviewed against commit 8a2cb42ad on 2026-10-23.
Reference: generated package page orchestrata_ultimate.postman (31 modules, 11,199 lines of code); key modules postman, sync_router, router, delivery, types. How a request reaches Postman and where it goes next is traced in the orchestrata overview; the pipeline that calls route_sync is the orchestrator.
The story
Every conversation in Orchestrata happens through messages: when the kernel dispatches work, when one volk hands off to another, when the pipeline needs an answer back, a CXP packet has to travel from a sender to a recipient — reliably, in order of importance, and with proof that it arrived. orchestrata_ultimate.postman is Postman (U:PS), the message routing and delivery engine (SPEC-002) that owns that job. Rather than letting every component talk to Redis ad hoc, the system funnels inter-volk traffic through a single broker that knows how to route, queue, retry, and account for every packet it touches.
At the center sits the Postman facade in postman.py, which implements the core IPostman protocol and inherits SyncRouterMixin from sync_router.py — the synchronous routing path (route_sync) that the orchestrator's PipelineRunner uses to move packets between pipeline stages without an async event loop. A message's life begins as a CXPPacket (from the neighboring cxp package) wrapped by EnvelopeHandler into a validated MessageEnvelope, with its body handled by PayloadHandler (encoding, gzip compression, size validation). The RoutingEngine decides who should receive it — resolving direct recipients, topic subscriptions, and static routes behind a TTL route cache — consulting configurable RoutingRules from RoutingRulesEngine and per-message FilterCriteria. From there the packet lands in a queue: queue.py offers in-memory, disk-backed, bounded, and Redis-backed implementations, all managed by QueueManager, with PriorityQueueImpl and its heap-based scheduler ensuring urgent traffic jumps the line without starving the rest. Finally DeliveryManager orchestrates the actual hand-off, DeliveryGuaranteeManager enforces the delivery mode (at-most-once, at-least-once, exactly-once), MessageStore and ReceiptStore persist the message and its DeliveryReceipt in Redis, and ReplayEngine can re-deliver anything that was stored, so a crashed consumer never means a lost message.
What makes the package navigable is its uniform architecture: interfaces.py defines a Protocol per broker component, and every concrete module implements exactly one of them, so any piece — a queue backend, the routing engine, the receipt store — can be swapped without touching the rest. Failures are equally structured: a single exception tree rooted at PostmanError covers message, delivery, queue, topic, routing, and configuration errors, and PostmanErrorHandler wraps risky operations with retry backoff and a per-destination CircuitBreaker that trips (raising CircuitOpenError) when a downstream keeps failing.
Postman does not live in isolation. It speaks CXP packets from the cxp package, persists through the shared core.redis_factory (Redis is the backbone for queues, stores, receipts, and replay), reads endpoints from core.config.infra, and audits routed packets into the knowledge graph via knowledge_graph.cxp_auditor (the Postman facade holds a CXPAuditor). PostmanGovernanceManager gates operations through the governance layer, EventEmittingPostman wraps the facade to emit routing events onto the observability mesh, and an operational surface — PostmanAdmin's FastAPI router, HealthChecker's liveness/readiness endpoints, and PostmanMetricsCollector's metrics export — lets operators watch and manage the broker. cli.py even runs Postman as its own standalone process.
Key responsibilities
- Routing — resolve a packet's recipients from direct addresses, static routes, topic subscriptions, and rule-based
FilterCriteria, with a TTL-cachedRoutingEngineand a synchronousroute_syncpath for the pipeline. - Queueing — hold undelivered messages across in-memory, disk-backed, bounded, priority, and Redis backends, managed by
QueueManagerwith a heap-orderedPriorityQueueImpland a dead-letter queue. - Delivery —
DeliveryManagerdrives the hand-off;DeliveryGuaranteeManagerenforces at-most-once / at-least-once / exactly-once semantics with acknowledgements, idempotency tokens, and timeout tracking. - Durability & replay —
MessageStoreandReceiptStorepersist envelopes, payloads, andDeliveryReceipts (MessageStore: SQLite is the primary store, Redis a one-hour cache, and graph audit events go out through a Redis queue);ReplayEnginere-delivers stored messages by id or query. - Subscriptions & topics —
SubscriptionManagerandTopicRegistrymatch agents to topic patterns for pub/sub fan-out. - Resilience — a structured
PostmanErrortree plusPostmanErrorHandlerwith retry backoff and per-destinationCircuitBreakers. - Operations & governance — admin API, health checks, metrics, governance gating, and event emission for observability.
Class diagram
Broker facade and delivery pipeline
The Postman facade is the public entry point; DeliveryManager composes the routing, envelope, and queue collaborators that carry a packet from acceptance to hand-off.
Queues, guarantees, stores and subscriptions
Behind the pipeline sit the durability and fan-out collaborators: queue management, delivery-guarantee bookkeeping, the message/receipt stores (SQLite primary, Redis cache), replay, and the subscription/topic registry.
Message data models and enums
The frozen MessageEnvelope (routing metadata) and its MessagePayload (body), plus the delivery bookkeeping records and the routing rule, are the value objects that flow through the broker. Enum classes below list their real values as members.
Exception hierarchy and resilience
A single rooted tree makes every failure catchable at the right granularity; PostmanErrorHandler retries with backoff and keeps a CircuitBreaker per destination.
Notes
- Spec: SPEC-002 (Postman / U:PS message routing and delivery).
- Source:
src/orchestrata_ultimate/postman/— facade inpostman.py, sync path insync_router.py, value objects and enums intypes.py, Protocol contracts ininterfaces.py, exception tree inexceptions.py. - Persistence: Redis (via
core.redis_factory) backs the queues.MessageStorewrites every message to SQLite first (sqlite_path, default./data/messages.db), caches it in Redis for an hour (msg:<id>), and pushes a graph audit event onto a Redis queue. Its docstring sums this up as "SQLite (primary), Redis (cache), graph (audit)". - Neighbors: consumes
cxp.CXPPacket; audits into the operational KG (orchkgon orchgraph; Neo4j until 2026-07-27) throughknowledge_graph.cxp_auditor.CXPAuditor; theEventEmittingPostmanwrapper publishes routing events;PostmanGovernanceManagergates operations. - Every concrete class here implements exactly one Protocol from
interfaces.py, so backends are swappable without touching callers. - Transport. Nothing in this package names a gRPC transport. The CXP transport between processes is cxpt, the direct transport that replaced grpcio on 2026-08-07 (see the orchestrata overview and the gRPC retirement page).
- Health check. The
health.pyreadiness probe checks Redis and the operational graph; its optional Bolt-driver probe still imports the driver package, whose name isneo4j.
Module inventory (8a2cb42ad)
31 modules, 11,199 lines of code. The narrative above names most of them; these are the ones it did not, or that changed:
| Module | Purpose |
|---|---|
delivery_outcome.py |
DeliveryOutcome (frozen: delivered, reason, response, error) and the DeliveryFailure enum (OK, NO_ROUTE, HANDLER_ERROR) — the honest result of a single routing attempt (SPEC-001 US-002 / SPEC-002). |
routing_rules.py |
RoutingRulesEngine(IRoutingRules) — add, remove, update, list and evaluate RoutingRules against an envelope and payload. |
filter.py |
MessageFilter implementation behind FilterCriteria-based routing. |
constants.py |
Shared broker constants (no classes or functions). |
cli.py |
click command group for running Postman as a standalone message-router process: start (config path, log level), status (placeholder), version, and the main console-script entry point. |
types.py, interfaces.py |
Value objects and enums (947 lines) and the per-component Protocols (1,366 lines). |
Class map (generated)
Generated from the live source AST by scripts/gen-module-class-diagrams.py — do not hand-edit. Abstract classes have a green border; members listed are those defined on the class itself (inherited members excluded). Solid empty-triangle arrows = in-package inheritance; dashed arrows into dashed boxes = external/stdlib/cross-package bases; filled diamond = composition (constructed in __init__); open diamond = aggregation (annotated/injected reference); diamond edge labels name the owning attribute.