refactor(database): scope untrusted restore to N/N-1

This commit is contained in:
SaladDay
2026-08-02 05:29:48 +00:00
parent ce6edf68a0
commit 3fa6b1f158
6 changed files with 536 additions and 1831 deletions
+16 -11
View File
@@ -26,20 +26,25 @@ impl CanonicalStage {
}
}
/// Selects the trusted local-upgrade path or the construction-only untrusted
/// Selects the trusted local-upgrade path or the construction-only N/N-1
/// restore path.
///
/// # Historical migration classification (blind-review authority)
///
/// Before this table is consulted, the untrusted database must exactly match
/// the `MigrationSourceSpec` for its declared `user_version`: table set,
/// column set, and every populated SQLite storage class. No current-schema
/// table is created during recognition. Each step is then checked mechanically
/// by `validate_migration_mapping_completeness`: every source column is either
/// an identity mapping with the same storage class or an explicit typed
/// disposition. The complete target source-spec is revalidated after every
/// step. Only after the chain reaches v17 may a separately constructed
/// canonical stage be created and populated.
/// LocalUpgrade retains the complete v1→v17 in-place chain below. The untrusted
/// SQL/binary entries are narrower: `UntrustedScratch` rejects v1..v15 before
/// this dispatcher, so only v16→v17 is reachable in `UntrustedRestore`.
///
/// A supported untrusted database must exactly match the v16 or v17
/// `MigrationSourceSpec`: table set, column set, and every populated SQLite
/// storage class. No current-schema table is created during recognition. The
/// v16→v17 step is checked mechanically by
/// `validate_migration_mapping_completeness`, and its complete v17 target spec
/// is revalidated before a separately constructed canonical stage is populated.
///
/// Rows v1→v2 through v15→v16 document and protect LocalUpgrade behavior and
/// preserve design groundwork for a future “historical backup import” project;
/// they are not accepted untrusted restore paths.
///
/// “Total shape map” means all source values are preserved under that declared
/// mapping and all added values are version-owned structural sentinels.
@@ -48,7 +53,7 @@ impl CanonicalStage {
/// `InvalidInput`. Local repair behavior is never reachable from
/// `UntrustedRestore`.
///
/// | Step | Class | `UntrustedRestore` construction and basis |
/// | Step | Class | Transform and preservation basis |
/// | --- | --- | --- |
/// | v1→v2 | Typed transform + total shape map | The singleton proxy and circuit rows require `id=1`; every field fans out unchanged to the three app rows owned by v2, six ownership settings remain byte-preserved while also producing explicit app flags, and prefixed skill keys map to typed `(directory, app_type)` rows. Missing/malformed rows, unsupported keys, booleans, or numeric domains abort. All settings and identity columns survive; new timestamps use a fixed structural sentinel and v2-owned empty tables are created without canonical seed data. |
/// | v2→v3 | Typed transform | Every skill row decodes as `(directory, app_type, installed, installed_at)` and deterministically produces id/name/directory/app enablement; empty directories, unsupported apps, invalid booleans, or collisions abort. No row is deferred to a filesystem rescan. |