v0.9.1 — seal pre-existing plaintext credentials on startup
Follow-up to v0.9.0. Apply this if you deployed v0.9.0.
v0.9.0 encrypted new writes and deliberately read older rows as-is, so upgrading didn't sign anyone out. The gap: a session row is only rewritten when the session is recreated, so real passwords stayed readable in cache.db until every pre-upgrade session expired — up to the 30-day session lifetime.
On the reference deployment that was 16 of 19 rows still in plaintext after the v0.9.0 deploy, with a working password legible in the first few bytes.
Existing rows are now sealed at startup in a single transaction, for both sessions and tracking-pixel senders. Sessions keep working across the migration, and the operator gets a log line saying how many rows were converted.
321 tests, 320 passing, 1 skipped.