JSONFileStore: centralised JSONEncoder creation — a single internal JSONEncoder.icceryPretty(dateEncoding:) helper now owns the .prettyPrinted + .sortedKeys configuration; the duplicate encoder path is removed and PresetStore.export resolves to the same helper.
VerificationHistoryStore.clear(): now calls load() before writing. A corrupt/unreadable history file propagates the error, leaves the on-disk bytes and in-memory cache untouched, and no replacement file is written.
ISO-8601 formatting maintained for history timestamps; settings order stays validate → atomic write → notification; .replaceWithDefault kept for settings/wizard, .throwCorrupt for history.
Refs #81
## Gap fixes
- `JSONFileStore`: centralised `JSONEncoder` creation — a single internal `JSONEncoder.icceryPretty(dateEncoding:)` helper now owns the `.prettyPrinted` + `.sortedKeys` configuration; the duplicate encoder path is removed and `PresetStore.export` resolves to the same helper.
- `VerificationHistoryStore.clear()`: now calls `load()` before writing. A corrupt/unreadable history file propagates the error, leaves the on-disk bytes and in-memory cache untouched, and no replacement file is written.
- ISO-8601 formatting maintained for history timestamps; settings order stays validate → atomic write → notification; `.replaceWithDefault` kept for settings/wizard, `.throwCorrupt` for history.
## Target files
- `Packages/ICCeryCore/Sources/ICCeryCore/Files/JSONFileStore.swift`
- `Packages/ICCeryCore/Sources/ICCeryCore/Profile/VerificationHistoryStore.swift`
- `Packages/ICCeryCore/Sources/ICCeryCore/Settings/PresetStore.swift`
- `Tests/ICCeryCoreTests/JSONFileStoreTests.swift`
- `Tests/ICCeryCoreTests/SettingsTests.swift`
- `Tests/ICCeryCoreTests/WizardGatingTests.swift`
- `Tests/ICCeryCoreTests/VerificationHistoryStoreTests.swift`
## Tests added/updated
- Missing file returns default (`JSONFileStore`).
- `.replaceWithDefault` returns default on corrupt JSON and leaves file bytes unchanged.
- `.throwCorrupt` throws on corrupt JSON and leaves bytes unchanged (existing, retained).
- Pretty output contains newlines and asserts lexical ordering of top-level keys.
- Invalid settings save over an existing valid file throws, preserves original bytes, and emits no success notification.
- Corrupt wizard JSON returns `.default` without overwriting corrupt bytes.
- Wizard session mode + `calibrationOriginalBasename` round-trip (existing `roundTrip`, retained).
- Malformed history file: `load()`, `append()`, and `clear()` all throw with bytes unchanged.
- History ISO-8601 timestamp round-trips through a fresh store.
## Test gate
`xcodebuild test -scheme ICCery -only-testing:ICCeryCoreTests/{JSONFileStoreTests,SettingsStoreTests,WizardStateStoreTests,VerificationHistoryStoreTests,PresetStoreTests}` — **25/25 passed, 0 failures** (DerivedData-feat-81-json-store-contracts, universal arm64+x86_64).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Refs #81
Gap fixes
JSONFileStore: centralisedJSONEncodercreation — a single internalJSONEncoder.icceryPretty(dateEncoding:)helper now owns the.prettyPrinted+.sortedKeysconfiguration; the duplicate encoder path is removed andPresetStore.exportresolves to the same helper.VerificationHistoryStore.clear(): now callsload()before writing. A corrupt/unreadable history file propagates the error, leaves the on-disk bytes and in-memory cache untouched, and no replacement file is written..replaceWithDefaultkept for settings/wizard,.throwCorruptfor history.Target files
Packages/ICCeryCore/Sources/ICCeryCore/Files/JSONFileStore.swiftPackages/ICCeryCore/Sources/ICCeryCore/Profile/VerificationHistoryStore.swiftPackages/ICCeryCore/Sources/ICCeryCore/Settings/PresetStore.swiftTests/ICCeryCoreTests/JSONFileStoreTests.swiftTests/ICCeryCoreTests/SettingsTests.swiftTests/ICCeryCoreTests/WizardGatingTests.swiftTests/ICCeryCoreTests/VerificationHistoryStoreTests.swiftTests added/updated
JSONFileStore)..replaceWithDefaultreturns default on corrupt JSON and leaves file bytes unchanged..throwCorruptthrows on corrupt JSON and leaves bytes unchanged (existing, retained)..defaultwithout overwriting corrupt bytes.calibrationOriginalBasenameround-trip (existingroundTrip, retained).load(),append(), andclear()all throw with bytes unchanged.Test gate
xcodebuild test -scheme ICCery -only-testing:ICCeryCoreTests/{JSONFileStoreTests,SettingsStoreTests,WizardStateStoreTests,VerificationHistoryStoreTests,PresetStoreTests}— 25/25 passed, 0 failures (DerivedData-feat-81-json-store-contracts, universal arm64+x86_64).