Skip to main content

The event database for decisions that stay correct.

Orisun preserves complete event history and lets a command declare the facts behind its decision. At commit time, Orisun checks that context again. Changed facts reject the write; a valid decision commits atomically and moves to catch-up plus live delivery.

One ordered history.
Every decision checked against the facts it used.

The stale-decision problem

Correct business logic can still commit the wrong result.

Two commands can read the same valid state and both make a reasonable decision. The second decision becomes unsafe when the first command changes the facts it relied on. Orisun makes that race part of the write contract.

Declared contextAccount balance $100position 42
Command ATransfer $80
Reads $100Decision validCommitted

Writes at position 43. The account balance is now $20.

Command BTransfer $60
Read $100Was valid at 42Rejected

ALREADY_EXISTS: re-read the context and decide again.

Without the checkBoth transfers land and the account reaches -$40.With OrisunThe stale second write never commits.
What changes

History becomes an active guardrail, not just an audit trail.

Orisun closes the loop between the evidence a command reads, the decision in application code, the atomic write, and the systems that react afterward.

Evidence

Preserve how the system got here

Keep the events behind current state so decisions, projections, audits, and future models share the same durable source of truth.

Validation

Refuse decisions made on changed facts

A command declares the events it relied on. Orisun checks that same subset inside the write transaction and rejects a stale save.

Scope

Match the real business invariant

Define consistency with event-content queries across the relevant entities instead of forcing every rule into one fixed stream.

Reaction

Recover and continue from every commit

Consumer checkpoints and ordered backend reads support replay. Core NATS hints and idle watchdogs wake subscriptions while NATS is healthy.

Where it matters

Use the facts that make each decision safe.

The application still owns its domain rules. Orisun gives each command a dynamic, content-defined consistency boundary for enforcing them under concurrency.

Payments and ledgers

Two transfers are each valid against the same balance, but not together.

Validate the source balance and both account histories before committing both legs atomically.

Inventory and reservations

Concurrent requests act on availability that another request has already consumed.

Scope the write to the product, reservation, and allocation events that determined availability.

Workflows and approvals

A step is approved after policy, permissions, or an earlier decision has changed.

Check the workflow and policy events the command evaluated before recording its outcome.

Agent actions

An agent proposes an action from facts that changed while it was reasoning or waiting on a tool.

Record the relevant facts as events and reject the action when its declared context is no longer current.
One command loop

Read, decide, validate, deliver.

Business decisions stay in application code. Orisun owns the transactional context check and the durable path from a committed event to every recovering subscriber.

1

Read the evidence

Read each required context and retain its complete query and latest matching position.

2

Make the decision

Apply business rules in application code and produce the next events.

3

Validate and commit

Save only if the same declared event subset is still at the expected position.

4

Deliver the result

Deliver matching events through ordered backend reads, triggered by Core NATS hints.

The mechanism

Consistency shaped around each command.

Command Context Consistency lets each decision declare the exact event subset it relies on. Query that context, remember its position, then save only if it remains unchanged. Define and activate the application boundary through the Admin API before entering this command loop.

Node.jsRead and save with the same criteria
const latest =
  await client.getLatestByCriteria({
    boundary: 'accounts',
    criteria,
  });
const expectedPosition = latest.contextPosition;

await client.saveEvents({
  boundary: 'accounts',
  query: {
    expectedPosition,
    subsetQuery: {criteria},
  },
  events,
});
Command checks, durable storage, and Core NATS subscription hints
Built as one system

The durable log and delivery path share one ordering contract.

Storage remains the source of truth. Core NATS carries empty wake-up hints; subscriptions read every event from the backend. Consumers persist their own checkpoints and handle ordered, at-least-once replay. JetStream provides leases and admin messaging.

  • Transactional event writes and context checks
  • Runtime boundary creation through a durable event-backed catalog
  • Subscription cursors and consumer checkpoints
  • Ordered backend reads for catch-up and new events
  • gRPC, auth, indexes, telemetry, and admin APIs
Read the delivery guarantees
Start locally

A complete event database in one SQLite container.

Run the event log, context checks, subscriptions, admin state, and embedded NATS together. The same EventStore API carries forward to every backend.

SQLitelocalhost:5005
docker run --rm \
  -p 5005:5005 \
  -e ORISUN_BACKEND=sqlite \
  -e ORISUN_NATS_STORE_DIR=/var/lib/orisun/nats \
  -e ORISUN_SQLITE_DIR=/var/lib/orisun/sqlite \
  -e ORISUN_NATS_CLUSTER_ENABLED=false \
  -e ORISUN_ADMIN_BOUNDARY=orisun_admin \
  -v orisun-data:/var/lib/orisun \
  orisunlabs/orisun:0.13.0-sqlite