@sebastienrousseau/dotfiles 0.2.481 → 0.2.500

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. package/CHANGELOG.md +122 -32
  2. package/LICENSE +1 -1
  3. package/README.md +211 -242
  4. package/docs/.vitepress/reports/localization-readability-audit.md +69 -0
  5. package/docs/AI.md +102 -0
  6. package/docs/COPYRIGHT +2 -2
  7. package/docs/NAMING_CONVENTIONS.md +95 -0
  8. package/docs/README.md +58 -249
  9. package/docs/adr/ADR-004-cli-architecture.md +2 -2
  10. package/docs/adr/ADR-006-shell-selection.md +2 -2
  11. package/docs/adr/ADR-007-multi-shell-parity.md +53 -0
  12. package/docs/adr/ADR-008-alias-system-architecture.md +85 -0
  13. package/docs/adr/README.md +2 -3
  14. package/docs/architecture/ARCHITECTURE.md +113 -0
  15. package/docs/architecture/INTEROP.md +36 -0
  16. package/docs/architecture/REPO_LAYOUT.md +237 -0
  17. package/docs/architecture/WALKTHROUGH.md +82 -0
  18. package/docs/architecture/fleet-deployment.md +73 -0
  19. package/docs/archive/EUXIS_2026_REVIEW.md +119 -0
  20. package/docs/archive/MILESTONE_v0.2.493.md +43 -0
  21. package/docs/{PLAN.md → archive/PLAN.md} +1 -1
  22. package/docs/guides/INSTALL.md +140 -0
  23. package/docs/{NEOVIM_IDE_GUIDE.md → guides/NEOVIM_IDE_GUIDE.md} +12 -12
  24. package/docs/guides/THEMING.md +222 -0
  25. package/docs/{TROUBLESHOOTING.md → guides/TROUBLESHOOTING.md} +36 -0
  26. package/docs/{WSL2_NIX_TROUBLESHOOTING.md → guides/WSL2_NIX_TROUBLESHOOTING.md} +8 -8
  27. package/docs/index.md +39 -0
  28. package/docs/interop/A2A.md +32 -0
  29. package/docs/manual/00-introduction.md +85 -0
  30. package/docs/manual/01-concepts/01-architecture.md +134 -0
  31. package/docs/manual/01-concepts/02-trust-model.md +178 -0
  32. package/docs/manual/01-concepts/03-theme-engine.md +182 -0
  33. package/docs/manual/01-concepts/04-fleet.md +142 -0
  34. package/docs/manual/01-concepts/05-self-healing.md +197 -0
  35. package/docs/manual/02-tutorials/01-first-install.md +192 -0
  36. package/docs/manual/02-tutorials/02-add-wallpaper.md +211 -0
  37. package/docs/manual/02-tutorials/03-create-profile.md +238 -0
  38. package/docs/manual/02-tutorials/04-encrypt-secret.md +275 -0
  39. package/docs/manual/02-tutorials/05-deploy-fleet.md +279 -0
  40. package/docs/manual/03-reference/01-dot-cli.md +413 -0
  41. package/docs/manual/03-reference/02-config-files.md +259 -0
  42. package/docs/manual/03-reference/03-environment.md +120 -0
  43. package/docs/manual/03-reference/04-templates.md +184 -0
  44. package/docs/manual/03-reference/05-feature-flags.md +118 -0
  45. package/docs/manual/04-cookbook/01-recipes.md +281 -0
  46. package/docs/manual/04-cookbook/02-troubleshooting.md +319 -0
  47. package/docs/manual/04-cookbook/03-faq.md +167 -0
  48. package/docs/manual/05-appendices/A-platform-matrix.md +97 -0
  49. package/docs/manual/05-appendices/B-security-checklist.md +78 -0
  50. package/docs/manual/05-appendices/C-glossary.md +36 -0
  51. package/docs/manual/05-appendices/D-bibliography.md +54 -0
  52. package/docs/manual/05-appendices/E-license.md +34 -0
  53. package/docs/manual/_toc.yml +58 -0
  54. package/docs/manual/command-index.md +58 -0
  55. package/docs/manual/concept-index.md +164 -0
  56. package/docs/operations/ATTESTATION.md +39 -0
  57. package/docs/operations/MAINTENANCE.md +59 -0
  58. package/docs/operations/MIGRATION.md +101 -0
  59. package/docs/operations/OPERATIONS.md +164 -0
  60. package/docs/operations/RELIABILITY.md +116 -0
  61. package/docs/{ROADMAP.md → operations/ROADMAP.md} +11 -11
  62. package/docs/operations/TESTING.md +195 -0
  63. package/docs/operations/TRACEABILITY.md +31 -0
  64. package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +61 -0
  65. package/docs/operations/VERSION_SYNC.md +344 -0
  66. package/docs/{ALIASES.md → reference/ALIASES.md} +2 -6
  67. package/docs/reference/ALIASES_CHEATSHEET.md +28 -0
  68. package/docs/reference/ALIASES_DEPRECATIONS.md +9 -0
  69. package/docs/reference/FEATURES.md +62 -0
  70. package/docs/reference/FONTS.md +108 -0
  71. package/docs/reference/PROFILES.md +65 -0
  72. package/docs/{SCREENSHOTS.md → reference/SCREENSHOTS.md} +26 -25
  73. package/docs/reference/SCRIPTS.md +67 -0
  74. package/docs/reference/SUPPORT_MATRIX.md +74 -0
  75. package/docs/reference/THEMES.md +113 -0
  76. package/docs/reference/TOOLS.md +105 -0
  77. package/docs/reference/UTILS.md +151 -0
  78. package/docs/security/AI_ACT_COMPLIANCE.md +90 -0
  79. package/docs/security/AUTOMATION_SECRETS.md +22 -0
  80. package/docs/security/COMPLIANCE.md +453 -0
  81. package/docs/security/ENCRYPTION.md +52 -0
  82. package/docs/security/FMEA.md +155 -0
  83. package/docs/security/INCIDENT_RESPONSE.md +575 -0
  84. package/docs/security/KEYS.md +45 -0
  85. package/docs/security/MCP_POLICY.md +69 -0
  86. package/docs/security/POLICY_RELEASES.md +33 -0
  87. package/docs/security/README.md +24 -0
  88. package/docs/security/SECRETS.md +146 -0
  89. package/docs/security/SECURITY.md +41 -0
  90. package/docs/security/SECURITY_CHECKLIST.md +44 -0
  91. package/docs/security/SOUP_REGISTER.md +32 -0
  92. package/docs/security/THREAT_MODEL.md +120 -0
  93. package/docs/security/VERIFICATION_VALIDATION.md +224 -0
  94. package/docs/themes/README.md +3 -17
  95. package/docs/themes/VISUAL_INTEGRITY_REPORT.md +26 -0
  96. package/docs/themes/hero-shot.svg +78 -0
  97. package/dot_config/.module-manifest.json +69 -0
  98. package/dot_config/ai/identity.md +20 -0
  99. package/dot_config/ai/patterns/architect.md +14 -0
  100. package/dot_config/ai/patterns/hardener.md +13 -0
  101. package/dot_config/ai/patterns/refactor.md +13 -0
  102. package/dot_config/aider/aider.conf.yml +1 -1
  103. package/dot_config/alacritty/alacritty.toml.tmpl +41 -469
  104. package/dot_config/atuin/config.toml +18 -1
  105. package/dot_config/bat/config +16 -1
  106. package/dot_config/claude/mcp_servers.json +3 -32
  107. package/dot_config/dotfiles/agent-card.json +29 -0
  108. package/dot_config/dotfiles/agent-profiles.json +92 -0
  109. package/dot_config/dotfiles/boot/README.md +1 -1
  110. package/dot_config/dotfiles/grub/README.md +1 -1
  111. package/dot_config/dotfiles/lock/README.md +1 -1
  112. package/dot_config/dotfiles/mcp-lock.json +33 -0
  113. package/dot_config/dotfiles/mcp-policy.json +52 -0
  114. package/dot_config/dotfiles/mcp-registry.json +47 -0
  115. package/dot_config/dotfiles/model-registry.json +20 -0
  116. package/dot_config/dotfiles/policy-bundles.json +38 -0
  117. package/dot_config/dotfiles/prompt-registry.json +16 -0
  118. package/dot_config/dotfiles/versions.env +18 -0
  119. package/dot_config/environment.d/50-ssh-agent.conf +2 -0
  120. package/dot_config/environment.d/90-wayland.conf +19 -0
  121. package/dot_config/firefox/user.js.tmpl +58 -0
  122. package/dot_config/fish/completions/dot-theme-sync.fish.tmpl +9 -0
  123. package/dot_config/fish/completions/dot.fish.tmpl +115 -0
  124. package/dot_config/fish/conf.d/000-perf-cache.fish +56 -0
  125. package/dot_config/fish/conf.d/aliases.fish.tmpl +77 -0
  126. package/dot_config/fish/conf.d/env.fish.tmpl +48 -0
  127. package/dot_config/fish/conf.d/functions.fish.tmpl +22 -0
  128. package/dot_config/fish/conf.d/init.fish.tmpl +151 -0
  129. package/dot_config/fish/config.fish.tmpl +44 -0
  130. package/dot_config/fish/fish_plugins +1 -0
  131. package/dot_config/fish/functions/_.fish +3 -0
  132. package/dot_config/fish/functions/_cached_eval.fish +58 -0
  133. package/dot_config/fish/functions/als.fish +46 -0
  134. package/dot_config/fish/functions/bg-upgrade.fish +7 -0
  135. package/dot_config/fish/functions/c.fish +3 -0
  136. package/dot_config/fish/functions/cat.fish +9 -0
  137. package/dot_config/fish/functions/d.fish +7 -0
  138. package/dot_config/fish/functions/dot.fish +34 -0
  139. package/dot_config/fish/functions/h.fish +3 -0
  140. package/dot_config/fish/functions/l.fish +7 -0
  141. package/dot_config/fish/functions/la.fish +7 -0
  142. package/dot_config/fish/functions/ll.fish +7 -0
  143. package/dot_config/fish/functions/log_error.fish +13 -0
  144. package/dot_config/fish/functions/log_info.fish +13 -0
  145. package/dot_config/fish/functions/lr.fish +7 -0
  146. package/dot_config/fish/functions/lra.fish +7 -0
  147. package/dot_config/fish/functions/ls.fish +7 -0
  148. package/dot_config/fish/functions/lt.fish +7 -0
  149. package/dot_config/fish/functions/lta.fish +7 -0
  150. package/dot_config/fish/functions/notify-run.fish +11 -0
  151. package/dot_config/fish/functions/q.fish +3 -0
  152. package/dot_config/fish/functions/silent-run.fish +7 -0
  153. package/dot_config/fish/functions/yy.fish +8 -0
  154. package/dot_config/fontconfig/fonts.conf.tmpl +13 -0
  155. package/dot_config/foot/foot.ini.tmpl +33 -0
  156. package/dot_config/fuzzel/fuzzel.ini.tmpl +18 -0
  157. package/dot_config/fzf/fzf.zsh +48 -0
  158. package/dot_config/ghostty/config.tmpl +69 -565
  159. package/dot_config/git/allowed_signers.tmpl +18 -0
  160. package/dot_config/git/commit-template +10 -0
  161. package/dot_config/gnupg/{gpg-agent.conf.tmpl → gpg-agent.conf} +3 -3
  162. package/dot_config/goose/config.yaml +2 -2
  163. package/dot_config/gtk-3.0/gtk.css.tmpl +59 -180
  164. package/dot_config/gtk-3.0/settings.ini.tmpl +5 -44
  165. package/dot_config/gtk-4.0/gtk.css.tmpl +79 -136
  166. package/dot_config/gtk-4.0/settings.ini.tmpl +5 -8
  167. package/dot_config/ipython/profile_default/ipython_config.py +19 -0
  168. package/dot_config/just/justfile +18 -0
  169. package/dot_config/kanshi/config.tmpl +22 -0
  170. package/dot_config/kitty/kitty.conf.tmpl +44 -508
  171. package/dot_config/lazygit/config.yml +18 -6
  172. package/dot_config/mako/config +47 -0
  173. package/dot_config/micro/settings.json +3 -0
  174. package/dot_config/mimeapps.list +77 -0
  175. package/dot_config/mise/config.toml +63 -5
  176. package/dot_config/mongosh/mongoshrc.js +1 -0
  177. package/dot_config/mpv/input.conf +47 -0
  178. package/dot_config/mpv/mpv.conf +47 -0
  179. package/dot_config/niri/config.kdl.tmpl +327 -0
  180. package/dot_config/nushell/aliases.nu +18 -0
  181. package/dot_config/nushell/completions.nu.tmpl +52 -0
  182. package/dot_config/nushell/config.nu.tmpl +86 -0
  183. package/dot_config/nushell/env.nu.tmpl +94 -0
  184. package/dot_config/nushell/functions.nu.tmpl +17 -0
  185. package/dot_config/nvim/init.lua +14 -0
  186. package/dot_config/nvim/lazy-lock.json +45 -14
  187. package/dot_config/nvim/lua/config/autocmds.lua +45 -1
  188. package/dot_config/nvim/lua/config/keymaps.lua +13 -8
  189. package/dot_config/nvim/lua/config/lazy.lua +22 -12
  190. package/dot_config/nvim/lua/config/options.lua +1 -0
  191. package/dot_config/nvim/lua/plugins/ai.lua +75 -0
  192. package/dot_config/nvim/lua/plugins/coding.lua +11 -29
  193. package/dot_config/nvim/lua/plugins/completion.lua +60 -0
  194. package/dot_config/nvim/lua/plugins/dap.lua +215 -4
  195. package/dot_config/nvim/lua/plugins/editor.lua +6 -10
  196. package/dot_config/nvim/lua/plugins/git.lua +1 -0
  197. package/dot_config/nvim/lua/plugins/lsp.lua +16 -81
  198. package/dot_config/nvim/lua/plugins/markdown.lua +1 -0
  199. package/dot_config/nvim/lua/plugins/rust.lua +1 -0
  200. package/dot_config/nvim/lua/plugins/sessions.lua +1 -0
  201. package/dot_config/nvim/lua/plugins/ui.lua +23 -51
  202. package/dot_config/paru/paru.conf +10 -0
  203. package/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl +81 -0
  204. package/dot_config/pueue/pueue.yml +34 -0
  205. package/dot_config/raycast/README.md +1 -1
  206. package/dot_config/ripgrep/ripgreprc +21 -0
  207. package/dot_config/shell/00-core-paths.sh.tmpl +62 -24
  208. package/dot_config/shell/05-core-safety.sh +47 -0
  209. package/dot_config/shell/10-secrets.sh +40 -0
  210. package/dot_config/shell/40-fzf-defaults.sh.tmpl +16 -0
  211. package/dot_config/shell/40-ls-colors.sh +48 -0
  212. package/dot_config/shell/50-logic-functions-core.sh.tmpl +10 -0
  213. package/dot_config/shell/51-logic-functions-extra.sh.tmpl +64 -0
  214. package/dot_config/shell/90-ux-aliases.sh.tmpl +90 -5
  215. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +33 -2
  216. package/dot_config/shell/Brewfile.cli +8 -0
  217. package/dot_config/shell/README.md +9 -9
  218. package/dot_config/shell/als_data.txt.tmpl +65 -0
  219. package/dot_config/shell/custom/auto_ls.zsh +20 -0
  220. package/dot_config/shell/custom/context_suggest.zsh +50 -50
  221. package/dot_config/shell/custom/error_analysis.zsh +29 -29
  222. package/dot_config/starship.toml.tmpl +85 -7
  223. package/dot_config/swaylock/config +43 -0
  224. package/dot_config/systemd/user/dotfiles-maintenance.service +8 -0
  225. package/dot_config/systemd/user/dotfiles-maintenance.timer +11 -0
  226. package/dot_config/systemd/user/pueued.service +12 -0
  227. package/dot_config/systemd/user/ssh-agent.service +12 -0
  228. package/dot_config/tmux/tmux.conf.tmpl +80 -38
  229. package/dot_config/topgrade.toml.tmpl +54 -0
  230. package/dot_config/user-dirs.dirs +9 -0
  231. package/dot_config/vscode/settings.json.tmpl +9 -50
  232. package/dot_config/waybar/config.jsonc.tmpl +90 -0
  233. package/dot_config/waybar/style.css.tmpl +211 -0
  234. package/dot_config/wezterm/wezterm.lua.tmpl +31 -203
  235. package/dot_config/xdg-desktop-portal/niri-portals.conf +5 -0
  236. package/dot_config/yazi/keymap.toml +67 -0
  237. package/dot_config/yazi/theme.toml +102 -0
  238. package/dot_config/zathura/zathurarc +52 -0
  239. package/dot_config/zellij/{config.kdl → config.kdl.tmpl} +1 -1
  240. package/dot_config/zsh/dot_zprofile +1 -7
  241. package/dot_config/zsh/dot_zshenv +2 -3
  242. package/dot_config/zsh/dot_zshrc.tmpl +368 -69
  243. package/dot_config/zsh/rc.d/00-alias-shims.zsh +77 -0
  244. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +17 -4
  245. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +4 -4
  246. package/dot_config/zsh/rc.d/20-zinit.zsh +65 -0
  247. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +101 -30
  248. package/dot_config/zsh/rc.d/99-alias-wrapper.zsh +32 -0
  249. package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
  250. package/dot_local/bin/executable_ai-update +195 -0
  251. package/dot_local/bin/executable_ai_core +113 -91
  252. package/dot_local/bin/executable_antigravity +11 -0
  253. package/dot_local/bin/executable_b64 +61 -36
  254. package/dot_local/bin/executable_bm +77 -0
  255. package/dot_local/bin/executable_cb +39 -0
  256. package/dot_local/bin/executable_dot +543 -132
  257. package/dot_local/bin/executable_dot-ai +36 -0
  258. package/dot_local/bin/executable_dot-bootstrap +77 -0
  259. package/dot_local/bin/executable_dot-launch-or-focus +52 -0
  260. package/dot_local/bin/executable_dot-load-benchmark +31 -0
  261. package/dot_local/bin/executable_dot-load-benchmark-pty +77 -0
  262. package/dot_local/bin/executable_dot-theme-sync +952 -0
  263. package/dot_local/bin/executable_dot_completion +2 -0
  264. package/dot_local/bin/executable_dtags +28 -0
  265. package/dot_local/bin/executable_epoch +43 -38
  266. package/dot_local/bin/executable_extract +32 -99
  267. package/dot_local/bin/executable_gbd +52 -0
  268. package/dot_local/bin/executable_gd +42 -0
  269. package/dot_local/bin/executable_git-ai-commit +35 -20
  270. package/dot_local/bin/executable_git-ai-diff +33 -18
  271. package/dot_local/bin/executable_gl +101 -0
  272. package/dot_local/bin/executable_hash +56 -18
  273. package/dot_local/bin/executable_hashsum +160 -0
  274. package/dot_local/bin/executable_hex +44 -8
  275. package/dot_local/bin/executable_jsonv +34 -10
  276. package/dot_local/bin/executable_jwt +22 -6
  277. package/dot_local/bin/executable_kill-port +18 -2
  278. package/dot_local/bin/executable_lorem +21 -6
  279. package/dot_local/bin/executable_mkscript +35 -0
  280. package/dot_local/bin/executable_monitor +56 -0
  281. package/dot_local/bin/{executable_ip → executable_myip} +16 -2
  282. package/dot_local/bin/executable_notify +22 -0
  283. package/dot_local/bin/executable_open +36 -0
  284. package/dot_local/bin/executable_pw +27 -0
  285. package/dot_local/bin/executable_rec-start +46 -0
  286. package/dot_local/bin/executable_rec-stop +35 -0
  287. package/dot_local/bin/executable_regex +49 -13
  288. package/dot_local/bin/executable_start-niri +8 -0
  289. package/dot_local/bin/executable_tmux-sessionizer +276 -149
  290. package/dot_local/bin/executable_tour +112 -74
  291. package/dot_local/bin/executable_up +21 -0
  292. package/dot_local/bin/executable_update +45 -11
  293. package/dot_local/bin/executable_uuid +37 -7
  294. package/dot_local/bin/executable_win +32 -0
  295. package/dot_local/bin/executable_yamlv +25 -7
  296. package/dot_local/share/bash-completion/completions/dot +62 -44
  297. package/dot_local/share/icons/hicolor/128x128/apps/rousseau.png +0 -0
  298. package/dot_local/share/icons/hicolor/16x16/apps/rousseau.png +0 -0
  299. package/dot_local/share/icons/hicolor/24x24/apps/rousseau.png +0 -0
  300. package/dot_local/share/icons/hicolor/256x256/apps/rousseau.png +0 -0
  301. package/dot_local/share/icons/hicolor/32x32/apps/rousseau.png +0 -0
  302. package/dot_local/share/icons/hicolor/48x48/apps/rousseau.png +0 -0
  303. package/dot_local/share/icons/hicolor/512x512/apps/rousseau.png +0 -0
  304. package/dot_local/share/icons/hicolor/64x64/apps/rousseau.png +0 -0
  305. package/dot_local/share/icons/hicolor/96x96/apps/rousseau.png +0 -0
  306. package/dot_local/share/icons/hicolor/scalable/apps/rousseau.png +0 -0
  307. package/dot_local/share/man/man1/dot.1 +149 -0
  308. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_download +64 -0
  309. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_install +18 -0
  310. package/dot_local/share/mise/plugins/kiro-cli/bin/executable_list-all +13 -0
  311. package/dot_local/share/wayland-sessions/niri.desktop.tmpl +6 -0
  312. package/dot_local/share/zsh/completions/_dot +283 -0
  313. package/install.sh +297 -210
  314. package/package.json +17 -5
  315. package/scripts/ci/check-copyright-headers.sh +96 -0
  316. package/scripts/ci/guard-gitleaks-checkout.sh +57 -0
  317. package/scripts/ci/install-chezmoi-verified.sh +64 -0
  318. package/scripts/ci/validate-ci-config.sh +41 -39
  319. package/scripts/demo/record.sh +3 -2
  320. package/scripts/diagnostics/a2a-conformance.sh +162 -0
  321. package/scripts/diagnostics/alias-governance.sh +137 -0
  322. package/scripts/diagnostics/aliases-cheatsheet.sh +73 -0
  323. package/scripts/diagnostics/aliases-manifest.sh +31 -0
  324. package/scripts/diagnostics/benchmark.sh +209 -29
  325. package/scripts/diagnostics/conflicts.sh +72 -0
  326. package/scripts/diagnostics/doctor-unified.sh +38 -0
  327. package/scripts/diagnostics/doctor.sh +491 -65
  328. package/scripts/diagnostics/drift-dashboard.sh +17 -6
  329. package/scripts/diagnostics/health.sh +351 -110
  330. package/scripts/diagnostics/history-analysis.sh +12 -4
  331. package/scripts/diagnostics/mcp-doctor.sh +575 -0
  332. package/scripts/diagnostics/perf.sh +225 -0
  333. package/scripts/diagnostics/scorecard.sh +118 -0
  334. package/scripts/diagnostics/secret-governance.sh +58 -0
  335. package/scripts/diagnostics/security-score.sh +139 -93
  336. package/scripts/diagnostics/smoke-test.sh +87 -0
  337. package/scripts/diagnostics/snapshot.sh +89 -0
  338. package/scripts/diagnostics/verify.sh +107 -0
  339. package/scripts/diagnostics/verify_state.sh +2 -2
  340. package/scripts/diagnostics/version-locks.sh +79 -0
  341. package/scripts/diagnostics/workstation-attestation.sh +181 -0
  342. package/scripts/docs/build-manual.sh +883 -0
  343. package/scripts/docs/check-manual.sh +213 -0
  344. package/scripts/dot/commands/agent.sh +465 -0
  345. package/scripts/dot/commands/ai.sh +416 -0
  346. package/scripts/dot/commands/aliases.sh +250 -0
  347. package/scripts/dot/commands/appearance.sh +21 -4
  348. package/scripts/dot/commands/core.sh +59 -4
  349. package/scripts/dot/commands/diagnostics.sh +132 -3
  350. package/scripts/dot/commands/fleet.sh +399 -0
  351. package/scripts/dot/commands/lint.sh +177 -0
  352. package/scripts/dot/commands/manual.sh +168 -0
  353. package/scripts/dot/commands/meta.sh +148 -17
  354. package/scripts/dot/commands/patterns.sh +54 -0
  355. package/scripts/dot/commands/restore.sh +57 -35
  356. package/scripts/dot/commands/secrets.sh +151 -9
  357. package/scripts/dot/commands/security.sh +3 -0
  358. package/scripts/dot/commands/tools.sh +268 -27
  359. package/scripts/dot/data/alias-deprecations.tsv +2 -0
  360. package/scripts/dot/lib/bento.sh +49 -0
  361. package/scripts/dot/lib/log.sh +194 -0
  362. package/scripts/dot/lib/platform.sh +98 -0
  363. package/scripts/dot/lib/ui.sh +507 -0
  364. package/scripts/dot/lib/utils.sh +318 -18
  365. package/scripts/fonts/install-nerd-fonts.sh +19 -10
  366. package/scripts/fonts/patch-fonts.sh +1 -0
  367. package/scripts/git-hooks/install.sh +11 -0
  368. package/scripts/git-hooks/pre-commit +12 -0
  369. package/scripts/git-hooks/pre-commit-audit.sh +145 -0
  370. package/scripts/git-hooks/pre-push +29 -0
  371. package/scripts/git-hooks/prepare-commit-msg +29 -0
  372. package/scripts/lib/secrets_provider.sh +158 -0
  373. package/scripts/maintenance/check-updates.sh +131 -0
  374. package/scripts/ops/ai-setup.sh +55 -0
  375. package/scripts/ops/bundle.sh +77 -0
  376. package/scripts/ops/chaos.sh +49 -0
  377. package/scripts/ops/chezmoi-apply.sh +245 -17
  378. package/scripts/ops/chezmoi-diff.sh +1 -0
  379. package/scripts/ops/chezmoi-remove.sh +2 -0
  380. package/scripts/ops/chezmoi-update.sh +34 -2
  381. package/scripts/ops/heal-chezmoi.sh +51 -0
  382. package/scripts/ops/heal-system.sh +128 -0
  383. package/scripts/ops/heal-tools.sh +340 -0
  384. package/scripts/ops/heal.sh +98 -342
  385. package/scripts/ops/post-apply-repair.sh +106 -0
  386. package/scripts/ops/prewarm.sh +127 -0
  387. package/scripts/ops/release.sh +252 -0
  388. package/scripts/ops/rollback.sh +86 -28
  389. package/scripts/ops/setup.sh +137 -0
  390. package/scripts/ops/teleport.sh +2 -1
  391. package/scripts/qa/coverage-baseline.sh +60 -0
  392. package/scripts/qa/docs-coverage.sh +111 -0
  393. package/scripts/qa/reliability-audit.sh +138 -0
  394. package/scripts/qa/traceability-coverage.sh +116 -0
  395. package/scripts/qa/validate-examples.sh +26 -0
  396. package/scripts/qa/wsl-contract.sh +11 -0
  397. package/scripts/release/package-policy-bundles.sh +125 -0
  398. package/scripts/secrets/age-init.sh +1 -0
  399. package/scripts/secrets/create-secrets-file.sh +1 -0
  400. package/scripts/secrets/encrypt-ssh-key.sh +1 -0
  401. package/scripts/security/backup.sh +44 -4
  402. package/scripts/security/dns-doh.sh +36 -14
  403. package/scripts/security/encryption-check.sh +27 -12
  404. package/scripts/security/enforce-policies.sh +11 -16
  405. package/scripts/security/firewall.sh +76 -20
  406. package/scripts/security/lock-configs.sh +2 -2
  407. package/scripts/security/lock-screen.sh +40 -18
  408. package/scripts/security/manage-secrets.sh +42 -29
  409. package/scripts/security/ssh-cert.sh +203 -0
  410. package/scripts/security/telemetry-kill.sh +40 -18
  411. package/scripts/security/usb-safety.sh +37 -15
  412. package/scripts/theme/apply-gnome-theme.sh +87 -56
  413. package/scripts/theme/extract-theme.py +677 -0
  414. package/scripts/theme/install-boot-logo.sh +1 -0
  415. package/scripts/theme/install-catppuccin-themes.sh +57 -33
  416. package/scripts/theme/install-cursors.sh +1 -0
  417. package/scripts/theme/install-file-icons.sh +1 -0
  418. package/scripts/theme/install-grub-theme.sh +11 -1
  419. package/scripts/theme/install-lock-icon.sh +1 -0
  420. package/scripts/theme/merge-wallpaper.sh +141 -0
  421. package/scripts/theme/rebuild-themes.sh +309 -0
  422. package/scripts/theme/switch.sh +308 -137
  423. package/scripts/theme/wallpaper-rotate.sh +66 -12
  424. package/scripts/theme/wallpaper-sync.sh +386 -31
  425. package/scripts/tools/cmatrix.sh +1 -0
  426. package/scripts/tools/detect-collisions.py +1 -1
  427. package/scripts/tools/emoji-picker.sh +4 -1
  428. package/scripts/tools/figlet-banner.sh +1 -0
  429. package/scripts/tools/log-rotate.sh +2 -1
  430. package/scripts/tools/lolcat-wrap.sh +1 -0
  431. package/scripts/tools/pipes.sh +1 -0
  432. package/scripts/tuning/linux.sh +23 -13
  433. package/scripts/tuning/macos.sh +13 -4
  434. package/scripts/uninstall.sh +85 -0
  435. package/scripts/version-sync.sh +487 -0
  436. package/templates/chezmoi-data/geekom-a9.toml.example +21 -0
  437. package/templates/chezmoi-data/mac-m1.toml.example +16 -0
  438. package/templates/chezmoi-data/mac-t2-linux.toml.example +21 -0
  439. package/templates/chezmoi-data/surface-pro-7p.toml.example +21 -0
  440. package/templates/projects/go/.github/workflows/ci.yml +31 -0
  441. package/templates/projects/go/README.md +1 -1
  442. package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +1 -0
  443. package/templates/projects/go/go.sum +0 -0
  444. package/templates/projects/molecule/README.md +1 -1
  445. package/templates/projects/node/.github/workflows/ci.yml +30 -0
  446. package/templates/projects/node/README.md +1 -1
  447. package/templates/projects/node/package-lock.json +12 -0
  448. package/templates/projects/node/src/index.js +1 -0
  449. package/templates/projects/packer/README.md +1 -1
  450. package/templates/projects/python/.github/workflows/ci.yml +34 -0
  451. package/templates/projects/python/README.md +1 -1
  452. package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +1 -0
  453. package/templates/projects/python/tests/test_basic.py +1 -0
  454. package/docs/ARCHITECTURE.md +0 -229
  455. package/docs/COMPLIANCE.md +0 -47
  456. package/docs/FEATURES.md +0 -166
  457. package/docs/FONTS.md +0 -147
  458. package/docs/INSTALL.md +0 -119
  459. package/docs/KEYS.md +0 -40
  460. package/docs/OPERATIONS.md +0 -130
  461. package/docs/PR_DESCRIPTION.md +0 -149
  462. package/docs/SECRETS.md +0 -76
  463. package/docs/SECURITY.md +0 -30
  464. package/docs/SECURITY_CHECKLIST.md +0 -25
  465. package/docs/TASK.md +0 -99
  466. package/docs/TESTING.md +0 -190
  467. package/docs/TOOLS.md +0 -146
  468. package/docs/UTILS.md +0 -105
  469. package/docs/WALKTHROUGH.md +0 -165
  470. package/dot_config/clippy.toml +0 -55
  471. package/dot_config/dotfiles/versions.env.tmpl +0 -19
  472. package/dot_config/firefox/user.js +0 -8
  473. package/dot_config/git/config.tmpl +0 -77
  474. package/dot_config/go/aliases.sh +0 -61
  475. package/dot_config/go/env.sh +0 -24
  476. package/dot_config/ice/README.md +0 -13
  477. package/dot_config/ipython/profile_default/ipython_config.py.tmpl +0 -5
  478. package/dot_config/lsd/config.yaml +0 -19
  479. package/dot_config/nvim/snippets/all.lua +0 -9
  480. package/dot_config/nvim/snippets/python.lua +0 -16
  481. package/dot_config/shell/00-container-detect.sh +0 -53
  482. package/dot_config/shell/05-core-safety.sh.tmpl +0 -13
  483. package/dot_config/shell/40-ls-colors.sh.tmpl +0 -31
  484. package/dot_config/shell/90-theme-switch.sh +0 -70
  485. package/dot_config/topgrade/topgrade.toml.tmpl +0 -42
  486. package/dot_config/waybar/style.css +0 -8
  487. package/dot_config/zsh/rc.d/20-zinit.zsh.tmpl +0 -22
  488. package/dot_local/bin/executable_zig-install +0 -89
  489. package/dot_local/bin/voice_ops +0 -7
  490. package/scripts/ops/health-check.sh +0 -380
  491. package/scripts/tests/README.md +0 -241
  492. package/scripts/tests/benchmark.sh +0 -91
  493. package/scripts/tests/framework/assertions.sh +0 -283
  494. package/scripts/tests/framework/mocks.sh +0 -201
  495. package/scripts/tests/framework/test_runner.sh +0 -189
  496. package/scripts/tests/integration/test_install.sh +0 -237
  497. package/scripts/tests/performance/benchmark_runner.sh +0 -156
  498. package/scripts/tests/performance/regression_check.sh +0 -73
  499. package/scripts/tests/performance/stress_test.sh +0 -65
  500. package/scripts/tests/test-aliases.sh +0 -25
  501. package/scripts/tests/test-docker.sh +0 -48
  502. package/scripts/tests/unit/test_ai_aliases.sh +0 -158
  503. package/scripts/tests/unit/test_ai_cli_checks.sh +0 -47
  504. package/scripts/tests/unit/test_backup.sh +0 -227
  505. package/scripts/tests/unit/test_case_functions.sh +0 -238
  506. package/scripts/tests/unit/test_cd_aliases.sh +0 -367
  507. package/scripts/tests/unit/test_dot_cli.sh +0 -217
  508. package/scripts/tests/unit/test_encode64.sh +0 -67
  509. package/scripts/tests/unit/test_environment.sh +0 -78
  510. package/scripts/tests/unit/test_extract.sh +0 -163
  511. package/scripts/tests/unit/test_framework_edge_cases.sh +0 -113
  512. package/scripts/tests/unit/test_genpass.sh +0 -298
  513. package/scripts/tests/unit/test_install_edge_cases.sh +0 -167
  514. package/scripts/tests/unit/test_installers.sh +0 -172
  515. package/scripts/tests/unit/test_keygen.sh +0 -68
  516. package/scripts/tests/unit/test_logging.sh +0 -96
  517. package/scripts/tests/unit/test_os_detection_comprehensive.sh +0 -388
  518. package/scripts/tests/unit/test_package_managers_comprehensive.sh +0 -321
  519. package/scripts/tests/unit/test_prependpath.sh +0 -66
  520. package/scripts/tests/unit/test_prependpath_refactored.sh +0 -89
  521. package/scripts/tests/unit/test_rd.sh +0 -230
  522. package/scripts/tests/unit/test_security_fixes.sh +0 -130
  523. package/scripts/tests/unit/test_security_scripts.sh +0 -87
  524. package/scripts/tests/unit/test_template_validation.sh +0 -238
  525. package/scripts/tests/unit/test_utility_functions.sh +0 -144
  526. package/scripts/tests/unit/test_wave1_alias_split.sh +0 -132
  527. package/scripts/tests/unit/test_wave1_ci_pinning.sh +0 -61
  528. package/scripts/tests/unit/test_wave1_gitleaks_config.sh +0 -52
  529. package/scripts/tests/unit/test_wave1_heal_fixes.sh +0 -97
  530. package/scripts/tests/unit/test_wave1_install_gpg.sh +0 -35
  531. package/scripts/tests/unit/test_wave1_zshenv_path.sh +0 -89
  532. package/scripts/tests/unit/test_wave1_zshrc_lazy_hook.sh +0 -115
  533. package/scripts/tests/unit/test_wave2_dot_new_guard.sh +0 -75
  534. package/scripts/tests/unit/test_zipf.sh +0 -76
  535. /package/docs/{LEGACY_ROADMAP.md → archive/LEGACY_ROADMAP.md} +0 -0
  536. /package/docs/{REPO_AUDIT.md → archive/REPO_AUDIT.md} +0 -0
  537. /package/docs/{KEY_ROTATION.md → security/KEY_ROTATION.md} +0 -0
  538. /package/dot_config/ansible/{ansible.cfg.tmpl → ansible.cfg} +0 -0
  539. /package/dot_config/docker/{config.json.tmpl → config.json} +0 -0
  540. /package/dot_config/k9s/{config.yaml.tmpl → config.yaml} +0 -0
  541. /package/dot_config/pypoetry/{config.toml.tmpl → config.toml} +0 -0
  542. /package/dot_config/{pyrightconfig.json.tmpl → pyrightconfig.json} +0 -0
  543. /package/dot_config/tflint/{tflint.hcl.tmpl → tflint.hcl} +0 -0
  544. /package/dot_config/yarn/{yarnrc.yml.tmpl → yarnrc.yml} +0 -0
  545. /package/dot_config/zsh/rc.d/{40-bell.zsh.tmpl → 40-bell.zsh} +0 -0
  546. /package/dot_config/zsh/rc.d/{50-login-fortune.zsh.tmpl → 50-login-fortune.zsh} +0 -0
