Fleet changelogs · dev.ecs0.net
jdmbair13m5-changelog-20260824-1327-config-audit-llm-install-permissions-repair

jdmbair13m5 — config audit, LLM toolchain install, permissions repair, app-profile page

Host: jdmbair13m5 (Apple M5, arm64, macOS 26.6.2, Homebrew /opt/homebrew) Agent: claude (Claude Code 2.1.240, session richh-75) Window: started 2026-08-22 23:51:38 EDT · closed 2026-08-24 13:27 EDT Scope: jdmbair13m5 only, plus two declared new-file writes to rdmsm4x:~/dataroo.net/wiki/. No shared fleet file (dev_update.zsh, FLEET.md, AGENT_COORDINATION.md, agent_msg.zsh, any global instruction file) was edited.


Summary

Audited Claude Code config and shell settings on the fleet's 6th host, installed the missing LLM toolchain to match rdmsm4x, repaired two real filesystem defects, and published an app-profile + permissions-repair page. Three findings correct existing fleet documentation.


1. Installs (Homebrew casks, all verified on PATH)

Cask Result
chatgpt 26.818.41705 → /Applications/ChatGPT.app
antigravity 2.9.1 → /Applications/Antigravity.app
antigravity-cli 1.1.19 → agy at /opt/homebrew/bin/agy
antigravity-ide 2.5.5 → agy-ide, antigravity-ide
ollama-app 0.32.15 → /Applications/Ollama.app, ollama on PATH

Already present, unchanged: claude (Desktop), claude-code@latest 2.1.240, codex 0.149.0.

Not installed, and why: nativ — https://blaizzy.github.io/nativ/ — MLX-VLM local-model GUI, Apple Silicon only, MIT, GitHub releases only; no Homebrew formula or cask exists. Queued.


2. Claude Code config (/doctor run)

Install health clean: single Homebrew install, no npm/native duplicates, no ~/.claude/local, all settings files parse, no hooks configured, version current for its cask channel (2.1.240 == published claude-code@latest 2.1.240). installMethod: null is normal for brew.

Files changed on this host:

File Change Undo
~/.claude/settings.json permissions.allow 2 → 48 rules (mirrored from rdmsm4x); added statusLine + SessionStart hook ~/.claude/settings.json.bak-doctor-20260823-000813
~/.claude/statusline-verify.sh new, sha256 prefix af91fd95e4e3 (matches rdmsm4x), mode 755 delete + drop the hook key

Shell/prompt now matches the fleet: .zshrc, ~/.config/starship.toml, ~/.claude/statusline.sh and statusline-verify.sh are all hash-identical to rdmsm4x. Statusline smoke-tested — renders host, date, time, cwd, model, context and limit segments.

permissions.defaultMode — do not read this changelog as authority. At ~00:08 EDT Rich chose auto in answer to this session and it was written; at 00:15 EDT he chose bypassPermissions in answer to a different session on this same host (richh-b6) and that was written. Later write won. Value as of 2026-08-24 13:27 EDT is bypassPermissions with the 48 allow rules intact beneath it. This session has not modified permissions since 00:08 and will not.

Not applied deliberately: ~/.zshrc.local from rdmsm4x. It contains live ATLASSIAN_API_TOKEN / ATLASSIAN_EMAIL exports. A credential is not copied to a new host. Referenced by NAME only, per house rules.

Not trimmed deliberately: ~/.claude/CLAUDE.md is 48,503 chars (~12.1k est. tokens) and trips the large-memory-file warning (~40k char floor). Lines 246–646 (26,693 chars, ~6.7k est. tokens) duplicate FLEET.md + AGENT_COORDINATION.md, which the file itself tells agents to read. Those blocks are written by sync_fleet_knowledge.zsh, so a local edit would be reverted by the next sync and would read as drift to peers. Raised with rdmsm4x instead (msg 20260823-001139-E4FEF029).


3. macOS permissions repair

