Skip to content
ciPublic

About

personal ops

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

persops - Personal OPS

dotfiles + nix setup + packages + configs

distro: OSX

Deployment

make deploy snapshots and checks the current flake before switching any target. Aglaea can deploy itself locally and Amalthea remotely; Amalthea can deploy only itself until remote SSH deployment is enabled on Aglaea. Ergane deploys only itself, and no other host can deploy it.

make deploy                                  # host defaults
make deploy TARGETS=amalthea
make deploy TARGETS=aglaea                   # run on aglaea
make deploy TARGETS="aglaea amalthea"        # run on aglaea
make deploy TARGETS=ergane                   # run on ergane

make switch picks the Darwin config named after hostname -s and refuses unknown hosts.

Amalthea is always deployed and verified before a selected Aglaea switch so a controller restart cannot interrupt remaining remote work. From an Amp orb, delegate to the Aglaea runner for both targets or the Amalthea runner for Amalthea only. Aglaea health warnings (exit 1) are reported without failing a successful activation; health failures (exit 2 or unexpected errors) still fail the deployment.

Darwin-only deployment builds the repository check and evaluates the selected machine. make check remains the full gate, including every machine and Linux checks; run it on Amalthea after the Rex metadata prefetch below.

Rex on Amalthea

Amalthea runs the official Rex NixOS login server. Tailscale Serve exposes it at https://amalthea.reverse-justitia.ts.net, and the accounts policy maps catalin.irimie@gmail.com to the existing cat account. The server starts at boot; its terminals run as cat, with the same files and permissions as an SSH login.

In Rex for Mac, choose Add Remote Host… and enter that address. For CLI access:

rex hosts add amalthea https://amalthea.reverse-justitia.ts.net
rex -S amalthea ls

Tailscale must be connected on the client. The service has no anonymous or public listener. Other named Tailscale Services keep their own HTTPS mappings.

The rex flake input pins the vendor's snapshot channel. Fetching its private beta package metadata requires the supplied package credential in a private netrc file; Amalthea's copy is /etc/nix/netrc, readable only by root. Keep that credential out of the repository and Nix store. Local make deploy fetches the inputs with sudo before running unprivileged checks and builds. For standalone make check, make build, or make switch, prefetch once after a Rex update or garbage collection:

sudo nix flake archive --option netrc-file /etc/nix/netrc .

Aglaea needs no Rex credential to deploy itself. To deploy Amalthea remotely from Aglaea, provision the vendor netrc outside this repository, owned by the invoking user with mode 0600, and set netrc-file to its absolute path in that user's Nix configuration. Never provision it on Ergane. See the vendor's Linux docs.

Check the service with systemctl status rex-login-server rex-tailscale-serve and its logs with journalctl -u rex-login-server -u rex-tailscale-serve.

Ergane (work Mac)

Ergane uses the work profile (lib/mksystem.nix): core CLI and language toolchains, coding agents, Slack, and work-safe casks. Personal apps, CTF/media tooling, and the extra language stacks stay on the personal profile. It is isolated from personal infrastructure: no persops vault token or home secrets (enforced by an assertion), restic, Tailscale, amalthea SSH entry, Atuin sync, share-page skill, or remote targets. Neovim skips Supermaven cloud completion there (vim.g.persops_profile).

Homebrew on ergane is fully declarative: a switch uninstalls any formula or cask not declared in darwin.nix or machines/ergane.nix. Commits are signed with the Secretive key ergane-sign; pushes authenticate through the 1Password SSH agent.

First switch on a fresh Mac:

  1. Install upstream Nix (multi-user). nix-darwin manages Nix here, as on aglaea, so don't install Determinate Nix.

  2. Hand apps that were installed outside Homebrew over to their casks, e.g. brew install --cask --adopt claude, or move the app to the Trash first.

  3. Run the first switch with nix-darwin pinned by this flake. It also sets the hostname, so later runs are plain make switch or make deploy:

    sudo nix --extra-experimental-features 'nix-command flakes' \
      run --inputs-from ~/p/persops nix-darwin#darwin-rebuild -- \
      switch --flake ~/p/persops#ergane

    If activation stops on unrecognized files in /etc, rename them with the .before-nix-darwin suffix it suggests and rerun.

