mirror of
https://github.com/home-assistant/core.git
synced 2026-08-28 02:24:46 -05:00
Fixes the correctness findings from plan-review-overhead §A (+E4), each with a regression test: - A2+A5: core now owns entry state on both router paths. The ConfigEntryRouter contract changes to raise ConfigEntryError on failure; core maps it to SETUP_ERROR (setup) or leaves the entry state untouched (refused unload — previously a refused unload was wrongly marked NOT_LOADED while the remote entry stayed loaded). Every SLF001 state poke moves out of router.py into config_entries.py, which owns ConfigEntry. - A4: the router setup/unload branches now honor entry.setup_lock, so a direct async_setup during a reload can no longer run two entry_setup RPCs concurrently for one entry. - A3: SandboxBridge.async_teardown sweeps _mirrored_services off hass.services — a respawned sandbox's re-registration was skipped by the has_service guard, leaving every call on a dead channel forever. - A6: the sandbox translation overlay merges inside _async_get_component_strings before the title fallback, so a provider dict without "title" gets the catalog/integration.name fill-in; _TranslationCache._async_load returns to dev-identical. - A7: proxy init + upsert share one _apply_description with symmetric clearing — a dropped device_class/device_info no longer sticks. - A8: the frame-size cap is enforced on write too (both channel mirrors); an oversize payload fails its own call with FrameTooLargeError (oversize replies come back as error frames) instead of making the peer abort the whole channel. - A1: state-attribute pushes run through json_safe — a datetime attribute raised ValueError inside the fire-and-forget push task and left main's proxy permanently stale. Main-side service_data/query args get the same coercion (_wire_safe) before dict_to_struct. - E4: FlowRunner.async_stop now stops the private hass (executor + timer leak per in-process sandbox), and InProcessSandbox.stop runs the graceful sandbox/shutdown first, like production. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QCotUYum6AoisyrxshoiJJ