Found during an adversarial re-review of the schema-v2 stack (#287/#288). The atomicity of the v1→v2 verification_reports migration was fixed in that stack (single IMMEDIATE transaction + DROP TABLE IF EXISTS ..._old + in-lock re-check). This issue tracks the remaining, lower-severity forward-compat gap.
Gap: the sqlite report registry (ordvec-manifest/src/sqlite.rs) has no persisted schema version (PRAGMA user_version or a version table). Migration decisions are made by sniffing column sets:
verification_reports fails closed on an unrecognized shape (verification_reports_needs_migration → refuse), which is correct.
active_manifest (drop_registry_table_on_schema_mismatch) is fail-open destructive: any column-set mismatch drops and recreates the table empty. This is intentional for the current v1→v2 drop (the pointer is rebuildable cache state, documented in-code), but a future v3 active_manifest opened by a v2 build would be destroyed, and alternating binary versions would ping-pong-destroy the pointer on every open.
Suggested fix: stamp PRAGMA user_version on create/migrate and gate migrations on it, so unknown (future) schemas fail closed consistently across both tables rather than the active_manifest path silently rebuilding.
Severity: medium-low. Pre-1.0, rebuildable state, no data-integrity or security impact. Not blocking the current release.
Found during an adversarial re-review of the schema-v2 stack (#287/#288). The atomicity of the v1→v2
verification_reportsmigration was fixed in that stack (single IMMEDIATE transaction +DROP TABLE IF EXISTS ..._old+ in-lock re-check). This issue tracks the remaining, lower-severity forward-compat gap.Gap: the sqlite report registry (
ordvec-manifest/src/sqlite.rs) has no persisted schema version (PRAGMA user_versionor a version table). Migration decisions are made by sniffing column sets:verification_reportsfails closed on an unrecognized shape (verification_reports_needs_migration→ refuse), which is correct.active_manifest(drop_registry_table_on_schema_mismatch) is fail-open destructive: any column-set mismatch drops and recreates the table empty. This is intentional for the current v1→v2 drop (the pointer is rebuildable cache state, documented in-code), but a future v3active_manifestopened by a v2 build would be destroyed, and alternating binary versions would ping-pong-destroy the pointer on every open.Suggested fix: stamp
PRAGMA user_versionon create/migrate and gate migrations on it, so unknown (future) schemas fail closed consistently across both tables rather than theactive_manifestpath silently rebuilding.Severity: medium-low. Pre-1.0, rebuildable state, no data-integrity or security impact. Not blocking the current release.