461ef88705
Anyone who ran hermes between Apr 15 (42aeb4ec) and Apr 22 (a7d78d3b) has schema_version=7 from the pre-renumber api_call_count migration. Whena7d78d3binserted reasoning_content as the new v7 and pushed api_call_count to v8, the 'if current_version < 7' gate was already false for those users, so reasoning_content was never created — sqlite3.OperationalError: no such column: reasoning_content on any /continue or /resume touching assistant replays. Replaces the version-gated ADD COLUMN chain with _reconcile_columns(): on every startup, parse SCHEMA_SQL via an in-memory SQLite and diff against PRAGMA table_info; ALTER TABLE ADD COLUMN for anything missing. Follows the Beets / sqlite-utils pattern — SCHEMA_SQL becomes the single source of truth for declared columns. Self-healing and idempotent. v10 trigram FTS backfill is retained in a version-gated block — that migration isn't a column add, it inserts existing message rows into the new FTS virtual table, so reconciliation can't express it. schema_version is also kept for future row-data migrations. Salvaged from #14097 (@kshitijk4poor) onto current main; v10 trigram preservation and the v9 codex_message_items column (stale-missed by the original branch) are covered automatically by reconciliation. Tests: - Regression: DB at old v7 with api_call_count but no reasoning_content gets the column on open - Idempotency: reopening the same DB is a no-op - Structural invariant: every SCHEMA_SQL column is in the live DB - Existing v2 migration test still passes - E2E verified against fresh / v1 / old-v7 / v9 DBs, plus v10 trigram backfill preserved