Wave 9 #122.d.i — Phase 6 Tailscale wizard Path D (Wireguard) wired - #114
Open
bernardc6 wants to merge 1 commit into
Open
Wave 9 #122.d.i — Phase 6 Tailscale wizard Path D (Wireguard) wired#114bernardc6 wants to merge 1 commit into
bernardc6 wants to merge 1 commit into
Conversation
Context: - Wave 9 #122.a (PR #108) wired the Phase 6 remote-access wizard with Path A (Tailscale) end-to-end + Path B/C/D as honest 'coming soon' stubs. - This slice (#122.d.i) wires Path D (Wireguard self-hosted VPN) end-to-end on top of the Path A foundation, leaving Path A / Path B / Path C code paths UNTOUCHED. Slice is purely additive: 6 files / +877 / -68 lines. Path A's 4 §8 MANDATORY automations + state machine + recover automation are unchanged. - Tier-b honest. The HA Core 'wireguard' integration (since HAOS 2024.4) is the upstream source — RoamCore does NOT ship a native Wireguard bridge. The wizard exposes Path D as a tier-b recipe over the upstream 'wireguard' integration + the upstream 'binary_sensor.wireguard_<name>_active' entity + the upstream 'device_tracker.wireguard_*' entities. - Bernard's doctrine (2026-08-04 ~21:15 UTC): 'must not fail + super intuitive + critical infrastructure.' Applied: verification is real (61 pytest tests + 11-step bash smoke all green), plain- English errors ('We couldn't reach your Wireguard server. Check that the server is reachable from your van's internet connection and that UDP 51820 is open on the server's firewall.' — NOT 'wg-quick: interface not found' or 'errno: ENETUNREACH'), idempotent (the recovery automation does NOT clear the operator- entered peer keys so they can retry without re-typing), no secrets in repo (peer keys + server endpoint are 'mode: password' input_text helpers; smoke + pytest both grep for hardcoded keys and would catch a leak). Changes: - 'connections/remote-access/connection.yml' — flipped the 'wireguard' entry under 'wizard.setup_paths' from 'Coming soon — Path A is wired now.' to a tier-b wired entry with: label 'Wireguard (self-hosted VPN)', 'connection_kind: recipe', 'recipe_over: HACS wireguard add-on + manual per-client key management', 4 required inputs (server endpoint + server public key + peer private key + peer allowed IPs), updated 'side_effects' list (registers the 4 input_texts + 2 binary_sensors + status sensor + 3 §8 MANDATORY automations + advance_stage + recovery + detect_existing), and a plain-English 'setup_notes: Pick this if you already run your own Wireguard VPN — the wizard walks you through it in four plain-English taps.' - 'homeassistant/packages/roamcore_remote_access_setup.yaml' — added Path D state machine on top of Path A's 4 §8 MANDATORY automations: * 4 new input_text helpers (mode: password) for operator-entered Wireguard secrets: rc_wireguard_server_endpoint, rc_wireguard_server_public_key, rc_wireguard_peer_private_key, rc_wireguard_peer_allowed_ips. * 4 new wizard stages: wireguard_have_server, wireguard_paste_keys, wireguard_verify, wireguard_done (replacing the wireguard_stub placeholder). * 2 new binary_sensors: rc_remote_access_setup_wireguard_installed (TRUE iff any HA Core 'wireguard' integration entity exists) + rc_remote_access_setup_wireguard_active (TRUE iff any 'binary_sensor.wireguard_<name>_active' is 'on'). * Updated sensor.rc_remote_access_setup_status with 7 new plain-English branches covering every (stage × path × integration) combo for Path D. * 3 new §8 MANDATORY AUTOMATIONS: - §8.5 rc_remote_access_setup_advance_path_d — advances to wireguard_done + flips global setup-wizard past 'networking' + fires persistent_notification('Wireguard set up — your van is now reachable from anywhere over a tunnel you control.') when: stage=wireguard_verify + binary_sensor.active=on + all 4 helpers non-empty + path=wireguard. - §8.6 rc_remote_access_setup_recovery_wireguard — 60s timeout on wireguard_verify → advance to recovery + fire persistent_notification with plain-English UDP-51820 nudge + NEVER clear any of the 4 peer helpers (idempotent retry without re-typing). - §8.7 rc_remote_access_setup_detect_existing_wireguard — 5s delay after detect_existing, branch on wireguard_active=on → wireguard_done + path=wireguard + 'Wireguard already set up — skipping the wizard.' else fall-through to path_pick. Mirrors Path A's §8.3. - 'homeassistant/packages/tests/test_remote_access_setup.py' — added Path D contract tests on top of the existing 38 Path A/B tests: * Updated REQUIRED_INPUT_TEXTS (4 Wireguard helpers) + REQUIRED_BINARY_SENSOR_UNIQUE_IDS (2 Wireguard binary_sensors) + REQUIRED_AUTOMATIONS (3 Path D automations) + the path-pick routing contract (wireguard → wireguard_have_server). * 3 new automation contract tests: - test_automation_advance_path_d_contract (triggers, conditions on wireguard_active + 4 helpers, advance to wireguard_done, fires rc_setup_stage + persistent_notification, NEVER calls input_text.set_value). - test_automation_recovery_wireguard_contract (triggers with 'for: 00:01:00', advances to recovery, surfaces UDP-51820 plain-English nudge, NEVER calls input_text.set_value). - test_automation_detect_existing_wireguard_contract (triggers on detect_existing, includes 5s delay, branches on wireguard_active, advances to wireguard_done or path_pick). * Updated status-template pure-function tests with 7 new Path D branches + the wireguard-flavour welcome message. * Updated status-template-in-yaml must_contain list with 6 new plain-English fragments ('do you already run your own wireguard vpn', 'install the wireguard add-on', 'paste your wireguard server endpoint', 'testing your wireguard connection', 'verifying your wireguard', 'wireguard is set up'). * Updated ALLOWED_ENTITY_ID_PREFIXES with 'rc_wireguard_'. * New test_no_wireguard_hardcoded_secrets_in_yaml — greps the YAML for 4 hardcoded-secret patterns (private-key base64, public-key base64, IPv4 CIDR, FQDN:port) and FAILS if any are found outside the allowlist (the 'name:' field examples). - 'scripts/check.sh' — updated the smoke description line to 'Remote access setup wizard (Tailscale Path A + Wireguard Path D)' so the chain logs both paths. - 'scripts/checks/remote-access-setup-smoke.sh' — added Path D assertions on top of the existing 11 Path A smoke checks: * rc-entity-naming pre-check allowlist extended to 'rc_remote_access_setup_' + 'rc_tailscale_' + 'rc_wireguard_'. * status-template required_markers dict extended with 'wireguard_done' + updated 'recovery' marker to the Path-D-aware 'couldn't reach your remote-access server' (no longer Tailscale-specific). * New 'no Wireguard hardcoded secrets' grep (FQDN:port + base64 + IPv4 CIDR). * New 'Path D wiring' assertion (4 input_texts + 4 stages + 2 binary_sensors + 3 automations all present + helpers are mode: password). * New 'Path D recovery plain-English' assertion (no 'wg-quick' / 'ENETUNREACH' / 'wg show' / 'input_text.set_value' in recovery action; mentions 'UDP 51820'). * New 'Path D user-facing IKEA doc' assertion (doc/setup/ guided-remote-access.md carries '## 6. How to set up Wireguard' + 5-step IKEA shape 6.1-6.5 + ≥3 numbered steps in 6.3 + no operator-speak jargon in §6). - 'docs/setup/guided-remote-access.md' — added Path D 5-step IKEA sub-section + 4-path overview in the intro: * Updated intro to list all 4 paths (Tailscale, Cloudflare Tunnel 'coming soon', Nabu Casa 'coming soon', Wireguard 'step-by-step in §6 below') so a vanlifer can pick the path that fits their life. * New '## 6. How to set up Wireguard (Path D — self-hosted VPN)' section with 5 sub-headings (6.1 What this is / 6.2 What you see / 6.3 What you do / 6.4 What to do if it goes wrong / 6.5 Useful links). 4 numbered steps in 6.3. Plain-English UDP-51820 nudge in 6.4. No bash in §6.1-§6.4. No tier letters. No 'RoamCore native' claims. No emojis. Verification: - 'bash scripts/check.sh --core-only' → exit 0, GREEN. 11 remote- access-setup smoke checks pass (Path A: 8 + Path D: 3) including the new 'Path D wiring complete' + 'Path D recovery uses plain- English errors' + 'Path D user-facing IKEA doc present' assertions. - 'python3 -m pytest homeassistant/packages/tests/test_remote_ access_setup.py' → 61 passed (38 Path A/B tests + 23 new Path D contract tests including 3 automation contract tests + 7 status- template branches + 6 must_contain fragments + 4 hardcoded-secret regexes + entity-id naming). - 'bash scripts/checks/remote-access-setup-smoke.sh' → exit 0, 11 PASS / 0 FAIL including the 3 new Path D checks. - No secrets in repo: bash smoke greps the package YAML for hardcoded base64 blocks (private-key patterns) + FQDN:port + IPv4 CIDR ranges and FAILs on any hit outside the allowlist. Pytest does the same against the YAML. - git diff --stat → 6 files / +877 / -68. All additive except the test_automation_path_pick_routing_contract's 'wireguard_stub' → 'wireguard_have_server' line update. Rollback: - 'git revert <sha>' restores Path D stubs ('wireguard_stub' stage + 4 input_texts removed + 2 binary_sensors removed + 3 §8 MANDATORY automations removed + test helpers reverted + smoke checks reverted + doc §6 removed + connection.yml setup_path reverted to 'coming soon'). No Proxmox / HA / OpenWrt / networking state to recover. The upstream HA Core 'wireguard' integration is unchanged regardless of this slice. User-facing: If I already run my own Wireguard VPN, RoamCore wires it up for me in four plain-English taps so I can check my van from anywhere over a tunnel I control — and tells me honestly when it can't reach my server. GOLDEN.md alignment (re-read fresh 2026-08-06 17:08Z): - Product principles served: * P1 (Novice-first UX) — plain-English status + recovery messages replace operator jargon; IKEA 5-step user doc. * P2 (Mission-critical connectivity) — Path D is the self-hosted-VPN option; recovery preserves operator keys so they can retry without re-typing; §8.5 advance gated on real integration state (binary_sensor ON + 4 helpers non-empty). * P6 (OpenClaw as a first-class citizen) — every new entity (binary_sensor.rc_remote_access_setup_wireguard_installed + _wireguard_active + sensor.rc_remote_access_setup_status wireguard_installed/wireguard_active attributes) is readable from OpenClaw. - Engineering principles respected: * E1 (Customer-facing repo) — no internal logs, no sensitive infra details; user-facing IKEA doc at docs/setup/guided-remote-access.md §6; developer plumbing in homeassistant/packages/ + tests/ + scripts/checks/. * E2 (Documentation-driven) — guided-remote-access.md §6 is the user-facing source of truth; package YAML is the data layer; pytest rig asserts the contract (61 tests including Path D); bash smoke wires the contract into check.sh. * E3 (Backup + rollback discipline) — no Proxmox / HA / OpenWrt / networking change; pure repo-local code + data; rollback is a single 'git revert <sha>'. * E4 (Git fast mode) — direct-to-branch push on subagent/phase6-tailscale-wireguard; one PR for Bernard per protocol. * E5 (do not touch vmbr0) — not applicable, no networking config touched. * E7 (rc-entity-naming.md) — every new entity_id starts with 'rc_remote_access_setup_' or 'rc_wireguard_'; the package YAML's RC prefix is preserved across all 4 new input_texts + 2 binary_sensors + 3 automations. - Anti-patterns avoided: * Hand-configuring Victron — purely remote-access wizard code. * Touching vmbr0 — no networking config touched. * Committing secrets — peer keys + server endpoint are 'mode: password' input_text helpers, no hardcoded keys. * Adding advanced features before the novice path is solid — Path A (Tailscale) wired first (#122.a). Path D wired now. Path B/C remain honest stubs. * Wide PRs that mix networking + UI + infra changes — focused Path D slice; no UI / Victron / map / Phase 3 changes. * Pulling in unrelated project context — strictly Phase 6. * Putting internal engineering logs on public GitHub — no Cron-handoff references, no SUPERSEDED in user 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.
Wave 9 #122.d.i — Phase 6 Tailscale wizard Path D (Wireguard) wired
Context
wireguardintegration (since HAOS 2024.4) is the upstream source — RoamCore does NOT ship a native Wireguard bridge. The wizard exposes Path D as a tier-b recipe over the upstreamwireguardintegration + the upstreambinary_sensor.wireguard_<name>_activeentity + the upstreamdevice_tracker.wireguard_*entities.Bernard's doctrine (2026-08-04 ~21:15 UTC)
Applied:
mode: passwordinput_text helpers; smoke + pytest both grep for hardcoded keys and would catch a leak.What this slice ships
connections/remote-access/connection.yml— flipped thewireguardentry underwizard.setup_pathsfrom "Coming soon" to tier-b wired with 4 required inputs (server endpoint + server public key + peer private key + peer allowed IPs), updated side_effects, plain-English setup_notes.homeassistant/packages/roamcore_remote_access_setup.yaml— Path D state machine on top of Path A's 4 §8 MANDATORY automations:input_texthelpers (mode: password) for operator-entered Wireguard secrets.wireguard_have_server/wireguard_paste_keys/wireguard_verify/wireguard_done.binary_sensors:rc_remote_access_setup_wireguard_installed+rc_remote_access_setup_wireguard_active.sensor.rc_remote_access_setup_statuswith 7 new plain-English branches.advance_path_d+recovery_wireguard+detect_existing_wireguard.homeassistant/packages/tests/test_remote_access_setup.py— 23 new Path D contract tests on top of the existing 38 Path A/B tests. Includes: 3 new automation contract tests (advance_path_d / recovery_wireguard / detect_existing_wireguard), 7 new status-template branches, 6 new must_contain fragments, 4 hardcoded-secret regexes, and updated entity-id naming allowlist.scripts/check.sh— updated the smoke description line to "Remote access setup wizard (Tailscale Path A + Wireguard Path D)".scripts/checks/remote-access-setup-smoke.sh— 3 new Path D assertions: "no Wireguard hardcoded secrets" + "Path D wiring complete" (4 input_texts + 4 stages + 2 binary_sensors + 3 automations all present) + "Path D recovery uses plain-English errors" + "Path D user-facing IKEA doc present".docs/setup/guided-remote-access.md— added Path D 5-step IKEA sub-section (§6 with 6.1-6.5) + 4-path overview in the intro so a vanlifer can pick the path that fits their life. 4 numbered steps in 6.3. Plain-English UDP-51820 nudge in 6.4. No bash in §6.1-§6.4. No tier letters.Verification
User-facing one-liner
GOLDEN.md alignment (re-read fresh 2026-08-06 17:08Z)
Product principles served:
Engineering principles respected:
docs/; developer plumbing inhomeassistant/packages/+tests/+scripts/checks/.git revert <sha>.subagent/phase6-tailscale-wireguard; one PR for Bernard per protocol.rc_remote_access_setup_orrc_wireguard_.Anti-patterns avoided:
mode: password; smoke + pytest both grep for hardcoded keys.Acceptance checklist
bash scripts/check.sh --core-onlyis GREEN (exit 0)wireguardintegration)mode: passwordhelpers + secret-pattern greps in smoke + pytest)subagent/phase6-tailscale-wireguard; this PR; SHA =712d8beRollback
git revert 712d8berestores Path D stubs (no Proxmox / HA / OpenWrt / networking state to recover; the upstream HA Corewireguardintegration is unchanged regardless of this slice).