apomesh-state-store-postgres
The production durable-persistence adapter family. This crate is the
Postgres side of the substrate’s state-store layer: the hexagonal
adapters that sit behind the substrate’s store ports and back a cloud
deployment. PostgresStateStore is the primary adapter — the durable
event log, snapshots, and the memory tiers — and it ships alongside the
HybridStateStore composition and a family of sibling Postgres adapters
(catalog, registries, credentials, tokens, assets) the daemon constructs
over one shared connection pool. Reach for this crate when a deployment
needs durable persistence rather than the in-memory or SQLite adapters.
Position in the workspace
Section titled “Position in the workspace”- Layer: state stores — the deployment-persistence adapters behind the substrate’s store ports. See The event log for the event-log and checkpoint model these adapters durably back.
- Depends on:
apomesh-protocol (wire types
decoded at the store boundary),
apomesh-substrate (the store
ports + domain types), and apomesh-state-store-redis (the cache
HybridStateStorecomposes inward). - Consumed by: apomesh-orchestrator-bin (constructs the store and every sibling adapter at boot), apomesh-worker (a pool for asset streaming), and apomesh-reseal (sealing-key rotation).
What it owns
Section titled “What it owns”- The primary durable
StateStore—PostgresStateStore: the tenant-bound event log (append with a bounded position-conflict retry, read, poll-based stream, prune),CheckpointSource-tagged snapshots, working memory, the episodic / semantic / procedural memory tiers, and the side-effect log. - pgvector semantic memory —
semantic_memoryuses ahalfvec+ HNSW cosine index; retrieval is a linear blend of vector cosine and BM25 (ts_rank_cdoverwebsearch_to_tsquery). The vector column’s dimension is provisioned at boot to the configured embedding provider’sembedding_dim()(ensure_embedding_dimension). - The production composition —
HybridStateStore(inhybrid.rs): write-through over the durable Postgres adapter (authoritative) plus the apomesh-state-store-redis cache (hot working-memory reads and a best-effort event-log replay buffer). - Embedded schema migrations — a
MIGRATIONSconst embeds eachmigrations/*.sqlviainclude_str!;run_migrationsapplies them transactionally and idempotently, tracked in_apomesh_migrations. The crate goes crate-direct onsqlx(nosqlx::migrate!macro) to avoid a SQLite-linkscollision — so the runner is inline. - At-rest sealing —
SecretSealer(ChaCha20-Poly1305, a fresh per-value nonce,apomesh-sealed:v1:tokens, key fromAPOMESH_SECRET_KEY) seals the secret-bearing fields of the credential and MCP adapters before INSERT so no cleartext lands in JSONB. - The sibling store family over one shared pool — the Postgres adapters for the agent catalog, the published-agent / strategy-config / published-skill registries, the mutable skill catalog, completed sessions, MCP servers, provider credentials, LLM config, provider profiles, runtime tokens, and assets.
It does not own the store ports. The StateStore, CredentialStore,
TokenStore, AgentCatalog, AssetStore, and registry traits are defined
in the substrate (apomesh-substrate-types / apomesh-substrate); the
in-memory and SQLite adapters live in apomesh-substrate-state. This crate
is only the Postgres adapter behind those ports.
Public surface
Section titled “Public surface”| Entry point | Contract |
|---|---|
PostgresStateStore | The primary durable StateStore adapter — connect(url, pool_size), then the boot triad below. |
run_migrations / ensure_embedding_dimension | Idempotent schema apply, then provision the vector column to the embedding dimension. Called once at boot. |
HybridStateStore | new(postgres, redis_cache, ttl) — the write-through production stack. |
SecretSealer | seal / unseal for secret-bearing fields; refuses to start without a valid key. |
PostgresProviderCredentialStore | The sealed CredentialStore adapter — secrets sealed on upsert, unsealed on list. |
PostgresAgentCatalog | The agent-manifest catalog (seed_shipped_manifests seeds the shipped defaults). |
PostgresAgentRegistry / PostgresStrategyConfigRegistry / PostgresPublishedSkillRegistry | The versioned-immutable registry family — per-version immutability and adapter-internal AllowedTenants permits-gating. |
PostgresCompletedSessionStore | The keyset-paginated terminated-session index. |
PostgresAssetStore | Content-addressed, chunked-row blob storage that streams rather than buffers. |
DbPool | The PgPool re-export the daemon captures once and shares across every sibling adapter. |
The daemon selects a backend from the [statestore] config section (a
closed StateStoreBackend enum: in-memory, sqlite, postgres, or
hybrid):
[statestore]working_memory_ttl_seconds = 86400
[statestore.backend]kind = "hybrid"postgres_url = "postgres://apomesh@localhost/apomesh"redis_url = "redis://localhost:6379"postgres_pool_size = 20For the durable backends it connects, migrates, provisions the vector column, then captures the pool once and reuses it for every sibling store:
use std::{sync::Arc, time::Duration};use apomesh_state_store_postgres::{HybridStateStore, PostgresStateStore};use apomesh_state_store_redis::RedisCache;
let pg = PostgresStateStore::connect(&postgres_url, pool_size).await?;pg.run_migrations().await?;pg.ensure_embedding_dimension().await?;
// One pool, captured once and shared across the completed-session index,// agent catalog, registries, and credential store.let pool = pg.pool().clone();
// The production stack wraps that same durable adapter with the Redis// hot cache (write-through).let store = HybridStateStore::new( Arc::new(pg), Arc::new(RedisCache::connect(&redis_url).await?), Duration::from_secs(working_memory_ttl_seconds),);Related
Section titled “Related”- Concepts: Sessions and events (the
event log + checkpoints), Memory plane (the
episodic / semantic / procedural tiers), and
Credential plane (what
SecretSealerprotects at rest). - Operate: Local stack — the Compose stack that
runs the
pgvectorreference image. - Contribute: Testing — the testcontainers-gated integration suite that boots Postgres + Redis per run.