The ontology's stated intent was "http when it has a url, else a process check", but the implementation emitted BOTH for every url-service — so ~17 fronted services carried a redundant process check that, under worst-of aggregation, let a fragile supplementary probe (wrong unit name, unreachable host, no guest agent) veto two healthy http checks and report the service "down" while it was up (authentik, zimaos, house, matrix, ...). buildKind now emits a process check only for services WITHOUT a url, or when an explicit probe_unit opts into binary-level depth. http is the canonical service-liveness probe (tests the real endpoint through the TLS terminator); the redundant process checks were removed.
644 lines
44 KiB
YAML
644 lines
44 KiB
YAML
# Oikos inventory seed — entity instances + relationships.
|
|
#
|
|
# Translated from the legacy /inventory.yaml (2026-07-07). Bootstraps the
|
|
# entities/relationships tables (migration 002); after ingest the DB is
|
|
# authoritative and this file is regenerated by `GET /api/v1/export`.
|
|
#
|
|
# Slug conventions: <prefix>:<name> —
|
|
# host: (proxmox-host, standalone-server) · ws: (workstation) · lxc: · vm:
|
|
# service: · ingress: · repo: (config-repo) · pool: · volume: · mesh: · lan:
|
|
# zone: (dns-zone) · idp: · person: · agent: · cluster: · backup:
|
|
#
|
|
# `state:` omitted = the type's lifecycle default (active).
|
|
# Mount details (mount_point) are attributes on `mounts` edges.
|
|
# Known thin spots are marked # THIN: backfill later.
|
|
|
|
version: 1
|
|
|
|
entities:
|
|
|
|
# ─── Sites, networks ───────────────────────────────────────────────
|
|
- {slug: "site:home", type: site, name: home}
|
|
- {slug: "site:ionos-dc", type: site, name: ionos-dc,
|
|
attributes: {address: IONOS datacenter (VPS)}}
|
|
- slug: "lan:lab"
|
|
type: lan
|
|
name: lab
|
|
attributes: {subnet: 192.168.8.0/24}
|
|
- slug: "lan:household"
|
|
type: lan
|
|
name: household
|
|
attributes: {subnet: 192.168.178.0/24} # Fritz LAN; static route to lab subnet
|
|
- slug: "mesh:netbird"
|
|
type: mesh
|
|
name: netbird
|
|
attributes:
|
|
provider: netbird
|
|
subnet: 100.122.0.0/16
|
|
domain: netbird.selfhosted
|
|
- slug: "mesh:tailscale"
|
|
type: mesh
|
|
name: tailscale
|
|
state: deprecated # migration to netbird in progress (infrastructure/mesh.md)
|
|
attributes: {provider: tailscale}
|
|
- slug: "zone:hubris.network"
|
|
type: dns-zone
|
|
name: hubris.network
|
|
attributes: {zone: hubris.network, authority: "Technitium (LXC 107), split-horizon"}
|
|
- slug: "zone:netbird.selfhosted"
|
|
type: dns-zone
|
|
name: netbird.selfhosted
|
|
attributes: {zone: netbird.selfhosted, authority: netbird-mgmt}
|
|
|
|
# ─── Machines ──────────────────────────────────────────────────────
|
|
- slug: "cluster:homelab"
|
|
type: cluster
|
|
name: Homelab
|
|
attributes: {quorum: "2-node, no QDevice tiebreaker yet"}
|
|
- slug: "host:hubris"
|
|
type: proxmox-host
|
|
name: hubris
|
|
attributes:
|
|
os: linux
|
|
lan_ip: 192.168.8.77
|
|
mesh: {netbird: {ip: 100.122.38.109, fqdn: proxmox-server.netbird.selfhosted}}
|
|
ssh: {port: 22, netbird_port: 22022, user: root}
|
|
age_pubkey: age1xkklkvnk5z0fsnh6cfgv70hy9ksfy8rdprwerzw4yk3p4p7cxcqs2yvpz6
|
|
- slug: "host:strong"
|
|
type: proxmox-host
|
|
name: strong
|
|
attributes:
|
|
os: linux
|
|
lan_ip: 192.168.178.181
|
|
ssh: {user: root}
|
|
age_pubkey: age1rtwvdct6avjkr3cyxv3vue3vqx4d524fjfr3vk7xrnvyrylnry5sm54sn4
|
|
note: >-
|
|
PVE 9.2.3 since 2026-07-01 (formerly workstation ludo-mini). Joined
|
|
Homelab cluster same day. Not yet netbird-enrolled — reachable via
|
|
household LAN / Fritz static route only.
|
|
- slug: "host:netbird-vps"
|
|
type: standalone-server
|
|
name: netbird-vps
|
|
attributes:
|
|
os: linux
|
|
provider: ionos
|
|
control_level: partial # managed via ssh from hubris; not a homelab client
|
|
public_ipv4: 82.165.190.79
|
|
mesh: {netbird: {ip: 100.122.165.149, fqdn: netbird-ionos.netbird.selfhosted}}
|
|
ssh: {user: root}
|
|
note: netbird mgmt+signal+relay+dashboard + coturn; sshd locked to hubris pubkey
|
|
- slug: "ws:mac-mini"
|
|
type: workstation
|
|
name: mac-mini
|
|
attributes:
|
|
os: macos
|
|
user: dtoro
|
|
lan_ip: 192.168.178.182
|
|
mesh: {netbird: {fqdn: mac-mini-234-17.netbird.selfhosted}}
|
|
age_pubkey: age169104ee1a9e1577d493820830560197f0adf56bf8f1c369d57c152c03f9437ae
|
|
note: only macOS in fleet; Oikos Docker host. Enrolled 2026-07-08.
|
|
enrolled_at: "2026-07-08T09:49:03Z"
|
|
mesh_ip: 192.168.178.182
|
|
hostname: mac-mini
|
|
- slug: "ws:republic-laptop"
|
|
type: workstation
|
|
name: republic-laptop
|
|
attributes:
|
|
os: linux
|
|
user: dtoro
|
|
mesh: {netbird: {fqdn: republic-laptop.netbird.selfhosted}}
|
|
|
|
# ─── LXCs ──────────────────────────────────────────────────────────
|
|
- {slug: "lxc:jellyfin", type: lxc, name: jellyfin,
|
|
attributes: {pve_id: 101, role: media-server, lan_ip: 192.168.8.246,
|
|
public_host: media.hubris.network,
|
|
note: "VAAPI transcode via Radeon 680M passthrough; migrated hubris→strong 2026-07-05"}}
|
|
- {slug: "lxc:nfs-export", type: lxc, name: nfs-export,
|
|
attributes: {pve_id: 102, role: storage-export, lan_ip: 192.168.8.200}}
|
|
- {slug: "lxc:paperless", type: lxc, name: paperless,
|
|
attributes: {pve_id: 103, role: document-archive, lan_ip: 192.168.8.130,
|
|
public_host: paperless.hubris.network}}
|
|
- {slug: "lxc:gitea", type: lxc, name: gitea,
|
|
attributes: {pve_id: 104, role: git-server, lan_ip: 192.168.8.121,
|
|
public_host: git.hubris.network,
|
|
note: "bare repos at /mnt/library/repos/dtoro/*.git"}}
|
|
- {slug: "lxc:apps", type: lxc, name: apps,
|
|
attributes: {pve_id: 105, role: docker-apps, lan_ip: 192.168.8.205,
|
|
age_pubkey: age1duyl8mkpgu80uv934dy8q7enqjms6yvdz264hme8uryuxmvvqesq6rusq0,
|
|
note: "legacy Oikos host; fallback during cutover (plan A6)"}}
|
|
- {slug: "lxc:auth-outpost", type: lxc, name: auth-outpost,
|
|
attributes: {pve_id: 106, role: authentik-gateway, lan_ip: 192.168.8.6}}
|
|
- {slug: "lxc:dns", type: lxc, name: dns,
|
|
attributes: {pve_id: 107, role: dns-server, lan_ip: 192.168.8.2}}
|
|
- {slug: "lxc:nextcloud", type: lxc, name: nextcloud,
|
|
attributes: {pve_id: 114, role: file-sync, lan_ip: 192.168.8.224,
|
|
public_host: cloud.hubris.network}}
|
|
- {slug: "lxc:elementsynapse", type: lxc, name: elementsynapse,
|
|
attributes: {pve_id: 118, role: matrix-server, lan_ip: 192.168.8.242,
|
|
public_host: matrix.hubris.network,
|
|
note: "migrated hubris→strong 2026-07-05"}}
|
|
- {slug: "lxc:sophia", type: lxc, name: sophia,
|
|
attributes: {pve_id: 119, role: workshop, lan_ip: 192.168.8.109}}
|
|
- {slug: "lxc:mule-images", type: lxc, name: mule-images,
|
|
attributes: {pve_id: 120, role: photo-management, lan_ip: 192.168.8.136,
|
|
public_host: photos.hubris.network}}
|
|
- {slug: "lxc:caddy", type: lxc, name: caddy,
|
|
attributes: {pve_id: 121, role: reverse-proxy, lan_ip: 192.168.8.175,
|
|
note: "terminates all *.hubris.network; /etc/caddy is a checkout of dtoro/caddy-conf"}}
|
|
- {slug: "lxc:arriman", type: lxc, name: arriman,
|
|
attributes: {pve_id: 122, role: arr-stack, lan_ip: 192.168.8.245,
|
|
public_hosts: [jellyseerr.hubris.network, qbit.hubris.network, sab.hubris.network],
|
|
note: "homarr/radarr/sonarr/lidarr/sab/qbit/bazarr/flaresolverr/prowlarr/jellyseerr; migrated to strong 2026-07-05"}}
|
|
- {slug: "lxc:trmnl", type: lxc, name: trmnl,
|
|
attributes: {pve_id: 128, role: trmnl-middleware, lan_ip: 192.168.8.211,
|
|
public_host: trmnl.hubris.network,
|
|
note: "not yet mesh/SOPS-enrolled"}}
|
|
- {slug: "lxc:house", type: lxc, name: house,
|
|
attributes: {pve_id: 129, role: family-planner, lan_ip: 192.168.8.244,
|
|
public_host: house.hubris.network,
|
|
age_pubkey: age1s07zs83ehtlg8jtwvr75ltc3c4cdlemfwjuxrwjtwkqxkl9tpggsyrzn2h,
|
|
note: "Yuvomi + WebDAV bridge to paperless; migrated to strong 2026-07-05"}}
|
|
- {slug: "lxc:grimmory", type: lxc, name: grimmory,
|
|
attributes: {pve_id: 130, role: book-library, lan_ip: 192.168.8.247,
|
|
public_host: books.hubris.network,
|
|
age_pubkey: age1uellsemnjrzgfg9fxw4jefpy05laxzggwnwhh6ny3wl7alyp6v8q0muxet}}
|
|
- {slug: "lxc:teddycloud", type: lxc, name: teddycloud,
|
|
attributes: {pve_id: 131, role: teddycloud, lan_ip: 192.168.8.150,
|
|
public_host: teddy.hubris.network,
|
|
note: "drift-caught 2026-07-06; no forward-auth gate on route; not a homelab client"}}
|
|
- {slug: "lxc:rclone", type: lxc, name: rclone,
|
|
attributes: {pve_id: 132, role: backup,
|
|
mesh: {netbird: {fqdn: rclone.netbird.selfhosted}},
|
|
age_pubkey: age1pwtdws2thdh7vzp2dzttl3zxgcs2tgpcsjsqgw3q04nyml4kvuqq467u4x}}
|
|
# verified live on hubris 2026-07-07 (pct list via MCP)
|
|
- {slug: "lxc:seanime", type: lxc, name: seanime,
|
|
attributes: {pve_id: 133, role: anime-media-server, lan_ip: 192.168.8.248,
|
|
public_host: seanime.hubris.network,
|
|
note: "systemd service at /opt/seanime; uses qbittorrent on arriman"}}
|
|
- {slug: "lxc:romm", type: lxc, name: romm,
|
|
attributes: {pve_id: 134, role: rom-manager, lan_ip: 192.168.8.249,
|
|
public_host: roms.hubris.network,
|
|
note: "docker compose + MariaDB sidecar at /opt/romm"}}
|
|
|
|
# ─── VMs ───────────────────────────────────────────────────────────
|
|
- {slug: "vm:zimaos", type: vm, name: zimaos,
|
|
attributes: {pve_id: 100, role: nas-frontend-eval, lan_ip: 192.168.8.195,
|
|
public_host: zimaos.hubris.network}}
|
|
- {slug: "vm:haos", type: vm, name: haos,
|
|
attributes: {pve_id: 108, role: home-automation, lan_ip: 192.168.8.101}}
|
|
|
|
# ─── Storage ───────────────────────────────────────────────────────
|
|
- {slug: "pool:local-lvm-hubris", type: storage-pool, name: local-lvm (hubris),
|
|
attributes: {type: lvm}}
|
|
- {slug: "pool:library-hubris", type: storage-pool, name: library (hubris),
|
|
attributes: {type: lvmthin, capacity_gb: 3700}}
|
|
# 2nd Samsung 990 EVO Plus NVMe; backs /mnt/library ext4 via
|
|
# /dev/mapper/library-library (knowledge/wiki/hosts/hubris.md)
|
|
- {slug: "pool:ludo-lvm", type: storage-pool, name: ludo-lvm (strong),
|
|
attributes: {type: lvm}}
|
|
- {slug: "volume:library", type: volume, name: library,
|
|
attributes: {path: /mnt/library, size_gb: 3700}}
|
|
- {slug: "volume:media-local", type: volume, name: media-local,
|
|
attributes: {path: /mnt/media_local}}
|
|
- {slug: "backup:proton-drive", type: backup-target, name: proton-drive,
|
|
attributes: {provider: proton, encrypted: true,
|
|
path: /mnt/backup,
|
|
note: "rclone stages here before pushing to Proton; freshness is checked on lxc:rclone via the backs-up-to edge"}}
|
|
# The pre-deploy pg_dump written by scripts/deploy.sh on every push to main.
|
|
# It was the lab's only untracked backup: its failure path is `|| echo
|
|
# WARNING` inside the deploy script, so a broken dump was invisible until a
|
|
# rollback needed it.
|
|
- {slug: "backup:oikos-predeploy", type: backup-target, name: oikos-predeploy,
|
|
attributes: {provider: local, encrypted: false,
|
|
path: /opt/oikos/backups,
|
|
note: "pre-deploy pg_dump on the mac-mini; one per deployed SHA"}}
|
|
|
|
# ─── Services ──────────────────────────────────────────────────────
|
|
- {slug: "service:proxmox-ui", type: service, name: proxmox_ui,
|
|
attributes: {url: "https://proxmox.hubris.network", port: 8006,
|
|
doc_page: knowledge/wiki/hosts/hubris.md,
|
|
risk_notes: "hypervisor UI — changes affect every guest on the node"}}
|
|
- {slug: "service:gitea", type: service, name: gitea,
|
|
attributes: {url: "https://git.hubris.network", port: 3000,
|
|
doc_page: knowledge/wiki/containers/104-gitea.md,
|
|
risk_notes: "hosts all config repos + deploy webhooks; outage blocks auto-deploy and sync"}}
|
|
- {slug: "service:caddy", type: service, name: caddy,
|
|
attributes: {doc_page: knowledge/wiki/containers/121-caddy.md,
|
|
risk_notes: "wide blast radius — every *.hubris.network route rides on it"}}
|
|
- {slug: "service:authentik", type: service, name: authentik,
|
|
attributes: {url: "https://auth.hubris.network",
|
|
doc_page: knowledge/wiki/containers/106-auth-outpost.md,
|
|
note: "core on VPS since 2026-05-31; LAN outpost = auth-outpost (LXC 106) 192.168.8.6:9000",
|
|
risk_notes: "SSO provider — outage locks login to OIDC/forward-auth services"}}
|
|
- {slug: "service:dns", type: service, name: dns,
|
|
attributes: {doc_page: knowledge/wiki/containers/107-dns.md,
|
|
risk_notes: "LAN-wide resolver — misconfig breaks name resolution for every client"}}
|
|
- {slug: "service:jellyfin", type: service, name: jellyfin,
|
|
attributes: {url: "https://media.hubris.network",
|
|
doc_page: knowledge/wiki/containers/101-jellyfin.md,
|
|
risk_notes: "native Authentik OIDC (no forward-auth gate); VAAPI depends on GPU passthrough on strong"}}
|
|
- {slug: "service:nextcloud", type: service, name: nextcloud,
|
|
attributes: {url: "https://cloud.hubris.network",
|
|
doc_page: knowledge/wiki/containers/114-nextcloud.md}}
|
|
- {slug: "service:paperless", type: service, name: paperless,
|
|
attributes: {url: "https://paperless.hubris.network",
|
|
doc_page: knowledge/wiki/containers/103-paperless.md,
|
|
risk_notes: "document archive — data irreplaceable; DB operations are destructive-class"}}
|
|
- {slug: "service:matrix", type: service, name: matrix,
|
|
attributes: {url: "https://matrix.hubris.network",
|
|
doc_page: knowledge/wiki/containers/118-elementsynapse.md,
|
|
risk_notes: "alert/approval channel for Oikos — outage silences agent escalation"}}
|
|
- {slug: "service:photos", type: service, name: photos,
|
|
attributes: {url: "https://photos.hubris.network",
|
|
doc_page: knowledge/wiki/containers/120-mule-images.md}}
|
|
- {slug: "service:arr-stack", type: service, name: arr_stack,
|
|
attributes: {doc_page: knowledge/wiki/containers/122-arriman.md,
|
|
note: "jellyseerr / qbit / sab on docker compose"}}
|
|
- {slug: "service:artifacto", type: service, name: artifacto,
|
|
attributes: {url: "https://artifacto.hubris.network",
|
|
doc_page: knowledge/wiki/containers/105-apps.md}}
|
|
- {slug: "service:trmnl", type: service, name: trmnl,
|
|
attributes: {url: "https://trmnl.hubris.network",
|
|
doc_page: knowledge/wiki/containers/128-trmnl.md,
|
|
note: "TRMNL e-ink plugin middleware (polled by TRMNL cloud)"}}
|
|
- {slug: "service:zimaos", type: service, name: zimaos,
|
|
attributes: {url: "https://zimaos.hubris.network",
|
|
doc_page: knowledge/wiki/vms/100-zimaos.md}}
|
|
- {slug: "service:haos", type: service, name: haos,
|
|
attributes: {doc_page: knowledge/wiki/vms/108-haos.md}}
|
|
- {slug: "service:teddycloud", type: service, name: teddycloud,
|
|
attributes: {url: "https://teddy.hubris.network",
|
|
doc_page: knowledge/wiki/containers/131-teddycloud.md,
|
|
risk_notes: "no forward-auth gate — reachable by anyone on LAN/mesh"}}
|
|
# The Go control plane itself: api/scheduler/notifier/web on the mac-mini,
|
|
# and what mcp.hubris.network fronts since the cutover. It existed in the
|
|
# database (created outside the seed) but was never declared here, so a
|
|
# fresh seed could not resolve the routes-to edge below.
|
|
- {slug: "service:oikos", type: service, name: oikos,
|
|
attributes: {url: "https://oikos.hubris.network",
|
|
host: "ws:mac-mini",
|
|
ports: {api: 8090, web: 8091, nomos_gateway: 8092},
|
|
note: "homelab automation platform — api/scheduler/notifier/web on mac-mini docker compose (project name oikos)"}}
|
|
- {slug: "service:homelab-mcp", type: service, name: homelab_mcp,
|
|
attributes: {port: 9810, systemd_unit: homelab-mcp,
|
|
endpoint: "https://mcp.hubris.network/mcp",
|
|
doc_page: knowledge/wiki/infrastructure/homelab-context.md,
|
|
risk_notes: "agents' primary read surface — outage degrades every agent to grepping the clone"}}
|
|
- {slug: "service:secrets-issuance", type: service, name: secrets_issuance,
|
|
attributes: {port: 9820, systemd_unit: secrets-issuance,
|
|
endpoint: "https://secrets.hubris.network/issue",
|
|
doc_page: .agents/operations/agent-enrollment.md,
|
|
risk_notes: "identity issuance — security-sensitive; key operations are destructive-class"}}
|
|
# Services derived from hosts.public_host (no legacy services entry):
|
|
- {slug: "service:house", type: service, name: house,
|
|
attributes: {url: "https://house.hubris.network", note: "Yuvomi family planner (derived)"}}
|
|
- {slug: "service:grimmory", type: service, name: grimmory,
|
|
attributes: {url: "https://books.hubris.network", note: derived}}
|
|
- {slug: "service:seanime", type: service, name: seanime,
|
|
attributes: {url: "https://seanime.hubris.network", port: 43211, note: derived}}
|
|
- {slug: "service:romm", type: service, name: romm,
|
|
attributes: {url: "https://roms.hubris.network", note: derived}}
|
|
- {slug: "service:jellyseerr", type: service, name: jellyseerr,
|
|
attributes: {url: "https://jellyseerr.hubris.network", note: derived (arriman)}}
|
|
- {slug: "service:qbit", type: service, name: qbit,
|
|
attributes: {url: "https://qbit.hubris.network", note: derived (arriman)}}
|
|
- {slug: "service:sab", type: service, name: sab,
|
|
attributes: {url: "https://sab.hubris.network", note: "derived (arriman); forward-auth gated"}}
|
|
|
|
# ─── Config repos ──────────────────────────────────────────────────
|
|
- {slug: "repo:caddy-conf", type: config-repo, name: dtoro/caddy-conf}
|
|
- {slug: "repo:gitea-customizations", type: config-repo, name: dtoro/gitea-customizations}
|
|
- {slug: "repo:mule-image", type: config-repo, name: dtoro/mule-image}
|
|
- {slug: "repo:artifacto", type: config-repo, name: dtoro/Artifacto}
|
|
- {slug: "repo:terminalito", type: config-repo, name: dtoro/terminalito}
|
|
- {slug: "repo:homelab-docs", type: config-repo, name: dtoro/oikos}
|
|
|
|
# ─── Ingress routes (Caddy, *.hubris.network) ──────────────────────
|
|
- {slug: "ingress:proxmox.hubris.network", type: ingress-route, name: proxmox.hubris.network}
|
|
- {slug: "ingress:git.hubris.network", type: ingress-route, name: git.hubris.network}
|
|
- {slug: "ingress:auth.hubris.network", type: ingress-route, name: auth.hubris.network}
|
|
- {slug: "ingress:media.hubris.network", type: ingress-route, name: media.hubris.network}
|
|
- {slug: "ingress:cloud.hubris.network", type: ingress-route, name: cloud.hubris.network}
|
|
- {slug: "ingress:paperless.hubris.network", type: ingress-route, name: paperless.hubris.network,
|
|
attributes: {forward_auth: true}}
|
|
- {slug: "ingress:matrix.hubris.network", type: ingress-route, name: matrix.hubris.network}
|
|
- {slug: "ingress:photos.hubris.network", type: ingress-route, name: photos.hubris.network}
|
|
- {slug: "ingress:artifacto.hubris.network", type: ingress-route, name: artifacto.hubris.network}
|
|
- {slug: "ingress:trmnl.hubris.network", type: ingress-route, name: trmnl.hubris.network}
|
|
- {slug: "ingress:zimaos.hubris.network", type: ingress-route, name: zimaos.hubris.network}
|
|
- {slug: "ingress:teddy.hubris.network", type: ingress-route, name: teddy.hubris.network,
|
|
attributes: {forward_auth: false}}
|
|
- {slug: "ingress:mcp.hubris.network", type: ingress-route, name: mcp.hubris.network}
|
|
- {slug: "ingress:secrets.hubris.network", type: ingress-route, name: secrets.hubris.network}
|
|
- {slug: "ingress:house.hubris.network", type: ingress-route, name: house.hubris.network}
|
|
- {slug: "ingress:books.hubris.network", type: ingress-route, name: books.hubris.network}
|
|
- {slug: "ingress:seanime.hubris.network", type: ingress-route, name: seanime.hubris.network}
|
|
- {slug: "ingress:roms.hubris.network", type: ingress-route, name: roms.hubris.network}
|
|
- {slug: "ingress:jellyseerr.hubris.network", type: ingress-route, name: jellyseerr.hubris.network}
|
|
- {slug: "ingress:qbit.hubris.network", type: ingress-route, name: qbit.hubris.network}
|
|
- {slug: "ingress:sab.hubris.network", type: ingress-route, name: sab.hubris.network,
|
|
attributes: {forward_auth: true}}
|
|
|
|
# ─── TLS certificates (Caddy-managed, *.hubris.network) ───────────
|
|
# Each cert's expiry is probed by dialing Caddy's lab IP (`dial`) with SNI
|
|
# set to the hostname — the scheduler container has no mesh/split-horizon
|
|
# DNS, so it can't resolve *.hubris.network, but it CAN reach Caddy on the
|
|
# lab LAN.
|
|
- {slug: "cert:proxmox.hubris.network", type: certificate, name: proxmox.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:git.hubris.network", type: certificate, name: git.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:auth.hubris.network", type: certificate, name: auth.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:media.hubris.network", type: certificate, name: media.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:cloud.hubris.network", type: certificate, name: cloud.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:paperless.hubris.network", type: certificate, name: paperless.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:matrix.hubris.network", type: certificate, name: matrix.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:photos.hubris.network", type: certificate, name: photos.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:artifacto.hubris.network", type: certificate, name: artifacto.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:trmnl.hubris.network", type: certificate, name: trmnl.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:zimaos.hubris.network", type: certificate, name: zimaos.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:teddy.hubris.network", type: certificate, name: teddy.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:mcp.hubris.network", type: certificate, name: mcp.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:house.hubris.network", type: certificate, name: house.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:books.hubris.network", type: certificate, name: books.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:seanime.hubris.network", type: certificate, name: seanime.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:roms.hubris.network", type: certificate, name: roms.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:jellyseerr.hubris.network", type: certificate, name: jellyseerr.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:qbit.hubris.network", type: certificate, name: qbit.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
- {slug: "cert:sab.hubris.network", type: certificate, name: sab.hubris.network, attributes: {dial: "192.168.8.175"}}
|
|
|
|
# ─── Governance ────────────────────────────────────────────────────
|
|
- {slug: "person:dtoro", type: person, name: dtoro,
|
|
attributes: {matrix_id: "@dtoro:avispero"}}
|
|
- {slug: "idp:authentik", type: identity-provider, name: authentik,
|
|
attributes: {issuer: "https://auth.hubris.network", auth_mode: both}}
|
|
- {slug: "agent:nomos", type: agent, name: nomos,
|
|
state: active,
|
|
attributes: {gateway_port: 8092, session_mode: smart_approve, note: "Phase 4 — Docker gateway mode"}}
|
|
- {slug: "agent:oikos", type: agent, name: oikos,
|
|
state: planned,
|
|
attributes: {note: "the OS control loop itself (scheduler/actuator) as an actor"}}
|
|
|
|
# ─── Archaeology (state: destroyed — kept for "what happened to X?") ─
|
|
- {slug: "lxc:claudio-bot", type: lxc, name: claudio-bot, state: destroyed,
|
|
attributes: {pve_id: 123, destroyed: "2026-06-04", reason: "replaced by Nomos Agent on mac-mini"}}
|
|
- {slug: "lxc:plato", type: lxc, name: plato, state: destroyed,
|
|
attributes: {pve_id: 126, destroyed: "2026-06-28", reason: "notes workspace decommissioned; data at /mnt/library/documents/plato"}}
|
|
- {slug: "lxc:mule-photos-new", type: lxc, name: mule-photos-new, state: destroyed,
|
|
attributes: {pve_id: 127, destroyed: "2026-05-22", reason: "PhotoPrism test stack promoted to LXC 120"}}
|
|
- {slug: "lxc:heaper", type: lxc, name: heaper, state: destroyed,
|
|
attributes: {pve_id: 116, destroyed: "2026-05-14", reason: "decommissioned; data at /mnt/library/heaper"}}
|
|
- {slug: "lxc:syncthing", type: lxc, name: syncthing, state: destroyed,
|
|
attributes: {pve_id: 109, destroyed: "2026-05-14", reason: "decommissioned; library subtree was empty"}}
|
|
- {slug: "lxc:seafile", type: lxc, name: seafile, state: destroyed,
|
|
attributes: {pve_id: 125, destroyed: "2026-05-13", reason: "Seafile Pro evaluation rejected"}}
|
|
- {slug: "lxc:arr-yunohost", type: lxc, name: arr-yunohost, state: destroyed,
|
|
attributes: {pve_id: 100, destroyed: "2026-04-28", reason: "migrated to docker stack on arriman (LXC 122)"}}
|
|
- {slug: "lxc:flaresolverr", type: lxc, name: flaresolverr, state: destroyed,
|
|
attributes: {pve_id: 106, destroyed: "2026-04-28", reason: "folded into the arriman docker compose"}}
|
|
- {slug: "lxc:marimo", type: lxc, name: marimo, state: destroyed,
|
|
attributes: {pve_id: 107, destroyed: "2026-04-28", reason: decommissioned}}
|
|
- {slug: "lxc:photoprism", type: lxc, name: photoprism, state: destroyed,
|
|
attributes: {pve_id: 110, destroyed: "2026-04-28", reason: "replaced by mule-images (LXC 120)"}}
|
|
- {slug: "lxc:karakeep", type: lxc, name: karakeep, state: destroyed,
|
|
attributes: {pve_id: 111, destroyed: "2026-04-28", reason: decommissioned}}
|
|
- {slug: "lxc:immich", type: lxc, name: immich, state: destroyed,
|
|
attributes: {pve_id: 112, destroyed: "2026-04-28", reason: "replaced by mule-images (LXC 120)"}}
|
|
- {slug: "lxc:reticulum", type: lxc, name: reticulum, state: destroyed,
|
|
attributes: {pve_id: 115, destroyed: "2026-04-28", reason: decommissioned}}
|
|
|
|
relationships:
|
|
|
|
# ─── Cluster membership ────────────────────────────────────────────
|
|
- {source: "host:hubris", target: "cluster:homelab", type: member-of}
|
|
- {source: "host:strong", target: "cluster:homelab", type: member-of}
|
|
|
|
# ─── Location ──────────────────────────────────────────────────────
|
|
- {source: "host:hubris", target: "site:home", type: located-at}
|
|
- {source: "host:strong", target: "site:home", type: located-at}
|
|
- {source: "ws:mac-mini", target: "site:home", type: located-at}
|
|
- {source: "host:netbird-vps", target: "site:ionos-dc", type: located-at}
|
|
|
|
# ─── Hosting (machine → guest) ─────────────────────────────────────
|
|
- {source: "host:hubris", target: "lxc:nfs-export", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:paperless", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:gitea", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:apps", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:auth-outpost", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:dns", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:nextcloud", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:sophia", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:mule-images", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:caddy", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:trmnl", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:teddycloud", type: hosts}
|
|
- {source: "host:hubris", target: "vm:zimaos", type: hosts}
|
|
- {source: "host:hubris", target: "vm:haos", type: hosts}
|
|
- {source: "host:strong", target: "lxc:jellyfin", type: hosts}
|
|
- {source: "host:strong", target: "lxc:elementsynapse", type: hosts}
|
|
- {source: "host:strong", target: "lxc:arriman", type: hosts}
|
|
- {source: "host:strong", target: "lxc:house", type: hosts}
|
|
- {source: "host:strong", target: "lxc:grimmory", type: hosts}
|
|
- {source: "host:strong", target: "lxc:seanime", type: hosts}
|
|
- {source: "host:strong", target: "lxc:romm", type: hosts}
|
|
- {source: "host:hubris", target: "lxc:rclone", type: hosts}
|
|
|
|
# ─── Service provision (compute → service) ─────────────────────────
|
|
- {source: "host:hubris", target: "service:proxmox-ui", type: provides}
|
|
- {source: "lxc:gitea", target: "service:gitea", type: provides}
|
|
- {source: "lxc:caddy", target: "service:caddy", type: provides}
|
|
- {source: "host:netbird-vps", target: "service:authentik", type: provides}
|
|
- {source: "lxc:dns", target: "service:dns", type: provides}
|
|
- {source: "lxc:jellyfin", target: "service:jellyfin", type: provides}
|
|
- {source: "lxc:nextcloud", target: "service:nextcloud", type: provides}
|
|
- {source: "lxc:paperless", target: "service:paperless", type: provides}
|
|
- {source: "lxc:elementsynapse", target: "service:matrix", type: provides}
|
|
- {source: "lxc:mule-images", target: "service:photos", type: provides}
|
|
- {source: "lxc:arriman", target: "service:arr-stack", type: provides}
|
|
- {source: "lxc:arriman", target: "service:jellyseerr", type: provides}
|
|
- {source: "lxc:arriman", target: "service:qbit", type: provides}
|
|
- {source: "lxc:arriman", target: "service:sab", type: provides}
|
|
- {source: "lxc:apps", target: "service:artifacto", type: provides}
|
|
- {source: "lxc:apps", target: "service:homelab-mcp", type: provides}
|
|
- {source: "lxc:apps", target: "service:secrets-issuance", type: provides}
|
|
- {source: "lxc:trmnl", target: "service:trmnl", type: provides}
|
|
- {source: "vm:zimaos", target: "service:zimaos", type: provides}
|
|
- {source: "vm:haos", target: "service:haos", type: provides}
|
|
- {source: "lxc:teddycloud", target: "service:teddycloud", type: provides}
|
|
- {source: "lxc:house", target: "service:house", type: provides}
|
|
- {source: "lxc:grimmory", target: "service:grimmory", type: provides}
|
|
- {source: "lxc:seanime", target: "service:seanime", type: provides}
|
|
- {source: "lxc:romm", target: "service:romm", type: provides}
|
|
|
|
# ─── Ingress → service ─────────────────────────────────────────────
|
|
- {source: "ingress:proxmox.hubris.network", target: "service:proxmox-ui", type: routes-to}
|
|
- {source: "ingress:git.hubris.network", target: "service:gitea", type: routes-to}
|
|
- {source: "ingress:auth.hubris.network", target: "service:authentik", type: routes-to}
|
|
- {source: "ingress:media.hubris.network", target: "service:jellyfin", type: routes-to}
|
|
- {source: "ingress:cloud.hubris.network", target: "service:nextcloud", type: routes-to}
|
|
- {source: "ingress:paperless.hubris.network", target: "service:paperless", type: routes-to}
|
|
- {source: "ingress:matrix.hubris.network", target: "service:matrix", type: routes-to}
|
|
- {source: "ingress:photos.hubris.network", target: "service:photos", type: routes-to}
|
|
- {source: "ingress:artifacto.hubris.network", target: "service:artifacto", type: routes-to}
|
|
- {source: "ingress:trmnl.hubris.network", target: "service:trmnl", type: routes-to}
|
|
- {source: "ingress:zimaos.hubris.network", target: "service:zimaos", type: routes-to}
|
|
- {source: "ingress:teddy.hubris.network", target: "service:teddycloud", type: routes-to}
|
|
# Re-pointed from service:homelab-mcp, which is deprecated — the Python MCP
|
|
# server on apps/105 was stopped at the Go cutover and mcp.hubris.network now
|
|
# fronts the Go api. Nomos recorded this correctly on 2026-07-12; the seed
|
|
# was the stale one, and re-asserting the old edge alongside it is what made
|
|
# ingress:mcp a cardinality violation.
|
|
- {source: "ws:mac-mini", target: "service:oikos", type: provides}
|
|
- {source: "ingress:mcp.hubris.network", target: "service:oikos", type: routes-to}
|
|
# Every public hostname is terminated by caddy. Without these the
|
|
# reverse proxy — the single widest point of failure in the lab —
|
|
# had a blast radius of one.
|
|
- {source: "ingress:proxmox.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:git.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:auth.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:media.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:cloud.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:paperless.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:matrix.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:photos.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:artifacto.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:trmnl.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:zimaos.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:teddy.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:mcp.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:secrets.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:house.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:books.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:seanime.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:roms.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:jellyseerr.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:qbit.hubris.network", target: "service:caddy", type: served-by}
|
|
- {source: "ingress:sab.hubris.network", target: "service:caddy", type: served-by}
|
|
# Each public route is served with its TLS certificate.
|
|
- {source: "ingress:proxmox.hubris.network", target: "cert:proxmox.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:git.hubris.network", target: "cert:git.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:auth.hubris.network", target: "cert:auth.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:media.hubris.network", target: "cert:media.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:cloud.hubris.network", target: "cert:cloud.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:paperless.hubris.network", target: "cert:paperless.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:matrix.hubris.network", target: "cert:matrix.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:photos.hubris.network", target: "cert:photos.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:artifacto.hubris.network", target: "cert:artifacto.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:trmnl.hubris.network", target: "cert:trmnl.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:zimaos.hubris.network", target: "cert:zimaos.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:teddy.hubris.network", target: "cert:teddy.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:mcp.hubris.network", target: "cert:mcp.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:house.hubris.network", target: "cert:house.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:books.hubris.network", target: "cert:books.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:seanime.hubris.network", target: "cert:seanime.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:roms.hubris.network", target: "cert:roms.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:jellyseerr.hubris.network", target: "cert:jellyseerr.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:qbit.hubris.network", target: "cert:qbit.hubris.network", type: uses-certificate}
|
|
- {source: "ingress:sab.hubris.network", target: "cert:sab.hubris.network", type: uses-certificate}
|
|
|
|
- {source: "ingress:secrets.hubris.network", target: "service:secrets-issuance", type: routes-to}
|
|
- {source: "ingress:house.hubris.network", target: "service:house", type: routes-to}
|
|
- {source: "ingress:books.hubris.network", target: "service:grimmory", type: routes-to}
|
|
- {source: "ingress:seanime.hubris.network", target: "service:seanime", type: routes-to}
|
|
- {source: "ingress:roms.hubris.network", target: "service:romm", type: routes-to}
|
|
- {source: "ingress:jellyseerr.hubris.network", target: "service:jellyseerr", type: routes-to}
|
|
- {source: "ingress:qbit.hubris.network", target: "service:qbit", type: routes-to}
|
|
- {source: "ingress:sab.hubris.network", target: "service:sab", type: routes-to}
|
|
|
|
# ─── Auth edges ────────────────────────────────────────────────────
|
|
- {source: "ingress:paperless.hubris.network", target: "idp:authentik", type: secured-by}
|
|
- {source: "ingress:sab.hubris.network", target: "idp:authentik", type: secured-by}
|
|
- {source: "service:jellyfin", target: "idp:authentik", type: authenticates-via}
|
|
- {source: "idp:authentik", target: "person:dtoro", type: authenticates}
|
|
|
|
# ─── Config repos ──────────────────────────────────────────────────
|
|
- {source: "service:caddy", target: "repo:caddy-conf", type: configured-by}
|
|
- {source: "service:gitea", target: "repo:gitea-customizations", type: configured-by}
|
|
- {source: "service:photos", target: "repo:mule-image", type: configured-by}
|
|
- {source: "service:artifacto", target: "repo:artifacto", type: configured-by}
|
|
- {source: "service:trmnl", target: "repo:terminalito", type: configured-by}
|
|
- {source: "service:homelab-mcp", target: "repo:homelab-docs", type: configured-by}
|
|
- {source: "service:secrets-issuance", target: "repo:homelab-docs", type: configured-by}
|
|
|
|
# ─── Service dependencies (blast-radius edges; grow over time) ─────
|
|
- {source: "service:paperless", target: "service:authentik", type: depends-on}
|
|
- {source: "service:homelab-mcp", target: "service:gitea", type: depends-on}
|
|
- {source: "service:jellyseerr", target: "service:jellyfin", type: depends-on}
|
|
- {source: "service:seanime", target: "service:qbit", type: depends-on}
|
|
- {source: "service:house", target: "service:paperless", type: depends-on}
|
|
- {source: "service:sab", target: "service:authentik", type: depends-on}
|
|
|
|
# ─── Network membership ────────────────────────────────────────────
|
|
- {source: "host:hubris", target: "lan:lab", type: connects-via}
|
|
- {source: "host:hubris", target: "mesh:netbird", type: connects-via}
|
|
- {source: "host:strong", target: "lan:household", type: connects-via}
|
|
- {source: "ws:mac-mini", target: "lan:household", type: connects-via}
|
|
- {source: "ws:mac-mini", target: "mesh:netbird", type: connects-via}
|
|
- {source: "ws:republic-laptop", target: "mesh:netbird", type: connects-via}
|
|
- {source: "host:netbird-vps", target: "mesh:netbird", type: connects-via}
|
|
- {source: "lxc:rclone", target: "mesh:netbird", type: connects-via}
|
|
- {source: "lxc:jellyfin", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:nfs-export", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:paperless", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:gitea", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:apps", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:apps", target: "mesh:tailscale", type: connects-via}
|
|
- {source: "lxc:auth-outpost", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:dns", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:nextcloud", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:elementsynapse", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:sophia", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:mule-images", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:caddy", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:arriman", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:trmnl", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:house", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:grimmory", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:teddycloud", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:seanime", target: "lan:lab", type: connects-via}
|
|
- {source: "lxc:romm", target: "lan:lab", type: connects-via}
|
|
- {source: "vm:zimaos", target: "lan:lab", type: connects-via}
|
|
- {source: "vm:haos", target: "lan:lab", type: connects-via}
|
|
|
|
# ─── Storage ───────────────────────────────────────────────────────
|
|
- {source: "pool:ludo-lvm", target: "volume:media-local", type: contains}
|
|
- {source: "pool:library-hubris", target: "volume:library", type: contains}
|
|
- {source: "host:hubris", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:jellyfin", target: "volume:media-local", type: mounts,
|
|
attributes: {mount_point: /mnt/media_local}}
|
|
- {source: "lxc:paperless", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:gitea", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:apps", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:nextcloud", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:sophia", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:mule-images", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:arriman", target: "volume:media-local", type: mounts,
|
|
attributes: {mount_point: /mnt/media_local}}
|
|
- {source: "lxc:grimmory", target: "volume:media-local", type: mounts,
|
|
attributes: {mount_point: /mnt/media_local}}
|
|
- {source: "lxc:teddycloud", target: "volume:library", type: mounts,
|
|
attributes: {mount_point: /mnt/library}}
|
|
- {source: "lxc:seanime", target: "volume:media-local", type: mounts,
|
|
attributes: {mount_point: /mnt/media_local/anime}}
|
|
- {source: "lxc:romm", target: "volume:media-local", type: mounts,
|
|
attributes: {mount_point: /mnt/media_local}}
|
|
- {source: "lxc:jellyfin", target: "pool:ludo-lvm", type: stores-on}
|
|
- {source: "lxc:arriman", target: "pool:ludo-lvm", type: stores-on}
|
|
- {source: "lxc:grimmory", target: "pool:ludo-lvm", type: stores-on}
|
|
- {source: "lxc:romm", target: "pool:ludo-lvm", type: stores-on}
|
|
- {source: "lxc:teddycloud", target: "pool:local-lvm-hubris", type: stores-on}
|
|
- {source: "lxc:rclone", target: "backup:proton-drive", type: backs-up-to}
|
|
# The mac-mini writes the pre-deploy dumps, so it is also where the freshness
|
|
# check runs — checkdefaults resolves a backup-target's host by walking this
|
|
# edge backwards.
|
|
- {source: "ws:mac-mini", target: "backup:oikos-predeploy", type: backs-up-to}
|
|
|
|
# ─── Governance ────────────────────────────────────────────────────
|
|
- {source: "person:dtoro", target: "agent:nomos", type: owns}
|
|
- {source: "person:dtoro", target: "agent:oikos", type: owns}
|