Skip to content

install --force re-signs the existing binary in place instead of replacing it; manual copies are linker-signed and killed when spawned #472

@halindrome

Description

@halindrome

Summary

codebase-memory-mcp install --force does not replace the installed binary when the target already exists — it re-signs the existing binary in place instead of copying the freshly-built one. An operator who builds from source and runs install -y --force is silently left with the OLD binary in the target path.

Repro

  1. Build a new binary: scripts/build.shbuild/c/codebase-memory-mcp.
  2. With an existing install present at the target (e.g. ~/.local/bin/codebase-memory-mcp), run ./build/c/codebase-memory-mcp install -y --force.
  3. Observe: the target's shasum -a256 is unchanged and does not match build/c/codebase-memory-mcp — the new build was not copied; the existing file was re-signed in place. Output reports rebuilding indexes and stopping running servers, but not a binary swap.

Secondary issue (code signing for manual installs)

Working around the above with a manual cp build/c/codebase-memory-mcp <target> produces a binary that runs from a terminal but is killed (Killed: 9) when spawned by another process (e.g. an MCP host) — so the MCP server silently fails to connect.

Cause: a freshly clang-built arm64 binary carries an adhoc, linker-signed signature (codesign -dvflags=0x20002(adhoc,linker-signed)). macOS refuses to exec linker-signed binaries in some spawn contexts even though codesign --verify passes on disk. Re-signing with codesign --force --sign - <target> (→ flags=0x2(adhoc)) fixes it — which is exactly what install does for the binary it signs, so a manual copy that skips that step is unlaunchable when spawned.

Impact

  • --force is effectively a no-op for the binary swap → operators run stale code believing they upgraded.
  • The signing requirement is undocumented, so hand-copied/dev builds break specifically when launched by an agent/MCP host (works when tested from a shell, masking the problem).

Suggested fix

  • install (especially with --force) should copy the freshly-built binary to the target, then sign it — not sign whatever is already at the target.
  • Document the codesign --force --sign - requirement for manual installs on macOS, or add a --from <path> option that copies + signs a specified build.

Environment

macOS (Apple Silicon / arm64). Surfaced during local-install testing for the Perl LSP work (#461).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions