Upgrade and Migration Strategy
This guide defines how blipcoard upgrades should handle SQLite schema
migrations, daemon/API compatibility, and rich payload blob storage.
Upgrade Model
Upgrade blipcoard as one local runtime:
blipdblipblipcoarddesktop app
Install matching binaries from the same release. The CLI and desktop app are
daemon clients; they should not be upgraded independently from blipd for
normal use.
Recommended upgrade sequence:
- Stop the daemon with
blip service stopor stop the foregroundblipdprocess. - Back up config, SQLite, SQLite sidecar files, and
blobs/. - Replace all installed binaries from the same release.
- Start the daemon with
blip service startor foregroundblipd. - Run
blip service statusandblip health. - Smoke-test list/search/routing and at least one rich payload preview/export if the store contains rich payloads.
Migration Timing
SQLite migrations run when a process opens the store through BlipStore::open().
The normal upgrade path is daemon startup:
blipdloads or creates config.blipdopens the configured SQLite database.BlipStore::open()applies pending numbered migrations inside an immediate SQLite transaction.- The store initializes the default
inboxand active workspace if needed. - The daemon starts serving IPC and clipboard ingestion.
blip service install only writes service manager files. It does not migrate
the database by itself. The first post-upgrade daemon start performs migration.
Some bootstrap or admin CLI paths currently open the store directly while the
daemon API is incomplete. Those paths also run pending migrations because they
use BlipStore::open(). Release tests should therefore verify both daemon
startup and any direct-store admin path that remains supported.
SQLite Schema Rules
Schema changes are numbered migrations in crates/blip-core/src/sql/ and are
registered in crates/blip-core/src/store.rs.
Rules for new migrations:
- Add a new SQL file with the next sequential number.
- Register it in
MIGRATIONS. - Increase
SCHEMA_VERSION. - Keep migration SQL idempotent where practical, but rely on
PRAGMA user_versionfor normal one-time execution. - Add a migration test that starts from the previous relevant schema version and verifies the resulting data shape.
- Treat migration failures as startup failures. Do not continue daemon startup against a partially upgraded or unknown store.
The migration runner updates PRAGMA user_version after each migration
succeeds. Store initialization also records the current schema version in
app_state.
Backup Requirements
Back up SQLite and blobs together before upgrades that can affect schema, payload metadata, retention, or blob references.
Include:
config.tomlblipcoard.db- SQLite sidecar files such as
blipcoard.db-walandblipcoard.db-shmwhen present blobs/
Simple file-copy backup:
blip service stop
# copy config.toml, blipcoard.db*, and blobs/
blip service start
The blob directory is part of the store. SQLite contains payload metadata and
blob references; blobs/ contains the bytes. Restoring only SQLite can leave
payload rows with missing blobs. Restoring only blobs/ can leave orphan files
that clients cannot see.
Before destructive migrations, release notes must explicitly recommend a full backup. Destructive means any migration that drops columns/tables, rewrites blob references, deletes payload metadata, changes retention behavior, or cannot be reversed by simply reinstalling the older binary.
Rollback Expectations
Rollback is not guaranteed after a migration has run.
Supported rollback expectation:
- If the new daemon has not started and no migration has run, reinstall the previous matching binaries.
- If a migration has run, restore the full pre-upgrade backup before running old binaries.
Not rollback-safe:
- Running older binaries against a database with a newer
PRAGMA user_version. - Restoring SQLite without matching
blobs/. - Restoring
blobs/without matching SQLite metadata. - Downgrading after retention cleanup or blob garbage collection has deleted data.
- Downgrading after a migration rewrites payload metadata or blob references.
The product should prefer clear startup or client errors over best-effort downgrade behavior.
Daemon/API Compatibility
The daemon API version lives in blip-api as DAEMON_API_VERSION. Clients send
their expected API version with each daemon request. The daemon rejects
unsupported request versions with a typed daemon error. The CLI also checks the
response API version and reports:
daemon API version mismatch: response used <actual>, expected <expected>
Action for users:
- Install matching
blip,blipd, and desktop binaries from the same release. - Restart the daemon.
- Re-run
blip healthorblip service status.
Desktop builds should bundle matching blipd and blip sidecars. CLI-only
packages should install matching blip and blipd binaries together. Mixed
versions are not a supported steady state.
Rich Payload Storage
Rich payload upgrades must account for both metadata and bytes:
- Text-compatible payload metadata lives in SQLite.
- Binary payload bytes and generated previews live under
blobs/. - Payload summaries can report missing blob states; missing blobs are not expected to panic clients.
- Garbage collection removes only unreferenced blobs.
Migration tests for rich payload changes should include:
- SQLite-only restore with missing blobs.
- Blob-only restore with no SQLite references.
- Complete restore with SQLite plus
blobs/. - Preview blob references as well as raw payload blob references.
- Retention cleanup after migration.
Release Migration Checklist
For every release that changes schema, payload metadata, blob layout, daemon API, or service startup:
- Build previous supported release binaries.
- Create a fixture store with plain text blips, rich text payloads, image payloads, file-list metadata, agent-readable and human-only workspaces, and at least one redacted/secret-like blip.
- Back up
config.toml,blipcoard.db*, andblobs/. - Upgrade to the candidate release.
- Start
blipdand confirm migrations complete. - Verify
PRAGMA user_versionandapp_state.schema_version. - Run
blip health,blip service status,blip workspaces,blip inbox,blip search,blip payload inspect,blip payload preview, andblip payload export. - Verify CLI and desktop clients can talk to the upgraded daemon without API mismatch errors.
- Verify an intentionally mismatched older client reports an actionable API mismatch error.
- Verify missing-blob and orphan-blob scenarios remain inspectable and garbage-collectable.
- Restore the pre-upgrade backup and confirm the previous supported release still works against the restored store.
- Record the migration source version, target version, platform, and result in release notes.
For releases without schema or daemon API changes, still smoke-test blip health, blip service status, and a basic list/search flow after replacing the
binaries.