Skip to content
HOW IT WORKS

How Statewave works

A clear data lifecycle: record raw events, compile durable memories, retrieve ranked context, govern with provenance and deletion.

  1. 1

    User asks a question

    "Following up on the billing issue from last week — any update?"

    New query to the app / LLM

  2. 2

    App asks Statewave for context

    Send subject + task

    subject_id=customer_123
    task=answer billing question

    Context request

  3. 3

    Statewave finds the right context

    Search memories

    • • profile facts
    • • preferences
    • • procedures
    • • past decisions

    Pull relevant episodes

    • • recent interactions
    • • support events
    • • raw conversation history

    Rank & filter

    • • semantic similarity
    • • recency · kind priority
    • • temporal validity · token budget

    ContextAssembler builds a ranked context bundle

  4. 4

    Return context to the LLM

    Facts
    Relevant episodes
    Procedures
    Provenance
    Assembled context

    Token-bounded context bundle

  5. 5

    LLM answers with memory

    Response is personalized, grounded, and aware of prior history.

    "Yes — the refund posted Friday and your account is active again. Anything else you'd like me to check?"

Behind the scenes — how memory is created

  1. A

    Record episodes

    Append-only raw events from chats, actions, tickets, or workflows.

  2. B

    Compile memories

    Heuristic or LLM compilers extract typed memories.

  3. C

    Store with provenance + embeddings

    Each memory links back to its source episodes.

  4. D

    Persist in Postgres + pgvector

    Durable memory runtime — your infrastructure.

Core loop: Record → Compile → Context → Govern

MEMORY LIFECYCLE

The core loop

Every interaction follows the same deterministic lifecycle: record, compile, retrieve and govern. Statewave transforms raw events into durable, structured memory ready for production AI agents.

Memory lifecycle: Record, Compile, Context, Govern
01

Record

Immutable episodes capture raw interaction truth — conversations, tool calls, decisions. Append-only, never mutated.

02

Compile

Pluggable compilers derive typed memories with confidence scores, validity windows, and provenance back to source episodes.

03

Context

Assembly service builds ranked, token-bounded, deterministic context bundles ready for any prompt.

04

Govern

Provenance inspection, subject timelines, GDPR-style deletion, authentication, rate limiting, webhooks.

Domain model

Episodes

Immutable raw event records. Conversations, tool calls, decisions, observations. The ground truth that Statewave remembers. Append-only, never mutated.

Memories

Compiled typed facts with confidence scores, validity windows, embeddings, and provenance back to source episodes. Kinds: profile_fact, episode_summary, procedure, artifact_ref.

Context Bundles

Runtime output: ranked, token-bounded, deterministic. Sections for task, facts, procedures, history, episodes. Ready to inject into any LLM prompt.

Support-native intelligence

Handoff packs

Compact escalation briefs with customer summary, active issue, attempted steps, resolution history, health score, and SLA status — ready for human or AI handoff.

Health scoring

Deterministic 0–100 scores with explainable factors: unresolved issues, repeat problems, SLA breaches. States: healthy (≥70), watch (40–69), at_risk (<40).

SLA tracking

First-response time, resolution time, per-session breach detection. Custom thresholds. Integrated into health scoring and handoff context.

Resolution tracking

Track issue state per session — open, resolved, unresolved. Surface resolution history when patterns recur. Repeat-issue detection built in.

PRIVACY

Privacy & data flow

Statewave is honest about what stays local and what leaves your network. Privacy depends on the four layers below, not just where Postgres runs.

Storage (Postgres + pgvector)

Runs
Your infrastructure
Leaves
Nothing.

Retrieval / ranking

Runs
Your infrastructure (Statewave server)
Leaves
Nothing — ranking is local and deterministic.

Compilation — heuristic

Runs
Your infrastructure
Leaves
Nothing. Default mode.

Compilation — LLM

Runs
Configured provider via LiteLLM
Leaves
Episode batches sent to the provider you choose. Self-hosted models keep this local.

Embeddings (optional)

Runs
Configured provider
Leaves
Episode/memory text sent for vectorization. Use a self-hosted embedding model to avoid this.

Your agent's LLM

Runs
Wherever you host it
Leaves
Statewave returns context to your agent; what your agent sends to its model is governed by your agent, not Statewave.

Fully local mode: heuristic compiler + a self-hosted embedding model (or text-only retrieval) means no Statewave-driven traffic leaves your network. Any additional privacy depends on the LLM your agent calls.

GOVERNANCE

Audit & governance

The v0.8 governance layer — extended in v0.9 with HMAC-signed receipts, receipt replay, detector-suggested labels (opt-in via STATEWAVE_AUTO_LABELING_ENABLED), and per-region residency pinning — lets every context assembly emit an immutable audit artifact, and per-memory sensitivity labels feed a declarative policy engine that filters memory access by caller identity. Both surfaces are designed for compliance review — not a "trust us" log, but addressable records with byte-level integrity hashes that a reviewer can verify without trusting the application that wrote them.

State-assembly receipts

Immutable, ULID-addressable record of which memories and episodes influenced an assembled context bundle, with a SHA-256 hash of the bytes delivered to the agent. Queryable by id or by subject/time-range with a stable cursor.

