How Swiftward works
The core concepts, how one decision is made, and what a rule looks like. Written for the engineer evaluating Swiftward.
Core concepts
The thing that happened: a prompt, a tool call, an order, a transaction, a piece of content. It carries its own timestamp, and the engine uses that time when it evaluates the event.
The subject a decision is about: a user, an agent, an account, a session. Swiftward keeps state for each entity: counters, counters over a time window, labels and metadata. State is ACID, and an event processed twice changes it only once. A rule reads that state, so it can ask whether this is the fifth request this hour.
A policy is a versioned set of rules. A rule is conditions plus effects: when the conditions hold, return this verdict and run these actions. A policy moves through draft, candidate, frozen, archived. Deploying is a separate step, and a deployment rolls back by naming the previous version.
The computed inputs a rule reads: a PII match, an injection-classifier score, a velocity counter, an LLM-as-judge result, the output of your own function. A signal can be a deterministic check or a model call, and you decide which rules rely on which.
The verdict is one of approved, flagged, or rejected. A rule can also redact a field, open a case for human review, update a counter, or send an alert or a webhook.
The tamper-evident record of one decision: the signals computed, the rules that matched, the state that changed, the verdict, the frozen policy version it ran on, and the record hash. It answers a dispute, and it is what you hand an auditor.
How a decision is made
An event arrives through a gateway or the API. The engine loads the entity's state, computes the signals the policy needs, and runs the rules. The verdict is decided first, and only then are the side effects carried out.
Every step is written to the decision record. Where a rule calls a model, the decision record shows what the model returned. Where a rule opens a case for a person, the audit trail shows who decided the case. What the engine guarantees while it does that — ordering, determinism, state — is on the engine.
Writing policy
Policy is configuration: structured, versioned, and readable as a diff. Two rules below: the first reads state in a condition, the second writes it in an effect. The second counts a refund only once it was carried out, not when it was approved.
rules:
refund_needs_an_operator_for_the_day: # on: mcp.input ยท tool: refund_transaction
all:
- path: "state.user.buckets.refunded_today"
op: gte
value: "{{ constants.operator_approves_daily_total_above_usd }}"
effects:
verdict: flagged
count_executed_refunds:
all:
- path: "event.type"
op: eq
value: "mcp.completed"
- path: "event.data.status"
op: eq
value: "success"
effects:
verdict: approved
state_changes:
user:
change_buckets:
refunded_today: "{{ signals.refund_amount }}" Every rule has this shape. The language also has priorities, fallbacks for errors, and reusable settings for the functions a rule calls. Your own scoring comes in as a signal that calls your service over HTTP, so none of your code runs inside our process. The record keeps what the signal asked and what came back.
Go deeper
- The platform overview: one image to deploy, Postgres for state and audit, and how the deployment grows.
- The engine: determinism, state, and the request path or the background.
- Safe change: backtest, shadow and A/B.
- Audit and evidence: the decision record, hash-chaining, SIEM forwarding, retention.
- Gateways: the six gateways, how identity and keys are handled, and what an agent can reach.
- Prompt injection guide and the maturity model.