Skip to content

fix: parent/child lock sync resolution#604

Open
ps851112 wants to merge 5 commits into
FutureTense:mainfrom
ps851112:fix/keymaster-parent-child-sync
Open

fix: parent/child lock sync resolution#604
ps851112 wants to merge 5 commits into
FutureTense:mainfrom
ps851112:fix/keymaster-parent-child-sync

Conversation

@ps851112
Copy link
Copy Markdown

Summary

Fixes child-lock sync not propagating from the parent lock due to parent relationship resolution/runtime linkage issues.

Root Cause

  • CONF_PARENT is stored as the config entry title (e.g. Front Door), but setup logic compared it only with CONF_LOCK_NAME (e.g. front_door), so parent_entry_id could remain unresolved.
  • During setup, normalized config data was updated, but runtime lock objects could still be created from stale entry data in the same pass.
  • Existing lock objects loaded from storage were not force-refreshed with updated relationship data during setup.
  • Relationship rebuild favored name matching and could miss valid links when parent_config_entry_id was already known.

Changes

  • Resolve parent by matching CONF_PARENT against entry.title with fallback to CONF_LOCK_NAME.
  • Use normalized setup data consistently during runtime lock setup.
  • Force coordinator lock refresh with add_lock(..., update=True) so existing locks are updated on startup/reload.
  • In relationship rebuild, prioritize explicit parent_config_entry_id before fallback name matching.

Validation

  • Reproduced with node8 parent and node9/14/15 children.
  • After restart and slot updates, child locks began syncing correctly from parent.

@tykeal tykeal changed the title Fix parent/child lock sync resolution Fix: parent/child lock sync resolution May 12, 2026
@firstof9 firstof9 changed the title Fix: parent/child lock sync resolution fix: parent/child lock sync resolution May 12, 2026
Copy link
Copy Markdown
Collaborator

@tykeal tykeal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! The problem you've identified is real — CONF_PARENT stores the entry title but the resolution only compared against CONF_LOCK_NAME, so parent/child relationships could silently fail to resolve. The fix approach is sound.

However, there are several items that need to be addressed before this can be merged:

CI Failures

Lint (ruff format): custom_components/keymaster/__init__.py needs reformatting. The project uses ruff format for code formatting.

Recommendation: Install pre-commit in your local dev environment. The repo has a .pre-commit-config.yaml that will catch formatting and linting issues before they reach CI:

pip install pre-commit
pre-commit install

This will automatically run ruff format, ruff check, and other hooks on every commit so you don't have to manually track these.

Pytest failures: 12 tests are failing with "Lingering timer" errors — likely related to the update=True change on add_lock() causing timer lifecycle issues during setup/reload. See the line comment for details.

Missing Test Coverage

This project enforces 100% patch coverage via Codecov. All new/changed lines must be covered by tests. Currently this PR has no test changes — you'll need to add tests covering:

  • Parent resolution matching against entry.title (the new path)
  • The setup_data flow ensuring resolved CONF_PARENT_ENTRY_ID is used consistently
  • The _rebuild_lock_relationships priority change (explicit ID before name fallback)
  • The update=True behavior on add_lock

See tests/test_init.py and tests/test_coordinator.py for existing patterns.

Copy link
Copy Markdown
Collaborator

@tykeal tykeal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line-level comments on specific areas of concern.

Comment thread custom_components/keymaster/__init__.py
Comment thread custom_components/keymaster/coordinator.py Outdated
Comment thread custom_components/keymaster/__init__.py Outdated
@tykeal tykeal added bug Something isn't working bugfix Fixes a bug and removed bug Something isn't working labels May 13, 2026
@tykeal
Copy link
Copy Markdown
Collaborator

tykeal commented May 14, 2026

@ps851112 Please see my comments above. I would strongly encourage you to rebase onto the latest main to pick up several linting fixes that have recently been merged.

@ps851112 ps851112 force-pushed the fix/keymaster-parent-child-sync branch from ed8abc7 to 7aa1be2 Compare May 14, 2026 21:42
@ps851112 ps851112 requested a review from tykeal May 14, 2026 22:25
@tykeal
Copy link
Copy Markdown
Collaborator

tykeal commented May 15, 2026

CI Status Update

CI has run and Prek (pre-commit) is failing with a mypy error:

tests/test_init.py:233: error: Item "None" of "Any | _Call | None" has no attribute "kwargs"  [union-attr]

This blocks Pytest and Coverage from running, so we can't verify the tests pass yet.

It looks like commit 60398a15 ("test: fix mypy await_args type guard") was intended to fix this, but the type narrowing isn't sufficient for mypy. You'll likely need a more explicit type guard — for example:

assert call_args is not None

or use isinstance / explicit None check before accessing .kwargs.

Recommendation: Install prek or pre-commit locally so you can catch these issues before pushing. The project's .pre-commit-config.yaml has all the hooks configured.


Additionally, all 3 review threads from the previous review are still unresolved with no responses. I've posted follow-up comments on each. Even if you believe the code changes address the concerns, please respond to the threads so we can have a productive discussion and move toward resolution. Thanks!

slurk85 and others added 5 commits May 26, 2026 04:43
- Make add_lock(update=...) conditional on existing lock presence, preserving fresh-setup vs reload semantics.
- In relationship rebuild, fall back to name matching when parent_config_entry_id is set but stale (entry deleted/unloaded).
- Remove redundant setup_data alias; use config_entry.data directly.
- Fix mypy union-attr narrowing in tests/test_init.py.
- Add test_rebuild_falls_back_to_name_when_parent_entry_stale.

Co-authored-by: paul.sayre <paul.sayre@outlook.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andrew Grimberg <tykeal@bardicgrove.org>
@tykeal tykeal force-pushed the fix/keymaster-parent-child-sync branch from 60398a1 to 222e445 Compare May 26, 2026 11:50
@tykeal
Copy link
Copy Markdown
Collaborator

tykeal commented May 26, 2026

Pushed updates to address all outstanding review feedback (maintainer push to contributor branch). Summary:

  • Made add_lock(update=...) conditional on existing lock presence
  • Added fallback to name matching when parent_config_entry_id is stale
  • Removed redundant setup_data alias
  • Fixed mypy narrowing in tests/test_init.py
  • Added test for stale-parent edge case
  • Rebased onto current main

Local validation is passing (prek run --all-files and python -m pytest tests/ -x). GitHub currently reports no checks for the updated head SHA. Thank you @ps851112 for the original investigation and fix — the parent/child resolution bug you found was a real issue.

@tykeal tykeal requested a review from Copilot May 26, 2026 11:53
@tykeal
Copy link
Copy Markdown
Collaborator

tykeal commented May 26, 2026

Reopening to re-trigger CI on the new commit.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@firstof9
Copy link
Copy Markdown
Collaborator

Seems github needs some coffee today.

@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.38%. Comparing base (cdb4922) to head (222e445).
⚠️ Report is 139 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #604      +/-   ##
==========================================
+ Coverage   84.14%   88.38%   +4.24%     
==========================================
  Files          10       39      +29     
  Lines         801     3892    +3091     
  Branches        0       30      +30     
==========================================
+ Hits          674     3440    +2766     
- Misses        127      452     +325     
Flag Coverage Δ
python 88.11% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

bugfix Fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants