main
  1_: {
  2  ssh = {
  3    # Keyed SSH registry. Each entry is `{ key; access; }` where
  4    # `access.<account>.<host|default>` resolves to one of:
  5    #   "trusted"        -> full unrestricted login
  6    #   { gated = "a"; } -> command="praetorian run a" restricted (see carthage)
  7    #   absent           -> no access on that host/account
  8    # Rendered via libx.authorizedKeysFor. Every entry MUST declare a non-empty
  9    # `access` (eval-time throw otherwise) so a key can never be silently
 10    # over-provisioned. Greppable unrestricted surface: `grep '"trusted"'`.
 11    vincent = {
 12      # Yubikeys (PIV - legacy, keep during transition)
 13      # TODO: phase these out once FIDO2/TPM coverage is complete.
 14      yubikey-piv-1 = {
 15        key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFT5Rx+4Wuvd8lMBkcHxb4oHdRhm/OTg+p5tvPzoIN9enSmgRw5Inm/SlS8ZzV87G1NESTgzDRi6hREvqDlKvxs=";
 16        access = {
 17          vincent.default = "trusted";
 18          root.default = "trusted";
 19        };
 20      };
 21      yubikey-piv-2 = {
 22        key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGHMa4rHuBbQQYv+8jvlkFCD2VYRGA4+5fnZAhLx8iDirzfEPqHB60UJWcDeixnJCUlpJjzFbS4crNOXhfCTCTE=";
 23        access = {
 24          vincent.default = "trusted";
 25          root.default = "trusted";
 26        };
 27      };
 28      yubikey-piv-3 = {
 29        key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBFzxC16VqwTgWDQfw2YCiOw2JzpH3z9XgHtKoHhBdHi2i9m9XUc7fIUeEIIf7P8ARRNd8q5bjvl8JY7LtPkNCU=";
 30        access = {
 31          vincent.default = "trusted";
 32          root.default = "trusted";
 33        };
 34      };
 35      # FIDO2 resident keys (touch is the gate -> unrestricted)
 36      homelab-servers = {
 37        key = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIODTc5Exm59skgJdu6/rA3CpX4k4P1CFBqCFtelWGGmEAAAAC3NzaDpob21lbGFi homelab-servers";
 38        access = {
 39          vincent.default = "trusted";
 40          root.default = "trusted";
 41        };
 42      };
 43      critical-infra = {
 44        key = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAGh5p44LvQrWjAMyC/5LjUnViqFl3ddVfiFnoiLgJb7AAAAEnNzaDpjcml0aWNhbC1pbmZyYQ== infra-touch-required";
 45        access = {
 46          vincent.default = "trusted";
 47          root.default = "trusted";
 48        };
 49      };
 50      okinawa-fido = {
 51        key = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEefW7gStvkrO98v6UUawwa3yOu896Ei8USE/Sh2DjaUAAAABHNzaDo= vincent@okinawa";
 52        access = {
 53          vincent.default = "trusted";
 54          root.default = "trusted";
 55        };
 56      };
 57      # Passage sync keys (non-SK, automated git pull only)
 58      # TODO: replace with the per-machine TPM approach.
 59
 60      # okinawa user key: TPM-sealed ecdsa via ssh-tpm-agent (machine-bound, no touch)
 61      okinawa-tpm = {
 62        key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBODwU2/sE+S51ShfL8t+QA9IMcVuQL+VLYuENUc5VDVD4AVoVj97BggowbAhtqDW6hdc0S3XSVrZs+aOSd9ukbg= vincent@okinawa-tpm";
 63        access = {
 64          vincent.default = "trusted";
 65          root.default = "trusted";
 66        };
 67      };
 68      # aomi user key: TPM-sealed ecdsa via ssh-tpm-agent (machine-bound, no touch)
 69      # Gated to git push+pull on carthage only.
 70      aomi-tpm = {
 71        key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGEL1A++UUsFnGmnrIR8S6A8IUFkR5WyxDPol2bs02TY0O+sWOPJFJZIAKqcWVSUIkxRoktUBMRe0mMZyiHa3jw= vdemeest@aomi-tpm";
 72        access.vincent = {
 73          carthage = {
 74            gated = "aomi-git";
 75          };
 76          kyushu = "trusted";
 77        };
 78      };
 79      kyushu-tpm = {
 80        key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBc8oKSsUPsgbOB+yrqLpxdI3lt0ONhlHhTwbnrobSgDat5J/w0ZOsHJUPNU/O2Hyqd9l0UXz3d7rnwfN1sO0tQ= vdemeest@kyushu-tpm";
 81        access.vincent = {
 82          carthage = {
 83            gated = "kyushu-git";
 84          };
 85          aomi = "trusted";
 86        };
 87      };
 88      # aion host key: has automation (restic backup to aix).
 89      # TODO: scope to aix + gate restic instead of full trust everywhere.
 90      aion-hostkey = {
 91        key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE3iD9Eaf5xglTyP+kIO9t8qQpF2H42rQ2AuUibs2hn7 vincent@aion";
 92        access = {
 93          vincent.default = "trusted";
 94          root.default = "trusted";
 95        };
 96      };
 97      # kyushu host key.
 98      # TODO: work on removing this key entirely.
 99      kyushu-hostkey = {
100        key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJOJ/Kd3KGVbd2QoOC+FqKxmNHLmrAEkP6lH0yqx1nO Kyushu's ssh key";
101        access = {
102          vincent.default = "trusted";
103          root.default = "trusted";
104        };
105      };
106      # Termux phones: git pull only (src/home, passage, ... under ~/git).
107      osaka-termux = {
108        key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICa0SyAspL7PBPudCjb7oCBG17WRmYnDQF7/BYkFwqDi oksaka-termux";
109        access.vincent.carthage = {
110          gated = "git-pull";
111        };
112      };
113      suzu-termux = {
114        key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0Q1oXzMMJG03n2VoxKKOGruyGBy8V8yanqgeeUYm+N suzu-termux";
115        access.vincent.carthage = {
116          gated = "git-pull";
117        };
118      };
119    };
120  };
121  syncthingFolders = {
122    sync = {
123      id = "7dshg-r8zr6";
124      path = "/home/vincent/sync";
125    };
126    documents = {
127      id = "oftdb-t5anv";
128      path = "/home/vincent/desktop/documents";
129    };
130    org = {
131      id = "sjpsr-xfwdu";
132      path = "/home/vincent/desktop/org";
133      versioning = {
134        type = "staggered";
135        params = {
136          cleanInterval = "3600"; # cleanup every hour
137          maxAge = "15768000"; # keep for ~6 months (182 days in seconds)
138        };
139      };
140    };
141    screenshots = {
142      id = "prpsz-azlz9";
143      path = "/home/vincent/desktop/pictures/screenshots";
144    };
145    wallpapers = {
146      id = "wpiah-ydwwx";
147      path = "/home/vincent/desktop/pictures/wallpapers";
148    };
149    claude-sync = {
150      id = "claude-sync"; # new consolidated folder
151      path = "/home/vincent/.local/share/claude-sync";
152    };
153    ai-sync = {
154      id = "ai-sync"; # unified AI agent storage (sessions, plans, learnings, research)
155      path = "/home/vincent/.local/share/ai-sync";
156    };
157    usage-metrics = {
158      id = "usage-metrics";
159      path = "/home/vincent/.local/share/usage-metrics";
160    };
161    paperless-media = {
162      id = "paperless-media";
163      path = "/neo/paperless/media";
164      versioning = {
165        type = "staggered";
166        params = {
167          cleanInterval = "3600"; # cleanup every hour
168          maxAge = "15768000"; # keep for ~6 months (182 days in seconds)
169        };
170      };
171    };
172    paperless-inbox = {
173      id = "paperless-inbox";
174      path = "/neo/paperless/consume";
175      # No versioning - temporary files get processed and deleted
176    };
177  };
178  net = {
179    dns = {
180      cacheNetworks = [
181        "192.168.1.0/24"
182        "10.100.0.0/24"
183      ];
184    };
185    vpn = {
186      endpoint = "46.224.100.116";
187    };
188    nfs = {
189      defaultHosts = {
190        rhea = {
191          server = "rhea.sbr.pm";
192          folders = [
193            "downloads"
194            "pictures"
195            "videos"
196          ];
197        };
198        zion = {
199          server = "rhea.sbr.pm";
200          rootPath = "/zion";
201          folders = [
202            "audiobooks"
203            "documents"
204            "ebooks"
205            "music"
206          ];
207        };
208        aion = {
209          server = "aion.sbr.pm";
210          folders = [
211            "audiobooks"
212            "music"
213          ];
214        };
215      };
216    };
217  };
218  machines = {
219    athena = {
220      net = {
221        ips = [ "192.168.1.183" ];
222        vpn = {
223          pubkey = "RWqH7RdIXg+YE9U1nlsNiOC7jH8eWjWQmikqBVDGSXU=";
224          ips = [ "10.100.0.83" ];
225        };
226        names = [
227          "athena.home"
228          "athena.vpn"
229          "athena.sbr.pm"
230        ];
231      };
232      ssh = {
233        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM/4KRP1rzOwyA2zP1Nf1WlLRHqAGutLtOHYWfH732xh";
234        # root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFQVlSrUKU0xlM9E+sJ8qgdgqCW6ePctEBD2Yf+OnyME root@aomiy";
235        # vincent = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJmTdMKYdgqpbQWBif58VBuwX+GqMGsMfB1ey1TKrM3 vincent@aomi";
236      };
237      # syncthing = {
238      #   id = "N3AMUVI-FM2BAOD-U3OMZDJ-UHMQE6J-ACMM5B7-S7BTK6P-PSM36NR-DVZHLQF";
239      #   folders = {
240      #     sync = {
241      #       type = "receiveonly";
242      #     };
243      #   };
244      # };
245    };
246    demeter = {
247      net = {
248        ips = [ "192.168.1.182" ];
249        vpn = {
250          pubkey = "/bBh4gvDty/AA2qIiHc7K0OHoOXWmj2SFFXdDq8nsUU=";
251          ips = [ "10.100.0.82" ];
252        };
253        names = [
254          "demeter.home"
255          "demeter.vpn"
256          "demeter.sbr.pm"
257        ];
258      };
259      ssh = {
260        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqQfEyHyjIGglayB9FtCqL7bnYfNSQlBXks2IuyCPmd";
261      };
262      # syncthing = {
263      #   id = "TXCV3TS-TUEOTH6-ETB3LBV-KCIHT4L-RCCOIE3-VPBCNJB-VHQEAYI-WOXK5A5";
264      #   folders = {
265      #     sync = {
266      #       type = "receiveonly";
267      #     };
268      #   };
269      # };
270    };
271    nagoya = {
272      net = {
273        ips = [ "192.168.1.80" ];
274        vpn = {
275          pubkey = "NCj5pwShre/xyRCK800ybjso1zIYUZ08YvFA2qGzhAI=";
276          ips = [ "10.100.0.80" ];
277        };
278        names = [
279          "nagoya.home"
280          "nagoya.vpn"
281          "nagoya.sbr.pm"
282        ];
283      };
284      ssh = {
285        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIfep1SkMsAPHggXFLfEJNzZb7eoihtkqDeQruG+TbhF";
286      };
287      # syncthing = {
288      #   id = "HZDLS5A-LKCEIYQ-DDMDYDF-DBTSRYH-HUNQSII-TVCDACT-DIYIO7V-G4K2EQV";
289      #   folders = {
290      #     sync = {
291      #       type = "receiveonly";
292      #     };
293      #   };
294      # };
295    };
296    aix = {
297      net = {
298        vpn = {
299          pubkey = "D1HoBqrqBchHOOi8mjKpVg5vZtt+iFy8wj4o3kGYwkc=";
300          ips = [ "10.100.0.89" ];
301        };
302        names = [
303          "aix.vpn"
304          "aix.sbr.pm"
305        ];
306      };
307      syncthing = {
308        id = "GHE6XF4-YCKEMZS-JEZYXA6-ETJI3SS-BQFFOCS-ZJAWN4D-Q33IQ46-OYL7BQM";
309        folders = {
310          sync = {
311            type = "receiveonly";
312          };
313        };
314      };
315      ssh = {
316        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEoUicDySCGETPAgmI0P3UrgZEXXw3zNsyCIylUP0bML";
317      };
318    };
319    kyushu = {
320      user = "vdemeest";
321      net = {
322        ips = [
323          "192.168.1.36"
324          "192.168.1.68"
325        ];
326        vpn = {
327          pubkey = "KVRzoPUw8UTQblYtbs/NLYLIVmtQehrc4Hacbpf5Ugs=";
328          ips = [ "10.100.0.19" ];
329        };
330        names = [
331          "kyushu.home"
332          "kyushu.vpn"
333          "kyushu.sbr.pm"
334        ];
335      };
336      ssh = {
337        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJOJ/Kd3KGVbd2QoOC+FqKxmNHLmrAEkP6lH0yqx1nO";
338      };
339      syncthing = {
340        id = "G6EVI7A-WFXEAI2-ZK3BI5C-7FZJNQH-PIPBHSC-57VZDKU-HN3WBCX-A757UQJ";
341        folders = {
342          org = { };
343          documents = { };
344          sync = { };
345          screenshots = { };
346          wallpapers = { };
347          claude-sync = { };
348          ai-sync = { };
349          usage-metrics = { };
350          paperless-media = {
351            type = "receiveonly";
352            path = "/home/vincent/desktop/paperless-media";
353          };
354          paperless-inbox = {
355            path = "/home/vincent/desktop/paperless-inbox";
356          };
357          # TODO: implement paused or filter theses
358          # photos = {
359          #   type = "receiveonly";
360          #   paused = true; # TODO: implement this, start as paused
361          # };
362          # music = {
363          #   type = "receiveonly";
364          #   paused = true; # TODO: implement this, start as paused
365          # };
366        };
367      };
368    };
369    aomi = {
370      user = "vdemeest";
371      net = {
372        ips = [ "192.168.1.23" ];
373        vpn = {
374          pubkey = "Pmu/0CjRaClmz+v25OV3SLd/V6Il8YLLavbtu8cYSGY=";
375          ips = [ "10.100.0.17" ];
376        };
377        names = [
378          "aomi.home"
379          "aomi.vpn"
380          "aomi.sbr.pm"
381        ];
382      };
383      ssh = {
384        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFL4OaoBtd/BzNeQvjB9AdYUiADk2PS0cKNmXu+PgkYY";
385      };
386      syncthing = {
387        id = "S6UM56N-TI2Z73H-IKO6F5Y-652ENJL-5BICIVD-JGFXED3-7JEJLZ2-XEIEXAL";
388        folders = {
389          sync = { };
390          org = { };
391          screenshots = { };
392          wallpapers = { };
393          claude-sync = { };
394          ai-sync = { };
395          usage-metrics = { };
396        };
397      };
398    };
399    shikoku = {
400      net = {
401        ips = [ "192.168.1.24" ];
402        vpn = {
403          pubkey = "foUoAvJXGyFV4pfEE6ISwivAgXpmYmHwpGq6X+HN+yA=";
404          ips = [ "10.100.0.2" ];
405        };
406        names = [
407          "shikoku.home"
408          "shikoku.vpn"
409          "shikoku.sbr.pm"
410        ];
411      };
412      ssh = {
413        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH18c6kcorVbK2TwCgdewL6nQf29Cd5BVTeq8nRYUigm";
414        vincent = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGxstR3xEf87leVVDS3GVPx8Ap9+eP+OfkSvM26V54XP vincent@shikoku";
415      };
416    };
417    # Hetzner Cloud VPS
418    # TODO: Update pubkey, hostKey, and syncthing id after provisioning
419    carthage = {
420      net = {
421        vpn = {
422          pubkey = "PQD1dtxhy9NMbmfy2OQPeLiQg0Alcfa1Mo4HVN5WqgA=";
423          ips = [ "10.100.0.1" ]; # VPN server
424        };
425        names = [
426          "carthage.vpn"
427          "carthage.sbr.pm"
428        ];
429      };
430      ssh = {
431        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHDurbEy1PiidOirbiPXz84ySdv3rwosPTAlCqacc73a";
432      };
433      # syncthing = {
434      #   id = "PLACEHOLDER_UNTIL_INSTALL";
435      #   folders = {
436      #     sync = { };
437      #   };
438      # };
439    };
440    sakhalin = {
441      net = {
442        ips = [ "192.168.1.70" ];
443        vpn = {
444          pubkey = "OAjw1l0z56F8kj++tqoasNHEMIWBEwis6iaWNAh1jlk=";
445          ips = [ "10.100.0.16" ];
446        };
447        names = [
448          "sakhalin.home"
449          "sakhalin.vpn"
450          "sakhalin.sbr.pm"
451        ];
452      };
453      ssh = {
454        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN/PMBThi4DhgZR8VywbRDzzMVh2Qp3T6NJAcPubfXz6";
455      };
456      syncthing = {
457        id = "3L2KCXM-D75XCVU-5JLMV6V-FKQID2K-LJA6GFB-R2G77LD-5WXFHJT-BB4B7Q5";
458        folders = {
459          org = { };
460          documents = { };
461          sync = { };
462          screenshots = { };
463          wallpapers = { };
464          # photos = {
465          #   type = "receiveonly";
466          #   paused = true; # TODO: implement this, start as paused
467          # };
468        };
469      };
470    };
471    rhea = {
472      net = {
473        ips = [ "192.168.1.50" ];
474        vpn = {
475          pubkey = "QBGdlPgtaLIh+WDLbuIWPL+Nr08mtfIqs6RwgVDAGjA=";
476          ips = [ "10.100.0.50" ];
477        };
478        names = [
479          "rhea.home"
480          "rhea.vpn"
481          "rhea.sbr.pm"
482        ];
483      };
484      ssh = {
485        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKFH3Lk4bRgNyFRK/Hzg1PvVbL/dpyI1SmLJFkb6VQDw";
486      };
487      syncthing = {
488        id = "73YP3XV-X3YLVBD-4KL77TS-DCFFXJ7-AYJDF3R-CJDRZNP-7YFPQNT-FKHJ7QW";
489        folders = {
490          org = { };
491          documents = { };
492          sync = { };
493          screenshots = {
494            path = "/neo/pictures/vincent/screenshots";
495          };
496          wallpapers = {
497            path = "/neo/pictures/vincent/wallpapers";
498          };
499          paperless-media = {
500            type = "receiveonly";
501            path = "/neo/paperless/media";
502          };
503          paperless-inbox = {
504            path = "/neo/paperless/consume";
505          };
506        };
507      };
508    };
509    aion = {
510      net = {
511        ips = [ "192.168.1.49" ];
512        vpn = {
513          pubkey = "Z145TsRbQTASEeAXsGkQR/PGvdI5rhHAXA5wllCKMGI=";
514          ips = [ "10.100.0.49" ];
515        };
516        names = [
517          "aion.home"
518          "aion.vpn"
519          "aion.sbr.pm"
520        ];
521      };
522      ssh = {
523        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAXDNi2KtoRU83y/V5OWnMbFWmxwBknPmrNWV4RChE7R";
524      };
525      syncthing = {
526        id = "YBQ6U6T-TMCZVUG-JNHGLRH-CZNZMHG-GQICVTK-LUXJR3H-KR2SXS7-CTNQCAU";
527        folders = {
528          org = { };
529          sync = { };
530          paperless-media = {
531            path = "/neo/paperless/media";
532          };
533          paperless-inbox = {
534            path = "/neo/paperless/consume";
535          };
536        };
537      };
538    };
539    synodine = {
540      net = {
541        ips = [ "192.168.1.20" ];
542        names = [
543          "synodine.home"
544          "synodine.sbr.pm"
545        ];
546      };
547      ssh = {
548        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDWdnPJg0Y4kd4lHPAGE4xgMAK2qvMg3oBxh0t+xO+7O";
549      };
550    };
551    wakasu = {
552      net = {
553        vpn = {
554          ips = [ "10.100.0.8" ];
555        };
556        names = [
557          "wakasu.vpn"
558          "wakasu.sbr.pm"
559        ];
560      };
561      # syncthing = {
562      #   id = "WM23THJ-ECXRLXA-HE5TIKO-VPLSMRY-Y2EWZI7-Q7JMLPX-5Q5UNEN-QMB7ZQJ";
563      #   folders = {
564      #     org = { };
565      #     documents = { };
566      #     sync = { };
567      #     screenshots = { };
568      #     wallpapers = { };
569      #   };
570      # };
571    };
572    # Home Assistant
573    hass = {
574      net = {
575        ips = [ "192.168.1.181" ];
576        vpn = {
577          ips = [ "10.100.0.81" ];
578        };
579        names = [
580          "hass.home"
581          "hass.vpn"
582          "hass.sbr.pm"
583        ];
584      };
585    };
586    okinawa = {
587      net = {
588        ips = [ "192.168.1.42" ];
589        vpn = {
590          pubkey = "SxH2pDYtAlK79s5K3YwplFm4hRn8lxnl4638IPRZnBk="; # From: sudo wg show wg0 public-key
591          ips = [ "10.100.0.14" ];
592        };
593        names = [
594          "okinawa.home"
595          "okinawa.vpn"
596          "okinawa.sbr.pm"
597        ];
598      };
599      ssh = {
600        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM8vCZ0h6geJZt6i5k6chEDZBggoyq91Z+oNSjvVeSfW root@okinawa"; # From: cat /etc/ssh/ssh_host_ed25519_key.pub
601      };
602      syncthing = {
603        id = "BTDYRYQ-IOUC6IE-2BRMDDG-4CX6OUU-XCEUMSG-QF5O463-YFTNHTS-3NGRUQX"; # From Syncthing UI (http://localhost:8384)
604        folders = {
605          sync = { };
606          org = { };
607          documents = { };
608          screenshots = { };
609          wallpapers = { };
610          claude-sync = { };
611          ai-sync = { };
612          usage-metrics = { };
613          paperless-media = {
614            type = "receiveonly";
615            path = "/home/vincent/desktop/paperless-media";
616          };
617          paperless-inbox = {
618            path = "/home/vincent/desktop/paperless-inbox";
619          };
620        };
621      };
622    };
623    # iPhone
624    hokkaido = {
625      net = {
626        ips = [ "192.168.1.115" ];
627        vpn = {
628          pubkey = "rN5ekYI/k3Ymd76vudCZtcaNNu6HmMLzB61uRXakV0M=";
629          ips = [ "10.100.0.5" ];
630        };
631        names = [
632          "hokkaido.home"
633          "hokkaido.vpn"
634          "hokkaido.sbr.pm"
635        ];
636      };
637      syncthing = {
638        id = "XD4XYNZ-DT3PJEY-UJYBHWX-6OQPPUI-HTW752L-FYTX3TW-GVHDTKW-PT336QV";
639        folders = {
640          documents = { };
641          sync = { };
642          org = { };
643        };
644      };
645    };
646    # Light Phone
647    suzu = {
648      net = {
649        vpn = {
650          ips = [ "10.100.0.65" ];
651          pubkey = "ufKLXzLkmYx1z7/VZJs9Ix6aXL3rYzP5B73QQP2WNx8=";
652        };
653        names = [
654          # "suzu.home"
655          "suzu.vpn"
656          "suzu.sbr.pm"
657        ];
658      };
659    };
660    # Boox tablet
661    osaka = {
662      net = {
663        vpn = {
664          ips = [ "10.100.0.64" ];
665          pubkey = "IJkiyMdHnhwxN9hFpDNVFKzByyqEQKIyIFBpYst65x8=";
666        };
667        names = [
668          # "oksaka.home"
669          "osaka.vpn"
670          "osaka.sbr.pm"
671        ];
672      };
673    };
674    # Houbeb's macbook pro 16
675    houbeb-makcbook-pro = {
676      net = {
677        vpn = {
678          ips = [ "10.100.0.71" ];
679          pubkey = "RANYR3ouf+3Bh+6kJVF1I0s5iglBGs7ucW6iRyv2cGc=";
680        };
681        names = [ ];
682      };
683    };
684  };
685  services = {
686    # Media services on rhea
687    immich = {
688      host = "rhea";
689      aliases = [ "photos" ];
690    };
691    jellyfin.host = "rhea";
692    jellyseerr.host = "rhea";
693    sonarr.host = "rhea";
694    radarr.host = "rhea";
695    lidarr.host = "rhea";
696    bazarr.host = "rhea";
697    prowlarr.host = "rhea";
698    transmission = {
699      host = "rhea";
700      aliases = [ "t" ];
701    };
702    transmission-music = {
703      host = "rhea";
704      aliases = [ "tm" ];
705    };
706    syncthing = {
707      host = "rhea";
708      aliases = [ "s" ];
709    };
710    homepage.host = "rhea";
711    # Wallabag read-it-later (runs on aion, proxied via rhea/Traefik)
712    wallabag = {
713      host = "rhea";
714      aliases = [ "read" ];
715    };
716    # Miniflux RSS reader (runs on aion, proxied via rhea/Traefik)
717    miniflux = {
718      host = "rhea";
719      aliases = [ "rss" ];
720    };
721    # Traefik dashboard
722    traefik.host = "rhea";
723    # Music streaming on aion (routed through rhea/traefik)
724    music.host = "rhea";
725    navidrome.host = "rhea";
726    # Podcast and audiobook management on aion (routed through rhea/traefik)
727    audiobookshelf.host = "rhea";
728    podcasts.host = "rhea";
729    # Ebook library management on rhea
730    calibre.host = "rhea";
731    books.host = "rhea";
732    # WebDAV on rhea
733    dav.host = "rhea";
734    # MQTT on demeter (routed through rhea/traefik)
735    mqtt.host = "rhea";
736    # Home Assistant on hass (routed through rhea/traefik)
737    home.host = "rhea";
738    # Services on sakhalin (routed through rhea/traefik)
739    paperless.host = "rhea";
740    grafana.host = "rhea";
741    # OpenCode web interface on okinawa (routed through rhea/traefik)
742    opencode.host = "rhea";
743    # Readwise Reader triage report on okinawa (routed through rhea/traefik)
744    reading.host = "rhea";
745    # XMPP messaging server on aion (VPN-only, direct access)
746    xmpp.host = "aion";
747  };
748}