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 id if 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_id are 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_count for routing
  • Workers claim partitions (or partition ranges)
  • FOR UPDATE SKIP LOCKED ensures 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

  1. Event arrives at Ingestion (HTTP/gRPC)
  2. Enqueued to Postgres (or Kafka) partitioned by entity_id
  3. Worker claims event from its partition
  4. Policy loaded (cached, version-pinned)
  5. Signals computed on demand (DAG order, cached)
  6. Rules evaluated deterministically (priority order)
  7. Verdict determined (first matching rule wins, or default)
  8. Effects computed (state changes: labels, counters, metadata)
  9. State committed transactionally with idempotency check (event id)
  10. Decision trace written (immutable audit record)
  11. Actions executed (webhooks, notifications — outside transaction)
  12. 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: