Skip to content

[P0] Define and enforce shared phone/email normalization contract #564

Description

@tinkermonkey

Problem

Phone numbers flow through two systems with different normalization behaviors:

  • context-helpers emits phones as whatever Apple Contacts returns: (555) 123-4567, 555-123-4567, +1 555 123 4567
  • context-library (PeopleMetadata) normalizes to digits + leading '+' — a different operation

The entity linker compares these two representations when building cross-links. A contact stored as (555) 123-4567 in Apple Contacts and a message sender arriving as 5551234567 from chat.db produces no link — silently. There is no test that catches this.

Proposed fix

1. Define E164 as the canonical format (+{country_code}{number}, e.g. +15551234567)

2. Implement normalization once — a shared utility usable by both systems:

  • In context-helpers: normalize at collection time before emitting the payload
  • In context-library: normalize at ingest time in PeopleMetadata and when querying domain_metadata in the entity linker

3. Write a round-trip integration test that:

  • Creates a contact with phone (555) 123-4567
  • Creates a message with sender 5551234567
  • Asserts that entity_links contains a row linking them after linker runs

Files to change

  • src/context_helpers/collectors/contacts/collector.py — normalize phones before emitting
  • src/context_helpers/collectors/imessage/collector.py — normalize sender/recipients before emitting
  • src/context_library/storage/models.pyPeopleMetadata phone normalization
  • src/context_library/core/entity_linker.py — normalize before JSON path comparison
  • New shared utility: src/context_library/core/normalize.py (or equivalent in helpers)

Notes

  • International numbers: phonenumbers library handles E164 conversion robustly including country code inference
  • This is a correctness bug, not just a quality issue — some portion of the existing 6,638 entity_links are missing because of this mismatch

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions