Files
home-network-k3s/docs/00-vision-and-scope.md
T
jakman85andClaude Opus 4.8 2cca9beac7 Switch VPN provider ExpressVPN -> PIA (ADR-0013 supersedes ADR-0012)
Operator turned off ExpressVPN auto-renew and purchased PIA. The single-shared-
gateway model is retained; provider/client/protocol change to PIA via Gluetun
over WireGuard with native port forwarding (qbittorrent-natmap port-sync).
Simpler than ExpressVPN: no custom OpenVPN config, just PIA user/pass
SOPS-encrypted; Gluetun provides the built-in kill-switch.

Updated: ADR-0013 (new) + ADR-0012 superseded + index; docs 00,01,03,07;
task board (T-3.2p/T-3.2, OQ-3).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-15 23:16:33 -05:00

13 KiB
Raw Blame History

00 — Vision & Scope

Vision

Build a home platform that behaves like a small private cloud. An operator declares a service — a container app or a virtual machine — in git, and the platform provisions it, secures it, exposes it under a trusted TLS URL, routes its traffic on the correct WAN, protects its data, updates it automatically, and reports on its health. Onboarding a new service is a pull request against a catalog, not a weekend of manual work.

The platform is delivered in two stages:

  • dev/test on local KVMs — the active build target, used to prove viability.
  • prod on 3 mini-PCs — the eventual home, designed for now but not built on yet.

Personas

  • Operator (primary user): runs the home network; wants to onboard/offboard services with minimal ceremony and zero data loss.
  • Platform (the system): reconciles declared state, enforces isolation and egress policy, renews certificates, updates workloads, and raises alerts.
  • Implementation agents: the AI teams building the platform from this spec.

In scope

  • A k3s-based platform with distributed storage (Longhorn) across 3 nodes.
  • Container workloads (PaaS) and VM workloads (IaaS) through one Kubernetes surface.
  • GitOps delivery, automated updates, trusted TLS, DNS, ingress.
  • Network isolation (default-deny east-west) and multi-WAN egress including VPN routing.
  • Observability with email + dashboard alerting.
  • A command-and-control web UI at the root of home.keithjackson.dev.
  • The initial service catalog (13 services, see 13-service-catalog.md).

Out of scope (for now)

  • Building on production mini-PC hardware (design-only until the roadmap flips it to active).
  • Multi-tenant / multi-operator RBAC beyond a single operator + platform automation.
  • Public multi-user SaaS concerns (billing, per-tenant isolation beyond network policy).
  • Non-keithjackson.dev domains.

The domain & DNS model

  • Public apex *.keithjackson.dev is available and its records resolve to the network's public IP.
  • All platform services live under *.home.keithjackson.dev.
  • Each service is reachable at <service>.home.keithjackson.dev (e.g. plex.home.keithjackson.dev).
  • The root home.keithjackson.dev serves the Command & Control (C2) center UI.

Requirements (stable IDs)

Requirement IDs are stable references used across ADRs, specs, the task board, and PRs. MUST is mandatory; SHOULD is strongly preferred and requires an ADR to deviate.

Platform & API surface — R-PLAT-*

  • R-PLAT-01 — The platform MUST run on k3s across 3 nodes with production-grade HA control plane in prod; dev/test MAY run fewer nodes but MUST exercise the same multi-node topology.
  • R-PLAT-02 — Container workloads MUST be onboarded and managed declaratively via the Kubernetes API, kubectl-class CLI, and YAML.
  • R-PLAT-03 — Virtual-machine workloads MUST be created, managed, and destroyed through the same Kubernetes API/CLI/YAML surface as containers (no separate hypervisor management plane for application VMs).
  • R-PLAT-04 — The platform MUST support create / destroy / rebuild of any workload on demand.

GitOps & delivery — R-GITOPS-*

  • R-GITOPS-01 — All application and platform desired state MUST be defined in git and reconciled automatically (pull-based GitOps).
  • R-GITOPS-02 — Onboarding a new service MUST be expressible as a change to a versioned catalog in git.
  • R-GITOPS-03 — The system MUST detect and correct drift between git and cluster state.

