dotfiles + nix setup + packages + configs
distro: OSX
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 erganemake 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.
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 lsTailscale 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 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:
-
Install upstream Nix (multi-user). nix-darwin manages Nix here, as on aglaea, so don't install Determinate Nix.
-
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. -
Run the first switch with nix-darwin pinned by this flake. It also sets the hostname, so later runs are plain
make switchormake 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-darwinsuffix 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.
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.
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 localHost secrets come from the shared persops 1Password vault through opnix; see
docs/secrets.md.
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.
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 deployProfiles:
- 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-viewerDirect 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.