Operator lever

emit_receipt: true per request, or tenant config receipts: always for compliance-grade tenants

Per-entry supersession status

Each selected memory carries its active | superseded | tombstoned state, source episodes, and provenance hash. Stale facts, resurrected tombstones, and unresolved conflicts are detectable from the receipt alone.

Operator lever

No config — recorded automatically

Sensitivity labels

Per-memory capability tags (pii, financial, secret, …) operators set via PATCH /v1/memories/{id}/labels. Stored as a typed TEXT[] column with a GIN index so policy filters run in milliseconds on the hot path.

Operator lever

Operator-supplied in v0.8; compiler/connector heuristic auto-labeling shipped in v0.9 — advisory `suggested_labels` separate from authoritative `sensitivity_labels`, promotion is an explicit operator action

Declarative policy engine

YAML or JSON policy bundles with six predicates (label match, caller_type, caller_id) and two actions (deny, redact). Bundles are content-hashed and immutable. Receipts reference the bundle hash, so "what did policy abc123 say on date Y?" is answerable forever.

Operator lever

POST /admin/policy/bundles to upload; receipts continue to record decisions even when policy_mode is log_only

Log-only vs enforce

log_only (default) records every decision into the receipt without filtering — operators can audit a policy for days before flipping enforce. enforce drops denied memories before ranking and redacts marked ones in place.

Operator lever

PATCH /admin/tenants/{id}/config { policy_mode: enforce }

Mandatory caller identity

caller_id and caller_type on every assembly call feed the policy evaluator. Compliance tenants can flip require_caller_identity: true so anonymous calls return 401 — making policy enforcement non-bypassable.

Operator lever

PATCH /admin/tenants/{id}/config { require_caller_identity: true }

Receipts and labels live alongside the existing provenance + supersession primitives — the governance layer was designed to extend the data model that was already there, not bolt on a parallel one. Full reference: receipts.md and sensitivity-labels.md.

RETRIEVAL

Scoring model

Ranking is deterministic and inspectable. Items are sorted by composite score and packed into your token budget. Support-agent workloads apply additional session, urgency, and repeat-issue signals on top of the core formula below.

Kind priority

3–10

profile_fact=10, procedure=8, episode_summary=5, raw_episode=3

Recency

0–5

Linear scale: most recent = max

Task relevance

0–8

Word overlap (0–5) or cosine similarity (0–8)

Temporal validity

-4 to +3

Currently valid = +3, expired = -4

Customization today: the weights are fixed. Filter the candidate set (by kind or subject) before retrieval, or subclass the assembler in your deployment if you need different defaults. Per-call weight overrides are not exposed — we'd rather ship that in response to a concrete misranking than speculatively. Full signal list: Ranking & Retrieval →

FAQ

Frequently asked questions

How does a raw event become retrievable memory?

Three endpoints carry the whole loop. POST /v1/episodes appends an immutable, content-hashed event under a subject. POST /v1/memories/compile turns new episodes into typed memories — profile_fact, procedure, episode_summary, artifact_ref — each with a confidence score, a validity window, and its source episode IDs. POST /v1/context returns a ranked, token-bounded bundle. Compilation is idempotent: running it twice creates no duplicates, a property the core repo covers with 708 unit tests and 56 eval assertions across the record → compile → retrieve path.

What is inside a context bundle?

Sections for the task, compiled facts, procedures, recent history, and raw episodes — ranked by composite score and packed until the token budget is spent, never truncated mid-item. Every row carries its kind, confidence, validity window, source episode IDs, and supersession state (active, superseded, or tombstoned), so the calling application can render or audit exactly what the model saw. The benchmark harness exercises budgets of 512, 1,024, 2,048, and 4,096 tokens.

How does Statewave decide which memories make the cut?

A fixed, inspectable scoring model rather than embedding distance alone. Kind priority scores profile_fact 10, procedure 8, episode_summary 5, and raw_episode 3. Recency is a linear scale with the newest item at maximum. Task relevance is word overlap (0–5), or cosine similarity (0–8) when embeddings are configured. Temporal validity adds +3 for a currently valid memory and −4 for an expired one. Support workloads layer session, urgency, and repeat-issue signals on top.

What is a state-assembly receipt?

An immutable, ULID-addressable record of one context call, introduced with the v0.8 governance layer and extended in v0.9 with HMAC signing and receipt replay. It carries a SHA-256 integrity hash of the bytes delivered to the agent, the per-entry supersession status, and the content hash of the policy bundle that was in force — so a reviewer can verify it without trusting the application that wrote it. Request one per call with emit_receipt, or set receipts: always per tenant.

Can I change the ranking weights?

Not today. The weights are constants in server/services/context.py with no per-tenant override, a deliberate choice to keep ranking deterministic and reproducible. You can scope requests by subject, filter /v1/memories/search results by kind, or modify the context assembler in your own self-hosted deployment. Per-call overrides stay unexposed on purpose: we would rather ship them in response to a concrete misranking than speculatively, because every knob is a new way for two deployments to disagree about the same subject.

Answers last checked against the Statewave docs and repositories on .