Networking, isolation & egress — R-NET-*

  • R-NET-01 — East-west traffic between services MUST be denied by default; communication is allowed only by explicit, port-level configuration (firewall-like).
  • R-NET-02 — Allow rules MUST be declarative, reviewable in git, and scoped per source → destination → port/protocol.
  • R-NET-03 — Networks MUST be configurable and isolatable (segments/namespaces with enforced boundaries).
  • R-NET-04 — The platform MUST support multiple egress paths selected by routing rules. Per OQ-1 the environment has one physical commercial WAN and no multi-ISP plans, so this is realized as two paths — the local internet path and the in-cluster vpn path — not multi-ISP routing. Physical multi-WAN (multiple ISP uplinks) is out of scope unless a future ADR reopens it.
  • R-NET-05 — A service MUST be able to declare its egress class: internet (standard local network/internet) or vpn (routed through a custom VPN connection). VPN routing MUST be enforced outside the service (a single shared in-cluster gateway), so a service cannot leak by misconfiguration (ADR-0013, OQ-3).
  • R-NET-06 — VPN-class egress MUST enforce a kill-switch: if the VPN tunnel is down, the service MUST NOT leak traffic to the standard internet.
  • R-NET-07 — Egress class MUST be a declarative property of the service, changeable via GitOps without re-architecting the workload.

Storage & state — R-STATE-*

  • R-STATE-01 — Stateful data MUST survive destroy/rebuild of the workload (PaaS and IaaS).
  • R-STATE-02 — Persistent storage MUST be distributed/replicated across the 3 nodes (Longhorn) so a single node loss does not lose data.
  • R-STATE-03 — The platform MUST provide scheduled backups to an off-cluster target and a tested restore path (disaster recovery).
  • R-STATE-04 — Bulk media storage (Plex library) MUST have a capacity strategy distinct from replicated app-config storage (replicating multi-TB media 3× is out of scope; see ADR-0003).

Automated updates — R-UPD-*

  • R-UPD-01 — Services MUST update to the latest stable versions on a schedule.
  • R-UPD-02 — Updates MUST require no human, no AI, and no hand-authored GitOps change to occur. Automation controllers acting on declarative policy are the permitted mechanism.
  • R-UPD-03 — Update policy MUST be per-service configurable (cadence, stability channel, pin/hold, auto-rollback on failed health).

TLS & certificates — R-TLS-*

  • R-TLS-01 — Every externally reachable service MUST present TLS from a credible, trusted, non-self-signed authority.
  • R-TLS-02 — Certificates MUST be automatically issued, renewed, and revoked without manual steps.
  • R-TLS-03 — Certificate issuance MUST work for internal-only services (no requirement to expose a service publicly just to validate a certificate).

DNS & ingress — R-DNS-*

  • R-DNS-01 — Services MUST be reachable at <service>.home.keithjackson.dev.
  • R-DNS-02 — DNS records MUST be managed automatically from declared service intent.
  • R-DNS-03 — Internal clients MUST resolve service names correctly (split-horizon where public and internal answers differ).

Observability & alerting — R-OBS-*

  • R-OBS-01 — Services MUST be monitored (metrics, logs, health).
  • R-OBS-02 — Issues MUST be reported by email.
  • R-OBS-03 — Issues and health MUST be visible on dashboards.
  • R-OBS-04 — The platform MUST alert on its own health (nodes, storage, GitOps reconciliation, certificate expiry, VPN tunnel state, backup success).

Command & control — R-C2-*

  • R-C2-01 — The root home.keithjackson.dev MUST serve a UI that surfaces the services running in the cluster and links to them.
  • R-C2-02 — The C2 UI MUST surface platform health (cluster, storage, GitOps, alerts) and provide controlled operational actions where safe.

Security & secrets — R-SEC-*

  • R-SEC-01 — Secrets MUST NOT be stored in plaintext in git; they MUST be encrypted at rest in the repo and decrypted only in-cluster.
  • R-SEC-02 — The platform MUST follow least-privilege for workload identities and network reach.
  • R-SEC-03 — All the above properties MUST be demonstrable/auditable (an operator can prove isolation, egress path, cert validity, and backup integrity).

Environments — R-ENV-*

  • R-ENV-01 — dev/test MUST be provisioned as local KVMs via IaC: created, baselined, cluster- joined, and managed as code.
  • R-ENV-02 — The same GitOps configuration MUST promote from dev/test to prod with only environment-scoped overrides.
  • R-ENV-03 — prod is a 3× mini-PC bare-metal k3s cluster with local storage; it MUST NOT be an active development surface until the roadmap declares it ready.

Conformance testing & governance — R-TEST-*

  • R-TEST-01 — Every requirement MUST be verified by automated, behavior-based tests (Given/When/Then style) that assert observable system behavior, not implementation internals.
  • R-TEST-02 — Tests MUST be reproducible: deterministic, hermetic (create and tear down their own fixtures), version-pinned, and runnable by a single command locally and in CI against any conforming cluster, producing machine-readable, requirement-tagged results.
  • R-TEST-03 — A conformance suite MUST gate delivery: merges are blocked unless the tests for the touched requirements pass, and phase exits are blocked unless the phase's full suite passes. "Demonstrated" means "the automated test passes," never a manual one-off.
  • R-TEST-04 — Tests MUST be traceable: each test declares the requirement ID(s) it verifies, and a coverage report maps every R-* requirement to its verifying test(s). Uncovered requirements are a gap to close, not an acceptable state.
  • R-TEST-05 — Safety-critical behaviors (default-deny, VPN kill-switch, data-survival on rebuild, DR restore, auto-rollback) MUST be verified by fault-injection behavior tests that prove fail-closed / no-data-loss outcomes, not merely happy-path checks.
  • R-TEST-06 (governance) — AI agents MUST NOT modify the specifications (this docs/ tree, the requirements, or accepted ADRs). Specs are changed only by the human operator/architect. Agents that find a spec wrong, blocking, ambiguous, or missing MUST stop and escalate and MAY draft a proposal, but MUST NOT self-approve or merge a spec/ADR change (see AGENTS.md §2 and §11).

Acceptance philosophy

Each requirement class maps to an automated, reproducible, behavior-based conformance test in dev/test (R-TEST-*). "Done" means the conformance test for the touched requirements passes — a green, reproducible result traced to requirement IDs — never "manifest merged" and never a manual demonstration. The testing approach is specified in docs/14-testing-and-conformance.md and ADR-0010; the gate checklist lives in agents/definition-of-done.md.

Governance: the specifications are human-owned and immutable to agents (R-TEST-06). Agents implement against the spec and prove conformance with tests; they never edit the spec to fit the implementation.

Open questions

Resolved (2026-08-15)

  • OQ-1 (WAN / edge) — RESOLVED: one commercial WAN, no multi-ISP plans; dumb SOHO edge (no VLAN/VPN/services). All segmentation + VPN in-cluster; edge does NAT + port-forward only. Physical multi-WAN out of scope. See 03, 09.

  • OQ-2 (bulk media) — RESOLVED (deferred backing): Plex bulk media lives outside the cluster; the specific backing is TBD later and does not block the core platform. Plex's metadata DB still lives on replicated Longhorn. The off-cluster DR backup target (for app config, Nextcloud, Gitea, etc.) remains to be chosen at Phase 4. See 04.

  • OQ-3 (VPN) — RESOLVED: PIA via Gluetun, cluster-provisioned, single shared in-cluster tunnel over WireGuard (non-TCP), native port forwarding, rules enforced outside the service (ADR-0013, supersedes ADR-0012's ExpressVPN choice). See 03.

  • OQ-4 (TLS/DNS challenge access) — RESOLVED: a scoped Cloudflare API token (Zone·DNS·Edit, keithjackson.dev), SOPS-encrypted, drives cert-manager DNS-01 and ExternalDNS. The static *.keithjackson.dev wildcard covers reachability but not TXT-challenge writes; the token handles issuance + record automation. Operator provides the token once. See 08.

Still open

  • OQ-BKP (off-cluster DR backup target): which S3-compatible endpoint or NFS host stores Velero/Longhorn backups of the irreplaceable tier. Needed by Phase 4, not blocking Phase 2. See 04.