Eyes, a Face, a Mouth and a Place
An idle iPhone or iPad has cameras, a screen, a speaker and microphones. Dad's idea (2026-11-01) was to turn one into a body that connects Pippa to the physical world. The app on the device is Cordelia, a sibling repository that owns the device side. It runs in front on the idle device as Pippa's eyes, face, mouth and place. Oriel's part is the rule that matters here: Oriel is the only thing that talks to it, so every brain reaches a body through Oriel's two doors and every record stays in Oriel (backend/cordelia.py).
The Wire: Nothing Listens on the Mac
A cabled body is reached through usbmuxd, the macOS service that already multiplexes connections to iOS devices over USB. Oriel opens one HTTP request per connection to the body's own loopback port. Nothing listens on the Mac, and no host name is involved. Off the cable, the same door is reached through the CoreDevice tunnel that Apple's devicectl keeps open: Oriel holds one observer process per off-cable body, because a tunnel lives only while a devicectl process holds it, reads the tunnel's address, and connects there. The tunnel rides a utun interface, outside the Local Network gate that blocks launchd services, and stays on the home network rather than the tailnet. Every connection notes the link it used (cable, wifi, or unreachable with why), and the page shows it: never a silent fallback.
The first contact sets a 256-bit pairing token the body keeps and Oriel keeps in a file only its account can read, never logged. A body that answers 401 to that token was paired by someone else; Oriel says so and stops.
Eyes Through the Same Gate
A body's two cameras are not a new kind of eye. They are inputs of kind cordelia with the role look, and a look through them is an ordinary look: the eyes gate first, then one still fitted inside the look's 1,600-token budget. They follow the eyes modes the way Pippa's own cameras do, because a body counts as home hardware: closed in Manual until Dad's words open them, open in Auto, and open in Broadcast only while On Air is on. BodyLink asks the gate before every photo and clip, exactly as RecorderLink does, and test_eyes_gate.py holds that no other code calls those routes. The face is told when the gate opens or closes for it.
There is also a door Dad can use with one finger: a tap on the camera button of the face opens the gate for that body's two cameras for five minutes, recorded as his own approval, and a second tap closes it. The face shows its small camera preview only while the gate says open.
No Photos of People Kept
Track three's habit is to record everything and read a little. A body is deliberately stricter. When a look takes a still, Apple's Vision framework checks the viewing copy for people before the look answers:
- no person: the original stays, with a sidecar saying it was checked;
- a person in it: the original is deleted once the look has its viewing copy;
- Vision could not run, or the picture could not even be opened: deleted too. Nothing unchecked is kept.
Short clips follow the same rule, and the body itself keeps nothing. The viewing copy is the look's answer, and it is cleaned up after two minutes. The asymmetry is intentional: a camera that faces the person using Pippa's face will often see someone, and a house should not accumulate a photo album nobody asked for.
The Face Says Who Is Using It
Dad asked for the face to show which brain is using the body, and at what effort. Every request made for someone carries X-Cordelia-By, -Model, -Effort and -Doing: a look names the brain, model and effort its caller sent, a shell call says "shell", and Oriel's own health probes name no one. The last use is kept and sent again whenever a body comes back, so a restart never blanks it. A camera that can be used by several brains should say, on the device, which one is using it right now.
Bodies Are Data, Not Constants
Dad's instruction once a second device appeared: don't fix it as "the Pippa phone", and don't make it a constant. The device list is the registry. Each record has a stable id, a key, a name Dad can change, its model, its capabilities as the body last reported them (mouth, ears, eyes and which cameras, face, location, hands) and its own settings. Callers ask the registry for a capability and never assume one. test_devices.py scans the code for any device named in it. A new device joins with a register command and Cordelia from TestFlight, and starts with the wake phrase off until Dad or Chief Pippa turns it on.
Keeping a body alive is part of the job too. iOS stops the camera of an app that is not in front, so the engine asks each body for status every 10 seconds, and one silent for five minutes is brought to the front, at most once every five minutes. A locked device takes the launch and stays behind its lock screen, so the keeper reads the lock state first and says "locked". No automation ever unlocks a body.