Initial baseline: home platform (k3s + Longhorn) specification repository

Greenfield spec set for a GitOps-driven PaaS+IaaS home platform: vision &
requirements (R-* IDs), architecture, 14 domain specs, 11 ADRs, roadmap
(phases + workstreams), and AI-agent coordination (roles, protocol,
definition-of-done, task board).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-15 22:37:56 -05:00
commit e8c555cfeb
37 files changed
+2830

No files matched your search

+189
View File
@@ -0,0 +1,189 @@
# 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`](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 WANs** with egress selection driven by routing
rules.
- **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).
- **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`](../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`](14-testing-and-conformance.md) and
[ADR-0010](../decisions/adr-0010-conformance-testing.md); the gate checklist lives in
[`agents/definition-of-done.md`](../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 (tracked, not blocking the architecture)
- **OQ-1 (WAN hardware)**: How many physical WAN uplinks exist in prod, and does the edge router do
the multi-WAN policy routing, or is a portion done in-cluster via egress gateways? See
[`03-networking-isolation-and-egress.md`](03-networking-isolation-and-egress.md).
- **OQ-2 (bulk media)**: Final home for the Plex media library — NAS/NFS vs. a dedicated large disk
vs. object storage. See [`04-storage-and-state.md`](04-storage-and-state.md) / ADR-0003.
- **OQ-3 (VPN provider)**: Commercial VPN provider + protocol (WireGuard preferred) and how many
concurrent tunnels/egress IPs are available.
- **OQ-4 (DNS provider API)**: Confirm Cloudflare (or equivalent) manages `keithjackson.dev` with an
API token scoped for ACME DNS-01 and ExternalDNS.