- install.sh: Add xattr/codesign fix after cp on macOS - install.sh: Add portable timeout verification using perl - INSTALL.md: Recommend cargo install --path as primary method - INSTALL.md: Document macOS signature issue and fix - blue doctor: Detect com.apple.provenance xattr with fix hint - blue doctor: Verify code signature with codesign --verify - blue doctor: 3-second liveness timeout for hanging binaries Fixes dyld hang at _dyld_start when copied binaries have stale signatures after Homebrew library updates. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.7 KiB
RFC 0060: Reliable Binary Installation
| Status | Accepted |
| Date | 2026-02-06 |
| Relates To | RFC 0052 (CLI Hook Management), RFC 0049 (Synchronous Guard) |
Summary
Fix the binary installation flow so it doesn't produce binaries that hang on macOS. Add cargo install --path support as the primary install method, and post-copy re-signing as a fallback safety net.
Problem Statement
The Bug
When the Blue binary is copied to ~/.cargo/bin/ (or /usr/local/bin/), macOS preserves stale extended attributes (com.apple.provenance) and the adhoc code signature from the original build. If Homebrew updates a dynamically linked library (e.g., openssl@3) between when the binary was built and when it's run, dyld hangs indefinitely at _dyld_start during signature verification. The process never reaches main().
Observed Behavior
$ blue init
[hangs forever — no output, 0 bytes written to stdout/stderr]
$ sample $PID
890 _dyld_start (in dyld) + 0 # 100% of samples stuck here
kill -9cannot terminate the process (state:UE— uninterruptible + exiting)- The same binary works fine when run from
target/release/bluedirectly - The same binary works fine when copied to
/tmp/without extended attributes
Root Cause
cp on macOS preserves extended attributes by default. The combination of:
com.apple.provenancexattr (marks binary as "downloaded/copied")- Stale adhoc linker signature from original
cargo build - Updated dylib versions on disk (Homebrew
openssl@3)
...causes dyld to enter a signature verification path that deadlocks.
Evidence
| Test | Result |
|---|---|
target/release/blue init |
Works (0.1s) |
cp to ~/.cargo/bin/blue then run |
Hangs at _dyld_start |
cp to /tmp/blue-copy then run |
Works (no provenance xattr) |
Symlink to target/release/blue |
Works |
xattr -cr + codesign --force --sign - |
Works |
Proposal
1. Support cargo install as primary method
Add workspace metadata so cargo install --path apps/blue-cli works correctly. This lets Cargo handle the build-and-install atomically, producing a freshly signed binary.
INSTALL.md becomes:
# Build and install (recommended)
cargo install --path apps/blue-cli
# Then configure for Claude Code
blue install
2. Post-copy re-signing in install.sh
For users who prefer install.sh or cp:
cp "$BINARY" "$INSTALL_DIR/blue"
# Fix macOS code signature after copy
if [[ "$OSTYPE" == "darwin"* ]]; then
xattr -cr "$INSTALL_DIR/blue"
codesign --force --sign - "$INSTALL_DIR/blue"
fi
3. Post-copy re-signing in blue install (Rust)
The handle_install_command currently doesn't copy the binary anywhere — it only sets up hooks, skills, and MCP config. But the SessionStart hook adds target/release/ to PATH, which is fragile. Instead:
- Add an optional
--binaryflag toblue installthat copies and re-signs the binary to~/.cargo/bin/ - Or detect if running from
target/release/and warn the user
4. blue doctor validation
Add a check to blue doctor that detects:
- Stale code signatures on the installed binary
- Mismatched binary vs source versions
- Presence of
com.apple.provenancexattr on the binary
Implementation Plan
Phase 1: Fix install.sh (immediate)
- Add
xattr -cr+codesign --force --sign -after everycpof the binary - Add a verification step that actually runs
blue --versionwith a timeout
Phase 2: Support cargo install --path
- Verify
cargo install --path apps/blue-cliworks with the current workspace layout - Update
INSTALL.mdto recommendcargo installas the primary method - Update
install.shto usecargo installinstead ofcpwhen possible
Phase 3: Harden blue doctor
- Add macOS signature check:
codesign --verifyon the installed binary - Add xattr check: warn if
com.apple.provenanceis present - Add timeout-based liveness check: run
blue --versionwith a 3s timeout
Files Changed
| File | Change |
|---|---|
install.sh |
Add post-copy re-signing for macOS |
apps/blue-cli/src/main.rs |
Add doctor checks for signature issues |
INSTALL.md |
Recommend cargo install --path as primary method |
Test Plan
install.shproduces a working binary on macOS after Homebrew openssl updatecargo install --path apps/blue-cliproduces a working binaryblue doctordetects provenance xattr on binary (warns with fix hint)blue doctorpasses on a freshly installed binary- Install flow works on Linux (no-op for codesign steps via
#[cfg(target_os = "macos")])
"Right then. Let's get to it."
-- Blue