LocalData/Proposal.md
Matt Bruce 126b9cf318 Docs: update docs for Proposal, README
Summary:
- Docs: update docs for Proposal, README

Stats:
- 2 files changed, 18 insertions(+), 6 deletions(-)
2026-01-18 13:43:08 -06:00

71 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LocalData Package Proposal
## Goal
Create a single, typed, discoverable namespace for persisted app data with consistent security guarantees and clear ownership. This makes it obvious what is stored, where it is stored, how it is secured, how it is serialized, who owns it, and which platforms it belongs to or should sync to.
## Package Placement
- localPackages/LocalData/
- Sources/LocalData/
- Tests/LocalDataTests/
## Dependencies
- Foundation
- Security (Keychain)
- CryptoKit (encryption)
- WatchConnectivity (sync helpers)
## Architecture
### Core Components
- **StorageKey** protocol - Defines storage configuration for each data type
- **StorageRouter** actor - Main entry point coordinating all storage operations
- **StorageProviding** protocol - Abstraction for storage operations
- **StorageKeyCatalog** protocol - Catalog of keys for auditing/validation
### Isolated Helper Classes (Actors)
Each helper is a dedicated actor providing thread-safe access to a specific storage domain:
- **KeychainHelper** - All keychain operations (set, get, delete, exists, deleteAll)
- **EncryptionHelper** - AES-256-GCM or ChaCha20-Poly1305 with PBKDF2/HKDF
- **FileStorageHelper** - File system operations (read, write, delete, list, size), including App Group containers
- **UserDefaultsHelper** - UserDefaults operations with suite and App Group support
- **SyncHelper** - WatchConnectivity sync operations
### Models
- **StorageDomain** - userDefaults, appGroupUserDefaults, keychain, fileSystem, encryptedFileSystem, appGroupFileSystem
- **SecurityPolicy** - none, keychain (with accessibility/accessControl), encrypted (AES-256 or ChaCha20-Poly1305)
- **Serializer** - JSON, property list, raw Data, or custom encode/decode with named serializer metadata
- **KeyMaterialSource** - Identifier for external key material providers
- **PlatformAvailability** - all, phoneOnly, watchOnly, phoneWithWatchSync
- **SyncPolicy** - never, manual, automaticSmall
- **KeychainAccessibility** - All 7 iOS options (whenUnlocked, afterFirstUnlock, etc.)
- **KeychainAccessControl** - All 6 options (userPresence, biometryAny, devicePasscode, etc.)
- **FileDirectory** - documents, caches, custom URL
- **StorageError** - Comprehensive error types
- **StorageKeyDescriptor** - Audit snapshot of a keys storage metadata
- **AnyStorageKey** - Type-erased storage key for catalogs
- **AnyCodable** - Type-erased Codable for mixed-type payloads
## Usage Pattern
Apps extend StorageKeys with their own key types and use StorageRouter.shared. This follows the Notification.Name pattern for discoverable keys.
## Audit & Validation
Apps can register a `StorageKeyCatalog` to generate audit reports and enforce key registration. Registration validates:
- Duplicate key names
- Missing descriptions
- Unregistered keys at runtime (debug assertions)
## Sync Behavior
StorageRouter can call WCSession.updateApplicationContext for manual or automaticSmall sync policies when availability allows it. Session activation and receiving data are owned by the app.
## Platforms
- iOS 17+
- watchOS 10+
## Future Ideas (Not Implemented)
- Migration helpers for legacy storage
- Key rotation strategies for encrypted data
- Watch-optimized data representations
Any future changes should keep LocalData documentation in sync with code changes.