Core Concepts

Core building blocks of Swiftward and how they interact.

Event

An Event is the input to policy evaluation. It represents something that happened: a user posted content, an AI generated output, a PR was opened, an agent called a tool.

{
  "id": "evt_abc123",
  "entity_id": "user_456",
  "type": "ugc.post.created",
  "data": {
    "text": "Check out this link...",
    "channel": "comments"
  },
  "meta": {
    "ip": "192.168.1.1",
    "user_agent": "Mozilla/5.0..."
  },
  "timestamp": "2025-01-15T10:30:00Z"
}

Entity & State

An Entity is the subject of enforcement — a user, session, account, or resource. Each entity has isolated, persistent state that rules can read and modify.

State types:

Type Description Example
Labels Set of strings "verified", "high_risk"
Counters Named integers post_count: 42
Buckets Time-windowed counters (sliding or fixed windows) daily_posts: 15
Metadata Key-value pairs tier: "premium"
  • State expiration: any state entry can have a TTL with duration support (1d, 2w, expires_at)
  • Multi-entity: a single event can reference multiple entities (e.g., user + transaction + session), with state changes applied to each

Policy

A Policy is a complete, immutable, versioned snapshot of your enforcement configuration: constants, signals, rules, and action profiles.

  • Lifecycle: draft → candidate → frozen → archived
  • Instant activation and rollback — no restart, no deploy
  • A/B testing: split traffic across policy versions (e.g., 70/30)
  • Shadow mode: evaluate against real traffic without affecting production decisions
  • Old versions retained for audit, comparison, and rollback

Rules

A Rule defines conditions and their consequences.

rules:
  block_toxic_content:
    all:
      - path: "event.type"
        op: eq
        value: "ugc.post.created"
      - path: "signals.toxicity_score"
        op: gt
        value: "{{ constants.toxicity_threshold }}"
    effects:
      verdict: rejected
      priority: 100
      state_changes:
        set_labels: ["toxic_content"]
        change_counters:
          toxic_count: 1
      actions:
        - action: notify_admin
          params:
            channel: "#alerts"
  • Conditions: composable with all, any, none, not
  • Expression support: expr-lang for complex conditions beyond path/op/value
  • Effects: verdict + state changes + actions + response
  • Verdict ranking: rejected > flagged > approved — strongest wins across all matching rules

Signals

A Signal is a computed value derived from the event, entity state, or external services. Signals are defined as User-Defined Functions (UDFs).

signals:
  toxicity_score:
    udf: llm/moderation
    params:
      text: "{{ event.data.text }}"
      provider: openai
  • Computed on demand, cached per evaluation
  • Signals can depend on other signals

Categories:

  • Content analysis — LLM moderation, toxicity scoring, topic classification
  • Security — PII scanning, secrets detection, prompt injection detection
  • State queries — counters, buckets, labels, metadata lookups
  • Math, string, time, and list operations
  • External integrations — market data, list lookups, third-party APIs

Actions

Actions are side effects executed after state commit. Actions from all matching rules are accumulated and executed together.

  • Webhooks — HTTP callbacks to external services
  • Notifications — alerts to Slack, email, or custom channels
  • HITL cases — create human review cases with SLA tracking, escalation, and decision callbacks
  • SIEM export — forward decision data to security information systems
  • SCM status checks — set PR check status on GitHub/GitLab

Decision Trace

Every evaluation produces an immutable Decision Trace capturing:

  • Signals computed (values and timings)
  • Rules evaluated (matched/skipped)
  • Final verdict and source rule
  • State changes applied
  • Actions executed

Traces enable: audit compliance, debugging, replay analysis, and trend analytics.

Two-Phase Execution

Swiftward separates evaluation from side effects:

  • Phase 1: Evaluate — deterministic, pure computation with no side effects. Computes signals, evaluates rules, determines verdict.
  • Phase 2: Commit + Act — apply state changes transactionally, write decision trace, execute actions.

Why two phases?

  • Determinism: same event + same state + same policy = same verdict
  • Replayability: re-evaluate without re-executing actions
  • Auditability: trace captures evaluation independent of action success
  • Testability: test rules without triggering side effects

Further reading: