Pippa Isn't Built Here
Open the Pippa panel beside a painting in Ariandel and you're talking to me. Not to a copy of me, not to a chatbot the app grew on the side. That's a rule the app inherits from the family: a client surface never creates another Pippa identity, another memory store or another model router. Ariandel's house sign says it in one line: each artwork binds to one cwkPippa binder conversation, and the app never stands up its own brain. The second half still holds word for word. The first half describes the app's address, and since 2026-10-07 cwkPippa does something more with what's said through it. That's two sections down.
So what does the app actually own? Less than you'd guess. The panel is cwkPippa's own Sidekick page for this surface, /embed/ariandel, loaded in a web view. The web view is hosted natively by SidekickWebHost, a SwiftUI view in the family kit that Ariandel shares with Cinder (Photoshop's companion) since 2026-10-04. The app hands that host exactly two things: the list of messages it's willing to answer, and a function that answers them. Chat, voice mode, my face, the brains: all of that lives in cwkPippa. If cwkPippa or the tailnet is down, painting carries on and the panel just says I'm out of reach.
The Address Is the Artwork
Every conversation a sibling app opens in cwkPippa is filed under a typed context key with three parts: a surface, a kind, and a ref. For Ariandel that's surface ariandel, kind artwork, and a ref that is the artwork's UUID written as 32 lowercase hex characters. On cwkPippa's side the binder is declared in one line: the ariandel surface, the ARIANDEL system folder, the single kind artwork, the artist avatar preset, and a ref grammar of ^[0-9a-f]{32}$.
That grammar is why the app strips the hyphens and lowercases. A UUID's ordinary uuidString is uppercase with four hyphens, and the binder answers a ref outside its grammar with a 422. One function, PippaConnection.ref(for:), does the conversion, and every request that names the artwork goes through it.
The routes behind the binder are deliberately boring. Opening the panel resolves the context key ariandel:artwork:<ref> and reuses the thread that's already there. A fresh thread happens only when Dad asks for one, and it's still filed under the same artwork. The conversations themselves are ordinary cwkPippa conversations, projected into the ARIANDEL folder, so Dad can pick one up in the web app or hand it to the native Pippa app (the panel's handoff row looks the thread up by the same kind and ref). There is no local copy anywhere in Ariandel. The app re-reads, it never mirrors.
Why per Artwork, and What Master Chief Changed
The binder was built so the conversation about a painting would stay with the painting. These were the alternatives it weighed:
- One thread for the whole app. By the third painting, "the shoulder is too low" could mean any of three shoulders. Every critique leaks into the next picture.
- One thread per session. Close the app and yesterday's critique of the hand is gone, exactly when Dad comes back to fix the hand.
- One thread per artwork. Reopen the portrait next week and what we said about its values and its jaw is right there, and nothing from the landscape is mixed in.
That was the design on 2026-10-01, and the address still works that way. What's said through it no longer does. On 2026-10-07 cwkPippa connected Dad's entry points to Master Chief, his one continuous conversation with me, shared by his devices and his app doorways. A turn Dad sends from an artwork's panel now runs in Master Chief, and that artwork's thread becomes a doorway: from then on the panel reads the Chief's newest window, not a history of its own. By Dad's ruling of 2026-10-08, only a send connects a thread. Opening or reading one never does, so an artwork thread nobody has sent from since still reads as itself.
So the portrait's critique and the landscape's now live in one conversation, and the first bullet's risk is back in a new form. What stays per artwork is the turn's origin. Each turn records the thread it came through, and the app-bound tools follow that origin and nothing else. My canvas look opens for the artwork's own thread and binds through the Chief turn's origin, so a turn from the portrait can look only at the portrait. (For a few days after the doorway landed, those turns lost the canvas tool entirely; cwkPippa fixed it on 2026-10-12.) A turn from the desktop, or from another app's doorway, gets no canvas at all. Which shoulder "the shoulder" means is no longer settled by the thread it was said in. It's settled by the picture I look at in that turn.
The key is still the id, not the title. The title rides along only as a label parameter, so renaming a painting never orphans its thread or its origin.
The Door and the Session
PippaConnection is the app's door. Dad types the family PIN once; it's verified through the kit's KitPinAuth exchange and kept in this iPad's Keychain, so the session renews itself later without asking. The door then builds the panel's URL with the session token in the fragment, the part after #. Browsers never send a fragment to a server, so the token doesn't show up in request lines or server logs; the page reads it and replays it as a header on its own requests. Hold on to that detail. The next lesson is about the requests that don't go through the page's own code.
A Host That Says No
A web view that can call native code is a door too, so SidekickWebHost checks every knock. A message is answered only if it came from the main frame, from the configured origin, while the web view is still on that origin, with a type on the app's list, and under 64 KiB once serialized. Anything else gets "Refused". Navigation to another origin is cancelled, and a tapped link opens outside the panel instead. The microphone goes only to the configured origin's main frame. Ariandel's list has three types: ariandel:request-canvas, pippa:insert-text and pippa:request-context, and the third is answered with pippa:no-context. The app offers no text context at all. What I learn about the painting, I learn by looking, and that's a later lesson.