@@ -405,7 +405,8 @@ pub const CREATE_SCHEMA: &str = "
405405 event_json TEXT NOT NULL CHECK (json_valid(event_json)),
406406 resolver TEXT,
407407 reason TEXT,
408- trace_id TEXT
408+ trace_id TEXT,
409+ turn_id TEXT
409410 );
410411 CREATE INDEX IF NOT EXISTS idx_security_ask_events_timestamp
411412 ON security_ask_events(timestamp_unix_ms);
@@ -1663,7 +1664,8 @@ pub fn migrate(conn: &Connection) {
16631664 event_json TEXT NOT NULL CHECK (json_valid(event_json)),
16641665 resolver TEXT,
16651666 reason TEXT,
1666- trace_id TEXT
1667+ trace_id TEXT,
1668+ turn_id TEXT
16671669 );
16681670 CREATE INDEX IF NOT EXISTS idx_security_ask_events_timestamp
16691671 ON security_ask_events(timestamp_unix_ms);
@@ -1773,6 +1775,49 @@ mod tests {
17731775 }
17741776 }
17751777
1778+ #[ test]
1779+ fn fresh_create_schema_has_no_migration_only_columns ( ) {
1780+ let conn = Connection :: open_in_memory ( ) . unwrap ( ) ;
1781+ create_tables ( & conn) . unwrap ( ) ;
1782+ let before = READY_SCHEMA_COLUMNS
1783+ . iter ( )
1784+ . map ( |( table, _) | ( * table, columns_for_schema ( & conn, "main" , table) ) )
1785+ . collect :: < BTreeMap < _ , _ > > ( ) ;
1786+
1787+ migrate ( & conn) ;
1788+
1789+ for ( table, columns_before_migrate) in before {
1790+ assert_eq ! (
1791+ columns_before_migrate,
1792+ columns_for_schema( & conn, "main" , table) ,
1793+ "fresh CREATE_SCHEMA must publish the final {table} shape; migrations are only for existing databases"
1794+ ) ;
1795+ }
1796+ }
1797+
1798+ #[ test]
1799+ fn fresh_schema_is_final_before_external_memory_rehydrate ( ) {
1800+ let conn = Connection :: open_in_memory ( ) . unwrap ( ) ;
1801+ create_tables ( & conn) . unwrap ( ) ;
1802+ create_memory_tables (
1803+ & conn,
1804+ & memory_uri_for_name ( "fresh_schema_is_final_before_external_memory_rehydrate" ) ,
1805+ )
1806+ . unwrap ( ) ;
1807+
1808+ // Reproduce the production ordering window: an external reader mirrors
1809+ // the freshly published schema before the writer runs legacy migrations.
1810+ migrate ( & conn) ;
1811+ sync_memory_tables_from_disk ( & conn, [ "security_ask_events" ] )
1812+ . expect ( "fresh canonical DDL must already match its post-migration shape" ) ;
1813+
1814+ assert_eq ! (
1815+ columns_for_schema( & conn, MEMORY_SCHEMA , "security_ask_events" ) ,
1816+ columns_for_schema( & conn, "main" , "security_ask_events" ) ,
1817+ "a fresh DB must not publish a pre-migration table shape to external readers"
1818+ ) ;
1819+ }
1820+
17761821 #[ test]
17771822 fn db_mem_disk_ready_rejects_missing_memory_schema ( ) {
17781823 let conn = Connection :: open_in_memory ( ) . unwrap ( ) ;
0 commit comments