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.
Overview
Section titled “Overview”| Primitive | What It Is | What It Answers |
|---|---|---|
| Entity | Anything with identity that participates in economic activity | Who or what is involved? |
| Fact | An immutable record of something that happened | What occurred? |
| Config | A versioned setting that governs behavior or determines values | What’s allowed? What does it cost? |
Entity
Section titled “Entity”Something with identity that participates in economic activity.
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}Each domain defines which entity fields should be indexed via a Domain Manifest:
// Example: Domain manifestconst domainManifest: DomainManifest = { entities: { account: { fields: { status: { type: 'string', indexed: true }, name: { type: 'string', indexed: true }, subtype: { type: 'string', indexed: true }, parent_id: { type: 'string', indexed: true }, } }, asset: { fields: { status: { type: 'string', indexed: true }, name: { type: 'string', indexed: true }, identifier: { type: 'string', indexed: true }, subtype: { type: 'string', indexed: true }, } } }};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
Something that happened. Immutable. Timestamped. Typed. Never modified, only appended.
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
- error - Something failed
Fact Traceability Invariants
Section titled “Fact Traceability Invariants”// Every Fact has required fields∀ Fact → id ≠ null AND timestamp ≠ null AND type ≠ 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 creationConfig
Section titled “Config”A versioned setting that governs behavior or determines values.
Schema
Section titled “Schema”Config { id: string // Unique identifier type: string // pricing, budget, routing, etc. category: string // policy | logic
name: string // Human-readable name applies_to: string // Entity ID this Config governs scope: string // account, campaign, asset 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 Categories
Section titled “Config Categories”Policy — governs, constrains:
- budget (eligibility thresholds)
- billing (payment relationships)
- hours (operating schedule)
Logic — calculates, evaluates:
- pricing (what to charge/pay)
- qualification (what counts as valid)
- routing (traffic direction)
- notification (alert triggers)
- webhook (external system alerts)
Config Versioning Rules
Section titled “Config Versioning Rules”- Configs are never modified in place
- Changes create new versions (version increments)
- Previous version gets superseded_at timestamp
- Facts reference both config_id and config_version
- Historical calculations can be exactly reproduced
Config Versioning Semantics
Section titled “Config Versioning Semantics”Version is an integer counter per config_id. Each Config change creates a new row with the same id, incremented version, and the previous row receives a superseded_at timestamp.
// Initial creationConfig { id: "cfg_123", version: 1, effective_at: T1, superseded_at: null, settings: {...} }
// After update at T2Config { id: "cfg_123", version: 1, effective_at: T1, superseded_at: T2, settings: {...} } // OLDConfig { id: "cfg_123", version: 2, effective_at: T2, superseded_at: null, settings: {...} } // CURRENTQuerying:
- Current Config:
WHERE id = ? AND superseded_at IS NULL - Config at point in time:
WHERE id = ? AND effective_at <= ? AND (superseded_at IS NULL OR superseded_at > ?) - Full history:
WHERE id = ? ORDER BY version ASC
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)
// No gaps in time coverage∀ Config(id, v) WHERE superseded_at IS NOT NULL → ∃ Config(id, v+1) WHERE effective_at = superseded_atNot 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”| Category | What It Contains |
|---|---|
| Primitive | Entity, Fact, Config |
| Typed Instance | Your domain-specific implementations |
| Derived Calculation | Attribution, ROI, aggregations |
| Cached State | Performance optimization |
| Resource | Templates, Integrations |
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)