Account state verified correct: richh UID 502, PrimaryGroupID 20, NFSHomeDirectory /Users/richh, shell /bin/zsh. No rich account exists in DirectoryServices. ~ 750 · ~/.ssh 700 · private keys 600 · .pub 644 · ~/.secrets 700. No world-writable files. No group anomalies.

lrwxr-xr-x  1 root  staff  4 Aug 21 06:57 /Users/richh/rich -> rich

Target was the relative string rich, resolved against its own parent — the link pointed at itself and dangled. Created Aug 21 06:57, the same minute as the legitimate /Users/rich compat symlink; the ln -s ran twice, once from inside /Users/richh instead of /Users. It was the only object in the entire home tree not owned by richh. Removed with sudo rm. Post-repair find /Users/richh -maxdepth 1 ! -user richh returns zero rows.

Defect 2 — stale install prefix (FIXED)

~/.config/uv/uv-receipt.json recorded install_prefix: /Users/rich/.local/bin. Resolved only via the compat symlink; would break if that link were ever removed. Rewritten to /Users/richh/.local/bin.

Snapshots for both: ~/.local/state/permissions-repair-20260823-003209/

Left alone, deliberately


4. Local LLM layout — three corrections to fleet documentation

4a. Ollama is split 2:2 by INSTALL METHOD, not just presence

All four Apple Silicon hosts run 0.32.15, but by two different mechanisms:

Host Method Binary Models RAM
rdmsm4x cask ollama-app inside /Applications/Ollama.app 10 128 GB
jdmbair13m5 cask ollama-app inside /Applications/Ollama.app 2 32 GB
rdmbair13m5 formula ollama Cellar/ollama/0.32.15/bin 6 32 GB
rdmbair15m5 formula ollama Cellar/ollama/0.32.15/bin 5 32 GB

Consequence: FLEET.md "do not re-fix" note #4 is HALF WRONG. It states "on macOS it's a menu-bar cask, not a brew services daemon." True on the two cask hosts; false on the two formula hosts, where it genuinely is a formula that can run as a service. Anyone acting on that note reaches the wrong conclusion on half the ARM fleet. Needs correcting when FLEET.md is next touched — flagged to rdmsm4x, not edited here.

4b. ToshLLM is Intel-only because it is x86_64-only

/Applications/ToshLLM.app on rdmpw3265m and rdmpw3275m only.

CFBundleIdentifier   dev.engel.toshllm
Version              0.85.7          Size 165 MB     LSMinimumSystemVersion 14.0
Executable           Mach-O 64-bit executable x86_64     <-- no arm64 slice
codesign             TeamIdentifier=not set              <-- ad-hoc, NOT notarized
Installed            2026-08-22 12:45

Not a policy split — an architecture constraint. No cask and no formula exists, so a brew adoption pass can never manage it; it must be excluded by name.

4c. Benchmark — jdmbair13m5 (M5, 32 GB, Mac17,3)

MODEL                  ARCH           LOAD_ms PREFILL_tps    GEN_tps   GEN_tok
qwen3.5:35b-mlx        qwen3_5_moe          4      713.73      40.89       160
qwen3.8:27b-mlx        qwen3_5              5      201.14      14.75       160

The MoE model wins on both axes despite being 3 GB larger on disk (21 GB vs 18 GB) — sparse activation against a dense 27.8B. Verified order-independent by running both orders. qwen3.5:35b-mlx should be this host's default.

METHOD WARNING, worth propagating. The first pass used a ~25-token prompt and reported prefill 27.3 (dense) vs 9.0 (MoE) — the opposite ranking. On a short prompt, prefill is dominated by fixed per-request overhead, so the number describes the harness, not the model. Any Ollama benchmark using a one-line prompt is measuring itself. Same family as the fleet's existing silent-wrong-answer traps: exit 0, no stderr, reads as a property of the system.

