# SPEC-009 — Persistence One SQLite database per deployment (`/bot.db`), replacing the per-channel pickle files (`.dat`, `.memory`). Stdlib `sqlite3` via worker threads — no new dependency (D-010). Without `history-directory` in config the bot runs memory-only, as before. ### PER-01 — History survives restarts (coverage: test) History entries written through the store are returned, in order and per channel, by a fresh store instance on the same database file. ### PER-02 — Memory survives restarts (coverage: test) The per-channel memory string written through the store is returned by a fresh store instance on the same database file. ### PER-03 — Existing pickles migrate exactly once (coverage: test) On responder start, when the database holds no rows for the channel and legacy pickle files exist, their content is imported and the pickle files are renamed to `*.migrated` (kept for rollback). A second start does not re-import. Users keep their history through the cutover (review consensus: migration is a decision, not an accident). ### PER-04 — Database hygiene (coverage: test) The database runs in WAL journal mode, carries `PRAGMA user_version` = schema version (currently 1) for future migrations/rollback policy, and the file is chmod 0600 (it stores conversation data). ### PER-05 — Writes run off the event loop (coverage: test) History and memory persistence happen in a worker thread (`asyncio.to_thread`) — a slow disk cannot stall Discord event handling (D6).