@@ -0,0 +1,275 @@
1
+ # Tutorial: Encrypt a Secret
2
+
3
+ How to store an API key (or any secret) encrypted in the repository using Age and SOPS — decrypted automatically on `dot apply`.
4
+
5
+ ## The Threat Model
6
+
7
+ Secrets in plaintext config files are:
8
+
9
+ - Committed to Git history (permanent record)
10
+ - Visible to every process on the machine
11
+ - Included in backup archives
12
+
13
+ Secrets encrypted with Age:
14
+
15
+ - Cipher text committed to Git is useless without the private key
16
+ - Private key (`~/.config/age/keys.txt`) never leaves the user's machine
17
+ - Per-machine policy: only authorized hosts hold keys for their share of secrets
18
+
19
+ ## Step 1: Generate an Age Key (First Time Only)
20
+
21
+ ```sh
22
+ age-keygen -o ~/.config/age/keys.txt
23
+ chmod 600 ~/.config/age/keys.txt
24
+ ```
25
+
26
+ The public key is embedded in the file:
27
+
28
+ ```sh
29
+ cat ~/.config/age/keys.txt
30
+ # created: 2026-04-16T09:00:00Z
31
+ # public key: age1qy90l...xyz
32
+ AGE-SECRET-KEY-1A...
33
+ ```
34
+
35
+ Copy the public key — you'll reference it when encrypting.
36
+
37
+ ## Step 2: Choose Encryption Method
38
+
39
+ Two approaches are supported:
40
+
41
+ | Method | Best For | Filename |
42
+ |:---|:---|:---|
43
+ | **Chezmoi encrypt** | Individual files (API tokens, config snippets) | `dot_config/token.age` |
44
+ | **SOPS** | YAML/JSON with multiple secrets, selective field encryption | `dot_config/creds.sops.yaml` |
45
+
46
+ ## Step 3A: Chezmoi-Encrypted File
47
+
48
+ Create an unencrypted source file:
49
+
50
+ ```sh
51
+ mkdir -p ~/tmp
52
+ echo "sk_live_abc123" > ~/tmp/stripe-key.txt
53
+ ```
54
+
55
+ Import it as encrypted:
56
+
57
+ ```sh
58
+ chezmoi add --encrypt ~/tmp/stripe-key.txt
59
+ ```
60
+
61
+ This:
62
+
63
+ 1. Reads `~/tmp/stripe-key.txt`
64
+ 2. Encrypts with your Age public key
65
+ 3. Stores encrypted content at `~/.dotfiles/dot_tmp/stripe-key.txt.age`
66
+ 4. Template reads encrypted content at apply time and decrypts to target
67
+
68
+ Delete the plaintext source:
69
+
70
+ ```sh
71
+ rm ~/tmp/stripe-key.txt
72
+ ```
73
+
74
+ On `dot apply`, chezmoi decrypts and writes to `~/tmp/stripe-key.txt`. If someone lacks the private key, they see only the encrypted `.age` file in Git.
75
+
76
+ ## Step 3B: SOPS-Encrypted YAML
77
+
78
+ SOPS encrypts **values** in YAML/JSON while preserving the structure. Useful when you want:
79
+
80
+ - Multiple secrets in one file
81
+ - Encryption of only sensitive fields (leaving metadata readable)
82
+ - Multi-recipient (e.g. the work laptop AND the backup laptop can decrypt)
83
+
84
+ Configure SOPS once:
85
+
86
+ ```yaml
87
+ # .sops.yaml (at repo root)
88
+ creation_rules:
89
+ - path_regex: \.sops\.yaml$
90
+ age: age1qy90l...xyz
91
+ ```
92
+
93
+ Create a secrets file:
94
+
95
+ ```yaml
96
+ # dot_config/credentials.sops.yaml
97
+ database:
98
+ host: db.prod.example.com
99
+ user: app
100
+ password: supersecret
101
+ api_keys:
102
+ stripe: sk_live_abc
103
+ sendgrid: SG.xyz
104
+ ```
105
+
106
+ Encrypt it:
107
+
108
+ ```sh
109
+ sops --encrypt --in-place dot_config/credentials.sops.yaml
110
+ ```
111
+
112
+ The file now contains ciphertext blobs where plaintext values were:
113
+
114
+ ```yaml
115
+ database:
116
+ host: ENC[AES256_GCM,data:...]
117
+ user: ENC[AES256_GCM,data:...]
118
+ password: ENC[AES256_GCM,data:...]
119
+ api_keys:
120
+ stripe: ENC[AES256_GCM,data:...]
121
+ sendgrid: ENC[AES256_GCM,data:...]
122
+ sops:
123
+ age:
124
+ - recipient: age1qy90l...xyz
125
+ enc: |
126
+ -----BEGIN AGE ENCRYPTED FILE-----
127
+ ...
128
+ ```
129
+
130
+ To edit the encrypted file:
131
+
132
+ ```sh
133
+ sops dot_config/credentials.sops.yaml
134
+ # Opens in $EDITOR with decrypted content; re-encrypts on save
135
+ ```
136
+
137
+ ## Step 4: Reference the Secret in a Template
138
+
139
+ Chezmoi has a built-in `decrypt` helper:
140
+
141
+ ```go
142
+ # dot_bashrc.tmpl
143
+ export STRIPE_KEY="{{ include "dot_tmp/stripe-key.txt.age" | decrypt | trim }}"
144
+ ```
145
+
146
+ For SOPS:
147
+
148
+ ```go
149
+ # Use the sopsDecrypt template function
150
+ {{- $creds := dict -}}
151
+ {{- $creds = sopsDecrypt "dot_config/credentials.sops.yaml" | fromYaml }}
152
+ export DB_PASSWORD="{{ $creds.database.password }}"
153
+ ```
154
+
155
+ ## Step 5: Commit and Verify
156
+
157
+ ```sh
158
+ cd ~/.dotfiles
159
+ git add .sops.yaml dot_config/credentials.sops.yaml dot_tmp/stripe-key.txt.age
160
+ git commit -sS -m "feat(secrets): add stripe and database credentials"
161
+ git push
162
+ ```
163
+
164
+ Verify the commit doesn't leak secrets:
165
+
166
+ ```sh
167
+ git log -p HEAD~1..HEAD | grep -v ENC | grep -iE 'password|secret|key' || echo "Clean"
168
+ ```
169
+
170
+ On the next machine:
171
+
172
+ ```sh
173
+ dot update
174
+ # Chezmoi decrypts using that machine's Age key
175
+ # If decryption fails, the template errors with a clear message
176
+ ```
177
+
178
+ ## Step 6: Multi-Recipient (Fleet)
179
+
180
+ To allow multiple hosts to decrypt the same secret, add more recipients:
181
+
182
+ ```yaml
183
+ # .sops.yaml
184
+ creation_rules:
185
+ - path_regex: \.sops\.yaml$
186
+ age: >-
187
+ age1qy90l...xyz,
188
+ age1z2x33...abc,
189
+ age1mm0kk...def
190
+ ```
191
+
192
+ Re-encrypt the affected files:
193
+
194
+ ```sh
195
+ sops updatekeys dot_config/credentials.sops.yaml
196
+ ```
197
+
198
+ Now any host with one of those three private keys can decrypt. Hosts without any matching key see the encrypted file but cannot read it.
199
+
200
+ ## Step 7: Rotate a Compromised Key
201
+
202
+ ```sh
203
+ # 1. Generate a new Age key on the affected host
204
+ age-keygen -o ~/.config/age/keys.txt.new
205
+ mv ~/.config/age/keys.txt.new ~/.config/age/keys.txt
206
+
207
+ # 2. Update .sops.yaml with the new public key
208
+
209
+ # 3. Re-encrypt all SOPS files with the new recipient list
210
+ find . -name '*.sops.yaml' -exec sops updatekeys {} \;
211
+
212
+ # 4. Commit and push
213
+ git add .sops.yaml dot_config/*.sops.yaml
214
+ git commit -sS -m "chore(secrets): rotate Age key"
215
+
216
+ # 5. On other fleet hosts
217
+ dot update
218
+ ```
219
+
220
+ Old key still works for existing ciphertext, but new secrets use the new key. To force deprecation, delete the old key from `.sops.yaml` and `sops updatekeys` all files.
221
+
222
+ ## Verifying No Plaintext Leaks
223
+
224
+ CI runs three secret scanners (`gitleaks`, `detect-secrets`, `trufflehog`) on every commit. You can run them locally:
225
+
226
+ ```sh
227
+ gitleaks detect --redact --source .
228
+ detect-secrets scan --update .secrets.baseline
229
+ trufflehog git file://. --only-verified
230
+ ```
231
+
232
+ If any scanner finds a potential leak, the commit is blocked.
233
+
234
+ ## Operational Rules
235
+
236
+ 1. **Never commit plaintext secrets** — use chezmoi encrypt or SOPS
237
+ 2. **Never commit `~/.config/age/keys.txt`** — it's gitignored; double-check before pushing
238
+ 3. **Age keys are per-host** — don't copy them via Git; use secure channels (1Password, Bitwarden, physical USB)
239
+ 4. **Rotate on team membership changes** — when someone leaves, update recipients and rotate all shared secrets
240
+ 5. **Audit with `dot verify --security`** — runs gitleaks + signature + policy hash checks
241
+
242
+ ## Troubleshooting
243
+
244
+ ### "Could not decrypt: no age key found"
245
+
246
+ `~/.config/age/keys.txt` is missing or unreadable:
247
+
248
+ ```sh
249
+ chmod 600 ~/.config/age/keys.txt
250
+ ls -la ~/.config/age/keys.txt
251
+ # -rw------- 1 user user 189 Apr 16 09:00 keys.txt
252
+ ```
253
+
254
+ ### "sops: file encrypted with outdated recipients"
255
+
256
+ A secret file has an old recipient list. Fix:
257
+
258
+ ```sh
259
+ sops updatekeys path/to/file.sops.yaml
260
+ ```
261
+
262
+ ### Secrets Not Applying After Apply
263
+
264
+ Check that `dot_tmp/stripe-key.txt.age` is committed. Run:
265
+
266
+ ```sh
267
+ chezmoi apply --verbose dot_tmp/stripe-key.txt
268
+ # Will show decrypt attempts and errors
269
+ ```
270
+
271
+ ## Next
272
+
273
+ - [Concept: Trust Model](../01-concepts/02-trust-model.md) — the security architecture
274
+ - [Reference: Secret operations](../03-reference/01-dot-cli.md#secrets)
275
+ - [Security: Secret management](../../security/SECRETS.md)
@@ -0,0 +1,279 @@
1
+ # Tutorial: Deploy to a Fleet
2
+
3
+ Roll out `.dotfiles` across multiple workstations and verify they're in sync.
4
+
5
+ ## Scenario
6
+
7
+ You have three hosts:
8
+
9
+ - **macbook-t2** — your MacBook (current host, already installed)
10
+ - **surface-pro** — your Linux laptop (new install)
11
+ - **geekom-a9** — your desktop NUC (new install)
12
+
13
+ Goal: all three running identical `.dotfiles` with per-host customization, with auditable cross-host attestation.
14
+
15
+ ## Step 1: Per-Host Install
16
+
17
+ On each new host:
18
+
19
+ ```sh
20
+ bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/master/install.sh)"
21
+ ```
22
+
23
+ During `chezmoi init`, answer with the host's preset:
24
+
25
+ - Surface Pro → `machine = "surface-pro"`
26
+ - Geekom A9 → `machine = "geekom-a9"`
27
+
28
+ ## Step 2: Exchange Signing Keys
29
+
30
+ Each host has its own SSH ED25519 key. To verify commits and attestations across the fleet, publish each host's public key to every other host.
31
+
32
+ **On each host, copy the public key:**
33
+
34
+ ```sh
35
+ cat ~/.ssh/id_ed25519.pub
36
+ # ssh-ed25519 AAAAC3N...jkl5 user@macbook-t2
37
+ ```
38
+
39
+ **Collect all three keys. Append them to `~/.ssh/allowed_signers` on every host:**
40
+
41
+ ```
42
+ user@macbook-t2 ssh-ed25519 AAAAC3N...jkl5
43
+ user@surface-pro ssh-ed25519 AAAAC3N...abc7
44
+ user@geekom-a9 ssh-ed25519 AAAAC3N...def9
45
+ ```
46
+
47
+ Optionally commit `allowed_signers` as a template so all hosts receive updates via `dot update`:
48
+
49
+ ```sh
50
+ # On macbook-t2
51
+ chezmoi add ~/.ssh/allowed_signers
52
+ git add -A && git commit -sS -m "feat(ssh): add fleet signing keys"
53
+ git push
54
+ ```
55
+
56
+ Now every other host gets the updated list on `dot update`.
57
+
58
+ ## Step 3: Share the Age Key (for Shared Secrets)
59
+
60
+ If you want shared secrets decrypted on all three hosts, each host must have an Age key recipient in `.sops.yaml`.
61
+
62
+ Option A: Share one key across all hosts (simpler, less granular).
63
+ Option B: Each host has its own key; all three are listed as recipients (better operational security).
64
+
65
+ For Option B:
66
+
67
+ ```sh
68
+ # On macbook-t2 (already set up)
69
+ grep "public key:" ~/.config/age/keys.txt
70
+
71
+ # On surface-pro
72
+ age-keygen -o ~/.config/age/keys.txt
73
+ grep "public key:" ~/.config/age/keys.txt
74
+
75
+ # On geekom-a9
76
+ age-keygen -o ~/.config/age/keys.txt
77
+ grep "public key:" ~/.config/age/keys.txt
78
+ ```
79
+
80
+ Add all three public keys to `.sops.yaml`:
81
+
82
+ ```yaml
83
+ creation_rules:
84
+ - path_regex: \.sops\.yaml$
85
+ age: >-
86
+ age1aaa...111, # macbook-t2
87
+ age1bbb...222, # surface-pro
88
+ age1ccc...333 # geekom-a9
89
+ ```
90
+
91
+ Re-encrypt existing secrets for the new recipients:
92
+
93
+ ```sh
94
+ # On macbook-t2
95
+ find . -name '*.sops.yaml' -exec sops updatekeys {} \;
96
+ git add .sops.yaml dot_config/*.sops.yaml
97
+ git commit -sS -m "chore(secrets): add fleet recipients"
98
+ git push
99
+ ```
100
+
101
+ Other hosts on `dot update` decrypt with their own private key automatically.
102
+
103
+ ## Step 4: Verify Fleet Alignment
104
+
105
+ From any host:
106
+
107
+ ```sh
108
+ dot fleet attest
109
+ ```
110
+
111
+ Expected output:
112
+
113
+ ```
114
+ Fleet Attestation — v0.2.500
115
+
116
+ Host Git SHA Policy Tools OK Drift Verified
117
+ -------------- ---------- --------- ---------- ------- --------
118
+ macbook-t2 abc123d 0x7f2a… ✓ 0 ✓
119
+ surface-pro abc123d 0x7f2a… ✓ 0 ✓
120
+ geekom-a9 abc123d 0x7f2a… ✓ 0 ✓
121
+ -------------- ---------- --------- ---------- ------- --------
122
+ FLEET STATUS: 3/3 aligned
123
+ ```
124
+
125
+ If any row shows drift or missing verification:
126
+
127
+ ```sh
128
+ # Check which host is out of sync
129
+ dot fleet diff
130
+
131
+ # SSH into the affected host and fix
132
+ ssh surface-pro
133
+ dot doctor && dot heal
134
+ dot update
135
+ ```
136
+
137
+ ## Step 5: Per-Host Customization
138
+
139
+ Each host has its own `~/.config/chezmoi/chezmoi.toml` — use it for things that shouldn't propagate:
140
+
141
+ ```toml
142
+ # surface-pro's chezmoi.toml
143
+ [data]
144
+ machine = "surface-pro"
145
+ theme = "dome-dark" # per-host default
146
+ default_shell = "fish"
147
+ terminal_font_size = 11 # smaller for HiDPI
148
+ ```
149
+
150
+ ```toml
151
+ # geekom-a9's chezmoi.toml
152
+ [data]
153
+ machine = "geekom-a9"
154
+ theme = "valley-dark" # different default
155
+ default_shell = "zsh"
156
+ terminal_font_size = 14 # larger for external 1440p
157
+ ```
158
+
159
+ Both hosts render from the same templates, producing correct platform-appropriate output.
160
+
161
+ ## Step 6: Fleet-Wide Updates
162
+
163
+ When you push a commit to master, each host pulls independently:
164
+
165
+ ```sh
166
+ # On each host
167
+ dot update
168
+ ```
169
+
170
+ `dot update` does:
171
+
172
+ 1. `git pull --rebase --autostash` in `~/.dotfiles`
173
+ 2. `chezmoi apply` with progress output
174
+ 3. `dot heal` if apply detected drift
175
+ 4. Reports changes applied
176
+
177
+ For simultaneous update across the fleet (requires SSH):
178
+
179
+ ```sh
180
+ dot fleet sync
181
+ # Connects to each host in parallel
182
+ # Runs `dot update` via SSH
183
+ # Collects outcomes
184
+ ```
185
+
186
+ ## Step 7: Secrets Rotation
187
+
188
+ When a secret is compromised (or as part of routine rotation):
189
+
190
+ ```sh
191
+ # 1. Edit the secret on any host
192
+ sops dot_config/credentials.sops.yaml
193
+ # Change the compromised value, save
194
+
195
+ # 2. Commit and push
196
+ git commit -sS -am "chore(secrets): rotate stripe key"
197
+ git push
198
+
199
+ # 3. All fleet hosts pick up the new value on next update
200
+ # On each host:
201
+ dot update
202
+ ```
203
+
204
+ Since hosts all have the Age private key for themselves, decryption is automatic.
205
+
206
+ ## Step 8: Decommission a Host
207
+
208
+ When retiring a host:
209
+
210
+ ```sh
211
+ # 1. Remove the host's public key from allowed_signers
212
+ # Edit dot_ssh/allowed_signers.tmpl (on any host)
213
+
214
+ # 2. Remove the host's Age public key from .sops.yaml
215
+
216
+ # 3. Re-encrypt all SOPS files (remove the decommissioned recipient)
217
+ find . -name '*.sops.yaml' -exec sops updatekeys {} \;
218
+
219
+ # 4. Commit
220
+ git commit -sS -am "chore(fleet): decommission geekom-a9"
221
+ git push
222
+
223
+ # 5. On the decommissioned host: wipe the dotfiles state
224
+ rm -rf ~/.dotfiles ~/.local/bin/dot ~/.config/chezmoi ~/.config/age
225
+ ```
226
+
227
+ ## Troubleshooting
228
+
229
+ ### "Fleet host unreachable"
230
+
231
+ `dot fleet` couldn't SSH to a host. Check:
232
+
233
+ ```sh
234
+ ssh surface-pro 'dot version'
235
+ # If this fails, fix SSH connectivity first
236
+ ```
237
+
238
+ ### Drift on One Host
239
+
240
+ Run `dot heal` on that host:
241
+
242
+ ```sh
243
+ ssh surface-pro 'dot heal'
244
+ ```
245
+
246
+ If drift persists:
247
+
248
+ ```sh
249
+ ssh surface-pro 'chezmoi diff | head -50'
250
+ # Inspect what's different
251
+ ```
252
+
253
+ ### Policy Hash Mismatch
254
+
255
+ One host has an older policy than the others. Usually means that host missed an update:
256
+
257
+ ```sh
258
+ ssh surface-pro 'dot update'
259
+ ```
260
+
261
+ ### Attestation Signature Failed
262
+
263
+ The host's SSH key isn't in `~/.ssh/allowed_signers` on the verifying host. Fix by redistributing `allowed_signers`.
264
+
265
+ ## Summary
266
+
267
+ A three-host fleet:
268
+
269
+ - Installs from one repository
270
+ - Has independent signing keys (each host verifies commits from others)
271
+ - Can share secrets across specific hosts via SOPS recipients
272
+ - Is auditable via `dot fleet attest`
273
+ - Updates independently with `dot update` (or in parallel with `dot fleet sync`)
274
+
275
+ ## Next
276
+
277
+ - [Concept: Fleet Architecture](../01-concepts/04-fleet.md)
278
+ - [Reference: Fleet Commands](../03-reference/01-dot-cli.md#fleet)
279
+ - [Operations: Fleet Deployment](../../architecture/fleet-deployment.md)