Local-first unifier and cleanup for Apple and Google contacts. Safety over surprise.
Most people have Apple and Google contacts in parallel — half duplicated, half stale, half junk. Existing tools either ignore it or silently auto-merge and corrupt the record.
Normalization, dedupe, merges, backups — all happen on your machine.
No writeback without explicit action, a preview, and a backup.
Every value carries source, lineage, and trust — visible in the UI.
Explicit, inspectable, deterministic. No hidden identity graphs.
One concrete row from Apple or Google is a SourceRecord. One real human, assembled from many rows, is a Person.
Grouping never mutates the underlying sources. That separation is why merges, unmerges, and restores work cleanly.
An email-only Google Other Contact is fine. An Apple personal contact with no phone and no email isn't. You write the rule.
Each record generates block keys. Only records that share at least one block proceed to scoring. Incremental, explainable, and it scales.
Before a merge applies, you see the records involved, the pair score, the field conflicts, the winning values we'd pick, and the alternates we'd keep.
Simulate the full operation. See creates, updates, deletes, conflicts, and blocks — without touching the source.
On by default. Snapshot the exact records and values about to change, with manifest, ruleset, and app version.
Single contact, one operation's batch, or the full snapshot. Rehydrate review state too.
Apply is blocked if dry-run fails, backup fails, or required permissions are missing.
Every operation writes an event: actor, type, affected contacts, result, backup ID. Filter it, jump from event to contact, restore from the snapshot attached.
The architecture — local-first, provenance, explainable scoring, backup-by-default — generalizes to any messy personal data.