Context
Child contract of #445 (R-15 Secure Storage). PR #564 merged the S5-A architecture baseline (docs/native/R15-SECURE-STORAGE-CONTRACT.md) with S5_A_ADMITTED = YES but explicitly does not admit this domain — it is an S5-A fail-closed blocker. S5_TERMINAL requires S5-A + S5-B1 + S5-B2 + S5-B3 all merged and post-merge green.
Scope
S5-B1 owns one coherent migration-evidence domain:
- Canonical source-evidence representation for plaintext packaged-IDB values (
compressData() in idbCore.ts produces either a raw value or an LZ-compressed UTF-16 string, chosen by a 10 KB threshold — neither is a stable byte sequence today).
canonical_destination_payload_bytes for every MIGRATE_TO_R15 destination record class — no per-class codec exists anywhere today, making source_value_digest unreproducible across independent Tauri/Qt adapters.
source_value_digest canonical payload equivalence, strictly separate from source_evidence_digest (mutation evidence) — this invariant must remain a hard rule.
- Source representation/version registries needed to reproduce these digests.
- Surviving legacy atomic-write temporary reconciliation (
<target>.tmp-<UUID> files that can contain real plaintext content and are not automatically junk).
- Identity-upgrade/recovery procedure for unbound AAD-less legacy sources (
SOURCE_IDENTITY_UNBOUND, representation-1 legacy plaintext with no independent identity proof) and unidentified legacy quarantine data (projectFsStore.ts:684-743 persists only a directory name, no path-independent recovery-id).
Before writing: inspect every current persisted representation in real source; build a finite representation inventory; do not generalize beyond representations that actually exist.
Non-goals
No implementation. No production authority switch. No touching services/storage/*, services/fs/*, src-tauri/**, or crates/**.
Size target
~300–900 meaningful lines. No PR-size exception authorized — if the domain genuinely cannot fit, split further rather than requesting one.
Parent
#445
Context
Child contract of #445 (R-15 Secure Storage). PR #564 merged the S5-A architecture baseline (
docs/native/R15-SECURE-STORAGE-CONTRACT.md) withS5_A_ADMITTED = YESbut explicitly does not admit this domain — it is an S5-A fail-closed blocker.S5_TERMINALrequires S5-A + S5-B1 + S5-B2 + S5-B3 all merged and post-merge green.Scope
S5-B1 owns one coherent migration-evidence domain:
compressData()inidbCore.tsproduces either a raw value or an LZ-compressed UTF-16 string, chosen by a 10 KB threshold — neither is a stable byte sequence today).canonical_destination_payload_bytesfor everyMIGRATE_TO_R15destination record class — no per-class codec exists anywhere today, makingsource_value_digestunreproducible across independent Tauri/Qt adapters.source_value_digestcanonical payload equivalence, strictly separate fromsource_evidence_digest(mutation evidence) — this invariant must remain a hard rule.<target>.tmp-<UUID>files that can contain real plaintext content and are not automatically junk).SOURCE_IDENTITY_UNBOUND, representation-1 legacy plaintext with no independent identity proof) and unidentified legacy quarantine data (projectFsStore.ts:684-743persists only a directory name, no path-independent recovery-id).Before writing: inspect every current persisted representation in real source; build a finite representation inventory; do not generalize beyond representations that actually exist.
Non-goals
No implementation. No production authority switch. No touching
services/storage/*,services/fs/*,src-tauri/**, orcrates/**.Size target
~300–900 meaningful lines. No PR-size exception authorized — if the domain genuinely cannot fit, split further rather than requesting one.
Parent
#445