- a non-ok integrity_check verdict raises DatabaseError carrying the
NOTADB marker so it classifies as corruption unconditionally; ANY
DatabaseError escaping the probe propagates (no more swallowing
structural problems as non-corruption)
- file URI built via Path.resolve().as_uri() so #/?/% in paths cannot
mis-target the probe
- migration-stage test now spies on NestQuestDatabase.open and asserts
the read-write open was NEVER reached: the whole-file preflight
rejecting corruption before the WAL transition is the mechanism
under test, and the byte-identical + no-sidecar assertions prove it
- store guard permits SELECT + PRAGMA integrity_check on the ro-conn
- preflight now runs PRAGMA integrity_check (whole-file validation,
not just sqlite_master) over a mode=ro connection, dispatched via
hass.async_add_executor_job so the event loop never blocks
- migration-stage corruption test fixture is now a ROLLBACK-JOURNAL
file created with plain sqlite3 (default journal mode), so the WAL
transition the guardrail protects against actually happens in the
test instead of being masked by an already-WAL fixture
- _preflight_existing_file probes an EXISTING file with a mode=ro URI
connection before the read-write open, so a corrupt file is detected
BEFORE WAL mode persists or sidecars appear; the preflight is inside
the same ConfigEntryNotReady classification as open()/migrations
- corruption classification now prefers sqlite_errorcode (SQLITE_CORRUPT/
SQLITE_NOTADB primary-byte match, locale-independent, Python 3.11+)
with message fallback including 'database disk image is malformed'
- the early-return path (existing runtime record) routes through
_async_open_database and reopens when db is None OR not connected
- new migration-stage corruption test: valid header + damaged page
4096+, asserts main file byte-identical AND no -wal/-shm sidecars
left behind; vacuous test replaced with pytest.raises form