Goal
Reduce Push's mutable sources of truth by storing channel cursors and backend session mappings in the existing canonical SQLite database.
Scope
- Add schema migrations for channel cursors and channel-qualified backend sessions.
- Preserve the current monotonic-cursor rule and backend-change session rotation behavior.
- Replace whole-file JSON rewrites with transactional SQLite operations.
- Migrate existing
state.json data idempotently on startup.
- Keep the legacy
last_row_id and unqualified iMessage-session compatibility rules during migration.
- Make migration crash-safe: never delete or invalidate the source before the database commit is verified.
- Retain a recoverable backup or explicit operator recovery path after successful migration.
- Keep the Slack durable inbox separate unless evidence shows its acknowledgement-queue semantics fit the same database safely.
- Update backup, recovery, security, architecture, and configuration documentation.
Dependencies
Non-goals
- Do not merge the append-only audit log into SQLite.
- Do not change conversation-history retention or add memory summarization.
- Do not remove compatibility in the same release that introduces migration.
Acceptance criteria
- Cursor advancement and backend-session changes are transactional.
- Cursor values never move backwards under concurrent or repeated writes.
- Existing
state.json installations migrate without losing cursors or resumable sessions.
- Repeating or crashing migration cannot duplicate, regress, or erase state.
- Backend changes still start fresh sessions and
/clear still rotates the exact channel-qualified session.
- Database or migration failure prevents unsafe polling progress and produces an actionable error.
- Tests cover legacy iMessage keys, multiple channels, multiple backends, empty session IDs, migration interruption, repeat migration, corrupt JSON, and concurrent cursor writes.
- Documentation clearly states which data lives in SQLite and how to recover the legacy file.
Verify
cargo fmt --all -- --check
cargo clippy --locked --all-targets -- -D warnings
cargo build --locked
cargo test --locked
Goal
Reduce Push's mutable sources of truth by storing channel cursors and backend session mappings in the existing canonical SQLite database.
Scope
state.jsondata idempotently on startup.last_row_idand unqualified iMessage-session compatibility rules during migration.Dependencies
state_path.Non-goals
Acceptance criteria
state.jsoninstallations migrate without losing cursors or resumable sessions./clearstill rotates the exact channel-qualified session.Verify
cargo fmt --all -- --checkcargo clippy --locked --all-targets -- -D warningscargo build --lockedcargo test --locked