CP02 · Implemented

Database migrations

Numbered application migrations run before the service becomes ready and record their name and UTC application time.

Atomic upgrades

Each current migration executes in a transaction. A failed statement rolls the migration back, leaves the schema version unchanged, closes the database, and prevents the server from listening.

Version behavior

A fresh database applies every migration in order. Restarting an up-to-date database is a no-op. The applied version is derived from validated migration history; on SQLite, PRAGMA user_version is only a compatibility mirror that a valid history may restore. A database with a schema version newer than the executable, or with history that is missing, non-contiguous, misnamed or in disagreement with the marker, is rejected rather than guessed at.

Current schema

Trestle-owned tables store migration history, system metadata, identities, events, jobs, audit facts and integration state. Collection validation prevents user schemas from colliding with the reserved namespace.

Upgrade discipline

CP22 provides checksum-verified binary update and rollback, while CP23 exercises every retained schema boundary and restore path. Back up first: executable rollback never promises an automatic database downgrade.

Offline cross-provider migration

An explicit offline trestle migrate command moves data between SQLite and the PostgreSQL provider using the portable logical format. It opens the source read-only, requires an empty destination, provider and schema preflight, a zero-write dry run, the explicit --confirm-migration flag, stable IDs, counts and a content checksum, and destination verification before cutover. Operator pg_dump and managed-service backup remain separate responsibilities.