Skip to content
C.W.K.
Stream
Lesson 02 of 04 · published

A Client, Not an Engine

~14 min · architecture, boundaries, client, audio

Level 0Lost
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

What is missing on purpose

Most of the family's apps are engines: a server process with its own port, a launchd job that keeps it alive, a database of its own. Kiln answers on one port, Bellows on another. Pathfinder has none of that. Its own house sign says it in a table row: Port / service: none, no engine. Dad ruled it at birth: app-only, and Pippa's location store is the shared one.

That is not minimalism for its own sake. Everything Pathfinder would need a server for already has an owner in cwkPippa, and a second owner is how two truths about Dad's whereabouts begin.

What it leans on instead

  • The location layer. Each fix goes there as reporter pathfinder, with the navigation report beside it. Destinations Pippa picks come back the same way, as a handoff the phone takes and acknowledges. Dad's Home and favorites are Pippa's list too, so she knows "집" and can send him there; the phone keeps a copy so the list opens with no network.
  • The maps door. Kakao's search, routes and travel times go through cwkPippa, where the REST key lives. Hangul place search on Apple's stack goes through Pippa's Apple Maps Server API door. No server key ships in the app.
  • The pins. Places Pippa recommends in chat persist in her location layer; the phone keeps a replica and draws them.
  • The talk. A talk is an ordinary cwkPippa conversation, born with origin_surface: pathfinder and continued for two hours, so one drive's talk is one thread. Pathfinder never talks to a model itself; the brain stays cwkPippa's.
  • Her voice. Spoken lines come from cwkBellows, chunk by chunk, into a cache on the phone.

A client has to hold credentials, so there is one named exception. A sibling's phone normally never holds a Pippa session. Pathfinder has no engine to hold it on its behalf, so its phone holds one through the kit's PippaDoor: the family PIN in the Keychain, the session minted by the family authority. Same shape as the Tidings and Rekindle phones, and written down as an exception rather than slipped in.

The invariants that keep it a client

  • Pippa learns about the drive only through her location layer. No side channel, no second store.
  • Guidance is a pure value. The PathfinderKit target has no MapKit, Core Location, audio or network inside it, so every rule that decides what Dad hears is under test on a Mac.
  • No traffic data of its own. Each map stack brings what it has.
  • When In Use, never Always. The phone measures in the background only during a guidance segment Dad started.
  • No numbers on screen. Coordinates go to Pippa and the store; the map shows the position.
  • Reports are dropped, never queued. A late position is not where he is.
Separate what fails differently; put together what must share one resource. Navigation left the Pippa app so a crash or a bad build of one cannot take down the other. The talk came into the navigation app because both need the same speaker and the same microphone, and only one app can referee those.

Why not inside the Pippa app?

The first ruling was about stability: navigation lives in its own app so the Pippa app's voice mode stays stable. A navigator is a large, fast-moving codebase; it should not share a crash with the conversation Dad uses all day.

The second ruling, a day later, went the other way for the talk, and the reason is the audio route. Dad wanted to talk with Pippa while being guided. Picture that as two apps. The Pippa app plays her voice and listens through its microphone. The navigation app speaks "300 m ahead, turn right" from a different process, at a moment the Pippa app never scheduled. Whatever the system's echo cancellation manages to remove, nothing in the Pippa app knows a turn is coming: it talks over the turn, and any part of the line that still reaches its microphone sounds like Dad cutting in.

Inside one app, there is a referee. Pathfinder's guidance plays on its own player, not on the talk's engine, so nothing counts on the talk's echo cancellation to remove it. Instead the talk becomes its gate: its ears close for a guidance line and half a second after, an urgent line cuts her off, an ordinary turn waits for her current stretch only when it ends within three seconds, and otherwise cuts her too. Those rules live in TalkInterplay in PathfinderKit and are under test. The architecture puts it in one sentence: the talk comes to the road, rather than the road to the Pippa app.

So the boundary is not "Pippa outside, navigation inside". It is: Pippa's identity, memory and brain outside, in cwkPippa; everything that touches the road and the car's audio inside one app that owns them.

Code

cwkPathfinder, clients/apple/PathfinderMobile/Sources/Pippa/PippaLink.swift: the link's contract (verbatim, lines 7-26)·swift
/// Pathfinder's two-way link to Pippa's location layer (Dad's ruling,
/// 2026-10-01).
///
/// Out: each fix, as reporter `pathfinder`, with the navigation report beside
/// it, so Pippa answers "am I on the right road?" from the route itself.
/// In: a destination Pippa picked (her `location` tool's `navigate`), taken
/// and acknowledged.
///
/// Pathfinder has no engine, so its phone holds a Pippa session through the
/// kit's `PippaDoor` (the Tidings and Rekindle shape): the PIN in the Keychain,
/// the session minted by the family authority, `X-Pippa-Session` on every call.
actor PippaLink {
  static let reporter = "pathfinder"

  struct ReportBody: Encodable {
    var fix: GeoFix
    var reporter: String
    var device: String
    var navigation: PippaNavigationReport?
  }
Who owns what (a diagram drawn for this lesson)·text
Dad's iPhone: Pathfinder (no port, no server)        office: cwkPippa
+-------------------------------------------+       +----------------------------------+
| PathfinderKit  guidance, voice chunks,    |       | location layer                   |
|                drive log (pure, tested)   |       |   fixes from every reporter      |
|                                           | fix + |   navigation report (< 120 s)    |
| Pippa link     reporter "pathfinder"      | ----> |   handoffs from her location tool|
|                                           | <---- |   saved places, recommended pins |
| Apple child    MapKit on the phone        |       |                                  |
| Kakao child    asks the maps door ------> | ----> | maps door: Kakao REST key,       |
|                                           |       |   Apple Maps Server API search   |
| Google child   Navigation SDK guides      |       |                                  |
|                its own routes             |       |                                  |
| the talk       one conversation, 2 hours  | ----> | conversation (origin_surface:    |
| PippaDoor      PIN in Keychain, session   |       |   pathfinder); the brain is here |
+-------------------------------------------+       +----------------------------------+
       |
       | chunk text
       v
  cwkBellows: Pippa's voice, cached on the phone chunk by chunk

External links

Exercise

Take an app or service you are building and list every piece of state it keeps. For each one, name the canonical owner: this app, or something else in your system. Wherever the answer is "something else" but your app still keeps a writable copy, write down what happens when the two disagree. Then list every hardware or OS resource it shares with another program (speaker, microphone, camera, a port, a file) and who referees each.
Hint
A read-only cache with a freshness rule is fine; Pathfinder keeps one for saved places and pins. The trouble is a second writable copy with no rule for who wins. For shared resources, the question that decided Pathfinder's talk is whether the two users must coordinate in real time. If they must, they usually belong in one process.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.