An upgraded install otherwise keeps 150 recorded rows (plus the one
2.4.x-only name) for migration files that no longer exist on disk. The SKIP
path now deletes exactly the replaced set plus that superseded name, by
explicit list only, before recording itself; module rows and any other
foreign history survive. Found by the upgrade rehearsals.
A single consolidation migration replaces the 150 removed historical files.
It decides — from reads alone — whether to build the boundary schema fresh,
skip on a fully-migrated 2.x database, or refuse a partial or inconsistent
history untouched. Fresh installs run it first and the live v3 chain after;
pre-2.x installs are directed through the latest 2.x release. The same
verdict backs a self-updater preflight so an unsafe upgrade is refused
before any file is copied. Schema verified identical to the boundary
fixtures on SQLite, MariaDB and PostgreSQL.