Skip to content

source records the last writer instead of where the address came from #75

Description

@rtunazzz

What happens

addresses.source reads as the origin of an address — its values are generated, icloud, inbox, and manual — but it is overwritten on every write rather than kept from the first one.

upsert_address assigns it unconditionally in its conflict clause (src/hidemyemail_generator/inbox.py:165):

ON CONFLICT(email) DO UPDATE SET
    ...
    source = excluded.source,

and three callers pass a different value for the same address over its lifetime:

Caller Value passed
_generatesrc/hidemyemail_generator/main.py:1219 generated
_sync_hme_to_dbsrc/hidemyemail_generator/main.py:1383 icloud
insert_messagesrc/hidemyemail_generator/inbox.py:390 inbox

Whichever ran most recently wins, so the column ends up describing the last thing that touched the row.

Reproduction

  1. hidemyemail generate --label test --count 1 → the new row has source = generated
  2. hidemyemail inbox sync-hme → the same row now has source = icloud
  3. Receive mail at that address and sync the inbox → it becomes source = inbox

Observed on a real account: after one sync-hme, all 748 addresses read icloud regardless of how each was actually created. A freshly generated address held generated for under a minute before the next sync overwrote it.

Impact

source is surfaced in hidemyemail inbox addresses table output, in its --result-json payload, and as a column in the addresses.csv export. Consumers of any of those get "last writer" rather than provenance, and the original value is not recoverable once overwritten.

For contrast, state in the same conflict clause is explicitly protected against being clobbered:

state = CASE
    WHEN addresses.state = 'unused' THEN excluded.state
    ELSE addresses.state
END,

so the two adjacent fields currently follow different merge rules.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions