blue/.blue/docs/rfcs/0060-reliable-binary-installation.accepted.md
Eric Garcia c745d11870 feat: RFC 0060 reliable binary installation
- 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>
2026-02-05 21:01:19 -05:00

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 -9 cannot terminate the process (state: UE — uninterruptible + exiting)
  • The same binary works fine when run from target/release/blue directly
  • 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:

  1. com.apple.provenance xattr (marks binary as "downloaded/copied")
  2. Stale adhoc linker signature from original cargo build
  3. 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 --binary flag to blue install that 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.provenance xattr on the binary

Implementation Plan

Phase 1: Fix install.sh (immediate)

  1. Add xattr -cr + codesign --force --sign - after every cp of the binary
  2. Add a verification step that actually runs blue --version with a timeout

Phase 2: Support cargo install --path

  1. Verify cargo install --path apps/blue-cli works with the current workspace layout
  2. Update INSTALL.md to recommend cargo install as the primary method
  3. Update install.sh to use cargo install instead of cp when possible

Phase 3: Harden blue doctor

  1. Add macOS signature check: codesign --verify on the installed binary
  2. Add xattr check: warn if com.apple.provenance is present
  3. Add timeout-based liveness check: run blue --version with 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.sh produces a working binary on macOS after Homebrew openssl update
  • cargo install --path apps/blue-cli produces a working binary
  • blue doctor detects provenance xattr on binary (warns with fix hint)
  • blue doctor passes 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