feat: sign and notarize the macOS app, fetch FastVLM on first run - #16
Merged
Conversation
Signing was producing an invalid bundle: build_app.sh re-signed ad-hoc with
--deep, and build.sh then copied the daemon, helpers and models into
Contents/Resources afterwards, breaking the seal ("a sealed resource is
missing or invalid"). The app is now built unsigned and signed once, after
staging, inside-out: nested executables first, app bundle last, then
notarize, staple, and sign/notarize/staple the .dmg.
Fixes found along the way:
- ENABLE_APP_SANDBOX was YES in Release. The ad-hoc re-sign was stripping it,
so it never bit; a real Developer ID signature would have sandboxed the app
and broken spawning the daemon, the Accessibility API, and ~/.patcha writes.
- MACOSX_DEPLOYMENT_TARGET was 26.2 while LSMinimumSystemVersion claimed 13.0.
Lowered to 14.0, which builds clean with no code changes.
- The daemon shells out to osascript, but NSAppleEventsUsageDescription was
missing. Under hardened runtime that crashes the process rather than
showing a denial.
- PatchaSourceRoot is stripped at staging time so releases do not ship a
local filesystem path.
The FastVLM captioner model (~810 MB) is no longer bundled; the daemon fetches
it to ~/.patcha/models/fastvlm on first run, resuming via HTTP Range and
publishing progress to ~/.patcha/model_download.json, which the menu bar
displays. Availability is re-checked per caption so gist starts working when
the download lands rather than needing a restart, and is now keyed to the full
file set instead of two files, which a partial download could satisfy.
This takes the .dmg from 1.0 GB to 84 MB. It also drops
decoder_model_merged_q4f16.onnx, 269 MB the captioner never loads.
Adds docs/RELEASING.md, a tag-triggered release workflow, and
`patcha fetch-models` for pre-seeding.
Claude-Session: https://claude.ai/code/session_01PLRQp3DqAuLw8A8UPeDf4p
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.
Signing was producing an invalid bundle: build_app.sh re-signed ad-hoc with --deep, and build.sh then copied the daemon, helpers and models into Contents/Resources afterwards, breaking the seal ("a sealed resource is missing or invalid"). The app is now built unsigned and signed once, after staging, inside-out: nested executables first, app bundle last, then notarize, staple, and sign/notarize/staple the .dmg.
Fixes found along the way:
The FastVLM captioner model (~810 MB) is no longer bundled; the daemon fetches it to ~/.patcha/models/fastvlm on first run, resuming via HTTP Range and publishing progress to ~/.patcha/model_download.json, which the menu bar displays. Availability is re-checked per caption so gist starts working when the download lands rather than needing a restart, and is now keyed to the full file set instead of two files, which a partial download could satisfy.
This takes the .dmg from 1.0 GB to 84 MB. It also drops decoder_model_merged_q4f16.onnx, 269 MB the captioner never loads.
Adds docs/RELEASING.md, a tag-triggered release workflow, and
patcha fetch-modelsfor pre-seeding.Claude-Session: https://claude.ai/code/session_01PLRQp3DqAuLw8A8UPeDf4p
What does this change?
Related issues
How was it tested?
cargo buildpasses (inrust/)cargo clippy --all-targetsis cleancargo fmt --allappliedcargo testpasses locally (some collector tests require macOS permissions)Checklist
type: descriptionconvention (feat:,fix:,chore:)~/.patcha,.env)