caa7f21f4c
Port from qwibitai/nanoclaw#3766: hold the SQLite write lock across a schema migration so two openers cannot interleave. The SessionDB writer connection is autocommit, so _rebuild_table's RENAME / CREATE / copy / DROP each committed on its own. A sibling process (gateway + CLI opening the same state.db) whose SCHEMA_SQL bootstrap ran between RENAME and CREATE recreated the table empty; the rebuilder's CREATE then failed with "table already exists", the heal was logged as "skipped", the rows stayed in *_legacy_pk and the live table was empty — silent loss of routing / usage accounting rows. BEGIN IMMEDIATE around the whole sequence (unless the caller already owns a transaction) makes the sibling wait under its existing lock patience, and a mid-rebuild failure rolls the RENAME back.