Wave 9 #122.d.iv — Phase 6 Tailscale wizard: mDNS roamcore.local fallback (Gate E 'local survives Tailscale failure') - #118
Open
bernardc6 wants to merge 1 commit into
Open
Conversation
…back Context: Gate E requires 'local survives Tailscale failure' — if the operator's Tailscale tailnet ever goes down (account paused, weak cellular for the VPN, Hub's internet offline), they must still be able to reach the dashboard from their phone on the same WiFi as the Hub. This slice wires the canonical RoamCore hostname (roamcore.local) into the dashboard fallback path so the operator can reach the Hub at the friendly name without typing an IP. The slice is additive — no overlap with #122.a (wizard), #122.d.ii (QR code), or #122.b/c/d.i (the four remote paths). NEW package homeassistant/packages/roamcore_local_mdns_fallback.yaml: - input_boolean.rc_local_mdns_fallback_enabled (default on, no operator input required). - input_text.rc_local_mdns_hostname (operator-editable, default 'roamcore' — purely cosmetic for operators who already have a 'roamcore' device on their network). - input_button.rc_local_mdns_retest (operator-facing re-probe). - shell_command.rc_local_mdns_probe (5s timeout via avahi-resolve / getent — never blocks the dashboard). - binary_sensor.rc_local_mdns_resolvable (UNKNOWN until first probe — doesn't pretend the fallback is up). - sensor.rc_local_mdns_resolved_ip + sensor.rc_local_mdns_status (3 plain-English states: reachable / reachable via direct IP / fallback unavailable). - 3 §8 MANDATORY automations: §8.M.1 register hostname on HA startup, §8.M.2 probe every 60s, §8.M.3 fallback tile surfacing on retest (auto-recovery via persistent_notification with the direct-IP hint). NEW pytest rig (32 tests): YAML parses + every required helper present + every §8 automation contract + hostname is operator- editable + status template covers all 4 (enabled × resolvable × ip) combos + status copy has no operator jargon + idempotency (re-parsing produces identical dict) + single shell_command (no duplicate mDNS service) + rc-entity-naming compliance + no secrets / hard-coded IPs leaked + IKEA doc has exactly 5 numbered sections + IKEA doc has operator→vanlifer translation table + IKEA doc has no SUPERSEDED banner. NEW bash smoke (13 assertions): file presence + YAML parse + rc-naming + helpers/automations/templates present + status coverage + no jargon + secrets-leak + idempotency + single shell_command + IKEA doc 5-step shape + §8.M.3 wiring + pytest rig green. NEW IKEA doc docs/setup/local-access-fallback.md: 5 numbered sections (What this is / What you see / What you do / What to do if it goes wrong / Useful links) + operator→vanlifer translation table. Opens with one plain-English sentence a vanlifer would understand. MOD connections/remote-access/connection.yml: +35 lines to add local_mdns_fallback as a separate wizard.setup_paths entry — explicitly NOT one of the four remote-access paths (A/B/C/D); documented as the Gate E safety net that always-on by default. MOD scripts/check.sh: +1 line wiring scripts/checks/local-mdns- fallback-smoke.sh into the core-only chain. User-facing: If Tailscale ever stops working, you can still open your RoamCore dashboard from your phone on the same WiFi as the Hub — at 'roamcore.local', no IP needed. Verification: - bash scripts/check.sh --core-only → exit 0 (GREEN) - bash scripts/checks/local-mdns-fallback-smoke.sh → 13/13 PASS - python3 -m pytest homeassistant/packages/tests/test_local_mdns_fallback.py -v → 32/32 PASS Rollback: revert this commit + the other agents' #122.d.ii commits on the next reset. The slice is purely additive (new package + new files + tiny additive edits to connection.yml and check.sh); no destructive ops, no Proxmox/HA/OpenWrt/vmbr0 touched. GOLDEN.md alignment: - Product principle 1 (novice-first UX): the IKEA doc opens with one plain-English sentence; the dashboard status copy is one of 3 plain-English states (no bash, no entity IDs). - Product principle 2 (mission-critical connectivity): this slice is the safety net that keeps the dashboard reachable when the primary remote-access path (Tailscale) is down. - Engineering principle 1 (customer-facing repo): user-facing doc lives in docs/setup/, NOT memory/ or Cron-handoff/. - Engineering principle 2 (documentation-driven): MkDocs site is the public surface; this slice adds an IKEA doc to the public tree. - Engineering principle 4 (git fast mode): direct-to-main push on subagent/phase6-local-mdns-fallback. - Engineering principle 5 (do not touch vmbr0): no networking change at all — this slice is repo-local code that orchestrates the upstream HA Core integration. - Engineering principle 7 (rc-entity-naming): every entity_id starts with rc_local_mdns_; tested explicitly in the pytest rig. - Anti-patterns avoided: - No secrets committed (tskey- / ts-auth- / hard-coded IPs all asserted absent in pytest + smoke). - No wide PR mixing unrelated changes (additive to the connection.yml + check.sh, not a rewrite). - No 'RoamCore ships a native mDNS engine' tier-claim stubs — the YAML honestly calls itself a tier-b recipe over the upstream HA Core integration. - No SUPERSEDED banner / no Cron-handoff / no internal jargon in the user-facing tree.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wave 9 #122.d.iv — Phase 6 Tailscale wizard sub-slice: mDNS
roamcore.localfallback so local survives Tailscale failure (Gate E verbatim).When Tailscale is down, the operator can still reach their dashboard from their phone on the same WiFi as the Hub — at
roamcore.local, no IP needed.What's new
NEW package
homeassistant/packages/roamcore_local_mdns_fallback.yaml(separate fromroamcore_remote_access_setup.yamlto avoid file-scope conflicts with Wave 9 #119b — Phase 2 canonical vehicle model mapping layer #122.a/b/c/d.i):input_boolean.rc_local_mdns_fallback_enabled(default ON, no operator input)input_text.rc_local_mdns_hostname(defaultroamcore, operator-editable)input_button.rc_local_mdns_retestshell_command.rc_local_mdns_probe(5s timeout viaavahi-resolve/getent)binary_sensor.rc_local_mdns_resolvable(UNKNOWN until first probe — doesn't pretend fallback is up)sensor.rc_local_mdns_resolved_ip+sensor.rc_local_mdns_status(3 plain-English states)rc_local_mdns_register_on_start— registers hostname on HA startuprc_local_mdns_probe_periodic— probes every 60src_local_mdns_fallback_tile_surfacing— surfaces fallback notification on retestNEW pytest rig
homeassistant/packages/tests/test_local_mdns_fallback.py— 32 tests covering YAML parse + every required helper + every §8 automation contract + hostname operator-editable + status template covers all 4 (enabled × resolvable × ip) combos + status copy has no operator jargon + idempotency + single shell_command (no duplicate mDNS service) + rc-entity-naming compliance + no secrets/hard-coded IPs leaked + IKEA doc 5-step shape + IKEA doc translation table + no SUPERSEDED banner.NEW bash smoke
scripts/checks/local-mdns-fallback-smoke.sh— 13 assertions: file presence + YAML parse + rc-naming + helpers/automations/templates present + status coverage + no jargon + secrets-leak + idempotency + IKEA doc 5-step + §8.M.3 wiring + pytest rig green.NEW IKEA doc
docs/setup/local-access-fallback.md— 5 numbered sections (What this is / What you see / What you do / What to do if it goes wrong / Useful links) + operator→vanlifer translation table. Opens with one plain-English sentence.MOD
connections/remote-access/connection.yml— +35 lines:local_mdns_fallbackentry underwizard.setup_pathsas a separate entry from the four remote paths (A/B/C/D), explicitly documented as the Gate E safety net that is always-on by default.MOD
scripts/check.sh— +1 line wiringscripts/checks/local-mdns-fallback-smoke.shinto the core-only chain.Tier discipline
Tier-b recipe over the HA Core
zeroconfintegration (since 2022.x — exposes an mDNS service registration service that this slice consumes) + ashell_commandfallback toavahi-set-hostnamefor Hub installs where the upstreamzeroconfintegration isn't loaded yet. HAOS ships an avahi-based mDNS responder by default; this slice wires the canonical RoamCore hostname (roamcore.local) into the dashboard fallback path.Verification
bash scripts/check.sh --core-only→ exit 0 (GREEN)bash scripts/checks/local-mdns-fallback-smoke.sh→ 13/13 PASSpython3 -m pytest homeassistant/packages/tests/test_local_mdns_fallback.py -v→ 32/32 PASSDoctrine / GOLDEN.md alignment
docs/setup/, NOTmemory/orCron-handoff/.vmbr0): no networking change at all — pure repo-local code that orchestrates the upstreamzeroconfintegration.rc_local_mdns_; tested explicitly.tskey-/ts-auth-/ hard-coded IPs all asserted absent).zeroconfintegration.Rollback
Revert this commit + any follow-up. The slice is purely additive (new package + new files + tiny additive edits to
connection.ymlandcheck.sh); no destructive ops, no Proxmox/HA/OpenWrt/vmbr0touched.