Feat/sops nix #12

Merged
finn.markwitz merged 16 commits from feat/sops-nix into main 2026-09-14 13:06:46 +02:00
16 Commits
Author SHA1 Message Date
finn.markwitz 9dbd6ff71d Merge branch 'main' into feat/sops-nix 2026-09-14 13:06:33 +02:00
finn.markwitzandClaude Sonnet 5 807eea7e4f feat(homepage): add Athena Dashboard link to jupiter's homepage
Hermes Agent's dashboard runs on mibook, but the homepage-dashboard
service only runs on jupiter, so wire it in as a manual cross-host
entry rather than via my.homepage.services (which is scoped per-host
and would be inert on mibook).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sux8hmeb2qadqPqbJ1zNzL
2026-09-10 11:09:48 +02:00
finn.markwitzandClaude Sonnet 5 67973559c0 feat(hermes-agent): expose dashboard on LAN with basic auth
Bind the backend to 0.0.0.0:9119 in dashboard mode so the web UI is
reachable from the local network, open the port in the firewall, and
add dashboard username/password credentials to the mibook hermes-env
secret.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sux8hmeb2qadqPqbJ1zNzL
2026-09-10 10:56:50 +02:00
finn.markwitz c4b29e1e06 feat(mibook): populate Hermes Agent credentials 2026-09-08 21:10:28 +02:00
finn.markwitzandClaude Sonnet 5 0756eb94cd docs: correct spec+plan for self-vs-inputs in imports
The fix subagent found that inputs.hermes-agent.nixosModules.default
inside `imports` causes infinite recursion in this repo's wiring
(inputs comes from _module.args, which merges after imports resolve;
self comes from specialArgs, which is available at import-time).
Tested both ways. Update docs to show self.inputs, matching commit
31e1910.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 17:51:31 +02:00
finn.markwitzandClaude Sonnet 5 31e1910d75 fix(mibook): import hermes-agent module from the profile, not machines/configuration.nix
machines/configuration.nix wired hermes-agent.nixosModules.default into
mibook's mibook-only modules list. modules/environments/default.nix is
machine-agnostic, so jupiter still evaluated a
services.hermes-agent = lib.mkIf false { ... } definition for an option it
never declared as existing — NixOS errors on that regardless of mkIf's
condition, breaking nixosConfigurations.jupiter (and the repo's sole CI
job) entirely.

Fix: import the upstream module unconditionally from inside
modules/environments/hermes-agent/default.nix itself, so the option is
declared everywhere modules/environments/default.nix loads, and only ever
turned on where my.profiles.hermes-agent.enable = true (mibook). Also adds
users.users.finn.extraGroups = [ "hermes" ], required for the hermes CLI to
be usable per the corrected design. machines/configuration.nix no longer
mentions hermes-agent.

Deviates from the reconciled spec/plan text in one respect: uses `self`
(from specialArgs) instead of `inputs` (from _module.args) to reach the
flake input inside `imports`. Using `inputs` there reproduced infinite
recursion — NixOS resolves a module's imports before _module.args
assignments are merged, so an import list cannot depend on an arg that
itself comes from config. `self` is available at import-time via
specialArgs, `inputs` is not, in this repo's wiring. See report for detail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 17:50:11 +02:00
finn.markwitzandClaude Sonnet 5 0249aae2ae docs: correct spec+plan per final whole-plan review findings
Final review (opus) found a Critical bug (jupiter's nixosConfigurations
stopped evaluating because hermes-agent.nixosModules.default was wired
through machines/configuration.nix's mibook-only module list, while
the profile module itself is loaded on both machines) plus three
Important gaps: secrets persist to /var/lib/hermes/.hermes/.env, not
/run/secrets; Telegram/Email need explicit ALLOWED_USERS or they're
wide open / silently drop messages; addToSystemPackages's CLI needs
group membership finn didn't have. All four corrected in the docs
here; the actual code fix is a separate dispatched task.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 17:44:39 +02:00
finn.markwitzandClaude Sonnet 5 ac32aca351 docs: correct plan's sops build-check assumption
Task 1's implementer found sops.validateSopsFiles makes secret-key
existence a build-time check (via manifest.json.drv), not an
activation-time one as the plan assumed. Corrects Step 10 to reflect
reality rather than leave future readers misled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 17:22:09 +02:00
finn.markwitz 731678ecac feat(mibook): add Hermes Agent profile module 2026-09-08 17:20:40 +02:00
finn.markwitzandClaude Sonnet 5 32e0faa82c chore: ignore .superpowers/ scratch workspace
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 17:01:54 +02:00
finn.markwitzandClaude Sonnet 5 a83f7e63a0 docs: implementation plan for Hermes Agent on mibook
Task 1 is agent-executable repo wiring (flake input, profile module,
secret declaration), build-checked with nix build. Tasks 2-5 are an
operator-run runbook: OAuth login, Anthropic billing check, Telegram
bot setup, and typing real secrets into $EDITOR via sops - none of
that is meant to pass through an agent session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 17:00:38 +02:00
finn.markwitzandClaude Sonnet 5 6212b4fcf7 docs: design spec for Hermes Agent on mibook
Locks in host (mibook, not jupiter), deployment mode (NixOS native
module), and auth (claude setup-token / ANTHROPIC_TOKEN, Max extra
credits) after a grilling round. Builds on feat/sops-nix as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbvwg3Qt2u9nbkEA3wL17S
2026-09-08 16:56:26 +02:00
finn.markwitz 621ca5dde6 docs: sops-nix secrets workflow
Operator runbook for adding a secret, adding a new host, and rotating
keys, plus a pointer from CLAUDE.md's architecture overview.
2026-09-08 15:43:50 +02:00
finn.markwitz a00916864c feat(mibook): decrypt placeholder secret via host age key
Proves the sops-nix pipeline end to end on mibook: encrypts a
throwaway secret to the operator + mibook host keys, declares it in
machines/mibook/secrets.nix, and verifies it decrypts to
/run/secrets/placeholder (root:root, 0400) on nixos-rebuild switch.

Also removes the dead `let secrets = config.sops.secrets;` binding
from both environments.nix files — leftover from an earlier abandoned
plan, never referenced.
2026-09-08 15:43:45 +02:00
finn.markwitz 3ab8bfbb91 feat(sops): add sops-nix input, core module and devShell tooling
Wires sops-nix into every machine via machines/core/sops.nix so hosts
decrypt with their existing SSH host key. Adds a devShell exposing
sops/age/ssh-to-age for the operator workflow, which also fixes .envrc's
previously no-op `use flake`.
2026-09-08 15:43:36 +02:00
finn.markwitz 70deb25080 chore: Flake Update 2026-08-21 10:30:01 +02:00