verify
Build, launch, and drive a Debug build of Rapture for Mac to verify changes end-to-end against its real surfaces (destination folder, relay folder, menu bar). Use when verifying capture/triage/relay c
SKILL.md.claude/skills/verify/SKILL.md
GitHubVerifying Rapture for Mac live
The app's surfaces are filesystem side effects (the notes destination, the iCloud relay folder) plus the menu bar. Drive them by dropping files and observing what the running app produces.
Build + launch
xcodebuild -derivedDataPath /tmp/RaptureMacDerived \
-project RaptureMac/RaptureMac.xcodeproj -scheme RaptureMac \
-configuration Debug build # test runs also produce the app
pkill -x Rapture # quit the installed app (watermark catch-up recovers anything missed)
open -n /tmp/RaptureMacDerived/Build/Products/Debug/Rapture.app # -n + the full path launches THIS bundle
ps -ax -o pid,comm | grep "Rapture.app/Contents/MacOS" # confirm the /tmp binary is the one running
Never move or rename /Applications/Rapture.app to get the Debug build to launch. Moving the installed app aside and back made macOS drop its Full Disk Access grant (2026-09-29): the user had to re-grant it and Quit & Reopen. open -n <full path> launches the Debug bundle without touching the installed one.
Always restore when done (and relaunch — the user's capture pipeline was running):
pkill -x Rapture
open /Applications/Rapture.app
ps -ax -o pid,comm | grep "Rapture.app/Contents/MacOS" # confirm /Applications is running again
Debug isolation (what to drive)
- Notes destination:
~/Documents/Rapture Notes (Debug)/ - Relay folder:
~/Library/Mobile Documents/iCloud~noisemeld~Rapture/Relay (Debug)/ - Settings/state:
~/Library/Application Support/Rapture for Mac (Debug)/{settings.json,state.json}
Drop .txt files at the destination root (or a .txt+.m4a pair in the relay folder) and watch the outputs. state.json is the best oracle: triagedRecords / relayFiledRecords / lastError record exactly what the app did and when.
Gotchas (all bitten before)
A freshly built debug binary re-triggers Full Disk Access onboarding, and granting it quits the app. Each rebuild is a new bundle at a new/changed signature, so TCC treats it as a new app: the FDA sheet opens on launch, and after the user grants FDA the app must quit and relaunch to see it (a running process never picks up a new grant). To the verifying agent this looks like the app silently vanished mid-test — no crash report, drops stop being processed. What to do: (a) if the surfaces under test don't need FDA (relay, triage, enrichment — most of them), tell the user up front they can ignore/dismiss the FDA sheet for this run; (b) poll process liveness (
kill -0 <pid>) between steps rather than assuming the pid survives; (c) if it exited, justopenit again — settings/state are on disk and the test continues where it left off; (d) if the user does grant FDA mid-run, expect exactly one quit-and-relaunch cycle and re-openafterwards.App Nap stalls the poll loops. A debug build launched via
openfrom a shell has no window and no user input, so macOS naps it — 5s polls stretched to ~18 minutes in one session. Wake it deterministically after each file drop:sample <pid> 1 >/dev/null 2>&1(attaching wakes the process), then wait ~10s (two poll ticks; the triage settle rule needs two same-size sightings ≥5s apart). The user-launched production app has not shown this in dogfooding, but keep it in mind if "nothing happens."The debug build has no Full Disk Access, so iMessage capture won't run (FDA poll loops harmlessly; a permissions window may open). Relay + triage surfaces need no FDA and are fully drivable.
log show/log streamreturn nothing from the sandboxed shell. Usestate.json, output files, andsample <pid>stacks as evidence instead.Don't pre-create files you expect the app to create; don't clean the debug notes folder — it's isolated scratch and prior artifacts are useful realism.
Exec'ing the binary directly never starts the pipeline.
pipeline.start()fires from the menu-bar label's.task, which needs a proper LaunchServices launch — a directly-exec'd binary sits idle forever (looks like "nothing happens", no errors). To pass an env var (e.g.RAPTURE_AI_FORCE_ENGINE=anthropic), uselaunchctl setenv KEY valuethenopen …/Rapture.app, andlaunchctl unsetenv KEYwhen done.Planting a keychain item with the
securityCLI blocks the app on an ACL dialog (invisible in a headless session — the process hangs insideSecItemCopyMatching). Add-A(any-app access) when planting a test key for the debug servicenoisemeld.RaptureMac.debug. App-created items (Settings → Triage → Save) never prompt.Don't relaunch the installed app while a test run is in flight — the shared bundle ID can abort the hosted test session partway ("TEST FAILED" with a fraction of the suite executed, zero failures). Re-run after the launch settles.