Skip to content

Architecture

This document provides an overview of the core architectural principles and data models used in the z0 SDK.

The z0 SDK is built on three main primitives: Entity, Fact, and Config.

An Entity is a container for identity and metadata. In the z0 SDK, every Entity is mapped 1:1 to a Cloudflare Durable Object. This provides:

  • Strong Isolation: Each entity’s data is isolated at the storage and execution level.
  • Consistency: Durable Objects provide single-threaded execution per instance, ensuring consistent state updates.
  • Locality: Facts related to an entity are stored within the same Durable Object instance.

A Fact is an immutable, point-in-time record of an event. Facts are the single source of truth for all activity within the ledger.

  • Append-Only: Facts are never modified or deleted. Errors are corrected by appending new “correction” facts.
  • Deterministic Replay: The state of an entity can be reconstructed at any time by replaying its facts in order.
  • Traceability: Every change to an entity’s state is backed by a fact, providing a complete audit trail.

Config represents versioned configuration primitives used for routing rules, pricing, or system-level settings.

  • Inheritance: Configs flow downward from Platform to Tenant to Entity.
  • Narrowing Scope: More specific scopes (e.g., Entity-level) can add stricter constraints but cannot relax parent constraints.
  1. Ingestion: External events arrive at a Ledger via API calls.
  2. Validation: The Ledger validates the event against current Configs and Invariants.
  3. Fact Appending: If valid, a new Fact is appended to the Ledger’s internal SQLite storage.
  4. State Update: The Ledger updates its CachedState (materialized view) based on the new Fact.
  5. Replication: Facts are asynchronously replicated to external storage (R2 Master Log) and delivered to subscribers via Webhooks.

Entities follow a defined lifecycle: activeretiringretiredanonymizeddeleted

  • active: Normal operation.
  • retiring: Draining in-flight operations. Only system facts accepted.
  • retired: Read-only state.
  • anonymized: GDPR-compliant state where PII is removed but facts are preserved.
  • deleted: Terminal state for cleanup.

The 1:1 mapping between Entities and Durable Objects is a fundamental architectural choice. The EntityLedger class is the base Durable Object implementation. When you create a new entity, the SDK uses the Durable Object namespace to get a unique stub for that entity based on its ID or name.

// Example of how the SDK maps an Entity to a Durable Object
const stub = namespace.get(namespace.idFromName(entityId));

This ensures that all operations for a specific entity are routed to the same physical instance, enabling strong consistency and simplified concurrency management.

The appendFact operation follows a specific sequence to ensure the ledger remains a reliable source of truth:

  1. Fact Persisted: The Fact is first written to the Durable Object’s local SQLite storage. This is a synchronous, durable operation.
  2. State Materialized: The CachedState is updated by replaying the new Fact through the updateCachedState handler.
  3. Side Effects Triggered: Synchronous Hooks are executed.

In this architecture, the Fact is the truth. Once a Fact is committed to SQLite, it persists even if subsequent state updates or hooks fail.

  • Sync Hooks: If a synchronous hook throws an error, the SDK logs the error and records a hook_error system fact, but does not fail the appendFact call. This is because the Fact is already committed. To prevent inconsistent states, Sync Hooks should be idempotent and should not be used for critical business logic validation.
  • Invariants: For critical validations that must prevent a Fact from being recorded (e.g., “balance cannot be negative”), use Invariants. Invariants are evaluated before the Fact is persisted.
  • Self-Healing: If CachedState becomes inconsistent due to a failure during the update process, it can be fully reconstructed by replaying the Fact history. The SDK provides a reconstructState method for this purpose.