z0 Primitives
Formal specification of the three irreducible concepts.
Everything in z0 is either a primitive, a typed instance of a primitive, a derived calculation, or cached state. There are exactly three primitives.
The Philosophy
Section titled “The Philosophy”You cannot change the past. You can only change how you look at it, and use that to make better decisions in the future.
You are not defined by circumstances, but by how you choose to interpret them.
This philosophy underpins everything. Facts record what happened. Config determines how we interpret it. Together they enable simulation, analysis, and optimization.
Overview
Section titled “Overview”| Primitive | What It Is | What It Answers |
|---|---|---|
| Entity | A container defined by its facts and config | Who or what is involved? |
| Fact | An immutable record of something that happened | What occurred? |
| Config | A versioned setting that governs behavior | What are the rules? How do we interpret? |
Something that happened. Immutable. Timestamped. Typed. Never modified, only appended.
Principles
Section titled “Principles”| # | Principle | Description |
|---|---|---|
| 1 | Facts are immutable | Once written, a fact cannot be changed. Corrections create new facts. |
| 2 | Time-travel to the past is possible | Any moment in history can be reconstructed by replaying facts. |
| 3 | Only new facts can be written | Facts append forward only. No backdating, no insertion into the past. |
Schema
Section titled “Schema”Fact { id: string // Unique identifier type: string // Event type subtype: string // Type-specific classification timestamp: timestamp // When it happened
tenant_id: string // Denormalized for O(1) scoping
// Entity Links source_id: string // What triggered this Fact entity_id: string // Primary entity involved
// Audit config_id: string // Which Config was applied config_version: integer // Which version of that Config
// Observability trace_id: string // Optional: links to execution trace
data: {} // Type-specific payload}Fact Types
Section titled “Fact Types”Facts are domain-specific. The platform provides the structure; your domain defines the types.
Example fact types:
- invocation - Tool was called
- outcome - Business state resolved
- charge - Money owed to us
- cost - Money owed to vendor
- lifecycle - Entity state changed
- config_change - Config was modified
- error - Something failed
Invariants
Section titled “Invariants”// Every Fact has required fields∀ Fact → id ≠ null AND timestamp ≠ null AND type ≠ null AND entity_id ≠ null
// Config audit trail required for config-dependent Facts∀ Fact(where requires_config) → config_id ≠ null AND config_version ≠ null
// Immutability∀ Fact → never updated after creation
// Facts with same ID must be identical∀ Fact f₁, f₂ WHERE f₁.id = f₂.id → f₁ = f₂
// If source_id set, source must exist∀ Fact f WHERE f.source_id ≠ null → ∃ Fact s WHERE s.id = f.source_idEntity
Section titled “Entity”A container with identity. Its type, state, and meaning are entirely derived from facts interpreted through config.
Principles
Section titled “Principles”| # | Principle | Description |
|---|---|---|
| 1 | An entity is defined by its facts and its config | Entity has no independent state. Type, structure, meaning - all derived from facts interpreted through config. |
| 2 | An entity has one home | One Durable Object per entity. Single source of truth. No split brain. |
| 3 | An entity has one owner | One tenant owns each entity. Tenant isolation is absolute. |
Schema
Section titled “Schema”The Entity primitive uses a generic schema with flexible index slots instead of hardcoded columns. This enables multi-domain support without schema migrations.
Database Schema (Durable SQLite)
Section titled “Database Schema (Durable SQLite)”CREATE TABLE entity ( -- Core fields (always present) id TEXT PRIMARY KEY, tenant_id TEXT, type TEXT NOT NULL,
-- Full entity data (JSON) data TEXT NOT NULL DEFAULT '{}',
-- Timestamps created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL,
-- Version for optimistic concurrency version INTEGER NOT NULL DEFAULT 1
-- Generated Columns for Indexing (Dynamic) -- The platform automatically adds columns for indexed fields: -- [field_name] [type] GENERATED ALWAYS AS (json_extract(data, '$.[field_name]')) VIRTUAL);TypeScript Interface (Generic)
Section titled “TypeScript Interface (Generic)”export interface Entity { id: string; type: string; tenant_id?: string; version: number; // Optimistic concurrency control metadata: Record<string, unknown>; // Arbitrary document storage created_at: number; updated_at: number; [key: string]: any; // Extension point for domain fields}Entity Type is Derived
Section titled “Entity Type is Derived”An entity’s type is not a fixed property - it’s derived from its facts. When an entity “pivots” (e.g., Lead → Customer), this is recorded as a fact:
Fact { type: "lifecycle", subtype: "pivot", entity_id: "ent_123", data: { from: "lead", to: "customer" }}Time-travel reconstructs the correct type at any point by replaying facts.
Benefits of Generic Schema
Section titled “Benefits of Generic Schema”- No schema migrations: New entity types don’t require database changes
- Multi-domain support: Multiple domains can coexist with different field mappings
- Full data preservation: Complete entity stored in
dataJSON column - Query performance: Promoted fields in index slots maintain query speed
- Type safety: Domain manifests provide compile-time field validation
Config
Section titled “Config”A versioned setting that governs behavior or determines values. The “lens” through which facts are interpreted.
Principles
Section titled “Principles”| # | Principle | Description |
|---|---|---|
| 1 | Configs are typed and versioned by type | Configs have types (schema, rules, goals, etc.). Each type versions independently. |
| 2 | Config changes are facts | Every config change is recorded as a fact. Full audit trail of what changed, when, and why. |
| 3 | Configs flow down and cannot be overridden | Platform → Tenant → Entity. Lower levels inherit from above and cannot override what is set above. |
| 4 | Config snapshots capture composite state | A snapshot records all config type versions at a point in time, enabling reconstruction. |
Config Types
Section titled “Config Types”Configs are typed. Common types include:
| Type | What It Defines | Example |
|---|---|---|
| Schema | Structure of data | ”Contact has name, email, phone” |
| Rules | Logic and constraints | ”Calls over 3 min are qualified” |
| Goals | What success looks like | ”Maximize qualified calls per dollar” |
Each type versions independently:
schema:contact v3rules:qualification v7goals:campaign v2Config Hierarchy
Section titled “Config Hierarchy”Configs flow down through the hierarchy. A config key set at a higher level cannot be set again at a lower level.
Platform Config (most general) ↓ inherited, cannot overrideTenant Config ↓ inherited, cannot overrideEntity Config (most specific)Example:
Platform sets: max_budget = $10,000Tenant tries: max_budget = $5,000 ✗ Rejected - already set aboveTenant tries: webhook_url = "..." ✓ Allowed - not set aboveSchema
Section titled “Schema”Config { id: string // Unique identifier type: string // schema, rules, goals, etc. category: string // policy | logic
name: string // Human-readable name applies_to: string // Entity ID this Config governs scope: string // platform, tenant, entity tenant_id: string // Denormalized for O(1) scoping
version: integer // Increments on change effective_at: timestamp // When this version became active superseded_at: timestamp // When replaced (null if current)
settings: {} // Type-specific configuration}Config Versioning
Section titled “Config Versioning”- Configs are never modified in place
- Changes create new versions (version increments)
- Previous version gets superseded_at timestamp
- Every config change creates a fact for audit
- Historical calculations can be exactly reproduced
Composite Snapshots
Section titled “Composite Snapshots”When any config type changes, a composite snapshot is created:
config_snapshot v1.3 = { schema:contact v3 rules:qualification v7 goals:campaign v2}This enables reconstruction: “What was the full programming at time T?”
Invariants
Section titled “Invariants”// Exactly one current version per config_id∀ config_id → COUNT(WHERE superseded_at IS NULL) = 1
// Versions are contiguous∀ Config(id, version > 1) → ∃ Config(id, version - 1)
// Config effective_at must precede superseded_at∀ Config c WHERE c.superseded_at ≠ null → c.effective_at < c.superseded_at
// Cannot override ancestor config∀ Config c at scope S → ¬∃ Config ancestor WHERE ancestor.type = c.type AND ancestor.scope < SSimulation
Section titled “Simulation”The power of facts + config: replay the same facts through different configs to see alternate outcomes.
Facts (locked) + Config v1 → Outcome A (what happened)Facts (locked) + Config v2 → Outcome B (what would have happened)Facts (locked) + Config v3 → Outcome C (what if?)This enables answering questions like:
- “If we had used this pricing model, what would revenue have been?”
- “If we rewarded conversion instead of volume, who would be top performers?”
- “If we changed the attribution window, how would spend shift?”
The past doesn’t change. The lens does.
Not Primitives
Section titled “Not Primitives”These are important but explicitly not primitives:
Resource
Section titled “Resource”Named settings with identity that don’t participate in economic activity directly.
| Type | Purpose |
|---|---|
| template | Reusable content |
| integration | External connections |
Resources have schemas but are not primitives. They don’t generate Facts.
Cached State
Section titled “Cached State”Derived state for runtime performance. Reconciled against Facts.
Examples:
- BudgetState (derived from charge Facts)
- CapState (derived from invocation Facts)
- AccessState (derived from access_* Facts)
Cached State is:
- Explicitly named
- Reconcilable against Facts
- Disposable (can be rebuilt)
- Never authoritative (Facts win on conflict)
Summary
Section titled “Summary”| Primitive | Principles |
|---|---|
| Fact | Immutable, Time-travel possible, Only new |
| Entity | Facts + config, One home, One owner |
| Config | Typed + versioned, Changes are facts, Flow down + no override, Snapshots |
Total: 10 principles across 3 primitives
The primitive model is complete. If something doesn’t fit, it’s either:
- A typed instance of a primitive
- A derived calculation
- Cached state
- A product concern (not infrastructure)