Never copy the persops-opnix token to ergane.

AeroSpace is installed through Homebrew only. Nix manages its configuration and zen-toggle script, which calls the Homebrew CLI. After a Homebrew AeroSpace upgrade, restart /Applications/AeroSpace.app to keep the server and CLI matched.

AWDL on macOS

modules/awdl.nix installs awdl and a root-owned, one-shot startup job on Aglaea and Ergane. AWDL defaults to off at boot; disabling it reduced the Wi-Fi latency spikes measured on Aglaea. Normal Wi-Fi and internet access remain enabled.

  • awdl on: enable for AirDrop and other nearby-device features.
  • awdl off: disable again.
  • awdl toggle: switch the current state.
  • awdl status: show the current state; also the default with no arguments.

Changes use sudo in a terminal or the native macOS authorization dialog without one. The startup job waits up to two minutes for AWDL to become available, then disables it once and exits. It does not continually enforce the off state, so manual awdl on is preserved until another change or reboot. Reloading a changed startup job during a Nix switch also reapplies the off default. macOS itself may reactivate AWDL for nearby-device features; use awdl status to check.

On Aglaea, the old hand-installed ~/.local/bin/awdl and /Library/LaunchDaemons/local.awdl-default-off.plist are retired after the first successful deployment. Nix owns the command in the system profile and /Library/LaunchDaemons/org.nixos.awdl-default-off.plist thereafter.

Apply Ergane's configuration locally on Ergane with make deploy TARGETS=ergane. The AWDL module uses only local macOS controls and adds no personal-infrastructure access to the work profile.

Updating AI Packages

Codex, Claude Code, and Pi-related agent packages are pinned through flake inputs.

To pull the latest AI versions and deploy them:

nix flake update codex-cli-nix claude-code-nix llm-agents
make local

Host secrets

Host secrets come from the shared persops 1Password vault through opnix; see docs/secrets.md.

Ops status

Amalthea's Grafana monitoring provides host and NVMe dashboards alongside the existing Uptime Kuma availability checks.

ops-status prints a local health summary for the current machine: Nix, persops VCS state, Restic, Time Machine, Tailscale, desktop services, and Linux systemd services where available. Use ops-status --remote for a small read-only amalthea SSH probe. On Aglaea, Storage Box client readiness is separate from the S3 home-backup jobs. Appended Restic stderr is diagnostic history; launchd exit codes and log freshness determine the reported job health. Missing or failed Aglaea backup jobs, an unavailable Nix daemon, and broken Tailscale are failures (exit 2). Stale diagnostics, desktop issues, and checks without a completed run are warnings (exit 1). Restic jobs wait up to two hours for a repository lock when another backup or maintenance operation is active.

Can also run nix flake update to refresh everything, then switch.

When Pi changes version, update modules/ai/pi/settings.json lastChangelogVersion to the new pi --version 2>&1, read Pi's installed CHANGELOG.md, and summarize the skipped Pi changelog entries in the handoff. This keeps Pi from showing the same changelog on every startup while still surfacing the news once during the update.

Adding AI Skills

Repo-owned skills live in modules/ai/skills/* and propagate from Nix into local agent dirs.

Default flow:

modules/ai/scripts/add-skill.sh shadcn/ui
make deploy

Profiles:

  • default all: Claude + Codex + Pi
  • --profile codex: Codex only

Example:

modules/ai/scripts/add-skill.sh --profile codex owner/repo
modules/ai/scripts/add-skill.sh https://github.com/shadcn/ui --skill shadcn
modules/ai/scripts/add-skill.sh https://github.com/openclaw/agent-skills/tree/main/skills/session-viewer

Direct GitHub tree/blob links must select a skill directory or its SKILL.md. The importer uses gh to resolve the branch, tag, or commit (including refs with slashes), pins installation to that commit, and records the revision and path in UPSTREAM.txt. Existing skill names are rejected across the entire batch before any copying or profile changes; updating existing skills remains a separate edit.

Removed shared skills are unlinked by Home Manager on the next deployment. The retired Pi Compound Engineering bundle (ce-*, its lfg launcher, and companion agents) is moved out of active discovery into ~/.pi/agent/backups/ during activation, preserving mutable local copies.

About

personal ops

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages