2026-07-25 athena 125-Commit Catch-Up and the Intel node-gyp Wall
Follow-on from 2026-07-25 Remote Obsidian MCP Access Session Rollover: while on athena anyway, brought the box current.
What I set out to do
Pull the dotfiles repo on athena and run hm switch. Expected routine.
What I actually did
athena was 125 commits behind, sitting at 2026-07-07. Clean fast-forward, but two things had to be cleared first. nvim/lazy-lock.json had local drift (lazy.nvim had self-updated its own pin) against many upstream “chore: update nvim plugins” commits, so the pull would have refused. Stashed rather than discarded. And ntfy/templates/signoz.yml looked like an untracked file but is a symlink into the nix store: home-manager output landing inside the repo tree, because the repo is ~/.config.
Then the switch failed, and lied about it.
Failure 1, the exit code. I ran hm switch 2>&1 | tee log; echo "EXIT=${PIPESTATUS[0]}". athena’s shell is zsh, which has no PIPESTATUS (it uses $pipestatus, 1-indexed). The expansion was empty, the trailing echo became the last command, and the whole thing returned 0 while the build had actually died. Only grepping the log for ^error showed the truth.
Failure 2, the actual break. bitwarden-cli bundles the native lmdb module, which node-gyp compiles from source. That needs full Xcode, and athena has Command Line Tools only, so /usr/bin/xcodebuild is a stub that errors. It cascaded through home-manager-path → activation-script → the generation. Nothing was applied.
Fixed by gating bitwarden-cli behind desktop, kept inline at its list position because packages.nix documents that gating must preserve ordering or every desktop host rehashes home-manager-path. A/B eval confirmed the aarch64 drvPath was byte-identical, and the package-list eval showed 0 bitwarden matches on x86_64-darwin against 1 on aarch64. Second switch landed: generation 10 → 11, bw correctly absent.
Also committed the previous session’s 2026-07-25 Lazy-Loading AGENTS.md and User-Only Skill Invocation work as three atomic commits, and fixed the root flake, which excluded x86_64-darwin and left athena with no direnv shell at all.
What was striking
- The comment explaining an exclusion was wrong, and it was wrong in a way that hid the real constraint. The root flake blamed arrow-cpp via LiteLLM for excluding Intel. But that governs the desktop HM profile in
nix/flake.nix; the root flake ships linters and formatters and has neither. The actual blocker was unstable dropping the platform. Believing the comment would have produced a fix that aborted. Same shape as the service-token reversal earlier today: a confidently-stated rationale on one side said nothing about the real constraint. - Two flakes, two pins.
nix/flake.nixalready solved x86_64-darwin with anixpkgs-26.05-darwininput. The root flake never received it. Solving a problem once in a repo does not mean it is solved everywhere. - “Builds on Intel with 0 errors” was true until it wasn’t. That note has held since 2026-07-04 Home Manager athena Server Profile. The real rule is narrower: anything with a node-gyp native module fails, and it only ever shows on athena, because aarch64 gets a cache hit and never compiles. Expect the next one.
- A trailing
echosilently becomes your exit status. Worth remembering for any wrapped remote command, not just this one.set -o pipefailworks in both shells; shell-specific array indexing does not. - The stale-comment and the lying-exit-code failures share a root: I trusted a summary (a comment, a status code) over the artifact it described.
direnv resolved, and a near-miss from brew upgrade
Pulled to bebad2a2 and direnv works on athena: loads the flake, uses the cached dev shell, resolves prek/stylua/ruff/shellcheck/just to store paths.
It looked broken first. nix develop --command true failed with [[ ! -v "${varName}" ]]: conditional binary operator expected, because -v needs bash 4.2+ and athena’s only bash is /bin/bash 3.2.57. An atlas control passed cleanly, which pointed at the platform rather than the flake. But direnv carries its own bash (bash_path = a nix bash-interactive-5.3p9), so it never touches the system one. The failure was an artifact of my SSH invocation, not the thing I was trying to test. Testing the proxy instead of the actual goal nearly produced a wrong conclusion.
Separately, a brew upgrade on the host bumped node to 26.5.0 while the MCP bridge had been running 21 days on the old one. Working, but only until something restarted it: a reboot would have been the first time mcpvault ever ran on node 26, and a failure there would have looked exactly like the outage this morning. Restarted it deliberately, under observation: new tree came up on Cellar/node/26.5.0, initialize returned mcpvault 1.28.1 in 4.5ms, edge still gives the healthy 401 Access challenge. cloudflared needed nothing (already 2026.7.3, which brew confirms is current, and its running process still maps a live binary rather than a deleted one).
Also gitignored the HM-generated /ntfy/ output, anchored like the existing /glance/ and /claude-ops/ entries so it cannot swallow a future source dir.
Top tomorrow
- Absent-data alert on the MCP bridge (carried over, still the highest-value item and the only thing that would have caught this morning’s rollover).
athena’s generation 11 is stale— done. Switched to generation 12 on47a7c3e0, then garbage collected: expired generations 3-11, 824 store paths deleted, 3.8 GiB freed (store 15G → 11G). GC ran clean, confirming the athena/atlas split holds: no.appbundles in athena’s store, so none of the App Management permission aborts that block GC on atlas.git statuson athena is now completely clean for the first time, since the/ntfy/ignore removed the last permanently-untracked file.athena’s Obsidian MCP setup is still hand-rolled outside Nix, so it drifts silently from the repo.— retracted, this was wrong. Checked the history when challenged on it. The Homebrew setup is a documented decision from the 2026-07-03 runbook (“Toolchain — DECIDED: Homebrew-only, not the Nix dotfiles flake”), on the reasoning that nixpkgs 26.05 is the last release supporting x86_64-darwin (ends 2026) while Homebrew covers the hardware to ~2027. Sequencing forced it too: the MCP went up at 23:17 on 07-03, and athena’s HM profile did not exist until2aff736at 11:25 the next morning. It remains deliberate, sincehome-server.nix’s curated imports omitobsidian-remote-mcp.nix. The real loose end is far smaller:home.nix:63-67still describes the retired NixOS box as owning the tunnel, which was logged as a follow-up that day and never done.
What was striking (second pass)
- “Upgrade succeeded” and “the running process uses the upgrade” are different claims.
brew cleanupdeletes the old Cellar path out from under a live process. Checking thetxtmapping inlsofdistinguishes them; the version string alone does not. - A long-lived process silently pins a dependency version. The 21-day-old bridge was the only thing standing between node 26.5.0 and a surprise at next boot.
Related
- Host: 2026-07-04 Home Manager athena Server Profile · 2026-07-20 lib.uv Refactor and athena 26.05 Pin
- Project: Dotfiles Host Profiles via Private Flake
- Commits:
0a8200d(bitwarden gate),7bb9f5a/fad6a84/7b94d1a(AGENTS.md + skill),bebad2a(root flake)