Skip to main content
The vault is Grind’s database layer. It lives in packages/core/src/vault/. The underlying storage is SQLite via libsql, with optional Turso cloud sync.

Storage Location

By default, the vault database is at ~/.grind/vault.db. This can be overridden via GRIND_VAULT_PATH.

Encryption

The vault is encrypted at rest using libsql’s AES encryption extension. The key is stored at ~/.grind/.key and set via GRIND_ENCRYPTION_KEY.
The encryption key is required to open the vault. If you lose it, your data is unrecoverable. Back it up to a password manager.

Turso Sync

For optional cloud backup and multi-device sync, configure a Turso database:
With these set, libsql operates in embedded replica mode. The local SQLite file is the primary, syncing bidirectionally with Turso.

Migrations

Migrations are SQL files in packages/core/drizzle/. The migration runner in vault/client.ts applies them on startup. The standard Drizzle migration runner uses Postgres-compatible syntax for migration tracking. Grind replaces it with a custom SQLite-compatible runner that uses a simple drizzle_migrations table. To generate a new migration after schema changes:

Schema

13 tables defined with Drizzle ORM in vault/schema.ts: users, quests, quest_logs, proofs, skills, rituals, signals, forge_rules, forge_runs, trust_log, companion_settings, conversations, messages. All timestamps are Unix epoch integers; primary keys are UUIDs.

Repository Pattern

All database access goes through repository objects. Each domain entity has a corresponding repository:
Repositories expose typed CRUD operations. They do not expose raw SQL; all queries go through Drizzle’s query builder.