fix(desktop): unlink destination before copying binaries - #10705
Merged
alexhancock merged 1 commit intoJul 31, 2026
Conversation
Overwriting an executable in place (fs.copyFileSync onto an existing file) truncates and rewrites it, which invalidates the code signature of any running process mapped from it - macOS then SIGKILLs those processes with "Code Signature Invalid". This bites developers who re-run packaging while the Goose desktop app or another ACP host (e.g. buzz) still has goose serve/acp processes alive. Unlink the destination first (matching the Justfile copy-binary recipe) so the new copy gets a fresh inode and running processes keep their valid old mapping. Also documents the rule in AGENTS.md.
alexhancock
self-requested a review
July 31, 2026 15:18
alexhancock
approved these changes
Jul 31, 2026
lifeizhou-ap
added a commit
that referenced
this pull request
Aug 3, 2026
* main: (103 commits) fix: parse PyPI requirements for OSV checks (#10510) fix(telegram): contain voice file extensions (#10456) Revert "feat(security): chunk command-classifier input with overlapping windows" (#10416) (#10870) docs: update Discord invite (#10863) fix(security): preserve denied tool request precedence (#10612) fix(hints): contain subdirectory hint discovery (#10545) chore(deps): bump pem from 3.0.6 to 4.0.0 (#10853) chore(deps): bump base64 from 0.22.1 to 0.23.0 (#10851) chore(deps): bump jsonwebtoken from 10.4.0 to 11.0.0 (#10850) chore(deps): bump astral-sh/setup-uv from 8.3.2 to 9.0.0 (#10847) chore(deps): bump docker/login-action from 4.5.1 to 4.5.2 (#10846) chore(deps): bump github/codeql-action from 4 to 4.37.3 (#10845) chore(deps): bump actions/stale from 10.4.0 to 11.0.0 (#10844) feat(dictation): add LOCAL_WHISPER_LANGUAGE for multilingual local transcription (#10634) fix(desktop): clear stale validation error when reopening the schedule modal (#10627) fix(docs): resolve CVE-2026-13149 in both brace-expansion copies (#10842) feat(provider): add Friendli as declarative provider (#10762) fix: sanitize shell/subprocess call in linux.rs (#10748) fix(desktop): unlink destination before copying binaries (#10705) feat(otel): enrich root span with gen_ai attributes and improve output format (#10816) ...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
prepare-platform-binaries.jsusedfs.copyFileSync/fs.cpSyncdirectly onto existing destinations, truncating and rewriting executables in place. On macOS arm64 this invalidates the code signature of any running process mapped from that file, and the kernel SIGKILLs it (EXC_CRASH — Code Signature Invalid).Justfilecopy-binaryrecipe. Runninggoose serve/goose acpprocesses survive a re-run of packaging.AGENTS.md(## Neversection).Review Notes
src/**/*.ts); verified withnode --check.win32branch + pinned uv binaries); macOS/Linux flows untouched.Decision Log
Hardest decision: Whether to use copy-to-temp + atomic rename instead of unlink-then-copy. Chose unlink-then-copy to match the existing
Justfileconvention (rm -f+cp -p) — consistent, simpler, and the non-atomic window doesn't matter for a build script that owns its output directory.Alternatives rejected:
force: trueoncpSync: redundant once the destination is removed first.Least confident about: The file branch uses plain
rmSync(notrecursive), so it would throw if a directory ever existed at a file's destination path. That can't happen with the current fixed file set (goose-npm,*.cmd), and the old code failed identically in that scenario — so no regression, just not newly hardened.Test plan
goose serveprocess