From 6fcbb1b4e36a2e0c8f1dba9ec62b768e143b7100 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:11:39 -0500 Subject: [PATCH 01/45] Prepare README for HACS release --- README.md | 70 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 4e72097..43d8aa9 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,59 @@ # Sharp Kitchen Integration -A Home Assistant custom integration for Sharp Kitchen-connected appliances -(built and tested against a Sharp SMD2489ES microwave), talking directly -to Sharp's real cloud API. +Unofficial Home Assistant custom integration for Sharp Kitchen-connected appliances, built and tested with the Sharp SMD2489ES Microwave Drawer. -## Features +## Supported and verified behavior -- Real Cognito Hosted-UI OAuth2 login (with automatic token refresh) and - mutual TLS client-certificate authentication to Sharp's device API. -- Manual cook control: cook time (minutes/seconds), power level, - Start/Pause/Stop, Open Drawer. -- Smart Cook presets (built-in automatic cook programs), with a - preset selector, weight/quantity slider, and Start button. -- Device settings exposed as switches: Easy Wave, Sound, Reminder Sound. -- Sensors: status, door state, time remaining, power, temperature. +- Sharp Kitchen account sign-in through the same hosted login flow used by the official app. +- Automatic token refresh and cloud communication. +- Manual microwave controls: cook time, power level, start, pause, stop, and open drawer. +- Smart Cook support for the full 29-program SMD2489ES catalog. + - Numeric programs expose the applicable quantity/weight control. + - Option programs expose the applicable option selector. + - Sensor programs use the appliance's sensor-cook behavior. +- Device settings: Easy Wave, Sound, and Reminder Sound. +- Sensors for status, drawer/door state, remaining time, power, and temperature. + +The currently verified appliance is the Sharp SMD2489ES. Other Sharp Kitchen-connected appliances may use related cloud APIs, but their controls are not claimed as supported until they are specifically verified. ## Installation -1. Copy the `custom_components/sharp_kitchen` folder into your Home - Assistant `config/custom_components/` directory. +### HACS + +HACS packaging is being prepared. Until the first release is published, install this repository as a custom HACS integration only for testing. + +1. In HACS, add this repository as a custom repository with category **Integration**. +2. Install **Sharp Kitchen**. +3. Restart Home Assistant. +4. Go to **Settings > Devices & services > Add integration** and search for **Sharp Kitchen**. +5. Sign in with the same account used by the Sharp Kitchen app. + +### Manual + +1. Copy `custom_components/sharp_kitchen` into your Home Assistant `config/custom_components/` directory. 2. Restart Home Assistant. -3. Go to Settings > Devices & Services > Add Integration, search for - "Sharp Kitchen", and log in with your Sharp Kitchen account - credentials. +3. Go to **Settings > Devices & services > Add integration** and search for **Sharp Kitchen**. + +## Smart Cook + +The integration contains the 29-program SMD2489ES Smart Cook catalog. The Home Assistant entities adapt to the selected program: + +- **Weight/quantity** for numeric programs such as Beverage Reheat. +- **Option** for programs such as Soften Ice Cream. +- No secondary value for sensor programs such as Fish / Seafood. + +A low-level `sharp_kitchen.start_smart_cook` action remains available for backward compatibility, but normal use should go through the validated entities. + +## Notes + +- This integration communicates with Sharp's cloud service and therefore requires internet access. +- The project is reverse engineered from observed behavior of the official Sharp Kitchen app because no public Sharp Kitchen API is known. +- Appliance writes should be treated like physical appliance controls: verify the selected program/settings before starting a cook cycle. -## Status +## Development and validation -Core cook/control functionality is fully working. Only 3 of Sharp's -~30 built-in Smart Cook presets are currently mapped (Defrost Ground -Meat, Beverage Reheat, Hot Water) — more will be added as they're -captured from the real app. +Release preparation includes HACS validation and Home Assistant hassfest validation. The repository intentionally contains only the Home Assistant integration; Appliance Control Center/dashboard presentation logic is maintained separately. ## Disclaimer -This is an unofficial, community-reverse-engineered integration. It is -not affiliated with or endorsed by Sharp Corporation. +This project is unofficial and is not affiliated with or endorsed by Sharp Corporation. From 6715b3423e97b2bafa6e9932969bc2f363bdf0d4 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:11:42 -0500 Subject: [PATCH 02/45] Set proposed release version to 0.9.0 --- custom_components/sharp_kitchen/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/sharp_kitchen/manifest.json b/custom_components/sharp_kitchen/manifest.json index b53b2b4..4e34d5e 100644 --- a/custom_components/sharp_kitchen/manifest.json +++ b/custom_components/sharp_kitchen/manifest.json @@ -8,5 +8,5 @@ "integration_type": "hub", "iot_class": "cloud_polling", "requirements": ["cryptography"], - "version": "0.8.2" + "version": "0.9.0" } From 18dd93df565f9c9cc40540d212b781b220bd37b6 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:11:44 -0500 Subject: [PATCH 03/45] Complete English service translations --- .../sharp_kitchen/translations/en.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/custom_components/sharp_kitchen/translations/en.json b/custom_components/sharp_kitchen/translations/en.json index 03871ec..77dccce 100644 --- a/custom_components/sharp_kitchen/translations/en.json +++ b/custom_components/sharp_kitchen/translations/en.json @@ -48,6 +48,24 @@ "description": "Whether to preheat before cooking." } } + }, + "start_smart_cook": { + "name": "Start Smart Cook", + "description": "Run a low-level Sharp Smart Cook command. Normal use should use the Smart Cook entities.", + "fields": { + "device_id": { + "name": "Device ID", + "description": "The numeric device ID from Sharp's backend." + }, + "auto_number": { + "name": "Preset Code", + "description": "Raw Smart Cook preset identifier from the Sharp app catalog." + }, + "auto_weight": { + "name": "App Parameter Value", + "description": "Exact app parameter value for the selected Smart Cook preset." + } + } } } } From c1c0ed6c6626f3364813c16f46f93cd94fd3c442 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:11:46 -0500 Subject: [PATCH 04/45] Add HACS repository metadata --- hacs.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 hacs.json diff --git a/hacs.json b/hacs.json new file mode 100644 index 0000000..b3eca99 --- /dev/null +++ b/hacs.json @@ -0,0 +1,3 @@ +{ + "name": "Sharp Kitchen" +} From 93bd2b5b8b8e15feff9f5a85adae0fe83ed4fb14 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:11:48 -0500 Subject: [PATCH 05/45] Add HACS validation workflow --- .github/workflows/validate-hacs.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/validate-hacs.yml diff --git a/.github/workflows/validate-hacs.yml b/.github/workflows/validate-hacs.yml new file mode 100644 index 0000000..ef21b47 --- /dev/null +++ b/.github/workflows/validate-hacs.yml @@ -0,0 +1,19 @@ +name: Validate with HACS + +on: + push: + pull_request: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +permissions: {} + +jobs: + validate-hacs: + runs-on: ubuntu-latest + steps: + - name: HACS validation + uses: hacs/action@main + with: + category: integration From 37a31ecf8c715ae40d1d54f373ec9fef66d2c75d Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:11:50 -0500 Subject: [PATCH 06/45] Add hassfest validation workflow --- .github/workflows/hassfest.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/hassfest.yml diff --git a/.github/workflows/hassfest.yml b/.github/workflows/hassfest.yml new file mode 100644 index 0000000..cce8e34 --- /dev/null +++ b/.github/workflows/hassfest.yml @@ -0,0 +1,18 @@ +name: Validate with hassfest + +on: + push: + pull_request: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: home-assistant/actions/hassfest@master From b8e72035a31c762b03175b2613d8e571d1062b16 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:13:56 -0500 Subject: [PATCH 07/45] Register Sharp Kitchen actions once at integration setup --- custom_components/sharp_kitchen/__init__.py | 64 ++++++++++++++------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/custom_components/sharp_kitchen/__init__.py b/custom_components/sharp_kitchen/__init__.py index 46d9a1d..e4a8eb0 100644 --- a/custom_components/sharp_kitchen/__init__.py +++ b/custom_components/sharp_kitchen/__init__.py @@ -16,6 +16,7 @@ import voluptuous as vol from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, ServiceCall +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -50,25 +51,30 @@ ) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - session = async_get_clientsession(hass) - client = SharpKitchenClient( - session, - refresh_token=entry.data[CONF_REFRESH_TOKEN], - phone_id=entry.data[CONF_PHONE_ID], - username=entry.data[CONF_COGNITO_USERNAME], - ) - - coordinator = SharpKitchenCoordinator(hass, client) - await coordinator.async_refresh_devices() - await coordinator.async_config_entry_first_refresh() +def _coordinator_for_device( + hass: HomeAssistant, device_id: int +) -> SharpKitchenCoordinator: + """Return the loaded coordinator that owns a Sharp backend device ID.""" + matches = [ + coordinator + for coordinator in hass.data.get(DOMAIN, {}).values() + if device_id in coordinator.devices + ] + if not matches: + raise HomeAssistantError(f"Sharp Kitchen device ID {device_id} is not loaded") + if len(matches) > 1: + raise HomeAssistantError( + f"Sharp Kitchen device ID {device_id} is ambiguous across configured accounts" + ) + return matches[0] - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator - await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) +async def async_setup(hass: HomeAssistant, config: dict) -> bool: + """Register integration-wide actions once, independent of config entries.""" async def _handle_start_cook(call: ServiceCall) -> None: - await client.async_start_cook( + coordinator = _coordinator_for_device(hass, call.data["device_id"]) + await coordinator.client.async_start_cook( call.data["device_id"], mode=call.data["mode"], cook_time=call.data["cook_time"], @@ -78,25 +84,43 @@ async def _handle_start_cook(call: ServiceCall) -> None: ) await coordinator.async_request_refresh() - hass.services.async_register( - DOMAIN, SERVICE_START_COOK, _handle_start_cook, schema=START_COOK_SCHEMA - ) - async def _handle_start_smart_cook(call: ServiceCall) -> None: - await client.async_start_smart_cook( + coordinator = _coordinator_for_device(hass, call.data["device_id"]) + await coordinator.client.async_start_smart_cook( call.data["device_id"], call.data["auto_number"], call.data["auto_weight"], ) await coordinator.async_request_refresh() + hass.services.async_register( + DOMAIN, SERVICE_START_COOK, _handle_start_cook, schema=START_COOK_SCHEMA + ) hass.services.async_register( DOMAIN, SERVICE_START_SMART_COOK, _handle_start_smart_cook, schema=START_SMART_COOK_SCHEMA, ) + return True + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + session = async_get_clientsession(hass) + client = SharpKitchenClient( + session, + refresh_token=entry.data[CONF_REFRESH_TOKEN], + phone_id=entry.data[CONF_PHONE_ID], + username=entry.data[CONF_COGNITO_USERNAME], + ) + + coordinator = SharpKitchenCoordinator(hass, client) + await coordinator.async_refresh_devices() + await coordinator.async_config_entry_first_refresh() + hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator + + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True From ecaa4feb5ec7dc52e4ceef44476f5045bfce8fa3 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:13:58 -0500 Subject: [PATCH 08/45] Use custom integration translations only --- custom_components/sharp_kitchen/strings.json | 53 -------------------- 1 file changed, 53 deletions(-) delete mode 100644 custom_components/sharp_kitchen/strings.json diff --git a/custom_components/sharp_kitchen/strings.json b/custom_components/sharp_kitchen/strings.json deleted file mode 100644 index 03871ec..0000000 --- a/custom_components/sharp_kitchen/strings.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "config": { - "step": { - "user": { - "title": "Connect to Sharp Kitchen", - "description": "Enter the email and password for your Sharp Kitchen (na-kitchen) account -- the same one used in the Sharp Kitchen phone app.", - "data": { - "email": "Email", - "password": "Password" - } - } - }, - "error": { - "invalid_auth": "Login failed. Check your email and password. If they're correct, Sharp's login may require a login method this integration doesn't support yet (see the README).", - "cannot_connect": "Logged in, but could not reach the Sharp Kitchen device service to verify your account. Please try again." - }, - "abort": { - "already_configured": "This Sharp Kitchen account is already set up." - } - }, - "services": { - "start_cook": { - "name": "Start Cook", - "description": "Start a manual cook on a Sharp Kitchen device.", - "fields": { - "device_id": { - "name": "Device ID", - "description": "The numeric device ID from Sharp's backend." - }, - "mode": { - "name": "Mode", - "description": "Cook mode name (\"microwave\" is confirmed working)." - }, - "cook_time": { - "name": "Cook Time", - "description": "Cook duration as H:MM:SS." - }, - "power": { - "name": "Power Level", - "description": "Microwave power level." - }, - "temperature": { - "name": "Temperature", - "description": "Target temperature for modes that use one." - }, - "with_preheat": { - "name": "With Preheat", - "description": "Whether to preheat before cooking." - } - } - } - } -} From 12cbb2115ab98ced19668308e71a4058502e1365 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:32:22 -0500 Subject: [PATCH 09/45] Add offline release-readiness tests --- tests/test_release_readiness.py | 79 +++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tests/test_release_readiness.py diff --git a/tests/test_release_readiness.py b/tests/test_release_readiness.py new file mode 100644 index 0000000..7275f00 --- /dev/null +++ b/tests/test_release_readiness.py @@ -0,0 +1,79 @@ +"""Release-readiness tests that do not contact Sharp or a live appliance.""" + +from __future__ import annotations + +import json +from pathlib import Path +import runpy + +ROOT = Path(__file__).resolve().parents[1] +INTEGRATION = ROOT / "custom_components" / "sharp_kitchen" + + +def _constants() -> dict: + return runpy.run_path(INTEGRATION / "const.py") + + +def test_manifest_identity_and_proposed_version() -> None: + manifest = json.loads((INTEGRATION / "manifest.json").read_text(encoding="utf-8")) + assert manifest["domain"] == "sharp_kitchen" + assert manifest["name"] == "Sharp Kitchen" + assert manifest["version"] == "0.9.0" + assert manifest["config_flow"] is True + assert manifest["iot_class"] == "cloud_polling" + + +def test_hacs_metadata_is_valid_json() -> None: + hacs = json.loads((ROOT / "hacs.json").read_text(encoding="utf-8")) + assert hacs["name"] == "Sharp Kitchen" + + +def test_smart_cook_catalog_has_all_29_programs() -> None: + presets = _constants()["SMART_COOK_PRESETS"] + assert len(presets) == 29 + assert len({preset["name"] for preset in presets.values()}) == 29 + assert {preset["parameter_type"] for preset in presets.values()} == { + "numeric", + "option", + "sensor", + } + + +def test_smart_cook_catalog_parameter_rules() -> None: + presets = _constants()["SMART_COOK_PRESETS"] + + for preset_id, preset in presets.items(): + parameter_type = preset["parameter_type"] + assert preset_id + assert preset["name"] + assert preset["category"] + + if parameter_type == "numeric": + minimum = float(preset["min_value"]) + maximum = float(preset["max_value"]) + default = float(preset["default_value"]) + step = float(preset["step"]) + assert minimum <= default <= maximum + assert step > 0 + assert preset.get("unit") + elif parameter_type == "option": + options = preset["options"] + assert options + assert str(preset["default_value"]) in options + assert all(str(key) and str(label) for key, label in options.items()) + else: + assert parameter_type == "sensor" + assert str(preset["default_value"]) == "0" + + +def test_english_translation_covers_both_actions() -> None: + translation = json.loads( + (INTEGRATION / "translations" / "en.json").read_text(encoding="utf-8") + ) + services = translation["services"] + assert "start_cook" in services + assert "start_smart_cook" in services + + +def test_custom_integration_does_not_ship_core_strings_json() -> None: + assert not (INTEGRATION / "strings.json").exists() From d634c253da5eb289fb0fae7cd6d02adfea9f8961 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:32:24 -0500 Subject: [PATCH 10/45] Add release-readiness test workflow --- .github/workflows/tests.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..16a31a3 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,22 @@ +name: Tests + +on: + push: + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: Install test runner + run: python -m pip install --upgrade pytest + - name: Run release-readiness tests + run: python -m pytest -q From 2de4ca5832deeeaf2b31f398def303444ced0c18 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:32:26 -0500 Subject: [PATCH 11/45] Add draft 0.9.0 release notes --- RELEASE_NOTES_0.9.0.md | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 RELEASE_NOTES_0.9.0.md diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md new file mode 100644 index 0000000..4b325a4 --- /dev/null +++ b/RELEASE_NOTES_0.9.0.md @@ -0,0 +1,45 @@ +# Sharp Kitchen 0.9.0 — Draft Release Notes + +> **Not for publication yet.** The formal release is blocked until the Sharp +> application credential and shared mTLS private-key distribution problem has +> an acceptable public-release architecture. + +## Highlights + +- Home Assistant support for the Sharp SMD2489ES Microwave Drawer. +- Manual cook controls for cook time, power, start, pause, and stop. +- Drawer open control. +- Full 29-program SMD2489ES Smart Cook catalog. +- Adaptive Smart Cook controls: + - numeric quantity/weight controls where required; + - option selectors where required; + - sensor-cook programs without an unnecessary secondary value. +- Easy Wave, Sound, and Reminder Sound settings. +- Sensors for appliance status, drawer/door state, remaining time, power, + and temperature. +- UI-based Home Assistant configuration. +- HACS repository metadata and validation workflows. +- Integration-wide actions registered once at Home Assistant integration + setup rather than once per config entry. +- English translations include both low-level cook actions. + +## Compatibility + +The Sharp SMD2489ES is the currently verified appliance. Support for other +Sharp Kitchen-connected appliances is not claimed until those appliances are +specifically verified. + +## Security / release blocker + +The working implementation currently depends on application authentication +material recovered from the official Sharp Kitchen application, including +mTLS client key material. Those working values remain unchanged on the +preserved implementation while a distribution architecture is investigated. + +No tag, GitHub release, or HACS default-store submission should be created +until that blocker is resolved and release validation is repeated. + +## Disclaimer + +Sharp Kitchen Integration is an unofficial community project and is not +affiliated with or endorsed by Sharp Corporation. From 43175263c9ba099686ee4c4a8e3fc389681eaa81 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:32:28 -0500 Subject: [PATCH 12/45] Document branding preparation --- BRANDING.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 BRANDING.md diff --git a/BRANDING.md b/BRANDING.md new file mode 100644 index 0000000..6297116 --- /dev/null +++ b/BRANDING.md @@ -0,0 +1,20 @@ +# Branding Preparation + +Home Assistant 2026.3 and later allows custom integrations to ship branding +inside `custom_components/sharp_kitchen/brand/`. + +Planned assets: + +- `brand/icon.png` — square integration icon. +- `brand/[email protected]` — optional high-resolution square icon. +- `brand/logo.png` — optional horizontal logo. +- Dark-mode variants only if the normal artwork does not remain legible. + +## Release constraints + +Do not copy Sharp corporate artwork, product photography, or trademarks into +this repository unless reuse rights are clear. A neutral original microwave- +drawer/integration mark is the preferred fallback for this unofficial project. + +The final PNG assets should be added only after the visual direction is +approved. Branding is preparation work only and does not authorize a release. From 49ae82dcc3b5752380ff9aac632c08e209fba373 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:34:29 -0500 Subject: [PATCH 13/45] Fix manifest for hassfest --- custom_components/sharp_kitchen/manifest.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/custom_components/sharp_kitchen/manifest.json b/custom_components/sharp_kitchen/manifest.json index 4e34d5e..fd03ce1 100644 --- a/custom_components/sharp_kitchen/manifest.json +++ b/custom_components/sharp_kitchen/manifest.json @@ -4,9 +4,8 @@ "codeowners": ["@aevans0001"], "config_flow": true, "documentation": "https://github.com/aevans0001/Sharp-Kitchen-Integration", - "issue_tracker": "https://github.com/aevans0001/Sharp-Kitchen-Integration/issues", "integration_type": "hub", "iot_class": "cloud_polling", - "requirements": ["cryptography"], + "issue_tracker": "https://github.com/aevans0001/Sharp-Kitchen-Integration/issues", "version": "0.9.0" } From 43bc94ac8c736f718d33735f3389025f57cf6394 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:34:31 -0500 Subject: [PATCH 14/45] Declare config-entry-only schema From 6038091747162461a01a0efae709c1de75b9fbcd Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:34:47 -0500 Subject: [PATCH 15/45] Declare config-entry-only schema --- custom_components/sharp_kitchen/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_components/sharp_kitchen/__init__.py b/custom_components/sharp_kitchen/__init__.py index e4a8eb0..8a05abc 100644 --- a/custom_components/sharp_kitchen/__init__.py +++ b/custom_components/sharp_kitchen/__init__.py @@ -26,6 +26,8 @@ _LOGGER = logging.getLogger(__name__) +CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) + PLATFORMS = ["sensor", "switch", "button", "number", "select"] SERVICE_START_COOK = "start_cook" From fe619e858487b4e8f85c102372c28ee49231e8ce Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:35:47 -0500 Subject: [PATCH 16/45] Document authentication release-blocker research --- AUTHENTICATION_ARCHITECTURE.md | 121 +++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 AUTHENTICATION_ARCHITECTURE.md diff --git a/AUTHENTICATION_ARCHITECTURE.md b/AUTHENTICATION_ARCHITECTURE.md new file mode 100644 index 0000000..fd9ca0b --- /dev/null +++ b/AUTHENTICATION_ARCHITECTURE.md @@ -0,0 +1,121 @@ +# Authentication Distribution Research + +This document records release-blocker research only. It does not change the +working authentication implementation. + +## Current blocker + +The working integration relies on application authentication material recovered +from the official Sharp Kitchen application, including a Cognito application +client credential and a shared mTLS client certificate/private key. The formal +HACS release must not embed the extracted private key. + +## Options under consideration + +### 1. User-provided Sharp application credential + user-provided mTLS PEM files + +Home Assistant can store user-entered OAuth client ID/client secret values +through its Application Credentials framework. The mTLS certificate/private key +would still need a separate mechanism, such as paths under the Home Assistant +configuration directory or values entered during a setup/reconfigure flow. + +Pros: +- public repository contains no extracted private key; +- no hosted relay service; +- closest to normal local secret management. + +Cons: +- ordinary Sharp users do not appear to have a supported developer portal for + creating their own Sharp Kitchen OAuth client; +- obtaining the same vendor-app credentials and mTLS private key currently + requires reverse-engineering/extraction work and is not a realistic normal + installation experience. + +### 2. User-supplied credential bundle produced by a separate extraction helper + +Keep extracted credential material out of the HACS repository. A separate tool +could produce a local bundle that the integration imports. + +Pros: +- HACS repository remains credential-free; +- integration setup could validate the bundle before saving paths/material. + +Cons: +- extraction of the mTLS private key remains technically difficult; +- the current research indicates the app's bundled PKCS#12 material is not a + simple user-exportable credential; +- adds a substantial prerequisite and support burden. + +### 3. Supported Sharp provisioning/pairing flow that generates per-installation mTLS credentials + +This is the preferred architecture if Sharp exposes such a flow. + +Pros: +- cleanest security model; +- no shared private key distribution; +- comparable to integrations that pair and generate/store a unique client + certificate for each Home Assistant installation. + +Cons: +- no such Sharp provisioning endpoint has been identified yet; +- requires further protocol research before it can be considered viable. + +### 4. User-provided certificate/key files obtained independently + +The integration would accept certificate and private-key paths or pasted PEM +material, but would not prescribe or automate extraction. + +Pros: +- technically straightforward for the Home Assistant integration; +- public repository stays free of the private key. + +Cons: +- poor user experience; +- most users cannot realistically obtain the material; +- support/documentation would still need to address how legitimate users obtain + it. + +### 5. Project-operated relay/proxy service holding the shared mTLS key + +Home Assistant would authenticate users locally, but Sharp API calls requiring +mTLS would transit a service controlled by the project. + +Pros: +- HACS package contains no Sharp private key; +- easiest end-user setup. + +Cons: +- creates a new hosted service, operating cost, privacy/security responsibility, + availability dependency, and trust boundary; +- routes appliance/account traffic through a third party; +- not recommended for this project unless all direct-client approaches fail. + +## Home Assistant Application Credentials + +Application Credentials is suitable for storing/selecting a user-provided +OAuth client ID and client secret. It does not store or provision a TLS client +certificate/private key. + +Sharp also uses a hosted-login flow tied to the official application's OAuth +client/redirect behavior. Application Credentials therefore does not, by +itself, make the current Sharp login flow a standard Home Assistant OAuth flow. +A separate compatibility investigation is required before refactoring login to +Home Assistant's OAuth helpers. + +## Current recommendation + +Do not change the working integration yet. + +Research in this order: + +1. Determine whether the Sharp backend/app has an undocumented supported + registration/provisioning operation capable of issuing a new client + certificate/key or otherwise removing the need for the shared app key. +2. If not, prototype a credential-free public integration that accepts + user-supplied client ID/secret and mTLS certificate/key material without + committing those values. +3. Evaluate whether a separate extraction/import helper can make that + user-supplied model realistic. +4. Treat a hosted relay as a last resort. + +No release, merge, tag, or HACS submission is authorized by this document. From d2273c88df95ebe2331cdebd040747ecae1210e5 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:35:49 -0500 Subject: [PATCH 17/45] Prepare repository description and topics --- REPOSITORY_METADATA.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 REPOSITORY_METADATA.md diff --git a/REPOSITORY_METADATA.md b/REPOSITORY_METADATA.md new file mode 100644 index 0000000..6ffecd5 --- /dev/null +++ b/REPOSITORY_METADATA.md @@ -0,0 +1,20 @@ +# Repository Metadata — Pending GitHub Settings Update + +Proposed GitHub repository description: + +> Home Assistant integration for Sharp Kitchen-connected appliances, including the SMD2489ES Microwave Drawer. + +Proposed repository topics: + +- home-assistant +- homeassistant +- hacs +- custom-integration +- sharp +- sharp-kitchen +- microwave +- smd2489es +- smart-home + +These values are release-preparation metadata only. They do not authorize a +release or HACS submission. From 5ef729e16917c23cd4f9cd50f70f9483e933ab2f Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:29:46 -0500 Subject: [PATCH 18/45] Add MIT license --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d2f2e0f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 aevans0001 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 9950237ee46c893d9aec6ed049ffa63b8c4c572b Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:30:35 -0500 Subject: [PATCH 19/45] Document release blocker and MIT license --- README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 43d8aa9..933fed6 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,24 @@ Unofficial Home Assistant custom integration for Sharp Kitchen-connected applian The currently verified appliance is the Sharp SMD2489ES. Other Sharp Kitchen-connected appliances may use related cloud APIs, but their controls are not claimed as supported until they are specifically verified. +## Release status + +Formal HACS release is currently **blocked** while the project investigates a +public-safe authentication architecture. The working implementation depends on +Sharp application authentication material, including shared mTLS client-key +material recovered from the official app. Those working values are being +preserved while the replacement architecture is researched. + +There is no published `0.9.0` release yet, and this repository should be +treated as development/testing software until that blocker is resolved. + ## Installation ### HACS -HACS packaging is being prepared. Until the first release is published, install this repository as a custom HACS integration only for testing. +HACS packaging is being prepared. Until the credential-distribution blocker is +resolved and a formal release is published, custom-repository installation is +for development/testing only. 1. In HACS, add this repository as a custom repository with category **Integration**. 2. Install **Sharp Kitchen**. @@ -54,6 +67,10 @@ A low-level `sharp_kitchen.start_smart_cook` action remains available for backwa Release preparation includes HACS validation and Home Assistant hassfest validation. The repository intentionally contains only the Home Assistant integration; Appliance Control Center/dashboard presentation logic is maintained separately. +## License + +MIT License. See `LICENSE`. + ## Disclaimer This project is unofficial and is not affiliated with or endorsed by Sharp Corporation. From 069b24a21b9ef1d3d8c9e516c0aa3b45a951dabc Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:30:50 -0500 Subject: [PATCH 20/45] Add blocked release checklist --- RELEASE_CHECKLIST.md | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 RELEASE_CHECKLIST.md diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md new file mode 100644 index 0000000..09372ae --- /dev/null +++ b/RELEASE_CHECKLIST.md @@ -0,0 +1,57 @@ +# Sharp Kitchen 0.9.0 Release Checklist + +This checklist is intentionally conservative. Completing preparation items does +not authorize a release. + +## Hard blockers + +- [ ] Replace the current public-distribution model for the Sharp application + credential and shared mTLS private key. +- [ ] Confirm the replacement authentication design without breaking the + currently working integration. +- [ ] Repeat privacy/confidential-data review after the authentication change. + +## Repository / HACS + +- [x] Public GitHub repository +- [x] One Home Assistant integration under `custom_components/sharp_kitchen` +- [x] `hacs.json` +- [x] README +- [x] MIT LICENSE +- [x] Issue tracker URL in manifest +- [x] Code owner in manifest +- [x] Versioned custom integration manifest +- [x] HACS validation workflow +- [x] hassfest workflow +- [x] Release-readiness tests +- [ ] Apply GitHub repository description +- [ ] Apply GitHub repository topics +- [ ] Add approved original brand icon +- [ ] HACS validation passes with no failed checks + +## Validation + +- [x] Offline release-readiness tests pass +- [x] hassfest passes after manifest/schema cleanup +- [ ] HACS validation passes +- [ ] Re-run all checks at final release commit +- [ ] Review final diff against working `main` +- [ ] Confirm no unintended dashboard/frontend files are included + +## Release + +- [ ] Freeze exact release commit +- [ ] Confirm proposed version +- [ ] Finalize release notes +- [ ] Final privacy/confidential-data sweep +- [ ] User approves tag/release +- [ ] Create tag and GitHub release +- [ ] Verify HACS install from released artifact +- [ ] User approves HACS default-store submission +- [ ] Submit to HACS + +## Current prohibition + +Do not merge the draft release PR, tag `0.9.0`, publish a GitHub release, +remove or rotate the working Sharp credentials, or submit to HACS while the +authentication architecture remains unresolved. From 0ba58a6f308d819667978d111b8520e8c3e4f001 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:35:18 -0500 Subject: [PATCH 21/45] Extend release-readiness tests for license and blocker --- tests/test_release_readiness.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_release_readiness.py b/tests/test_release_readiness.py index 7275f00..5b5cde7 100644 --- a/tests/test_release_readiness.py +++ b/tests/test_release_readiness.py @@ -77,3 +77,16 @@ def test_english_translation_covers_both_actions() -> None: def test_custom_integration_does_not_ship_core_strings_json() -> None: assert not (INTEGRATION / "strings.json").exists() + + +def test_mit_license_is_present() -> None: + license_text = (ROOT / "LICENSE").read_text(encoding="utf-8") + assert license_text.startswith("MIT License") + assert "Permission is hereby granted, free of charge" in license_text + assert "Copyright (c) 2026 aevans0001" in license_text + + +def test_release_blocker_is_documented() -> None: + readme = (ROOT / "README.md").read_text(encoding="utf-8") + assert "Formal HACS release is currently **blocked**" in readme + assert "There is no published `0.9.0` release yet" in readme From b8b905f3c9cdc069bcb1a074bb46a6ee296a4e46 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:35:20 -0500 Subject: [PATCH 22/45] Refresh draft release notes --- RELEASE_NOTES_0.9.0.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md index 4b325a4..3877cd9 100644 --- a/RELEASE_NOTES_0.9.0.md +++ b/RELEASE_NOTES_0.9.0.md @@ -39,6 +39,17 @@ preserved implementation while a distribution architecture is investigated. No tag, GitHub release, or HACS default-store submission should be created until that blocker is resolved and release validation is repeated. +## Release preparation status + +- MIT License selected. +- Offline release-readiness tests pass. +- Home Assistant hassfest passes. +- HACS repository validation is still expected to remain blocked until the + default branch carries the release metadata/branding and the authentication + architecture blocker is resolved. +- Draft PR #1 remains unmerged. +- No `0.9.0` tag or GitHub release exists. + ## Disclaimer Sharp Kitchen Integration is an unofficial community project and is not From 50e78b47367066c0b2133c9b14a21abd6af1120f Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:35:22 -0500 Subject: [PATCH 23/45] Add privacy and confidential-information review --- PRIVACY_REVIEW.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 PRIVACY_REVIEW.md diff --git a/PRIVACY_REVIEW.md b/PRIVACY_REVIEW.md new file mode 100644 index 0000000..14a4571 --- /dev/null +++ b/PRIVACY_REVIEW.md @@ -0,0 +1,39 @@ +# Privacy and Confidential-Information Review + +Last reviewed: 2026-10-06 + +Scope: release/hacs-readiness tracked release-preparation files and repository +metadata prepared for the future Sharp Kitchen 0.9.0 release. + +## Personal-information sweep + +No release-preparation file introduced: + +- personal email addresses; +- home/street addresses; +- IPv4 addresses; +- MAC addresses; +- Windows user-profile paths; +- UNC/network paths; +- personal credentials, refresh tokens, or account-specific identifiers. + +Release-preparation commits expose the GitHub account identity through normal +Git commit metadata; no personal email address was returned by the connected +GitHub tooling. + +## Known intentional authentication material in the preserved working code + +The pre-existing working integration still contains Sharp application +authentication material recovered from the official application, including the +Cognito application credential and shared mTLS certificate/private-key +material. + +This material is the explicit hard blocker for formal HACS release. It was not +introduced by the HACS-readiness work and has not been removed, rotated, or +modified because doing so would break the preserved working implementation. + +## Release rule + +Repeat this review after any future authentication-architecture change and +before freezing the release commit. No tag, merge, release, or HACS submission +is authorized by this review. From 578cdd07abbbd8ce446595271358ee24b6faa801 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:52:34 -0500 Subject: [PATCH 24/45] Add temporary Sharp Kitchen brand icon --- custom_components/sharp_kitchen/brand/icon.png | Bin 0 -> 5956 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 custom_components/sharp_kitchen/brand/icon.png diff --git a/custom_components/sharp_kitchen/brand/icon.png b/custom_components/sharp_kitchen/brand/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..153161045fa1cf7ff456324253ac63f90c13b04f GIT binary patch literal 5956 zcmV-K7rW?*P)&% z?&`46-ZaPktf!@oh>8`c`W=7OqBJ;6OH=|(uLmJc0A0@jNU;DrmjD|~m7j7%26;QfalZ1x4OuSB1sX^V~l`C3AZ<4xFlpw5< z8bKu_$cIwO2fhMQ2}K~`=3!{-2$>{TLa89#G)wA$YO?X9snk5`@wlO=YU9kY12yuU z2OrKn&T}4nFG6CZ#CPX$&hPyHzyEV)XMz9YjkF&1efV3PAVHF>2w;~_F#(W;E6+Xw zfGjMMv%>-Gy3P#%V7WB`O!z;`H_r|O;M~lo-x`8?3;@gX@c;mOc8iy8b@_bDPQPFT zX`KJSyM#~I{$M-ihx3!grT^|F0kUtR>{)KZ`~Z+W#(GGA+_F#IwUP`b24?--Sxp9x zK7Y_pPhA8w?z{_~0Im-V7Y4%tm@jcZ*#&g>M~qfESP2u$ekcDys|1|81_*S8`GH$T zZ2-vr;Uf;kdw{l_dcy~-*9}mDyYF3g*H1TZJZ+VLGi@2Qw+!4C%KDVht4CG<`&ZO! z@A=JSFpBW^K-xZw!jR4{Km@E9=2`%6*U65W<}>ROaZ{!p|9Ry0zmE{zTahC z!8Tw7KKdzY0I)_WKs%J+ZovUm+d9^EtQ!E_+?}I#udw|vp#atZ;D`>uoo?C3^~)SK z0boa<0r=VNVR$!!H2}aDQ~*w?l@1c1Geuv9ofH6oD@O`|tJgd0ge+Vxms#fudzKM* zC^_M6AFL~xEsfjiu{a6&QZN0Y1i*Q2ZF55hP|oTGL#rbT1Rubm^6!twB7ke31UQ0% zt*~UPN6bPAjR@c?e+B^X%1p4P=eA4_WXnly5laz7Jwo%+z zfoHb1gmqWnNqhC(vZQrk>Kkd2D;MX2N}E9nj4GM1 z3RkmfMVP0?nLBG0RO?;e;DX!%0C*|}##aXbun;a|bpU16gSQ4}So9s~e<2mtUx?EA^7g(=Xj z(GmbL=QXz{2?O#|Pa~}`6^Y;)3INC!T!cj-H0JVS>WF8Ik#Qd z>Dlm}DF7U6_{3?R2LzJK^Z0*cU6a`lLvh4ggJZTFJfk=d(H@-pvQpJ4WdN|FanLGF z$QosEOle?1UX?_;V`Q3t2Y_Qql1f7NDyn6V5XJGN-;h(@94}I+0BVk$dPqF?mrMXg z0QO8urA!s=XAi4>FMA>&s?(={r%-r(g8(7f$+Dx){yT`l|dhVrWzXKrsal z@@OV|RoWywY8_gAEH5}*D22xaMAkq#o@0`L%iYen*%Q}Ubv z0z`MBYXGpP^u(rQwgS8ZKqcoR05JLwJ|sDI7yv%`2$ic8Q_<%E4sg3R!MhveeE!Qm zH5g$A;`_c&u@DUrZw~>$dyg_dRW#rmTebY83y&!~|3+_hO@WNVB7WS&I$FhE9F#i> zw5f?CzvviyY41NF8Q|B`oRGUlK|r3DQpL>;6bxC2UDbV~ z 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 Date: Tue, 6 Oct 2026 07:53:41 -0500 Subject: [PATCH 25/45] Record approved temporary brand icon --- BRANDING.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/BRANDING.md b/BRANDING.md index 6297116..8e9ff79 100644 --- a/BRANDING.md +++ b/BRANDING.md @@ -3,18 +3,26 @@ Home Assistant 2026.3 and later allows custom integrations to ship branding inside `custom_components/sharp_kitchen/brand/`. -Planned assets: +## Current temporary icon -- `brand/icon.png` — square integration icon. -- `brand/[email protected]` — optional high-resolution square icon. -- `brand/logo.png` — optional horizontal logo. -- Dark-mode variants only if the normal artwork does not remain legible. +The user approved a temporary Sharp Kitchen integration icon and it is now +present on the release-preparation branch at: + +`custom_components/sharp_kitchen/brand/icon.png` + +The current icon is a square 256×256 PNG based on original appliance artwork +created for this integration, with the user-requested Sharp wordmark. It is +approved as a temporary integration icon and may be replaced before or after a +future release. -## Release constraints +The image does not copy Sharp product photography. Because the wordmark is a +Sharp trademark, its use should remain limited to identifying compatibility +with Sharp Kitchen and should not imply endorsement. -Do not copy Sharp corporate artwork, product photography, or trademarks into -this repository unless reuse rights are clear. A neutral original microwave- -drawer/integration mark is the preferred fallback for this unofficial project. +## Optional future assets + +- `brand/[email protected]` — optional higher-resolution square icon. +- `brand/logo.png` — optional horizontal logo. +- Dark-mode variants only if needed for legibility. -The final PNG assets should be added only after the visual direction is -approved. Branding is preparation work only and does not authorize a release. +Branding preparation does not authorize a release. From 0dc1eb045504661b37476a73af296eaca00b640a Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:53:44 -0500 Subject: [PATCH 26/45] Update release checklist for branding --- RELEASE_CHECKLIST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md index 09372ae..a8f111e 100644 --- a/RELEASE_CHECKLIST.md +++ b/RELEASE_CHECKLIST.md @@ -26,7 +26,7 @@ not authorize a release. - [x] Release-readiness tests - [ ] Apply GitHub repository description - [ ] Apply GitHub repository topics -- [ ] Add approved original brand icon +- [x] Add approved temporary brand icon - [ ] HACS validation passes with no failed checks ## Validation @@ -36,7 +36,7 @@ not authorize a release. - [ ] HACS validation passes - [ ] Re-run all checks at final release commit - [ ] Review final diff against working `main` -- [ ] Confirm no unintended dashboard/frontend files are included +- [x] Confirm no unintended dashboard/frontend files are included ## Release From 087734f7fb8fc515f128afdeb7f6cfd397a881ba Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:53:46 -0500 Subject: [PATCH 27/45] Update draft release notes for branding --- RELEASE_NOTES_0.9.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md index 3877cd9..ab23503 100644 --- a/RELEASE_NOTES_0.9.0.md +++ b/RELEASE_NOTES_0.9.0.md @@ -19,6 +19,7 @@ and temperature. - UI-based Home Assistant configuration. - HACS repository metadata and validation workflows. +- Temporary Sharp Kitchen brand icon added for HACS/Home Assistant presentation. - Integration-wide actions registered once at Home Assistant integration setup rather than once per config entry. - English translations include both low-level cook actions. From ebe7fa3c29eb4159ca2e13eaa72677c2f042a0d7 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:54:16 -0500 Subject: [PATCH 28/45] Refresh privacy review after branding --- PRIVACY_REVIEW.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PRIVACY_REVIEW.md b/PRIVACY_REVIEW.md index 14a4571..453a84f 100644 --- a/PRIVACY_REVIEW.md +++ b/PRIVACY_REVIEW.md @@ -1,6 +1,6 @@ # Privacy and Confidential-Information Review -Last reviewed: 2026-10-06 +Last reviewed: 2026-10-06 (after temporary branding addition) Scope: release/hacs-readiness tracked release-preparation files and repository metadata prepared for the future Sharp Kitchen 0.9.0 release. @@ -21,6 +21,11 @@ Release-preparation commits expose the GitHub account identity through normal Git commit metadata; no personal email address was returned by the connected GitHub tooling. +A fresh scan of the full PR diff after adding the temporary brand icon found +no personal email addresses, IP addresses, MAC addresses, local user paths, +street address, personal name, bearer tokens, or AWS-style access keys in the +release-preparation changes. + ## Known intentional authentication material in the preserved working code The pre-existing working integration still contains Sharp application From bd0efdd691aac90c05cc572cabb46d8ae48b070a Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:54:45 -0500 Subject: [PATCH 29/45] Validate bundled brand icon --- tests/test_release_readiness.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_release_readiness.py b/tests/test_release_readiness.py index 5b5cde7..a44c526 100644 --- a/tests/test_release_readiness.py +++ b/tests/test_release_readiness.py @@ -90,3 +90,13 @@ def test_release_blocker_is_documented() -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") assert "Formal HACS release is currently **blocked**" in readme assert "There is no published `0.9.0` release yet" in readme + + +def test_brand_icon_is_256_square_png() -> None: + icon = INTEGRATION / "brand" / "icon.png" + data = icon.read_bytes() + assert data[:8] == b"\x89PNG\r\n\x1a\n" + assert data[12:16] == b"IHDR" + width = int.from_bytes(data[16:20], "big") + height = int.from_bytes(data[20:24], "big") + assert (width, height) == (256, 256) From 9b0e303cbf66981be0e39d4ff13655f693eab6e8 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:56:27 -0500 Subject: [PATCH 30/45] Expand Sharp credential provisioning research --- AUTHENTICATION_ARCHITECTURE.md | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/AUTHENTICATION_ARCHITECTURE.md b/AUTHENTICATION_ARCHITECTURE.md index fd9ca0b..c84c926 100644 --- a/AUTHENTICATION_ARCHITECTURE.md +++ b/AUTHENTICATION_ARCHITECTURE.md @@ -102,6 +102,44 @@ itself, make the current Sharp login flow a standard Home Assistant OAuth flow. A separate compatibility investigation is required before refactoring login to Home Assistant's OAuth helpers. +## Additional provisioning research + +Public Sharp material reviewed during release preparation continues to direct +SMD2489ES users through the Sharp Kitchen app for appliance pairing. The +published pairing flow covers Wi-Fi/app/account pairing but does not document +issuance of a new client TLS certificate or private key to third-party clients. + +Sharp also publishes an Alexa account-linking path using the user's Sharp +account. This proves that Sharp supports account linking outside the mobile app, +but it does not expose a public device-control API, a user-created OAuth client, +or a per-installation mTLS credential flow that Home Assistant could currently +reuse. + +Public GitHub/code searches for the Sharp Kitchen backend host, API path, +application package, and bundled PKCS#12 filename did not uncover an independent +implementation or a documented certificate-registration endpoint. + +### Best viable public-safe fallback at this checkpoint + +If no Sharp provisioning endpoint is discovered, the most practical direct +client design is: + +1. Remove vendor-app secrets/key material from the future public release only + after a tested replacement exists. +2. Let the user supply OAuth application values locally. +3. Store/select the OAuth client ID and client secret through Home Assistant + Application Credentials where compatible with Sharp's hosted-login behavior. +4. Let the user supply the mTLS certificate and private key as local files, + preferably under `/config/sharp_kitchen/`. +5. Store only file paths/references in the config entry, not private-key text. +6. Validate certificate/key parsing and matching during setup/reconfigure. +7. Keep extraction/import outside the HACS package, ideally through a separate + local helper if a repeatable extraction method can be made practical. + +This is not as user-friendly as true vendor provisioning, but it keeps the HACS +repository free of the extracted private key and avoids a project-operated +cloud relay. + ## Current recommendation Do not change the working integration yet. From 1be0e0589026ee333f06330e3aa9e230943ba1d6 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:59:41 -0500 Subject: [PATCH 31/45] Update HACS readiness checklist --- RELEASE_CHECKLIST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md index a8f111e..cf0e267 100644 --- a/RELEASE_CHECKLIST.md +++ b/RELEASE_CHECKLIST.md @@ -17,7 +17,7 @@ not authorize a release. - [x] One Home Assistant integration under `custom_components/sharp_kitchen` - [x] `hacs.json` - [x] README -- [x] MIT LICENSE +- [x] MIT LICENSE (also applied to default `main` branch) - [x] Issue tracker URL in manifest - [x] Code owner in manifest - [x] Versioned custom integration manifest @@ -27,7 +27,7 @@ not authorize a release. - [ ] Apply GitHub repository description - [ ] Apply GitHub repository topics - [x] Add approved temporary brand icon -- [ ] HACS validation passes with no failed checks +- [ ] HACS validation passes with no failed checks (currently 7/9; description/topics remain) ## Validation @@ -35,14 +35,14 @@ not authorize a release. - [x] hassfest passes after manifest/schema cleanup - [ ] HACS validation passes - [ ] Re-run all checks at final release commit -- [ ] Review final diff against working `main` +- [x] Review current release diff against working code baseline - [x] Confirm no unintended dashboard/frontend files are included ## Release - [ ] Freeze exact release commit - [ ] Confirm proposed version -- [ ] Finalize release notes +- [x] Keep draft release notes current (final publication wording still blocked) - [ ] Final privacy/confidential-data sweep - [ ] User approves tag/release - [ ] Create tag and GitHub release From 865b57edb4e9629d398fecef5575ee4d74f13cc1 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:59:43 -0500 Subject: [PATCH 32/45] Record current HACS validation status --- RELEASE_NOTES_0.9.0.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md index ab23503..7f6fc7b 100644 --- a/RELEASE_NOTES_0.9.0.md +++ b/RELEASE_NOTES_0.9.0.md @@ -45,9 +45,7 @@ until that blocker is resolved and release validation is repeated. - MIT License selected. - Offline release-readiness tests pass. - Home Assistant hassfest passes. -- HACS repository validation is still expected to remain blocked until the - default branch carries the release metadata/branding and the authentication - architecture blocker is resolved. +- HACS validation currently passes 7 of 9 repository checks. The MIT license and brand icon now pass; only the GitHub repository description and topics remain as non-authentication HACS metadata items. - Draft PR #1 remains unmerged. - No `0.9.0` tag or GitHub release exists. From 662bc68587dc97be4d7faf0f0e09a531471b7a8f Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:59:46 -0500 Subject: [PATCH 33/45] Document exact repository metadata command --- REPOSITORY_METADATA.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/REPOSITORY_METADATA.md b/REPOSITORY_METADATA.md index 6ffecd5..668c35b 100644 --- a/REPOSITORY_METADATA.md +++ b/REPOSITORY_METADATA.md @@ -18,3 +18,19 @@ Proposed repository topics: These values are release-preparation metadata only. They do not authorize a release or HACS submission. + + +## Exact GitHub CLI command + +The connected GitHub toolset used during release preparation cannot mutate +repository About/Topics settings. If GitHub CLI is already authenticated, the +remaining metadata can be applied with: + +```powershell +Clear-Host +gh repo edit aevans0001/Sharp-Kitchen-Integration --description "Home Assistant integration for Sharp Kitchen-connected appliances, including the SMD2489ES Microwave Drawer." --add-topic home-assistant --add-topic homeassistant --add-topic hacs --add-topic custom-integration --add-topic sharp --add-topic sharp-kitchen --add-topic microwave --add-topic smd2489es --add-topic smart-home + +``` + +Applying repository description/topics does not merge the release PR, tag a +release, change authentication, or publish to HACS. From 216e301495d43bd8cf12c971fcb1f5881d1211d2 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 08:01:37 -0500 Subject: [PATCH 34/45] Record final pre-auth privacy diff review --- PRIVACY_REVIEW.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/PRIVACY_REVIEW.md b/PRIVACY_REVIEW.md index 453a84f..ae15694 100644 --- a/PRIVACY_REVIEW.md +++ b/PRIVACY_REVIEW.md @@ -42,3 +42,18 @@ modified because doing so would break the preserved working implementation. Repeat this review after any future authentication-architecture change and before freezing the release commit. No tag, merge, release, or HACS submission is authorized by this review. + + +## Current release-preparation diff verification + +The current `main...release/hacs-readiness` file list was reviewed after +branding, license, tests, and documentation updates. + +The release-preparation diff does **not** modify the Sharp authentication +implementation files `api.py`, `const.py`, or `config_flow.py`. The +working credential values and authentication protocol therefore remain +unchanged by this preparation work. + +A fresh pattern scan of the PR diff found no personal email address, IP address, +MAC address, local user path, street address, personal name, bearer token, or +AWS-style access key introduced by the release-preparation changes. From 2d892a6397699e01a2ea89e2b4af6a8b251b3d9f Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:29:18 -0500 Subject: [PATCH 35/45] Replace brand icon with approved neutral artwork --- .../sharp_kitchen/brand/icon.png | Bin 5956 -> 14474 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/custom_components/sharp_kitchen/brand/icon.png b/custom_components/sharp_kitchen/brand/icon.png index 153161045fa1cf7ff456324253ac63f90c13b04f..84fcf2dd5b296bb1ba131b4f7d154cf66839a945 100644 GIT binary patch literal 14474 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 z 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 Date: Tue, 6 Oct 2026 16:29:45 -0500 Subject: [PATCH 36/45] Document approved brand-neutral icon --- BRANDING.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/BRANDING.md b/BRANDING.md index 8e9ff79..28e618b 100644 --- a/BRANDING.md +++ b/BRANDING.md @@ -3,21 +3,30 @@ Home Assistant 2026.3 and later allows custom integrations to ship branding inside `custom_components/sharp_kitchen/brand/`. -## Current temporary icon +## Current approved icon -The user approved a temporary Sharp Kitchen integration icon and it is now +The user approved a brand-neutral Sharp Kitchen integration icon and it is now present on the release-preparation branch at: `custom_components/sharp_kitchen/brand/icon.png` -The current icon is a square 256×256 PNG based on original appliance artwork -created for this integration, with the user-requested Sharp wordmark. It is -approved as a temporary integration icon and may be replaced before or after a -future release. +The current icon is a square 256×256 PNG created specifically for this +integration. It shows an original stainless-steel microwave drawer viewed +straight-on with the drawer slightly open, a subtle warm interior glow, a dark +navy/charcoal rounded-square background, a black control panel, and a small +digital display. -The image does not copy Sharp product photography. Because the wordmark is a -Sharp trademark, its use should remain limited to identifying compatibility -with Sharp Kitchen and should not imply endorsement. +The icon intentionally contains: + +- no manufacturer logo; +- no Sharp wordmark; +- no model number; +- no Wi-Fi symbol; +- no product photography; +- no copied corporate artwork. + +The design is intended to remain recognizable at small Home Assistant/HACS icon +sizes while being completely original and brand-neutral. ## Optional future assets From 13633277cbf5887e6b93362d9375181b78cd85a4 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:29:49 -0500 Subject: [PATCH 37/45] Update checklist for final brand-neutral icon --- RELEASE_CHECKLIST.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md index cf0e267..e1a1cec 100644 --- a/RELEASE_CHECKLIST.md +++ b/RELEASE_CHECKLIST.md @@ -26,7 +26,7 @@ not authorize a release. - [x] Release-readiness tests - [ ] Apply GitHub repository description - [ ] Apply GitHub repository topics -- [x] Add approved temporary brand icon +- [x] Add approved brand-neutral icon - [ ] HACS validation passes with no failed checks (currently 7/9; description/topics remain) ## Validation @@ -43,7 +43,7 @@ not authorize a release. - [ ] Freeze exact release commit - [ ] Confirm proposed version - [x] Keep draft release notes current (final publication wording still blocked) -- [ ] Final privacy/confidential-data sweep +- [x] Final pre-auth privacy/confidential-data sweep - [ ] User approves tag/release - [ ] Create tag and GitHub release - [ ] Verify HACS install from released artifact From e8fd9fe077821ca519d6aa021f7157362532bd33 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:29:55 -0500 Subject: [PATCH 38/45] Update release notes for brand-neutral icon --- RELEASE_NOTES_0.9.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md index 7f6fc7b..77499b5 100644 --- a/RELEASE_NOTES_0.9.0.md +++ b/RELEASE_NOTES_0.9.0.md @@ -19,7 +19,7 @@ and temperature. - UI-based Home Assistant configuration. - HACS repository metadata and validation workflows. -- Temporary Sharp Kitchen brand icon added for HACS/Home Assistant presentation. +- Original brand-neutral microwave-drawer icon added for HACS/Home Assistant presentation. - Integration-wide actions registered once at Home Assistant integration setup rather than once per config entry. - English translations include both low-level cook actions. @@ -45,7 +45,7 @@ until that blocker is resolved and release validation is repeated. - MIT License selected. - Offline release-readiness tests pass. - Home Assistant hassfest passes. -- HACS validation currently passes 7 of 9 repository checks. The MIT license and brand icon now pass; only the GitHub repository description and topics remain as non-authentication HACS metadata items. +- HACS validation currently passes 7 of 9 repository checks. The MIT license and brand-neutral icon pass; only the GitHub repository description and topics remain as non-authentication HACS metadata items. - Draft PR #1 remains unmerged. - No `0.9.0` tag or GitHub release exists. From ab0a4308c615a275de018b43a2bb8969707706ad Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:30:03 -0500 Subject: [PATCH 39/45] Refresh privacy review after icon replacement --- PRIVACY_REVIEW.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PRIVACY_REVIEW.md b/PRIVACY_REVIEW.md index ae15694..0dbc332 100644 --- a/PRIVACY_REVIEW.md +++ b/PRIVACY_REVIEW.md @@ -1,6 +1,6 @@ # Privacy and Confidential-Information Review -Last reviewed: 2026-10-06 (after temporary branding addition) +Last reviewed: 2026-10-06 (after approved brand-neutral icon replacement) Scope: release/hacs-readiness tracked release-preparation files and repository metadata prepared for the future Sharp Kitchen 0.9.0 release. @@ -21,7 +21,7 @@ Release-preparation commits expose the GitHub account identity through normal Git commit metadata; no personal email address was returned by the connected GitHub tooling. -A fresh scan of the full PR diff after adding the temporary brand icon found +A fresh scan of the full PR diff after replacing the earlier temporary icon with the approved brand-neutral icon found no personal email addresses, IP addresses, MAC addresses, local user paths, street address, personal name, bearer tokens, or AWS-style access keys in the release-preparation changes. From 5f894c3def9c46059f401b73c3edf33ec00aeef7 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:31:06 -0500 Subject: [PATCH 40/45] Document SHARP HOME migration findings --- AUTHENTICATION_ARCHITECTURE.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/AUTHENTICATION_ARCHITECTURE.md b/AUTHENTICATION_ARCHITECTURE.md index c84c926..f1f060f 100644 --- a/AUTHENTICATION_ARCHITECTURE.md +++ b/AUTHENTICATION_ARCHITECTURE.md @@ -119,6 +119,34 @@ Public GitHub/code searches for the Sharp Kitchen backend host, API path, application package, and bundled PKCS#12 filename did not uncover an independent implementation or a documented certificate-registration endpoint. +## 2026 SHARP HOME migration findings + +Sharp introduced a newer **SHARP HOME** app in 2025. Current 2026 Sharp pairing +documentation distinguishes appliance revisions by model suffix rather than +migrating every existing SMD2489ES automatically: + +- `SMD2489ESF` uses the SHARP HOME app. +- `SMD2489ESA/B/D/E` use the older Sharp Kitchen app. + +The SHARP HOME Android package is `jp.co.sharp.chglobal.na`. Sharp's current +documentation also shows **SHARP HOME - Kitchen** account linking through Google +Home and Alexa using a Sharp account, with Google Home relinking required every +180 days. + +This is important because it demonstrates a newer Sharp cloud/account-linking +stack that supports third-party smart-home ecosystems. However, the public +documentation does **not** expose: + +- a third-party developer API for direct appliance control; +- a way for Home Assistant users to register their own OAuth application; +- a method to issue a Home Assistant-specific client TLS certificate/key; +- evidence that older Sharp Kitchen SMD2489ES revisions can migrate to the + SHARP HOME backend. + +Therefore the newer SHARP HOME ecosystem is worth separate future protocol +research, especially for `SMD2489ESF` and later models, but it does not yet +remove the credential blocker for the existing Sharp Kitchen implementation. + ### Best viable public-safe fallback at this checkpoint If no Sharp provisioning endpoint is discovered, the most practical direct From 1450970946ea3c0afaff46046d6591c0804a39a7 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:31:30 -0500 Subject: [PATCH 41/45] Record final safe-preparation privacy sweep --- PRIVACY_REVIEW.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/PRIVACY_REVIEW.md b/PRIVACY_REVIEW.md index 0dbc332..4f7bdec 100644 --- a/PRIVACY_REVIEW.md +++ b/PRIVACY_REVIEW.md @@ -57,3 +57,16 @@ unchanged by this preparation work. A fresh pattern scan of the PR diff found no personal email address, IP address, MAC address, local user path, street address, personal name, bearer token, or AWS-style access key introduced by the release-preparation changes. + + +## Final safe-preparation sweep before authentication work + +After the final brand-neutral icon replacement and authentication-research +documentation updates, the complete PR diff was scanned again. + +Result: no newly introduced personal email address, IP address, MAC address, +Windows/UNC path, street address, personal name, bearer token, or AWS-style +access key was found. + +The authentication implementation itself remains unchanged and is still the +explicit hard blocker for public release. From 22a4eddf50941be3fc5365ebb08af6b11b6d87a8 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:31:41 -0500 Subject: [PATCH 42/45] Refresh release notes with authentication research --- RELEASE_NOTES_0.9.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md index 77499b5..0ccca63 100644 --- a/RELEASE_NOTES_0.9.0.md +++ b/RELEASE_NOTES_0.9.0.md @@ -46,6 +46,7 @@ until that blocker is resolved and release validation is repeated. - Offline release-readiness tests pass. - Home Assistant hassfest passes. - HACS validation currently passes 7 of 9 repository checks. The MIT license and brand-neutral icon pass; only the GitHub repository description and topics remain as non-authentication HACS metadata items. +- Authentication research now documents Sharp's newer SHARP HOME ecosystem for later appliance revisions, but no public provisioning/API path has yet been found that resolves the existing Sharp Kitchen mTLS blocker. - Draft PR #1 remains unmerged. - No `0.9.0` tag or GitHub release exists. From 6f1c644fac94483b9535d3031b659c3b3eb4242f Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:33:37 -0500 Subject: [PATCH 43/45] Document recommended public-safe credential design --- AUTHENTICATION_ARCHITECTURE.md | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/AUTHENTICATION_ARCHITECTURE.md b/AUTHENTICATION_ARCHITECTURE.md index f1f060f..2c06344 100644 --- a/AUTHENTICATION_ARCHITECTURE.md +++ b/AUTHENTICATION_ARCHITECTURE.md @@ -168,6 +168,50 @@ This is not as user-friendly as true vendor provisioning, but it keeps the HACS repository free of the extracted private key and avoids a project-operated cloud relay. +## Home Assistant architecture implications + +Home Assistant's current Application Credentials framework assumes that users +can obtain an OAuth client ID and client secret from the provider. It supports +standard authorization-code flows, PKCE, and custom OAuth implementations, but +it does not provision or store a TLS client certificate/private key as part of +that framework. + +Home Assistant Cloud Account Linking can provide a smoother OAuth experience +when the provider cooperates with Nabu Casa, but that would require Sharp to +support/approve an appropriate OAuth/API integration. It is not something this +project can manufacture from the existing mobile-app credentials. + +The Bosch SHC integration remains the strongest architectural comparison: +during registration it generates a unique SSL certificate/key pair and +registers that client with the controller. Sharp's published pairing flow does +not currently expose an equivalent client-registration step. + +### Recommended public-safe design if Sharp offers no provisioning API + +The best implementable design with the information currently available is: + +1. Keep the public HACS repository free of the extracted shared mTLS private key + and vendor-app client secret. +2. Provide a separate, local-only extraction/import helper that contains no + Sharp secret material itself and operates on a user's legitimately obtained + app installation/package. +3. Have that helper write the resulting credential bundle locally under a + dedicated Home Assistant configuration directory such as + `/config/sharp_kitchen/`. +4. Have the integration validate and consume the local certificate/key files + without copying them into `custom_components`. +5. Use Home Assistant Application Credentials for client ID/secret only if the + Sharp hosted-login implementation can be made compatible and users can + realistically obtain/provide those values. +6. Do not use a project-operated proxy unless direct-client approaches are + exhausted, because a proxy creates a new privacy/security/availability + dependency. + +This approach is less convenient than vendor-supported provisioning, but it is +the cleanest currently viable way to separate secret distribution from the +public HACS package while preserving direct communication between Home +Assistant and Sharp. + ## Current recommendation Do not change the working integration yet. From 6f85a1d8e000506b276605252f82e87592ffd274 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:22:51 -0500 Subject: [PATCH 44/45] Mark non-auth HACS checks complete --- RELEASE_CHECKLIST.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md index e1a1cec..856d587 100644 --- a/RELEASE_CHECKLIST.md +++ b/RELEASE_CHECKLIST.md @@ -24,16 +24,16 @@ not authorize a release. - [x] HACS validation workflow - [x] hassfest workflow - [x] Release-readiness tests -- [ ] Apply GitHub repository description -- [ ] Apply GitHub repository topics +- [x] Apply GitHub repository description +- [x] Apply GitHub repository topics - [x] Add approved brand-neutral icon -- [ ] HACS validation passes with no failed checks (currently 7/9; description/topics remain) +- [x] HACS validation passes with no failed checks ## Validation - [x] Offline release-readiness tests pass - [x] hassfest passes after manifest/schema cleanup -- [ ] HACS validation passes +- [x] HACS validation passes - [ ] Re-run all checks at final release commit - [x] Review current release diff against working code baseline - [x] Confirm no unintended dashboard/frontend files are included From 4d89f12e28b1ae8b4c63e79a7511b663f2dbcfe1 Mon Sep 17 00:00:00 2001 From: aevans0001 <33299008+aevans0001@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:22:53 -0500 Subject: [PATCH 45/45] Record clean HACS validation --- RELEASE_NOTES_0.9.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE_NOTES_0.9.0.md b/RELEASE_NOTES_0.9.0.md index 0ccca63..70f0998 100644 --- a/RELEASE_NOTES_0.9.0.md +++ b/RELEASE_NOTES_0.9.0.md @@ -45,7 +45,7 @@ until that blocker is resolved and release validation is repeated. - MIT License selected. - Offline release-readiness tests pass. - Home Assistant hassfest passes. -- HACS validation currently passes 7 of 9 repository checks. The MIT license and brand-neutral icon pass; only the GitHub repository description and topics remain as non-authentication HACS metadata items. +- HACS validation now passes all repository/integration checks after the GitHub description and topics were applied. - Authentication research now documents Sharp's newer SHARP HOME ecosystem for later appliance revisions, but no public provisioning/API path has yet been found that resolves the existing Sharp Kitchen mTLS blocker. - Draft PR #1 remains unmerged. - No `0.9.0` tag or GitHub release exists.