Skip to content

Keep household members' names in the home (#20) - #71

Merged
kaboomAE merged 2 commits into
mainfrom
fix/household-names-20
Sep 27, 2026
Merged

kaboomAE merged 2 commits into
mainfrom
fix/household-names-20

Conversation

@kaboomAE

Copy link
Copy Markdown
Owner

Fixes #20. Intended for the next release. No version bump and no release in this PR; the manifest stays at 0.21.2 and the manager's companion change handles agents until they update.

What changes

The owner's decision (2026-09-27): send no person names, no person entities' friendly names and no log lines that carry them; where the manager needs to know something, send a count or a stable anonymous id.

Rather than cut each path out (which would break person tiles on family dashboards, Live Activities to phones and the Users tab, and miss the next path), the rule sits at the agent's only door to the manager, cloud_link.py:

  • Outbound: every snapshot and command reply goes through privacy.Pseudonymiser.scrub. Each household name, anywhere in any string or key, becomes a stable id: "Layla's iPhone" → hm_3f2a91c07d's iPhone, person.omar → person.hm_8c1e0b44a2, mobile_app_laylas_iphone → mobile_app_hm_…_iphone, and the same in log lines, rooms, automations and the users_list reply.
  • Inbound: every command goes through reveal, which turns the home's own ids back into names, as an entity id or as written depending on where they sit. Ids the home did not issue, and token/password fields, are left alone.
  • Keyed: the id is an HMAC under a secret created on the home (.storage/dartec_ha_manager.privacy) and never sent, so the manager cannot hash a list of first names back to a person.
  • Whose names: everyone My Home counts (owner and person accounts: display name and username) and every person.* entity except those linked to Dartec's, panel or system accounts. Matched word by word (3+ letters), as HA slugs them, with a possessive "s"; Arabic names as Arabic words (عمر is hidden, عمرو is not). Generic words (home, admin, bin, …) are never matched.
  • Fail closed: if the names cannot be read, the snapshot carries only core and commands are refused with privacy_unavailable. The home stays online.
  • The snapshot carries privacy: {"version": 1}; the inventory digest is folded with the names so the manager refetches when they change, and a reply is scrubbed once, before and after names merged, so its digest still matches.

The limit: a name the home does not know (a phone named after someone with no person or account) is not hidden.

Tests

  • tests/test_privacy.py: 20 claims over a synthetic Arabic- and English-speaking household (Maryam Al Hashimi, Omar, Layla, ليلى, عمر الهاشمي, a renamed child): no spelling of any name anywhere in a scrubbed snapshot or users_list reply; ids stable, keyed per home and consistent between prose and ids; dashboards, notify actions and every snapshot id reveal back to the home's real ones; staff/panel accounts, عمرو, "Next dawn" and hex ids untouched; generic words and short names handled.
  • tests/live/run_live_household.py now fails on any name anywhere in the snapshot and requires both people as person.hm_…. The check it replaces had a literal backspace character where a regex word boundary was meant, so it had never matched anything.
  • tests/live/run_live.py counts the owner's person as an id in the inventory check.

Run locally: unit suite 868 passed; hassfest clean; run_live.py 2026.9.3 passed; run_live_household.py passed on 2026.9.3 and 2026.8.3. No bench or real home was touched.

Companion manager PR: cleans older agents' snapshots on arrival, refuses ids to agents that cannot resolve them, and purges names already stored (kaboomAE/dartec-ha-manager-server).

🤖 Generated with Claude Code

Every snapshot and command reply now leaves through one filter in
cloud_link: each household name, wherever it appears, becomes a stable id
(hm_ + 10 hex, an HMAC under a secret kept in .storage and never sent).
Inbound commands have the ids turned back into names, so a dashboard tile
for person.hm_... is saved with the real person, and a Live Activity to
notify.mobile_app_hm_..._iphone reaches the right phone.

Whose names: everyone My Home counts, by display name and username, and
every person entity except those linked to Dartec's, a panel's or Home
Assistant's own accounts. Matched word by word, as HA slugs them, with a
possessive s; Arabic names as Arabic words. Generic words are never
matched. If the names cannot be read, the snapshot carries the core
section only and commands are refused, rather than leaking.

The snapshot is marked privacy.version 1, so the manager knows it may send
ids to this home. Not released: intended for the next release.

The live household test's name check had a literal backspace where a
regex word boundary was meant, so it had never matched anything. It now
fails on any name anywhere in the snapshot, and requires the people as ids.
The rig's customer is called "Live test", like the owner the rig onboards,
so the integration title is sent as "Dartec: hm_... / Integration rig".
Check the brand's spelling and the retitle, not the name.
@kaboomAE
kaboomAE merged commit 703cdc9 into main Sep 27, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Snapshot sends household members' names through person entities and HA log lines

1 participant