Finish the recurring-sync simplification so the engine is predictable:
SourceInstanceKey = normalized series/event ID + anchored instance dateShadowNoteManager.SourceInstanceKey is the canonical recurring-instance identity.InstanceDate and still parse legacy note formats.TLAPlus/ShadowSyncInstances.tla is the authoritative model.TLAPlus/ShadowSyncInstances_Small.cfg is the current TLC config.TLAPlus/ShadowSyncEdgeCases.tla is historical and documents the older series-level abstraction.InstanceDate to new shadow notes with legacy parsing fallback.v3 migration from legacy rawEventID@timestamp keys to instance-aware keys.shadowEventID as a recovery path for touched legacy records.SyncInvariants to use instance-aware store keys instead of the obsolete sourceEventID@timestamp assumption.shadowEventID.suppressedShadows, removed-destination cleanup).shadowEventID, not just load-time migration.v3.Block It OutTests target build: use the shared Debug scheme; a raw target build without a scheme still defaults to Release and breaks @testable import Block_It_OutShadowSyncInstances.tla: passingxcodebuild test -project "Block It Out.xcodeproj" -scheme "Block It Out - Sim (StoreKit)" -destination 'platform=iOS Simulator,OS=18.6,name=iPhone 16' -only-testing:'Block It OutTests/ShadowSnapshotStoreTests' -only-testing:'Block It OutTests/SyncPropertyTests'-only-testing must use the bundle name Block It OutTests (with spaces), not BlockItOutTestsSyncService’s occurrence-move logic so recurring shadows no longer suppress per-instance updates, normalize identity handling, and eliminate overlapping branches that rely on normalized series IDs.ShadowSnapshotStore.ShadowSyncInstances.tla with /opt/homebrew/bin/java to ensure the formal model still reflects our intention.