The build/install/run procedure for Aposemati that actually works, plus the naming traps that cost real time during the build sessions. Both apps are installed and running on hardware with these steps.

For Agents

Canonical copy lives in /Users/levander/coding/aposemati/HANDOVER.md (committed as 961d996, current as of 2026-08-19). Reference that first — this note exists so the traps are findable from the vault and survive a repo you have not cloned yet. Team NZZ28CZ49H, bundle id com.aposemati.camera. The .xcodeproj files are generated by XcodeGen and not committed.

The traps

1. The iOS product is Aposemati.app, NOT AposematiCamera.app

The scheme is AposematiCamera; the product is Aposemati.app. Pointing devicectl at AposematiCamera.app fails with a missing-path error that reads like a failed build.

/tmp/apo-ios/Build/Products/Debug-iphoneos/Aposemati.app     ← correct
/tmp/apo-ios/Build/Products/Debug-iphoneos/AposematiCamera.app ← does not exist

2. The xcodebuild destination id= is NOT the devicectl identifier

The same phone has two different UUIDs and they are not interchangeable:

ToolIdentifierWhere it comes from
xcodebuild -destination 'id=…'00008140-000E40302607801Cxcodebuild -showdestinations
xcrun devicectl device install app --device …03750A7F-3281-5C89-A327-EE7E944515F6xcrun devicectl list devices

Using the wrong one gives an unhelpful “device not found” from a tool that can plainly see the phone.

3. swift build and swift test cannot see Apps/ at all — and it is silent

Neither app target is in Package.swift, so the Mac app was broken for five commits in Phase 2, through two full-suite runs and a warning-free swift build. Nothing signalled.

Run both app builds as a gate at every task boundary (~90 s, no keychain, tree untouched — the .xcodeproj stays gitignored):

cd Apps/AposematiHost && xcodegen generate && xcodebuild \
  -project AposematiHost.xcodeproj -scheme AposematiHost -destination 'platform=macOS' \
  CODE_SIGNING_ALLOWED=NO -derivedDataPath /tmp/apo-gate build
 
cd Apps/AposematiCamera && xcodegen generate && xcodebuild \
  -project AposematiCamera.xcodeproj -scheme AposematiCamera \
  -destination 'generic/platform=iOS Simulator' \
  CODE_SIGNING_ALLOWED=NO -derivedDataPath /tmp/apo-gate build

Corollary: anything under Apps/ gets reasoned about, never executed. Put logic behind a testable seam in AposematiCore instead.

Commands

swift test                                    # 418 tests as of Phase 2 (219 at the end of Phase 1)

iOS app:

cd Apps/AposematiCamera && xcodegen generate
xcodebuild -project AposematiCamera.xcodeproj -scheme AposematiCamera \
  -destination 'id=00008140-000E40302607801C' -allowProvisioningUpdates \
  DEVELOPMENT_TEAM=NZZ28CZ49H CODE_SIGN_STYLE=Automatic \
  -derivedDataPath /tmp/apo-ios build
 
xcrun devicectl device install app \
  --device 03750A7F-3281-5C89-A327-EE7E944515F6 \
  /tmp/apo-ios/Build/Products/Debug-iphoneos/Aposemati.app

macOS app:

cd Apps/AposematiHost && xcodegen generate
xcodebuild -project AposematiHost.xcodeproj -scheme AposematiHost \
  -configuration Debug -derivedDataPath /tmp/apo-mac build
open /tmp/apo-mac/Build/Products/Debug/Aposemati.app

Running it

  1. Launch both apps.
  2. Compare the six digits and confirm on both screens — see aposemati-pairing-security-model for why both sides must confirm.
  3. The shutter on the Mac enables only after acceptance.

Permissions: Camera and Local Network on the phone; Local Network on the Mac.

A denied Local Network permission does not error

The browser simply parks and finds nothing, forever. This is why the UI surfaces that state explicitly rather than showing a generic spinner. If discovery never finds anything, check the permission before you debug the transport.

Signing

Apple Development certificate, team NZZ28CZ49H. It does not work out of the box on a fresh machine:

  • The WWDR G3 intermediate may be missing. Without it, codesign fails with errSecInternalComponent while security find-identity -v -p codesigning reports 0 valid identities even though the certificate plainly exists.
    curl -O https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
    security import AppleWWDRCAG3.cer -k ~/Library/Keychains/login.keychain-db
  • A new device must be registered by building once from the Xcode GUI. The CLI cannot do it, even with -allowProvisioningUpdates.

Full account: aposemati-apple-signing-gotchas.