"Not because Apple is pretty. That much a year is worth it."
One Path Through Everything
This quest has followed one small family of apps, Spark, from a package to a phone. This lesson puts the whole path in one place, in the order the pieces have to exist, with the lesson behind each step. The order is the point: several of the traps in earlier tracks were a step done in the intuitive order instead of the real one.
The Shared Logic First
Start with a Swift package in Swift 6 language mode, because a data race should be a compile error on your desk rather than a trap on someone's phone. Put the values, the Codable types and the rules both apps share in a library target. Give every stored document an explicit init(from:) so the first added field migrates instead of wiping a file. Test the pure logic with Swift Testing where it lives, and remember that a closure handed to an Objective-C API from a main-actor context is a review item, not a detail.
The Mac App
Pick the shape: AppKit owns windows and text where input composition and split views matter, SwiftUI hosts settings and forms, and @Observable models feed both. Build with SwiftPM and a script that assembles the bundle, strips extended attributes, signs with the one self-signed identity, installs by rename and verifies at the final path. Check that the designated requirement names the certificate, not a hash, so permissions survive the next build. If it is a utility, give it a LaunchAgent that restarts it only after a failure. Prove the installed bundle with a hash check and bounded stages, and ship copies of that one build to the other Macs.
The Phone App
Generate the Xcode project from project.yml with one universal target, the team written in source, a share extension and an App Group, and a watch app if the capture belongs on the wrist. Keep it a thin client: a strict engine location, the HTTPS twin or the lone ATS key, a byte budget on every call, a socket that reconnects without replaying commands, and an outbox where the local write is the capture. Run the tests on a dedicated simulator and make every skip loud, then remember what the Simulator cannot exercise: a microphone, Data Protection, a real share from Mail.
Delivery
Archive first, so the identifiers exist; then create the App Store Connect record by choosing the bundle id. Authenticate with a team API key. Let the pipeline refuse dirty inputs, bump the build number in the source, archive with a kept log, gate the archive, and upload behind a status-and-banner check. What it prints is fact one of four. Processed, assigned and installed are separate facts, and installed is a number read on the device.
None of this works on a free account, which is the condition this quest set at the start. The membership pays for TestFlight, App Store Connect records, App Groups across extensions and push keys, and every later track stands on those. The rest is the discipline this last track is named for: every claim in the path above was measured by someone before it became a rule, and the next claim you add should be too.