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: