The Part That Decides What Dad Hears
A navigation app is mostly side effects. A GPS chip that answers when it feels like it, a map that animates, a speaker shared with music and calls, a network that drops in tunnels, a watch on the other end of a radio link. Buried inside all of that is a much smaller thing: a set of rules. When do I say "300 m ahead"? Has the car left the road, or did one fix just bounce off a building? Are we there yet?
Those rules are arithmetic over a line and a stream of points. Pathfinder pulls every one of them into a single value, GuidanceEngine, in the PathfinderKit package. Its own doc comment says it plainly: a pure value, feed it fixes, read events and a snapshot. It never talks to Core Location, a provider, a speaker or the network, "so every rule that decides what Dad hears is testable on a Mac." The architecture doc makes that invariant 2.
Inputs, Outputs, Nothing Else
In: a GuidanceFix. Coordinate, horizontal accuracy in metres, speed, course and a timestamp. Core Location reports an unknown speed or course as a negative number; by the time it reaches the engine that has become nil, because the app translates at its edge and the rules never have to remember Apple's sentinel.
Out: one call, mutating func update(_ fix: GuidanceFix) -> [GuidanceEvent], returns what should happen because of that fix. The vocabulary is small: started, announce (carrying which step, which stage, the spoken distance, the instruction and an optional chained one), offRoute(lateral:), backOnRoute, rerouted and arrived. Most fixes return an empty array, and that is the point: silence is an answer too.
Readable at any time: a GuidanceSnapshot. Phase (waitingForFix, onRoute, offRoute, arrived), progress along the route, remaining distance and time, the next spoken step and how far it is, the fix snapped onto the route, the lateral error, the smoothed speed and when the last fix came. The type's comment calls it "everything a screen or Pippa's report shows about the drive right now."
One detail tells you the design is serious: rerouted is in the vocabulary, yet this engine never says it. When Pathfinder reroutes, its session simply builds a new engine on the new route. Only a provider that guides itself (Google's Navigation SDK, read through FeedTrip, which you met in the previous track) has a reroute to report, and it reports it in the same words, so everything downstream reads one vocabulary.
What the Engine Never Touches
Check the imports and the claim holds. Every file in the PathfinderKit target imports Foundation, and the voice cache adds CryptoKit for its SHA-256 keys. No MapKit, no Core Location, no AVFoundation, no URLSession. The kit even owns its own Coordinate type, "so the guidance rules never depend on CoreLocation or MapKit; the app converts at its edge." MapKit lives in a sibling target, PathfinderAppleMaps, which pays its own translation cost.
The engine also never speaks. It says announce step 1, stage prepare, 300 m, and the app's PromptComposer turns that into Pippa's chunks, and the player plays them. Swap the speaker, the language or the voice and not one guidance rule moves.
The side effects live in the app's NavigationSession. On every location sample it logs the fix to the drive log, calls engine.update, copies the snapshot and reacts to each event: say a line, log it, start a reroute. That is the classic shape sometimes called functional core, imperative shell: the decisions are a value; the shell only carries them out.
Why a Value Is Testable
Given the same route, config and fixes, update returns the same events. So a test is three lines of intent: build a route, build fixes, collect events. Time is not read from a clock; it rides inside each fix. A tunnel gap, a four-second confirmation window or a fix that arrives five minutes late are just timestamps in a test, with no sleeping and no flakiness.
The kit's test helper, TestRoutes, lays out synthetic geometry in metres east and north of one origin: "East 3 km, left turn, north 2 km, arrive", with the turn at 3,000 m and the destination at 5,000 m, "so every expected distance is exact by construction." A drive helper emits one fix per second at a chosen speed with a course along the line. On top of that the Guidance suite asserts what Dad hears: each stage of a town drive once, highway warnings earlier, a GPS gap speaking only the latest stage, a single wild fix ignored, a wrong-way drive caught, a car park start joining the route.
Synthetic geometry is not only convenient. It is a privacy rule. A test fixture gets copied, committed and read by people who should never learn where you live, so this quest's sketches use an arbitrary origin and never a real home.