Script: ~/.local/state/ollama_bench.zsh (v2 — ~400-token prompt, explicit warmup so the first model does not absorb the cold-load penalty alone, prints architecture beside the numbers).

rdmbair13m5 is identical silicon (Mac17,3, M5, 32 GB) and carries 6 models to this host's 2 — the clean A/B pair, and the parity target for model pulls.


5. Published artifact — app profile + permissions repair page

Content: 107 non-font casks tiered by host spread (16 universal / 12 / 14 / 23 / 42 one-offs) with per-app adoption-risk class and a live-regenerating brew install command; the brew adoption exclusion standard and a drop-in dev_update.zsh function; the 8-check macos_permissions_repair procedure with its two silent-false-clean traps; open questions.

dev.dataroo.net origin is DOWN — re-verified 2026-08-24 13:27 EDT

nginx is not running on rdmsm4x and there is no cloudflared config there; the only listener is a Python process on 127.0.0.1:8765. The 401 from https://dev.dataroo.net/ is Cloudflare Access answering at the EDGE, not the site. It looks "up and protected" while nothing is behind it. apps.html is staged correctly and will serve when nginx returns.

Serving bug worth keeping

Python's http.server calls getfqdn() on every client address for its log line. A tailnet IP has no PTR record, so the handler blocks on DNS before writing a byte: TCP connects, HTTP hangs. nc -z succeeded from rdmsm4x while curl timed out at 15 s — that split is the diagnostic. The macOS firewall was already permitting the binary; disabling it would have fixed nothing and weakened the host. Fix: address_string() returning the raw IP + ThreadingHTTPServer. Reusable server: ~/.local/state/serve_appprofile.py.


6. Brew adoption standard (proposed, not yet installed into dev_update.zsh)

Never --greedy: every GUI cask sampled on this fleet is flagged auto_updates — Warp, Obsidian, Chrome, Ghostty, Raycast, Docker, Parallels, Dropbox, Ollama, Claude, Setapp. Those self-update in place, so on-disk version routinely exceeds the cask's pinned version and --greedy reinstalls them backwards.

Exclusion classes: Setapp-managed bundles (Setapp on 4 hosts; Paste is a Setapp app), Mac App Store installs, licensed/activated apps, and unnotarized direct downloads with no cask (ToshLLM).

Live double-management already present: Microsoft Excel/Word/PowerPoint/Outlook/OneNote and OneDrive are Mac App Store installs on jdmbair13m5 and exist as casks on another host.


7. Coordination

.zprofile — the one file where this host is AHEAD

rdmsm4x:~/.zprofile hardcodes /opt/homebrew/bin/brew and /Users/richh/.local/bin. jdmbair13m5 carries the architecture-correct variant that branches on /opt/homebrew vs /usr/local and uses $HOME. Per the no-hardcoded-prefix rule the jdmbair13m5 version should be promoted upward, not overwritten. sha256 prefix e0574cfb0943.


8. Fleet documentation found stale (flagged, not edited)

  1. FLEET.md §3 — agy listed as on "all 5"; it is on all 6 as of 2026-08-22. The "Claude Code specifics" block says "all five" throughout.
  2. FLEET.md note #4 — the Ollama cask-vs-formula error above (§4a).
  3. FLEET.md / CLAUDE.md — permissions.defaultMode documented as bypassPermissions fleet-wide. Observed: rdmsm4x ran auto, jdmbair13m5 ran dontAsk at session start. Three values, one claim. The file is right that this key is an observation, not a setting anyone owns — a live session rewrites it.
  4. ~/CLAUDE.md code-signing claim about rdmbair15m5 (§7).

Upstream, not a fleet file: the /doctor skill's check 8 hardcodes permissions.defaultMode = "auto" as its recommended option. That collides with Rich's standing instruction and will recur on every /doctor run on every host until amended. Not edited unilaterally — raised for whoever owns skill propagation.


Verification performed

Outstanding

See ~/dev/fleet/hosts/jdmbair13m5-onboarding/ISSUES.md.