Done-condition: the household roster's slug matches the entity_id slug Home Assistant actually assigns for a child's display name — HA's real slugify (homeassistant.util.slugify) instead of a hand-rolled Latin-only mirror — so a non-Latin display name yields the same slug the per-child entity_ids use and auto-discovery resolves those children, with a test covering at least one non-Latin name.
Why
sensor._slugify NFKD-normalized and ASCII-encoded-ignoring, so non-Latin characters were DROPPED (京子 → unknown), while HA's real slugifier transliterates through unidecode (京子 → jing_zi, Дана → dana, Zoë → zoe). Per-child entity_ids are derived from the child name by HA's real slugify, so the roster's slugs diverged and the party-board/strategy auto-discovery silently failed for non-Latin households.
What changed
custom_components/nestquest/sensor.py: _slugify now delegates to the real homeassistant.util.slugify at runtime and composes the object-id cap (64 - len("sensor.")) the roster needs — verified against HA 2024.6 sources: HA's slugify does NOT truncate (it delegates to python-slugify's frozen legacy pipeline + an unknown sentinel); the ENTITY REGISTRY truncates the full <domain>.<slug> id at MAX_LENGTH_STATE_ENTITY_ID (64), so the roster keeps its own cap and does not double-cap.
tests/conftest.py: the mocked homeassistant package now provides a faithful homeassistant.util.slugify stub — python-slugify's legacy pipeline step for step (quotes→dashes, NFKD, transliterate via the real unidecode dev dependency, entity decoding, lowercase, dash folding, separator mapping, unknown sentinel), verified byte-for-byte against real python-slugify (HA's wrapper, separator _) across 52 Latin/Cyrillic/CJK/Greek/fullwidth/entity-reference name shapes.
tests/test_sensors.py: existing tests kept; added test_slugify_transliterates_non_latin_names_like_home_assistant (Дана → dana, 京子 → jing_zi, Zoë → zoe) and test_non_latin_child_names_resolve_auto_discovery, which asserts the roster slug equals the slug HA's entity-id derivation (slugify("NestQuest <name> quests due today")) actually embeds for the per-child sensor.
pyproject.toml/uv.lock: unidecode added to the DEV group only (test-harness stand-in; the integration's runtime slugify comes from HA itself).
Checks
TZ=UTC uv run pytest -q → 1711 passed (baseline 1709 + 2 new tests)
TZ=UTC uv run pytest -q tests/test_sensors.py → 26 passed
Task: 67775be9-6b0d-4839-bbe1-bb8eaefaa5f4 — Auto-discovery slug must match Home Assistant's real slugify.
Feature-review finding (P2) remediation — Maestro task `67775be9-6b0d-4839-bbe1-bb8eaefaa5f4` (Feature 20, zero-config panel dashboard).
**Done-condition:** the household roster's `slug` matches the entity_id slug Home Assistant actually assigns for a child's display name — HA's real slugify (`homeassistant.util.slugify`) instead of a hand-rolled Latin-only mirror — so a non-Latin display name yields the same slug the per-child entity_ids use and auto-discovery resolves those children, with a test covering at least one non-Latin name.
## Why
`sensor._slugify` NFKD-normalized and ASCII-encoded-ignoring, so non-Latin characters were DROPPED (京子 → `unknown`), while HA's real slugifier transliterates through unidecode (京子 → `jing_zi`, Дана → `dana`, Zoë → `zoe`). Per-child entity_ids are derived from the child name by HA's real slugify, so the roster's slugs diverged and the party-board/strategy auto-discovery silently failed for non-Latin households.
## What changed
- `custom_components/nestquest/sensor.py`: `_slugify` now delegates to the real `homeassistant.util.slugify` at runtime and composes the object-id cap (`64 - len("sensor.")`) the roster needs — verified against HA 2024.6 sources: HA's slugify does NOT truncate (it delegates to python-slugify's frozen legacy pipeline + an `unknown` sentinel); the ENTITY REGISTRY truncates the full `<domain>.<slug>` id at `MAX_LENGTH_STATE_ENTITY_ID` (64), so the roster keeps its own cap and does not double-cap.
- `tests/conftest.py`: the mocked `homeassistant` package now provides a faithful `homeassistant.util.slugify` stub — python-slugify's legacy pipeline step for step (quotes→dashes, NFKD, transliterate via the real `unidecode` dev dependency, entity decoding, lowercase, dash folding, separator mapping, `unknown` sentinel), verified byte-for-byte against real python-slugify (HA's wrapper, separator `_`) across 52 Latin/Cyrillic/CJK/Greek/fullwidth/entity-reference name shapes.
- `tests/test_sensors.py`: existing tests kept; added `test_slugify_transliterates_non_latin_names_like_home_assistant` (Дана → `dana`, 京子 → `jing_zi`, Zoë → `zoe`) and `test_non_latin_child_names_resolve_auto_discovery`, which asserts the roster slug equals the slug HA's entity-id derivation (`slugify("NestQuest <name> quests due today")`) actually embeds for the per-child sensor.
- `pyproject.toml`/`uv.lock`: `unidecode` added to the DEV group only (test-harness stand-in; the integration's runtime slugify comes from HA itself).
## Checks
- `TZ=UTC uv run pytest -q` → **1711 passed** (baseline 1709 + 2 new tests)
- `TZ=UTC uv run pytest -q tests/test_sensors.py` → **26 passed**
Task: 67775be9-6b0d-4839-bbe1-bb8eaefaa5f4 — Auto-discovery slug must match Home Assistant's real slugify.
The per-child entity ids are derived from the child name by Home
Assistant's real slugifier, which transliterates every script through
unidecode; the hand-rolled Latin-only mirror in sensor.py dropped
non-Latin characters instead (slugging 京子 to "unknown"), so the
roster's slugs diverged from the actual entity ids and the
party-board/strategy auto-discovery silently failed for non-Latin
households.
Use homeassistant.util.slugify at runtime, composing the registry's
64-character entity-id cap the roster needs (verified against HA
2024.6: slugify itself does not truncate; the entity registry
truncates the full <domain>.<slug> id). Give the mock harness a
faithful homeassistant.util.slugify stub — python-slugify's frozen
legacy pipeline with unidecode, verified byte-for-byte against real
python-slugify across Latin, Cyrillic, CJK and Greek name shapes —
and cover the non-Latin resolution contract in tests (roster slug ==
the object id HA's entity-id derivation produces).
Feature-review finding (P2): auto-discovery slug must match Home
Assistant's real slugify.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Feature-review finding (P2) remediation — Maestro task
67775be9-6b0d-4839-bbe1-bb8eaefaa5f4(Feature 20, zero-config panel dashboard).Done-condition: the household roster's
slugmatches the entity_id slug Home Assistant actually assigns for a child's display name — HA's real slugify (homeassistant.util.slugify) instead of a hand-rolled Latin-only mirror — so a non-Latin display name yields the same slug the per-child entity_ids use and auto-discovery resolves those children, with a test covering at least one non-Latin name.Why
sensor._slugifyNFKD-normalized and ASCII-encoded-ignoring, so non-Latin characters were DROPPED (京子 →unknown), while HA's real slugifier transliterates through unidecode (京子 →jing_zi, Дана →dana, Zoë →zoe). Per-child entity_ids are derived from the child name by HA's real slugify, so the roster's slugs diverged and the party-board/strategy auto-discovery silently failed for non-Latin households.What changed
custom_components/nestquest/sensor.py:_slugifynow delegates to the realhomeassistant.util.slugifyat runtime and composes the object-id cap (64 - len("sensor.")) the roster needs — verified against HA 2024.6 sources: HA's slugify does NOT truncate (it delegates to python-slugify's frozen legacy pipeline + anunknownsentinel); the ENTITY REGISTRY truncates the full<domain>.<slug>id atMAX_LENGTH_STATE_ENTITY_ID(64), so the roster keeps its own cap and does not double-cap.tests/conftest.py: the mockedhomeassistantpackage now provides a faithfulhomeassistant.util.slugifystub — python-slugify's legacy pipeline step for step (quotes→dashes, NFKD, transliterate via the realunidecodedev dependency, entity decoding, lowercase, dash folding, separator mapping,unknownsentinel), verified byte-for-byte against real python-slugify (HA's wrapper, separator_) across 52 Latin/Cyrillic/CJK/Greek/fullwidth/entity-reference name shapes.tests/test_sensors.py: existing tests kept; addedtest_slugify_transliterates_non_latin_names_like_home_assistant(Дана →dana, 京子 →jing_zi, Zoë →zoe) andtest_non_latin_child_names_resolve_auto_discovery, which asserts the roster slug equals the slug HA's entity-id derivation (slugify("NestQuest <name> quests due today")) actually embeds for the per-child sensor.pyproject.toml/uv.lock:unidecodeadded to the DEV group only (test-harness stand-in; the integration's runtime slugify comes from HA itself).Checks
TZ=UTC uv run pytest -q→ 1711 passed (baseline 1709 + 2 new tests)TZ=UTC uv run pytest -q tests/test_sensors.py→ 26 passedTask: 67775be9-6b0d-4839-bbe1-bb8eaefaa5f4 — Auto-discovery slug must match Home Assistant's real slugify.
Independent Claude Sonnet 5 review completed for this exact commit.