Last Updated: 2026-05-23 Status: Initial programmatic model and full-cache rebuild implemented; UI wiring and targeted invalidation pending
Core Data is not the forensic archive. It is the bounded, UI-friendly store for values already derived from the SQLite archive.
Use Core Data for: - observation rows shown in timelines; - type summaries and expensive counts; - daily/monthly aggregate display rows; - diff summary rows; - export history/status rows; - archive health/status rows; - local app state and settings that are not forensic evidence.
Do not use Core Data for: - the only copy of HealthKit samples; - raw record payload history; - relationship evidence; - point-in-time reconstruction truth; - large record tables.
SQLite wins on disagreement.
Core Data may contain two categories of entities.
Rebuildable cache entities
Can be deleted and rebuilt from SQLite:
- CachedObservationRow;
- CachedTypeSummary;
- CachedDailyAggregate;
- CachedDiffSummary;
- CachedExportManifest;
- CachedArchiveHealth.
Local app state/settings Not forensic, not necessarily rebuildable: - selected type preferences; - UI display preferences; - last opened screen/state; - feature flags for legacy-device UI simplification.
Cache rebuild must not delete settings unless the user explicitly resets the app.
Purpose: timeline/list display.
Required fields:
- observationID;
- observedAt;
- status;
- triggerReason;
- timeZoneIdentifier;
- trackedTypeCount;
- visibleRecordCount;
- appearedCount;
- disappearedCount;
- representationChangedCount;
- archiveSchemaVersion;
- cacheSchemaVersion;
- sourceAggregateHash;
- computedAt.
Purpose: per-observation/per-type summary cards and reports.
Required fields:
- observationID;
- sampleTypeIdentifier;
- displayName;
- visibleRecordCount;
- appearedCount;
- disappearedCount;
- representationChangedCount;
- earliestStartDate;
- latestEndDate;
- valueSum;
- valueMax;
- aggregateHash;
- computedAt.
Purpose: charts and report tables.
Required fields:
- observationID;
- sampleTypeIdentifier;
- bucketStart;
- bucketEnd;
- timeZoneIdentifier;
- visibleRecordCount;
- valueSum;
- valueMax;
- sourceRevisionDisplayHash;
- aggregateHash;
- computedAt.
Purpose: observation comparison list/detail.
Required fields:
- fromObservationID;
- toObservationID;
- sampleTypeIdentifier;
- appearedCount;
- disappearedCount;
- representationChangedCount;
- consolidationLikely;
- uncertaintyReason;
- sourceAggregateHash;
- computedAt.
Purpose: export history/status display.
Required fields:
- exportID;
- exportKind;
- createdAt;
- fromObservationID;
- toObservationID;
- filterSummary;
- recordCount;
- manifestHash;
- fileURLBookmarkData;
- status;
- computedAt.
Purpose: archive status screen.
Required fields:
- archiveSchemaVersion;
- cacheSchemaVersion;
- lastIntegrityCheckAt;
- lastIntegrityStatus;
- lastErrorKind;
- lastErrorMessageHash;
- cacheBuildID;
- computedAt.
Invalidate/rebuild cache rows when: - archive schema version changes; - archive reset/reinitialization occurs; - selected type registry changes; - a new observation commits in SQLite; - aggregate hashes change; - cache schema version changes.
Rebuild order: 1. archive health/status; 2. observation rows; 3. type summaries; 4. daily/monthly aggregates; 5. diff summaries; 6. export status rows.
Partial rebuild is allowed when SQLite can identify affected observations/types. Full rebuild must remain available for repair and tests.
Implementation note, 2026-05-24: CoreDataArchiveCacheStore defines the cache model programmatically and can rebuild all cache entities from the SQLite archive. The first implementation rebuilds observation rows, type summaries, daily aggregates, adjacent-observation diff summaries, export manifest rows, and archive health rows. It is intentionally rebuildable: deleting the Core Data cache must not touch the SQLite archive.
Legacy or low-memory UI should still use the same Core Data cache. It may reduce: - chart density; - default date range; - preview row count; - simultaneous loaded detail panes.
It must preserve: - capture; - cached summaries; - report generation; - paged SQLite detail/export access.