Architecture
Swiftward is a modular policy enforcement engine designed for on-premises deployment. It runs as a single binary that can operate as one process or be deployed as role-based components for horizontal scaling.
Components
Ingestion
- Accepts events via HTTP or gRPC
- Supports sync (wait for verdict) and async (return immediately) modes
- Validates event schema, assigns
idif missing - Routes to queue partitioned by
entity_id
Workers
- Pull events from queue in partition order
- Load active policy version
- Evaluate rules via the Rules Engine
- Commit state changes transactionally
- Execute actions (side effects) after commit
- Write decision traces for audit
Control API
- CRUD for policy versions (YAML upload, validation)
- Activate/rollback policy versions without restart
- Query decision traces and state
- Manage DLQ (inspect, replay, discard)
- Dry-run policy testing
Gateways (Optional)
- Protocol adapters for specific integrations (e.g., SCM webhooks)
- Transform external formats to Swiftward events
- Can run in-process or standalone
Deployment Modes
| Mode | Description | Use Case |
|---|---|---|
| Single Process | All components in one binary | Development, low-volume production |
| Role-Based | Separate processes for ingestion, workers, control API | Horizontal scaling, isolation |
Configuration determines which roles a process runs:
role: "ingestion,worker,control_api" # Comma-separated active roles
Postgres-First Design
Swiftward uses Postgres as the primary data store:
| Data | Table(s) | Description |
|---|---|---|
| Event Queue | inbox_events |
Events pending/processing, with FOR UPDATE SKIP LOCKED polling |
| Dead Letter Queue | dlq_events |
Failed events for inspection and replay |
| Entity State | state_labels, state_counters, state_metadata |
Per-entity labels, counters, and key-value pairs |
| Policy Versions | ruleset_versions |
Compiled policy snapshots with active flag |
| Execution History | analytics_events |
Decision traces (immutable audit log) |
| Applied Effects | applied_effects |
Audit trail of state mutations |
Why Postgres?
- Single dependency for moderate workloads (thousands of events/sec)
- ACID transactions for state consistency
- Familiar operational model (backups, replication, monitoring)
- No distributed coordination complexity
Partitioning and Ordering
Events are partitioned by entity_id (e.g., user ID, session ID).
Guarantees:
- Events for the same
entity_idare processed in order - Events for different
entity_ids can be processed in parallel - State mutations for an entity are serialized
Implementation:
- Queue uses
entity_id % partition_countfor routing - Workers claim partitions (or partition ranges)
FOR UPDATE SKIP LOCKEDensures no duplicate processing
Optional Adapters
Swiftward supports high-volume adapters via configuration only — no code changes required.
| Adapter | Purpose | When to Use |
|---|---|---|
| Kafka | Ingestion buffering, cross-DC replication | >10k events/sec, multi-region |
| Redis | Signal caching, rate limiting state | High cache hit rates, rate limiting |
| ClickHouse / Druid | Analytics, aggregations | Long-term trace storage, dashboards |
Data Flow
- Event arrives at Ingestion (HTTP/gRPC)
- Enqueued to Postgres (or Kafka) partitioned by
entity_id - Worker claims event from its partition
- Policy loaded (cached, version-pinned)
- Signals computed on demand (DAG order, cached)
- Rules evaluated deterministically (priority order)
- Verdict determined (first matching rule wins, or default)
- Effects computed (state changes: labels, counters, metadata)
- State committed transactionally with idempotency check (event
id) - Decision trace written (immutable audit record)
- Actions executed (webhooks, notifications — outside transaction)
- Response returned (sync mode) or event marked complete (async)
API Endpoints
Ingestion (default port 8080)
| Endpoint | Method | Description |
|---|---|---|
/api/v1/ingest/async |
POST | Enqueue event for background processing |
/api/v1/ingest/sync |
POST | Synchronous evaluation with immediate response |
/health |
GET | Health check |
Control API (default port 8081)
| Endpoint | Method | Description |
|---|---|---|
/api/v1/rules/test |
POST | Dry-run rule evaluation |
/api/v1/rules/{version} |
GET | Get compiled rules |
/api/v1/rules/upload |
POST | Upload/validate rules |
/api/v1/analytics/events |
GET | List execution records with filters |
/api/v1/analytics/events/{event_id} |
GET | Get single execution record |
/api/v1/analytics/timeseries |
GET | Time-series aggregation |
/api/v1/analytics/topn |
GET | Top N entities by dimension |
/health |
GET | Health check |
What Swiftward is NOT
Swiftward is purpose-built for policy enforcement. It is not:
- A general BPM/workflow orchestrator — no long-running workflows, human tasks, or complex state machines
- A rules engine for business logic — designed for Trust & Safety, not pricing or eligibility rules
- A real-time streaming processor — not a replacement for Flink/Spark; processes events individually
- A data pipeline — does not transform or route data between systems
- An ML platform — can call external ML/LLM services but does not train or host models
If you need general workflow orchestration, consider Temporal, Airflow, or similar. Swiftward focuses on fast, deterministic, auditable policy decisions.
Further reading: