Skip to content
Unverified: This page has not yet been anchored to automated code tests.

vox-db API Reference (generated)

Crate: vox-db · Version: 0.6.0 · Target: Library (lib.rs)

Codex / VoxDb facade: schema migrations, store ops, Turso/libSQL access for the Vox workspace.

vox-db — High-level database facade for Vox

Section titled “vox-db — High-level database facade for Vox”

Provides a unified API over Turso/libSQL for packages, code artifacts, agent memory, Codex reactivity, and related tables. Prefer this crate over talking to turso::Connection directly in application code.

NameWhat it is
[VoxDb]Stable Rust type for this facade; use it in signatures and tests.
[Codex]Type alias for VoxDb — same type, product-facing name in docs/UI.
ArcaInternal name for schema + SQL owned by this crate (crates/vox-db/src/schema/).
vox-packagePackage registry / artifacts — not the SQL schema SSOT.

Use [VoxDb::store] (async method) for content-addressed blob writes (ops_cas); it is not a getter.

  • Remote (Turso cloud) — always available
  • Local (file-based Turso) — local feature (default)
  • In-memory — DbConfig::Memory, tests only (local feature)
  • Embedded replica (local + cloud sync) — replication feature

User-global relational data uses [DbConfig::resolve_canonical] / [canonical_store::resolve_canonical_config]. Repo-backed interactive surfaces default to the workspace journey store (.vox/store.db) via [workspace_journey_store::connect_workspace_journey_optional]; set VOX_WORKSPACE_JOURNEY_STORE=canonical for legacy user-global / Turso. See [canonical_store] and [workspace_journey_store].

Built-in and app-supplied migrations run through [turso::Connection::execute_batch], which uses execute and fails on statements that return rows (e.g. bare SELECT, assignment PRAGMA unless handled with pragma_update). [VoxDb::connect] / [VoxDb::open] apply pragmas via pragma_update and skip empty migration bodies; see also [VoxDb::apply_migrations].

use vox_db::{VoxDb, DbConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = VoxDb::connect(DbConfig::Remote {
url: "turso://my-db.turso.io".to_string(),
token: "my-token".to_string(),
}).await?;
let hash = db.store("fn", b"fn hello(): return 42").await?;
println!("Stored: {hash}");
Ok(())
}

SHA3-512 Base32Hex hashing utilities.

FeatureDefault / Enables
defaultlocal
host-integrationdep:keyring, dep:vox-config, dep:vox-repository, dep:vox-secrets
legacy-importquarantine
local—
quarantine—
replication—
test-support—
DependencyKind
vox-astNormal
vox-configNormal
vox-db-typesNormal
vox-mesh-typesNormal
vox-orchestrator-typesNormal
vox-plugin-typesNormal
vox-repositoryNormal
vox-secretsNormal
vox-telemetryNormal
vox-codegenDevelopment
vox-compilerDevelopment
vox-test-harnessDevelopment
ModuleDescription
auto_migrateCompare live SQLite schema to @table / collection declarations; non-destructive migrations.
benchmark_telemetryBenchmark observations stored in research_metrics (bench:<repository_id> sessions).
build_hints—
capabilitiesTurso / search tuning helpers (VOX_EMBEDDING_SEARCH_CANDIDATE_MULT, etc.).
circuit_breakerCircuit breaker for write operations.
codex_chatUser chat, tool calls, usage limits, topics (manifest chat/search slices).
connect_policyCanonical connect policy helpers (strict vs optional degraded surfaces).
history_store—
legacyExplicit namespace for migration-era and cutover-only pathways.
redact—
research_metrics_contractLudus / extended gamify_* contracts and metrics keys (DDL in baseline schema/domains).
schema—
schema_extensionsIdempotent schema extensions (FTS).
storeLegacy import/export planning and verification for greenfield Codex releases.
telemetry_sink—
canonical_storeCanonical Codex storage policy (vox.db vs project store vs training sidecar).
codex_legacy—
codex_schemaManifest-derived readiness (baseline digest, required tables).
collection—
data_flow—
ddl—
error_enrichment—
exec_time_telemetry—
sql_util—
hash—
learning—
legacy_import_extras—
memoryParameters for [VoxDb::store_memory]. Alias of [crate::store::SaveMemoryParams] so application code can depend on vox-db only.
migrationDeclarative SQL migrations using the schema_version table (see crate::schema).
normalizeSQL normalization and content-addressable hashing.
writer_actorData directory and per-user id helpers (delegates to vox_config).
paths—
pool—
outcome_recorder—
populi_control_telemetryMens control-plane audit (populi_control_event in research_metrics).
populi_registry_telemetryOpt-in mens local-registry publish rows (VOX_MESH_CODEX_TELEMETRY).
preferencesRegistry-scoped user preferences (stored as JSON in the local config directory).
project_store—
research_doc_io—
research_pipeline—
schema_digestAST → [crate::SchemaDigest] for LLM context and codegen.
secretsOS keyring helpers for API tokens and similar secrets.
syntax_k_telemetry—
temporal_claims—
toestub_store—
training_runMens QLoRA training run persistence (CRUD for populi_training_run table).
types—
workflow_journalInterpreted workflow journal (workflow_journal_entry in research_metrics).
workspace_journey_storeWorkspace journey store resolution (.vox/store.db vs canonical) for repo-backed MCP/daemon flows.
mesh_exec_leases—
mesh_locks—
oratio_eval—
plugin_state_backend—
web_cacheContent-addressed local web cache with HTTP 304 support.
facade—
StructDescription
VoxDbHigh-level database facade for the Vox ecosystem (Codex). Owns a single [VoxDb] (one Turso connection). Higher-level helpers (memory, learner, schema sync) delegate to that store; advanced callers use [Self::store] for direct access. Concurrency: one connection per VoxDb handle; Sync/safe across concurrent callers because [GuardedConnection] serializes access to the shared turso::Connection (see its docs for why this is required even though VoxDb/Connection are Clone).
GuardedConnectionSerializes access to a shared turso::Connection to avoid turso::Error::Misuse("concurrent use forbidden"). ## Root cause this fixes turso::Connection::clone() does not create an independent connection: it clones an Arc to the same underlying turso_sdk_kit::rsapi::TursoConnection, which itself guards every step() (the primitive under query/execute/execute_batch/prepare) with an atomic ConcurrentGuard. Two async tasks that call into any clones of the same connection at literally the same instant (e.g. two Tauri GUI commands dispatched close together on a multi-threaded Tokio runtime, or a background poll racing a user action) can have their step() polls genuinely overlap on different OS threads, tripping that guard and returning Err(Misuse("concurrent use forbidden")). Since VoxDb is Clone and is shared as one Arc<VoxDb> across all GUI commands (see vox-gui/src/commands/gui_db_pool.rs), this happened routinely under ordinary concurrent chat usage, and the resulting error surfaced to users as a “Message not saved” toast — the write silently never reached the database. ## Fix Hold a tokio::sync::Mutex<()> around each real network/IO-bearing call (query/execute/execute_batch/pragma_update) before delegating to the wrapped turso::Connection. The lock lives behind an Arc so every clone of a GuardedConnection (and every clone of the owning VoxDb) shares the same lock — matching the fact that they already share the same underlying Turso connection. Implements [std::ops::Deref] to turso::Connection so call sites that need a raw &turso::Connection (e.g. [crate::auto_migrate::AutoMigrator::new], schema migrations run once at connect time) keep compiling unchanged via deref coercion. Method resolution prefers inherent methods on GuardedConnection over ones reached through Deref, so the ~400 existing call sites across this crate (and the many downstream crates that call VoxDb::connection(), e.g. vox-gamify, vox-populi, vox-sql, generated vox-codegen output) that do conn.query(..) / conn.execute(..) / conn.execute_batch(..) get the lock automatically without any call-site changes. ## Known residual gap turso::Connection::last_insert_rowid() is a synchronous, non-blocking read of connection-local state and does not go through ConcurrentGuard at all (confirmed by reading turso-0.6.1’s source), so it is intentionally left un-guarded here — wrapping it would require holding the lock across the execute + last_insert_rowid pair (a call-site change) rather than per-call. Callers that do this pairing (e.g. codex_chat.rs::chat_ensure_workspace_conversation) are not actually safe from this crate’s concurrency bug class: on the multi-threaded Tokio runtime this crate runs under, a different task on a different OS thread can execute its own guarded execute() (acquiring and releasing the lock) between this caller’s execute() and its last_insert_rowid() read, since nothing holds the lock across that gap — no explicit .await yield is required for that interleaving. This does not reproduce the Misuse("concurrent use forbidden") bug this type fixes (the two individual calls are each correctly guarded), but it can silently return the other task’s row id. It is noted here as a narrower, pre-existing (not introduced by this change) correctness edge case for future hardening (e.g. INSERT ... RETURNING).
GuardedRowsRows fully drained from [GuardedConnection::query] while its mutex guard was held, so nothing about iterating this value can race (or deadlock against) another guarded call on the same [GuardedConnection] — see the guard-lifetime note on query for why a lazy, still-locked cursor isn’t safe here.
EnumDescription
ReadConsistencyWhether to pull embedded-replica updates before application-level reads.
FunctionDescription
content_hashCompute a SHA3-512 hash of the given data, returning Base32Hex-encoded string.
in_memoryConnect to an ephemeral in-memory database for testing.
in_memoryConnect to an ephemeral in-memory database for testing.
queryGuarded [turso::Connection::query]. Returns [GuardedRows] rather than a bare turso::Rows. The bare cursor is lazy, so a guard dropped when this function returns (before the caller reads a single row) would let row-streaming race other tasks’ execute/query on the same connection. Holding the guard on the returned value instead (rather than only inside this function) is not an option either: tokio::sync::Mutex isn’t reentrant, and this crate’s callers routinely do let mut rows = conn.query(...).await?; then, later in the same scope, another guarded call on conn (e.g. claim_skill_identity’s SELECT-then-INSERT) — rows would still be lexically alive at that point (Rust drops locals at end of scope, not at last use), so a guard tied to it would self-deadlock. Instead, drain every row into an owned buffer while still holding the guard, then release it before returning — the lock covers the entire real connection access and nothing outlives this function.
executeGuarded [turso::Connection::execute].
execute_batchGuarded [turso::Connection::execute_batch].
pragma_updateGuarded [turso::Connection::pragma_update].
nextMirrors [turso::Rows::next]‘s signature (async fn returning a Result) purely so existing rows.next().await? call sites keep compiling unchanged; the buffer is already fully materialized, so this never actually awaits or errors.
TypeDescription
MemoryParams—
CodexPublic product name for the unified database facade (Codex over Arca/Turso). VoxDb remains the stable Rust type name; new documentation should prefer Codex.