Skip to the content.

ADR-002: Pure Go SQLite via modernc.org

Status: Accepted
Date: 2026-05-09

Context

Embercore’s engine needs a local, embedded database for persisting plans, checkpoints, runs, and artifacts. The storage layer (Hestia agent + internal/store/) requires:

The two main Go SQLite options are:

  1. mattn/go-sqlite3 — CGo binding to the C SQLite library. Fast, battle-tested, but requires a C compiler and CGo enabled.
  2. modernc.org/sqlite — Pure Go translation of the SQLite C source. No CGo, slightly slower, but fully portable.

Decision

We use modernc.org/sqlite v1.50.0 as our SQLite driver (registered as "sqlite" for database/sql).

Key configuration in internal/store/store.go:

db, err := sql.Open("sqlite", dbPath)
// Enable WAL mode for concurrent agent writes
db.Exec("PRAGMA journal_mode=WAL")
// Enforce referential integrity
db.Exec("PRAGMA foreign_keys=ON")

WAL mode

Write-Ahead Logging allows concurrent reads and writes without full database locks. This is critical because:

Migration system

Schema is managed via internal/store/migrations.go with a migrations table tracking applied versions. Tables include:

Table Purpose
plans Serialized plan specs and metadata
checkpoints Step-level approval/rejection records
runs Execution runs with state tracking
artifacts Generated output files and content
migrations Schema version tracking

Consequences

Benefits:

Trade-offs:

Related decisions: