Files
home-network-k3s/agents/task-board.md
T
jakman85andClaude Opus 5.5 250fb54154 docs: bring the specification in line with the accepted implementation
The operator ruled the implementation repo's main (50c8719) the latest
and accepted state. Sync the spec to it.

Accepted changes are reflected: one bare-metal environment, TrueNAS bulk
storage, R2 off-cluster backup, CloudNativePG, single-node VPN gateway
with Cilium fail-closed, inbound WireGuard, per-app auth sidecars,
Renovate, the CI gate as approver, and the pm-agent. New ADR-0017..0025;
ADR-0016 corrected and accepted; R-* IDs unchanged, eight amended.

Where the implementation has simply not met a requirement, the
requirement stands and the shortfall is recorded in docs/16-known-gaps.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-08 22:46:00 -06:00

9.9 KiB
Raw Blame History

Task Board

FROZEN — historical seed. By the operator's ruling of 2026-08-31 this board is not the status surface; the repository is. Nobody edits it, and its contents and the instructions below no longer describe live work. Its T-* IDs stay stable because the implementation repo cites them. Live status: ./conformance/run.sh --status in the implementation repo; dated snapshot: ../docs/16-known-gaps.md.

The live who's-doing-what. Agents claim an item (set Owner + Status) before starting, respect Blocked-by, and mark done only after its automated, reproducible behavior test passes green (definition-of-done.md, ../docs/14-testing-and-conformance.md). Seeded from ../roadmap/phases.md + ../roadmap/workstreams.md.

The specs, ADRs, and roadmap are not editable by agents (R-TEST-06). Every "Prove …" task below is an automated conformance test (co-owned with WS-TEST), not a manual demo.

Status values: todo · in-progress · blocked · review · done Add new items at the bottom of the relevant phase; keep IDs stable.


Phase 0 — Foundations

ID Task WS Serves Blocked-by Owner Status
T-0.1 Create implementation repo structure (platform/apps/catalog/clusters) WS-GITOPS R-GITOPS-02 — — todo
T-0.2 CI: lint + schema validation + build/dry-run gates WS-GITOPS R-GITOPS-01 T-0.1 — todo
T-0.3 Author ServiceDefinition schema + renderer contract WS-GITOPS R-GITOPS-02 T-0.1 — todo
T-0.4 Conformance harness: Chainsaw runner + reproducibility contract + JUnit + coverage report + CI merge gate WS-TEST R-TEST-01/02/03/04 T-0.1 — todo
T-0.5 L0 Kyverno policy gate (default-deny present, no plaintext secrets, schema-valid ServiceDefinitions) WS-TEST R-TEST-01, R-NET-01, R-SEC-01 T-0.4 — todo

Phase 1 — dev/test Cluster Bring-up

ID Task WS Serves Blocked-by Owner Status
T-1.1 OpenTofu libvirt module for 3 node VMs (+ Longhorn data disk) WS-INFRA R-ENV-01 — — todo
T-1.2 cloud-init baseline (users, SSH, sysctls, virt/Longhorn prereqs) WS-INFRA R-ENV-01 T-1.1 — todo
T-1.3 Ansible: k3s HA install, Cilium CNI, disable flannel/kube-proxy/Traefik WS-INFRA R-PLAT-01 T-1.2 — todo
T-1.4 Bootstrap Flux + SOPS age key WS-GITOPS/WS-SEC R-GITOPS-01, R-SEC-01 T-1.3 — todo
T-1.5 Prove node destroy/rebuild from IaC (no data loss) WS-INFRA R-ENV-01, R-STATE-01 T-1.4 — todo

Phase 2 — Platform Core (net/storage/TLS/DNS/ingress)

ID Task WS Serves Blocked-by Owner Status
T-2.1 Longhorn (3-replica StorageClass) + bulk external-mount indirection (media lives off-cluster, backing TBD — OQ-2 resolved) WS-STORAGE R-STATE-02/04 T-1.4 — todo
T-2.2 Default-deny network baseline (per-namespace) + Hubble WS-NET R-NET-01/03 T-1.3 — todo
T-2.3 Render dependencies → CiliumNetworkPolicy from ServiceDefinition WS-NET/WS-GITOPS R-NET-02 T-0.3, T-2.2 — todo
T-2.4p Prereq: operator creates scoped Cloudflare API token (Zone·DNS·Edit, keithjackson.dev); store SOPS-encrypted WS-SEC R-TLS-01, R-SEC-01 — — todo
T-2.4 cert-manager + Let's Encrypt DNS-01 wildcard *.home.keithjackson.dev (via Cloudflare token) WS-SEC R-TLS-01/02/03 T-1.4, T-2.4p — todo
T-2.5 ExternalDNS (Cloudflare token) + Gateway API listeners (VIP via Cilium L2 announcement) + split-horizon (PiHole) WS-NET R-DNS-01/02/03 T-2.4 — todo
T-2.6 Prove: default-deny (DNS-only probe), PVC survives rebuild, trusted cert, auto-DNS WS-NET/STORAGE/SEC R-NET/STATE/TLS/DNS T-2.1..2.5 — todo
T-2.7 Deploy Kyverno in-cluster as admission enforcer (same policies as the CI L0 gate) WS-TEST/WS-SEC R-SEC-02, R-NET-01, R-SEC-01 T-1.4, T-0.5 — todo

Phase 3 — Egress & VPN (single WAN; no multi-WAN — OQ-1)

ID Task WS Serves Blocked-by Owner Status
T-3.0 L3 fault-injection harness — in-cluster Chainsaw Job (CI-triggered, scoped test SA) using script/try/finally (force tunnel down, kill node, inject bad image, trigger restore) WS-TEST R-TEST-05, R-SEC-02 T-0.4 — todo
T-3.1 Egress classes; Cilium Egress Gateway wiring (steer vpn pods → gateway) WS-NET R-NET-04/05 T-2.2 — todo
T-3.2p Prereq: provide PIA username/password + .ovpn; store in Ansible vault on the egress-gateway node(s) (ADR-0015) WS-SEC R-NET-05 — — todo
T-3.2 Node-level PIA/OpenVPN tunnel (host systemd, Ansible, split-tunnel) on egress-gateway node(s) + CiliumEgressGatewayPolicy steering egress-class=vpn + host nftables kill-switch + host PF helper for qBittorrent (ADR-0015) WS-NET R-NET-05/06 T-3.1, T-3.2p — todo
T-3.3 Edge-router multi-WAN split — out of scope (single WAN, dumb SOHO edge; OQ-1) WS-NET R-NET-04 — — won't-do
T-3.4 Prove: VPN IP egress, kill-switch fail-closed (central), egress-class flip via git WS-NET R-NET-05/06/07 T-3.0, T-3.2 — todo

Phase 4 — Observability, Backup/DR & Updates

ID Task WS Serves Blocked-by Owner Status
T-4.1 kube-prometheus-stack + Loki + Alloy + Alertmanager(email) WS-OBS R-OBS-01/02/03 T-2.1 — todo
T-4.2 Platform-health alerts (node/Longhorn/Flux/cert/VPN/backup) WS-OBS R-OBS-04 T-4.1 — todo
T-4.3 Velero + Longhorn off-cluster backup schedule (needs backup-target choice — S3/NFS endpoint) WS-STORAGE R-STATE-03 T-2.1, OQ-BKP — todo
T-4.4 DR drill: restore namespace + volumes from off-cluster backup WS-STORAGE R-STATE-03 T-4.3 — todo
T-4.5 Flux image-automation + Renovate + per-service update policy WS-UPDATE R-UPD-01/02/03 T-0.3, T-4.1 — todo
T-4.6 Prove: auto stable update on schedule, bad-update auto-rollback+alert, pin holds WS-UPDATE R-UPD-* T-4.5 — todo

Phase 5 — IaaS Proof (KubeVirt)

ID Task WS Serves Blocked-by Owner Status
T-5.1 Install KubeVirt + CDI; Longhorn-backed VM disks WS-VM R-PLAT-03 T-2.1, T-2.2 — todo
T-5.2 kind: vm ServiceDefinition path; run one representative VM WS-VM/WS-GITOPS R-PLAT-03/04 T-5.1, T-0.3 — todo
T-5.3 Prove: VM lifecycle via kubectl/virtctl, rebuild w/o data loss, default-deny+egress, guest auto-update WS-VM R-PLAT-03, R-NET-, R-UPD- T-5.2 — todo

Phase 6 — Service Onboarding + C2

ID Task WS Serves Blocked-by Owner Status
T-6.1 Onboard pihole (DNS underpinning) WS-APPS R-DNS-03 T-2.5 — todo
T-6.1a Onboard gitea early (bootstrapping-critical; self-hosts GitOps source + CI/CD) WS-APPS R-STATE-03 T-4.4 — todo
T-6.1b Migrate GitOps source local→Gitea; move CI to Gitea Actions (Kyverno gate + Chainsaw Job trigger; PR merge gate); off-cluster repo mirror WS-GITOPS R-GITOPS-01, R-TEST-03 T-6.1a — todo
T-6.1c Onboard Keycloak (IdP) + PostgreSQL (Longhorn, DR-critical) + oauth2-proxy forward-auth at Gateway; declarative realm/clients/groups; MFA; break-glass path WS-SEC R-IDP-01..06 T-2.5, T-2.6 — todo
T-6.1d Render ServiceDefinition auth block → Keycloak OIDC client / oauth2-proxy protection WS-SEC/WS-GITOPS R-IDP-02/03 T-0.3, T-6.1c — todo
T-6.2 Onboard plex (bulk tier + public exposure) WS-APPS R-STATE-04 T-2.6, T-6.1 — todo
T-6.3 Onboard qbittorrent, jackett (VPN + kill-switch) WS-APPS R-NET-05/06 T-3.4 — todo
T-6.4 Onboard sonarr, radarr (VPN + arr↔downloader allows) WS-APPS R-NET-02/05 T-6.3 — todo
T-6.5 Onboard seerr (allows to arr + plex) WS-APPS R-NET-02 T-6.2, T-6.4 — todo
T-6.6 Onboard nextcloud (DR-critical + backups) WS-APPS R-STATE-03 T-4.4 — todo
T-6.7 Onboard minecraft, unifi, semaphore, kasm WS-APPS app reqs T-2.6 — todo
T-6.8 C2 UI: Homepage root + Grafana + Headlamp + Flux status + auth WS-C2 R-C2-01/02 T-4.2, T-6.* — todo

Phase 7 — Production Readiness (CLOSED until operator opens it)

ID Task WS Serves Blocked-by Owner Status
T-7.1 Bare-metal provisioning checklist (design-only) WS-INFRA R-ENV-03 — — todo
T-7.2 prod overlay (no base edits) + cutover plan WS-INFRA/WS-GITOPS R-ENV-02 Phases 1–6 done — blocked
T-7.3 Full prod DR drill WS-STORAGE R-STATE-03 T-7.2 — blocked

Open questions

OQ Question Blocks Status
OQ-1 WAN count + edge router — ✅ resolved: 1 WAN, dumb SOHO edge; multi-WAN out of scope; VPN + segmentation in-cluster
OQ-2 Bulk-media home — ✅ resolved: media outside cluster, backing TBD later (not blocking)
OQ-3 VPN provider/protocol + egress steering — ✅ resolved: PIA over OpenVPN-UDP (ADR-0013); steering = node-level host tunnel + Cilium Egress Gateway + host nftables kill-switch (ADR-0015, supersedes the in-cluster-Gluetun steering — a Gluetun pod's tun0 can't be steered by Cilium egress gateway)
OQ-4 DNS-01 challenge access — ✅ resolved: scoped Cloudflare API token (Zone·DNS·Edit), SOPS-encrypted; drives cert-manager + ExternalDNS. Operator provides token (T-2.4p)
OQ-BKP Off-cluster DR backup target (S3/NFS endpoint) T-4.3 ⛔ OPEN — needed by Phase 4, not Phase 2