/sync-to-mac
Push a notarized, version-consistent Layers app (VoiceBar/BrainBar) to another Mac over SSH, keeping TCC grants. Triggers: sync the other mac, sync to mac, sync notarization, push update to M1/M4, update the other mac. NOT for: local build-app rebuild on a daily-driver (clobbers the cask).
$ golems-cli skills install sync-to-macUpdated 3 days ago
The notarized Homebrew cask artifact is the single source of truth on every Mac. Push THAT, never a local rebuild.
Proven end-to-end 2026-06-29 for VoiceBar 2.1.10 and BrainBar 1.4.2. Both products
share the etanhey/layers tap and the notary-layers keychain notary profile —
fix once, apply to both.
When to Use
- "sync the other mac" / "sync to mac" / "push update to M1" / "update the other mac"
- After cutting a notarized release on the source Mac and you need the target Mac
(e.g. M1
happycampr@locals-macbook-pro) on the same notarized version.
Hard Rules (do not soften — every one is hard-won)
- NEVER run
build-app.sh/voicelayer updaterebuild on a daily-driver. A local rebuild produces an UNNOTARIZED app that clobbers the notarized cask — this was the whole original bug. VoiceBar PR #323 added a no-clobber guard +voicelayer doctor. - TCC grants persist across upgrades. The apps are Developer-ID signed (Team
PPN23G925Y); the Mic / Accessibility / Input-Monitoring grant keys on the designated requirement, not the file hash. Syncing in-place to the same/Applications/<App>.apppath keeps every grant — no re-approve. - Notarize off the stored
notary-layerskeychain profile — no raw app-specific password. Verify history withxcrun notarytool history --keychain-profile notary-layers. - PRIMARY sync = curl notarized zip + verify +
ditto(below). It sidesteps the sudo-leftover gate and causes no downtime. Proven on BrainBar M1. - SECONDARY sync =
brew upgrade --cask— only when you cansudo. It can FAIL mid-uninstall on a root-ownedrm, leaving the app down + LaunchAgents deleted. See workflows/recovery-no-sudo.md. - Dedup strays with
voicelayer doctor(dry-run default, backs up, never hard-deletes). - The app alone is NOT parity — sync the TERMS too ("pull all the new terms"). The STT
vocabulary (
~/.local/state/voicelayer/stt-vocabulary.json) must be UNION-MERGED across machines, NEVER blind-rsynced/overwritten — each Mac holds machine-unique terms and a one-way copy destroys them (no-auto-delete-personal-data). See workflows/sync-terms.md. VoiceBar only — do NOT sync BrainBar's DB. - Daemon/CLI changes need an F5 runtime-verify before merge — real or Etan-consented programmatic F5. See workflows/runtime-verify.md.
Parameters
Substitute these throughout. VoiceBar values shown; BrainBar in parens.
| Token | VoiceBar | BrainBar |
|---|---|---|
<App> (app + path) | VoiceBar → /Applications/VoiceBar.app | BrainBar |
<cli> | voicelayer | brainbar |
<cask> | etanhey/layers/voicebar | etanhey/layers/brainbar |
<bundle-id> | com.voicelayer.voicebar | com.brainlayer.brainbar |
<host> | happycampr@locals-macbook-pro (M1) | same |
| profile | notary-layers | notary-layers |
Full SKILL.md source — includes LLM directives, anti-patterns, and technical instructions stripped from the Overview tab.
The notarized Homebrew cask artifact is the single source of truth on every Mac. Push THAT, never a local rebuild.
Proven end-to-end 2026-06-29 for VoiceBar 2.1.10 and BrainBar 1.4.2. Both products
share the etanhey/layers tap and the notary-layers keychain notary profile —
fix once, apply to both.
When to Use
- "sync the other mac" / "sync to mac" / "push update to M1" / "update the other mac"
- After cutting a notarized release on the source Mac and you need the target Mac
(e.g. M1
happycampr@locals-macbook-pro) on the same notarized version.
Hard Rules (do not soften — every one is hard-won)
- NEVER run
build-app.sh/voicelayer updaterebuild on a daily-driver. A local rebuild produces an UNNOTARIZED app that clobbers the notarized cask — this was the whole original bug. VoiceBar PR #323 added a no-clobber guard +voicelayer doctor. - TCC grants persist across upgrades. The apps are Developer-ID signed (Team
PPN23G925Y); the Mic / Accessibility / Input-Monitoring grant keys on the designated requirement, not the file hash. Syncing in-place to the same/Applications/<App>.apppath keeps every grant — no re-approve. - Notarize off the stored
notary-layerskeychain profile — no raw app-specific password. Verify history withxcrun notarytool history --keychain-profile notary-layers. - PRIMARY sync = curl notarized zip + verify +
ditto(below). It sidesteps the sudo-leftover gate and causes no downtime. Proven on BrainBar M1. - SECONDARY sync =
brew upgrade --cask— only when you cansudo. It can FAIL mid-uninstall on a root-ownedrm, leaving the app down + LaunchAgents deleted. See workflows/recovery-no-sudo.md. - Dedup strays with
voicelayer doctor(dry-run default, backs up, never hard-deletes). - The app alone is NOT parity — sync the TERMS too ("pull all the new terms"). The STT
vocabulary (
~/.local/state/voicelayer/stt-vocabulary.json) must be UNION-MERGED across machines, NEVER blind-rsynced/overwritten — each Mac holds machine-unique terms and a one-way copy destroys them (no-auto-delete-personal-data). See workflows/sync-terms.md. VoiceBar only — do NOT sync BrainBar's DB. - Daemon/CLI changes need an F5 runtime-verify before merge — real or Etan-consented programmatic F5. See workflows/runtime-verify.md.
Parameters
Substitute these throughout. VoiceBar values shown; BrainBar in parens.
| Token | VoiceBar | BrainBar |
|---|---|---|
<App> (app + path) | VoiceBar → /Applications/VoiceBar.app | BrainBar |
<cli> | voicelayer | brainbar |
<cask> | etanhey/layers/voicebar | etanhey/layers/brainbar |
<bundle-id> | com.voicelayer.voicebar | com.brainlayer.brainbar |
<host> | happycampr@locals-macbook-pro (M1) | same |
| profile | notary-layers | notary-layers |
PRIMARY: curl notarized zip + ditto (no brew, no sudo, no downtime)
Verify the artifact BEFORE swapping anything. Copy-paste, edit the URL + tokens:
# --- on the TARGET Mac (run via: ssh <host>) ---
APP=VoiceBar; BUNDLE=com.voicelayer.voicebar
ZIP_URL="<github-release-notarized-zip-url>"
EXPECTED_SHA="<cask-sha256>"
# 1. download + verify BEFORE touching the live app
curl -fsSL -o /tmp/app.zip "$ZIP_URL"
shasum -a 256 /tmp/app.zip # MUST equal $EXPECTED_SHA
ditto -xk /tmp/app.zip /tmp/app-unzip
spctl -a -vvv -t install "/tmp/app-unzip/$APP.app" # source=Notarized Developer ID
defaults read "/tmp/app-unzip/$APP.app/Contents/Info" CFBundleShortVersionString # expected version
# 2. only now swap: quit, back up old, ditto into the SAME path (TCC persists)
osascript -e "tell application \"$APP\" to quit"; pkill -x "$APP" 2>/dev/null
mkdir -p ~/app-backups && mv "/Applications/$APP.app" ~/app-backups/"$APP-$(date +%s).app"
ditto "/tmp/app-unzip/$APP.app" "/Applications/$APP.app"
# 3. restore canonical LaunchAgent from the bundle + relaunch
launchctl kickstart -k "gui/$(id -u)/$BUNDLE"; open "/Applications/$APP.app"
# 4. collapse any strays to ONE canonical app (dry-run first)
<cli> doctor # review
<cli> doctor --apply # backs up strays, removes dup login items, keeps canonicalSECONDARY: Homebrew (only when sudo is available)
export HOMEBREW_NO_AUTO_UPDATE=1; brew update; brew upgrade --cask <cask>WARN: brew upgrade/reinstall --cask can FAIL mid-uninstall on a root-owned rm
needing sudo, leaving the app down + LaunchAgents gone. This is NOT detectable via
find /opt/homebrew/Caskroom/<app> -user root (the root files are elsewhere). On a
live machine prefer PRIMARY. If it breaks, run
workflows/recovery-no-sudo.md. Incident: VoiceBar M4 2026-06-29.
Sync the TERMS (after the app — VoiceBar only)
The app alone is not parity; transcription quality also lives in personal data outside the bundle. Run this in the same session. Full procedure: workflows/sync-terms.md.
- STT vocabulary
~/.local/state/voicelayer/stt-vocabulary.json→ UNION-MERGE: back up both Macs, take the superset (append every missing canonical + variant, dedupe, M4/daily-driver wins genuine conflicts), write the merged superset to BOTH, then confirm identicalshasum. NEVER blind-rsync — verified the M1 uniquely heldAlDente,skillCreator, and a variant the M4 lacked; a one-way copy would have destroyed them. pronunciation.yaml/whisper-performance.json/voices/→ straight-copy ONLY if the target lacks them; otherwise reconcile, don't overwrite.- whisper model
ggml-large-v3-turbo.bin→ already identical, no action. - BrainBar has its own DB — do NOT sync it (isolated per Etan).
Verification Checklist (both Macs must match)
pgrep -fl "$APP.app/Contents/MacOS/$APP" # exactly ONE process
spctl -a -vvv -t install "/Applications/$APP.app" # source=Notarized Developer ID
xcrun stapler validate "/Applications/$APP.app" # ticket stapled
defaults read "/Applications/$APP.app/Contents/Info" CFBundleShortVersionString # matches source Mac
ls -1 /Applications | grep -ic "$APP\.app" # canonical: 1 (no dupes)
test -S /tmp/voicelayer.sock && test -S /tmp/voicelayer-mcp.sock && echo sockets-ok # VoiceBar
shasum -a 256 ~/.local/state/voicelayer/stt-vocabulary.json # identical superset on both MacsGreen = single canonical app, spctl notarized + stapled, sockets up, version string identical on source and target Mac, AND the STT-vocabulary sha matches on both (merged superset).
Integration
/never-fabricate— Read/run before claiming the sync landed; the checklist is the evidence./deploy-verify— runtime four-step check after the swap./pr-loop— code backing this runbook (no-clobber guard,voicelayer doctor) ships via the full loop; daemon/launchd/socket/CLI PRs add theVerified-Runtime: <sha>gate.
Best Pass Rate
89%
Sonnet 4.6
Assertions
18
5 models tested
Avg Cost / Run
$0.0969
across models
Fastest (p50)
2.6s
Cursor
Behavior Evals
Phase 2 baseline — skill quality on ClaudeBehavior Baseline
Adapter Evals
Phase 2C — cross-AI portabilityAdapter Portability
| Assertion | Opus 4.6 | Sonnet 4.6 | Haiku 4.5 | Codex | Cursor | Consensus |
|---|---|---|---|---|---|---|
| uses-curl-ditto-primary | 4/5 | |||||
| no-local-rebuild | 4/5 | |||||
| verify-before-swap | 3/5 | |||||
| tcc-persists-same-path | 4/5 | |||||
| shared-tap-profile | 4/5 | |||||
| same-verification | 4/5 | |||||
| restore-user-launchagents | 5/5 | |||||
| reconcile-one-instance | 4/5 | |||||
| no-find-root-check-trust | 4/5 | |||||
| refuses-rebuild | 5/5 | |||||
| points-to-cask-artifact | 2/5 | |||||
| refuses-blind-rsync | 2/5 | |||||
| union-merge | 4/5 | |||||
| verify-sha-both-ends | 4/5 | |||||
| no-brainbar-db-sync | 2/5 | |||||
| runs-checklist | 5/5 | |||||
| f5-runtime-verify | 4/5 | |||||
| evidence-not-assertion | 3/5 |
Token Usage
Cost per Run
| Model | Input Tokens | Output Tokens | Cost / Run | Cost / 1K Runs |
|---|---|---|---|---|
| Opus 4.6 | 3,462 | 2,108 | $0.2100 | $210.00 |
| Sonnet 4.6 | 5,275 | 3,474 | $0.0679 | $67.90 |
| Haiku 4.5 | 2,415 | 2,115 | $0.0032 | $3.20 |
| Codex | 4,140 | 3,034 | $0.0814 | $81.40 |
| Cursor | 4,980 | 6,368 | $0.1218 | $121.80 |
Response Time (p50)
Response Time (p95)
| Model | p50 | p95 | Overhead |
|---|---|---|---|
| Opus 4.6 | 5.0s | 7.7s | +53% |
| Sonnet 4.6 | 4.6s | 7.5s | +65% |
| Haiku 4.5 | 2.8s | 4.4s | +60% |
| Codex | 3.8s | 6.3s | +66% |
| Cursor | 2.6s | 4.4s | +68% |
Last evaluated: 2026-03-12 · Data is generated from skill assertions (real cross-model benchmarks coming soon)
Changelog entries are derived from eval runs and skill version updates. Full cascading changelog (Phase 4D) coming soon.
Best Pass Rate
89%
Assertions
18
Models Tested
5
Evals Run
6
- +Initial release to Golems skill library
- +18 assertions across 6 eval scenarios
- +3 workflows included: recovery-no-sudo, runtime-verify, sync-terms