Wave 9 #123.d.v — Phase 7 Gate E (remote access) acceptance test - #126
Open
bernardc6 wants to merge 1 commit into
Open
Wave 9 #123.d.v — Phase 7 Gate E (remote access) acceptance test#126bernardc6 wants to merge 1 commit into
bernardc6 wants to merge 1 commit into
Conversation
Context ======== Phase 7 of the 2026-08-03 directive. This slice delivers the fifth of the six release gates — Gate E (remote access), which proves: Tailscale setup, same PWA local+remote, no IP selection, local survives Tailscale failure Gate E is the "remote access reliability contract" — the guarantee that a vanlifer can reach their dashboard from anywhere, and that their local WiFi connection still works even if the remote one drops — so they never lose access to their van. Mirrors the existing Gate A + Gate B + Gate C + Gate D slice shape (PRs #115, #120, Gate C, Gate D) so future slices land the same way. Branched off `origin/main` (no prior commits). Changes ======= **NEW files (4 files, fully self-contained):** - `scripts/tests/acceptance/gate_e_remote_access.sh` — the canonical bash contract. 13 stages covering: setup wizard reachable from PWA + QR code pairing (canonical tailscale:// format + 5-minute TTL) + guided wizard paths (A Tailscale / B Cloudflare / C Nabu Casa / D Wireguard) + same PWA local+remote (no IP selection) + local mDNS fallback within 5s + round-trip HA → tunnel → phone → tunnel → HA within 10s + plain-English recovery notification + reboot-survives + idempotent + cleanup trap on EXIT + no secrets + rc-entity-naming honored. - `scripts/tests/acceptance/test_gate_e_remote_access.py` — pytest rig with INLINE MagicMock fixtures (DOES NOT depend on `scripts/tests/acceptance/conftest.py` — Gate A/B/C/D's conftest is on unmerged PR branches and the cron merges those separately). 28 pytest tests covering the 13 stages + idempotency + plain-English error copy + rc-entity-naming + secrets-leak grep + QR code format check + IKEA doc shape + the 6 inline mock fixtures (mock_tailscale_endpoint, mock_tailscale_auth_key, mock_tunnel_response, mock_mdns_fallback, mock_round_trip_nonce, mock_pwa_manifest_response) + vendor-neutral phrasing + no Wave/tier/PR/cron jargon + no bash commands in user-facing §1-§4 + rig-is-self-contained (no conftest dependency). - `scripts/checks/gate-e-remote-access-smoke.sh` — developer- convenience smoke check. 11 bash assertions: pytest rig importable + 13 stages present + 4 wizard paths (A/B/C/D) + QR code format check + plain-English error copy + no bash in user-facing doc §1-§4 + no vendor tokens + rc-entity-naming + IKEA doc shape + no Wave/tier/PR/cron jargon + idempotent re-run. - `.github/workflows/acceptance-gate-e.yml` — GitHub Actions workflow (runs on push to main + PR + weekly Monday 06:00 UTC + manual dispatch). Mirrors the Gate A + Gate B + Gate C + Gate D workflow shape. **User-facing IKEA 5-step runbook:** - `docs/runbooks/automated-acceptance-tests-gate-e.md` — IKEA 5-step (What this is / What you see / What you do / What to do if it goes wrong / Useful links). Vendor-neutral phrasing ("your phone" / "your van" / "remote access" / "local WiFi" — NO "Tailscale" / "Wireguard" / "Cloudflare" / "Nabu Casa" / "Hub" in §1-§4). No bash commands in §1-§4. No file paths, function names, PR numbers, branch names, "Wave N" or "tier-X" labels, "the cron" or "the sub-agent" references. Includes a operator→vanlifer translation table at the bottom so users can decode internal jargon they might encounter in test logs. **Umbrella runbook (additive):** - `docs/runbooks/automated-acceptance-tests.md` — the umbrella runbook that points to each gate-specific runbook. Includes +1 section "### Gate E — remote access" appended at the end of the existing umbrella runbook (one paragraph plain English, vendor-neutral). (Other gates' sections will be added by their respective PRs.) **scripts/check.sh (+1 run_if_present block):** - `scripts/check.sh` — adds the new Gate E smoke check to the core-only chain. Pattern mirrors the existing entries (does NOT touch any other section). Verification ============ - [x] code change is minimal + additive (no rewrite of unrelated files) - [x] `bash scripts/check.sh --core-only` is GREEN (exit 0) - [x] standalone `bash scripts/checks/gate-e-remote-access-smoke.sh` is GREEN (exit 0, 11/11 assertions pass) - [x] `bash scripts/tests/acceptance/gate_e_remote_access.sh --mock` exits 0 with plain-English "Gate E mocked on this host" message and is parseable for the 13-stage structure - [x] `python3 -m pytest scripts/tests/acceptance/test_gate_e_remote_access.py -v` is GREEN — 28 passed in ~3.5s - [x] user-facing `docs/runbooks/automated-acceptance-tests-gate-e.md` is IKEA 5-step with operator→vanlifer table at the bottom; vendor-neutral phrasing (no "Tailscale" / "Wireguard" / "Cloudflare" / "Nabu Casa" / "Hub" in §1-§4) - [x] `docs/runbooks/automated-acceptance-tests.md` has the new Gate E section appended (additive only, no rewrites of existing sections) - [x] no secrets in repo (grep -E 'token|api_key|password|secret|tskey-' returns no hardcoded secret-shaped strings in any of the new files; mode: password on input_text only) - [x] anti-slop self-check pre-flight: no "RoamCore native" claims, no tier letters in user copy, no bash commands in user §1-§4, no operator-speak jargon, vendor-neutral phrasing Rollback ======== ```bash git revert <sha> -- .github/workflows/acceptance-gate-e.yml \ scripts/tests/acceptance/gate_e_remote_access.sh \ scripts/tests/acceptance/test_gate_e_remote_access.py \ scripts/checks/gate-e-remote-access-smoke.sh \ docs/runbooks/automated-acceptance-tests-gate-e.md \ docs/runbooks/automated-acceptance-tests.md \ scripts/check.sh ``` The slice is fully additive — rollback removes only the new files + the run_if_present line in check.sh + the Gate E section in the umbrella runbook. No migrations to undo; no external state to clean up (the bash test caches mock fixtures at `${ROAMCORE_GATE_E_CACHE:-.cache/gate-e}`, which is gitignored). GOLDEN.md alignment =================== **Product principles served:** - **P2 (Mission-critical connectivity):** Gate E IS the remote-access reliability contract — LTE primary + Starlink failover + remote access; network failures must not lose data or lock the user out. From GOLDEN.md: "Mission-critical connectivity — LTE primary, Starlink failover, Tailscale-like remote access. Network failures must not lose data or lock the user out." - **P1 (Novice-first UX):** same PWA local+remote, no IP selection required from the user, vendor-neutral plain-English errors. From GOLDEN.md: "Novice-first UX — Apple-grade onboarding. Power users get an 'Advanced mode.' Fail-softly UI everywhere." **Engineering principles respected:** - **E1 (Customer-facing repo):** User-facing IKEA doc lands at `docs/runbooks/automated-acceptance-tests-gate-e.md` (correct location, in `docs/`). Developer plumbing lives in `scripts/tests/acceptance/` + `scripts/checks/` (internal locations). NO SUPERSEDED banners in user tree. - **E2 (Documentation-driven):** Each gate ships with a user-facing IKEA doc + an operator-facing runbook (the smoke check's plain-English output is the operator surface). - **E3 (Backup + rollback discipline):** Stage 5 of Gate E ("local survives remote-access failure") IS the rollback story — the local mDNS fallback is the rollback path when remote access fails. Acceptance test only; no Proxmox / HA / OpenWrt / vmbr0 changes. - **E4 (Git fast mode):** Direct-to-main push on `subagent/phase7-gate-e-acceptance`; open PR via `gh pr create`. - **E7 (Naming follows rc-entity-naming.md):** Re-read fresh — every canonical entity id starts with `rc_remote_access_*` prefix (Stage 13 grep asserts this; smoke check assertion 8 verifies the regex). No vendor tokens in any entity id. **Anti-patterns explicitly avoided:** - ❌ Touching `vmbr0` (no networking config changes — Gate E is an acceptance test only, the bash script uses canned mock data) - ❌ Committing secrets or auth keys (mode: password on input_text only; secrets-leak grep in Stage 12 + smoke check assertion 9) - ❌ Wide PRs that mix networking + UI + infra (acceptance test only, no Tailscale config changes — those live on the Phase 6 PRs) - ❌ Pulling in unrelated project context (RoamCore-only) - ❌ Putting internal engineering logs on the public GitHub (IKEA- style runbook; vendor-neutral phrasing; no "the cron" / "the sub-agent" / Wave labels / tier labels in user copy) User-facing =========== Verifies, automatically, that you can reach your dashboard from anywhere — and that your local connection still works even if the remote one drops — so you never lose access to your van. Reviewer: @bernardc6 Reference: - `/home/bernard/clawd/RoamCore/GOLDEN.md` (constitution) - `/home/bernard/.openclaw/workspace/memory/roamcore/2026-08-03-directive.md` (Phase 7 / Gate E section) - PR #115 (Gate A foundation) + PR #120 (Gate B connection flow) + the Gate C + Gate D PRs for reference shape
|
|
||
| from __future__ import annotations | ||
|
|
||
| import hashlib |
| import pytest | ||
|
|
||
| try: | ||
| import yaml |
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 #123.d.v — Phase 7 Gate E (remote access) acceptance test
Phase 7 of the 2026-08-03 directive. This slice delivers the fifth of the six release gates — Gate E (remote access), which proves:
Gate E is the "remote access reliability contract" — the guarantee that a vanlifer can reach their dashboard from anywhere, and that their local WiFi connection still works even if the remote one drops — so they never lose access to their van.
Scope (tight — these files ONLY)
scripts/tests/acceptance/gate_e_remote_access.sh— 13-stage bash contract (561 LOC)scripts/tests/acceptance/test_gate_e_remote_access.py— pytest rig with INLINE fixtures (28 tests, 767 LOC; DOES NOT depend on conftest.py)scripts/checks/gate-e-remote-access-smoke.sh— 11 bash assertions (253 LOC).github/workflows/acceptance-gate-e.yml— GitHub Actions workflow (94 LOC)docs/runbooks/automated-acceptance-tests-gate-e.md— IKEA 5-step vanlifer-facing runbook (87 LOC)docs/runbooks/automated-acceptance-tests.md— umbrella runbook with### Gate E — remote accesssection appended (70 LOC)scripts/check.sh— +1run_if_presentblock for the new smoke check (+8 lines)Acceptance checklist
bash scripts/check.sh --core-onlyis GREEN (exit 0)bash scripts/checks/gate-e-remote-access-smoke.shis GREEN (exit 0, 11/11 assertions pass)bash scripts/tests/acceptance/gate_e_remote_access.sh --mockexits 0 with plain-English "Gate E mocked on this host" message and is parseable for the 13-stage structurepython3 -m pytest scripts/tests/acceptance/test_gate_e_remote_access.py -vis GREEN — 28 passed in ~3.5sdocs/runbooks/automated-acceptance-tests-gate-e.mdis IKEA 5-step with operator→vanlifer table at the bottom; vendor-neutral phrasing (no "Tailscale" / "Wireguard" / "Cloudflare" / "Nabu Casa" / "Hub" in §1-§4)docs/runbooks/automated-acceptance-tests.mdhas the new Gate E section appended (additive only, no rewrites of existing sections)subagent/phase7-gate-e-acceptance; PR openedbash scripts/check.sh --core-onlyGREENTier discipline
Per GOLDEN.md: tier-c — community test recipe over the test rig. The test infrastructure is upstream pytest + GitHub Actions (the off-the-shelf test plumbing), not a RoamCore-native test engine.
Self-contained slice
This slice is fully self-contained — its pytest rig is runnable WITHOUT
scripts/tests/acceptance/conftest.py(which is on the unmerged Gate A PR #115). All 6 inline MagicMock fixtures (mock_tailscale_endpoint,mock_tailscale_auth_key,mock_tunnel_response,mock_mdns_fallback,mock_round_trip_nonce,mock_pwa_manifest_response) live insidetest_gate_e_remote_access.pyso the rig can ship independently.Idempotency proof
Both runs exit 0 with the same plain-English summary.
Rollback plan
The slice is fully additive — rollback removes only the new files + the
run_if_presentline incheck.sh+ the Gate E section in the umbrella runbook. No migrations to undo; no external state to clean up.GOLDEN.md alignment (full quote in commit body)
Product principles served:
Engineering principles respected:
docs/runbooks/automated-acceptance-tests-gate-e.md(correct location). Developer plumbing lives inscripts/tests/acceptance/+scripts/checks/.subagent/phase7-gate-e-acceptance; open PR viagh pr create.rc_remote_access_*prefix.Anti-patterns explicitly avoided:
vmbr0(no networking config changes — Gate E is an acceptance test only)User-facing one-liner
Reviewer
@bernardc6
Reference
/home/bernard/clawd/RoamCore/GOLDEN.md(constitution)/home/bernard/.openclaw/workspace/memory/roamcore/2026-08-03-directive.md(Phase 7 / Gate E section)