Fleet changelogs · dev.ecs0.net
jdmbair13m5-changelog-20260825-0450-host-fixes-claude-permissions-xcode-pip-docker

jdmbair13m5 — HOST-LOCAL FIXES — 2026-08-25 04:33–04:50 EDT

Host: jdmbair13m5 (Mac17,3 M5, macOS 26.6.2, richh UID 502) Agent: claude@jdmbair13m5 (Opus 5 1M), session bf8bfeac Scope of THIS document: changes made to THIS MACHINE only. Fleet-wide and cross-host work is in the companion doc SESSION-RESUME-jdmbair13m5-20260825-0450.md — deliberately kept separate.


1. Claude Code would not relaunch — "permission denied" — FIXED (was blocking all work)

Symptom: Rich could not start a new Claude Code session at all. The running session survived only because it was still executing from the OLD 2.1.240 inode.

Cause: the documented Homebrew-cask bug. The claude-code@latest upgrade to 2.1.243 landed 2026-08-25 03:36 and the binary arrived mode 644:

/opt/homebrew/Caskroom/claude-code@latest/2.1.243/claude   ->   -rw-r--r--

Fix: chmod +x on the resolved binary. Also cleared a com.apple.quarantine xattr.

Verified: claude --version -> 2.1.243 (Claude Code); a fresh spawn exits 0.

THE DOCUMENTED FLEET GUARD IS A NO-OP HERE — must be corrected fleet-wide

CLAUDE.md currently prescribes:

test -x "$(readlink -f "$(command -v claude)")" || chmod +x "$(readlink -f "$(command -v claude)")"

That guard silently passes while the binary is mode 644. The Caskroom carries an inherited ACL:

0: group:admin inherited allow read,write,execute,append,readattr,writeattr,...

richh is in admin, so access(2) — and therefore test -x — returns TRUE with no execute bit in the mode. Observed directly: [ -x ] reported EXECUTABLE while stat reported -rw-r--r-- and exec failed. Test the mode bits instead:

case "$(stat -f %Sp "$B")" in *x*x*x) : ;; *) chmod +x "$B" ;; esac

Quarantine was NOT the blocker. codex, agy and ollama all run fine while still quarantined. Mode 644 was the fault; the xattr clear was incidental.

Also checked, clean: superpowers/hooks/run-hook.cmd is -rwxr-xr-x; no other cask binary lacks +x (only codex-package.json, correctly — it is JSON).


2. Xcode was BROKEN — xcodebuild unusable — FIXED

Symptom: dev_update reported "Xcode first-launch tasks are pending" and xcodebuild -runFirstLaunch failed (exit 1).

Cause — worse than the message suggests: /Applications/Xcode.app (26.6) was installed, but the active developer directory pointed at the Command Line Tools:

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory
'/Library/Developer/CommandLineTools' is a command line tools instance

So this host could not run xcodebuild at all — no simulators, no iOS SDKs.

Fix: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer sudo xcodebuild -license accept sudo xcodebuild -runFirstLaunch # -> "Install Succeeded", exit 0

Verified: xcodebuild -version -> Xcode 26.6, Build 17F113. xcodebuild -showsdks lists iOS 26.5, iOS Simulator 26.5, DriverKit 25.5.

FLEET ACTION: worth checking every host that builds RTTy / LogTTY / rooDB. A CLT-selected host cannot xcodebuild, and dev_update surfaces it only as a vague "first-launch tasks pending". Check with env -u DEVELOPER_DIR xcode-select -p (the -u matters: a DEVELOPER_DIR in the environment silently overrides the answer).


3. pip3 check reported problems — FIXED the Homebrew way

Symptom: wheel 0.47.0 requires packaging, which is not installed.

Context: pip3 is /opt/homebrew/Cellar/python@3.14/3.14.7/bin/pip3 and the PEP 668 EXTERNALLY-MANAGED marker is present. Per the standing rule, anything under a brew Cellar is Homebrew's to upgrade — a pip install here would be a forbidden forced write into the Cellar (and pip would refuse without --break-system-packages).

Fix: brew install python-packaging (26.3). Verified: python3 -m pip check -> No broken requirements found.


4. Docker — NOT a host fault; correctly reported

Docker Desktop is installed and healthy. Launched it and proved it: docker info -> 29.7.2, docker system prune -f succeeded (0B reclaimed, 0 containers, 0 images).

It then exited on its own ~1 minute later: ExitHealthyState, exit 0, "process terminated due to explicit cancel" — its Resource Saver idling the VM. dev_update does not stop it (its Docker section is read-only, verified by reading the source).

Conclusion: a stopped daemon on an idle machine is CORRECT. No host change made. The fix belongs in the script's severity classification — see the companion doc.


5. Antigravity PATH entries are STALE — reported, NOT changed

Both are on PATH and neither directory exists:

/Users/richh/.antigravity/antigravity/bin        MISSING
/Users/richh/.antigravity-ide/antigravity-ide/bin MISSING

agy itself is fine: /opt/homebrew/Caskroom/antigravity-cli/1.1.20/antigravity.

This stale PATH string is the source of the documented pgrep -f agy false positive — Codex MCP server processes carry it in their environment, so a pattern match on "agy" hits their env block rather than a real agy process.

Not removed: it lives in a shell rc that may be fleet-shared. Left for rdmsm4x to rule on.


6. Global CLAUDE.md adopted from rdmsm4x

Local was dba7b5458a8bdd14 (48,781 B, 623 lines); adopted rdmsm4x's e31b4e0d7fa02d6a (57,091 B, 742 lines). Backup: ~/.claude/CLAUDE.md.bak-preAdopt-20260825-044645.

Three sections gained, zero lost (verified by heading-level diff):

  1. Directory naming — never give a non-bundle folder a macOS bundle extension (.app, etc.).
  2. Unattended escalation to Fable 5 — pre-authorized when unattended AND a named trigger is met; attended sessions still ask.
  3. External-budget workers — codex (ChatGPT budget) and agy (Google budget) as worker tiers, strict isolation via ~/dev/_handoff/, caps of 2 codex + 1 agy alongside 2 Claude subagents.

Permissions safety check (read-only, nothing written): permissions.defaultMode is bypassPermissions — correct, matching the standing instruction. Not touched.

CAVEAT: adopted verbatim, which may include lead-host-specific rules. Rich has asked claude@rdmsm4x to tailor a fleet version and has left that call to them. If a tailored version arrives, take it over this verbatim copy; the backup above makes that trivial.


Undo