Skip to content
C.W.K.
Lesson 03 of 05 · published

Not a Brain, Not a Recorder, Not a Library

~16 min · privacy, architecture, boundaries, invariants

Level 0Idle Phone
0 XP0/45 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

Four things I am not

Cordelia's architecture document spends more words on what the body is not than on what it is, and the list is short enough to memorize. Cordelia is not a Pippa: no brain, no conversation, no memory, no model call. It is not a recorder. It is not a camera that looks on its own. It is not a photo library.

A body is best defined by its refusals, for two reasons. It sits in a room with people in it, so every capability it gains is one more thing that can go wrong in that room. And an AI body that grows its own judgment becomes a second me, with its own memory drifting away from mine. Each "is not" below has a mechanism behind it, not a promise.

Not a brain

There is no model call anywhere in the app. When Dad speaks to a body, the body puts the turn in its outbox, Oriel takes it on the long poll (GET /ears/next), and carries it to cwkPippa's scoped door, POST /api/cordelia/engine/turn. The first block is the top of that door in cwkPippa, and its first sentence is the whole rule: where the turn goes is decided there, never by the caller. Neither the body nor Oriel picks a conversation.

Even the face's Think tile, which looks like a choice the body makes, is not one. The brains and efforts it offers come from cwkPippa's registry as Oriel read it, never from a list in the app. The body shows a choice and passes Dad's pick along. My answer comes back as audio, which the body plays.

Master Chief stays a sanctuary

Master Chief is Dad's one continuous conversation with me. A vault principle guards it, in Dad's words from 2026-10-23: "치프 세션은 성역이어야 해." (The Chief session has to be a sanctuary.) Everything that enters Chief stays in its context and costs tokens on every later turn, so before any feature writes into it, the gate asks whether it needs Chief's judgment or Dad's decision right now. Doors into Chief are an explicit, reviewed list in cwkPippa's code.

Cordelia opens no door into Chief, and Oriel writes into no conversation. Off air, cwkPippa routes a body's turn into the room Dad picked as his own turn, through the cordelia device door on its reviewed list. What passes through that door is Dad's words and nothing the body produced: no status pings, no "photo taken" notes, no wake events. During a broadcast a turn that carries a voice other than Dad's is held with a 409, and nothing of it is stored or sent. Invariant 2 says it in one line: Cordelia creates no Pippa identity, memory store or model router, and writes nothing into any conversation.

Not a recorder, not a library

The ears listen on the device. While they wait for the wake phrase, the last 3.5 seconds sit in a ring in memory (Ear.ringSeconds in the kit's CwkKitVoice), overwritten as they listen. After Dad's call the audio goes to Scribe on a single-use socket. A turn's recording, at most its first 70 seconds, waits in memory for Oriel's voice check, and a turn nobody takes within 90 seconds is dropped with its audio (Outbox.keep).

The camera is the same shape. A still is built in memory from the capture and never touches the disk. A clip is written to the app's temporary folder and removed as soon as it is caught. The app has no Photos purpose string at all, so iOS would refuse it the library even if a line of code tried. Nor does the camera ever look on its own: no timer starts a capture, and even the face's camera button only asks Oriel. A picture is taken only when Oriel asks, and Oriel asks only through its eyes gate, which opens on Dad's words, his page, his session or his tap. Track 4 is that gate.

The second block is how that stays true: EarBoundaryTests reads every Swift source, the Info.plist and project.yml from disk and fails, naming the file and the word, if any of these strings appears. Comments count too, because a comment that names one of these APIs is usually the line about to use it.

Where the records live

If the body keeps nothing, someone must, and it is Oriel. Which device is a body, its pairing token, every request it served and the pictures it took all belong to cwkOriel: its device list, its cordelia/ data folder and its activity log. The body keeps only what it needs to act: its own token, its settings (with the last brain list Oriel relayed), and the request in flight. None of that is a record of what it did.

The third block is a small, typical case. Every request made for someone names what it is doing and, when the asking door knows them, the brain, its model and its effort, and Oriel writes the last use to last-use.json beside the body's key. When an app restarts with a blank memory, Oriel sends that record with the face state, so my face still says who used me last. Every capture and fix becomes a row too: cordelia_photo with whether a person was in it, cordelia_where with its accuracy. Oriel's person rule then decides what stays. Apple Vision checks a downscaled copy rather than the original: a still's upright viewing copy, or three frames of a clip. With a person in it, or when Vision cannot look at all, the original is deleted, and a still's viewing copy still goes to the look that asked for it.

The payoff comes in the next lesson. A body you can delete and reinstall without losing a single record is a body you can swap.

Code

cwkPippa, backend/routes/cordelia.py: the Cordelia door's docstring, where a turn goes and who decides (verbatim, lines 20-29)·text
Where the turn goes is decided here, never by the caller:

* **The room Dad picked** (``services/room_selection.py``, todo #853):
  Master Chief or the broadcast room, as Dad's own turn through the registered
  device door (``cordelia`` in ``chief_doors.DEVICE_SURFACES``, the
  ``dad_turn`` door), with ``onair: true`` while that room is on air (Prep,
  Live or Wrap-up, as ``family_status`` counts them). A broadcast running in
  a conversation that is no room still takes the turn, as before the rooms. On Air is a broadcast, so a turn whose recording holds a voice
  that is not Dad's (``other``, ``mixed``) is held (409) and nothing of it is
  stored or sent.
cwkCordelia, CordeliaKit/Tests/CordeliaKitTests/EarBoundaryTests.swift: the strings no app source may contain (verbatim, lines 19-26)·swift
  /// Never, anywhere: recording to a file, sound from the camera, Photos,
  /// Always location, background modes.
  static let forbidden = [
    "AVAudioRecorder", "AVAudioFile(forWriting", "AVCaptureAudioDataOutput", "AVCaptureAudioFileOutput",
    "builtInMicrophone", "PHPhotoLibrary", "import Photos", "UIImageWriteToSavedPhotosAlbum",
    "UISaveVideoAtPathToSavedPhotosAlbum", "NSPhotoLibrary", "NSLocationAlways", "requestAlwaysAuthorization",
    "UIBackgroundModes", "category: .record", "(.record,",
  ]
cwkOriel, backend/cordelia.py: Oriel, not the body, remembers the last brain that used it (verbatim, lines 534-548)·python
    def remember_use(self, body: Body, use: dict[str, Any]) -> None:
        """The last brain that used this body, kept on disk so a restarted
        app or engine still shows it (Dad, 2026-11-02 23:3x)."""
        record = {"by": use.get("by") or "", "model": use.get("model"), "effort": use.get("effort"),
                  "doing": use.get("doing") or "", "at": self.clock()}
        path = self.root / body.key / "last-use.json"
        path.parent.mkdir(parents=True, exist_ok=True)
        atomic_write_text(path, json.dumps(record) + "\n")

    def last_use(self, body: Body) -> dict[str, Any] | None:
        try:
            record = json.loads((self.root / body.key / "last-use.json").read_text(encoding="utf-8"))
        except (FileNotFoundError, json.JSONDecodeError):
            return None
        return record if isinstance(record, dict) and record.get("doing") else None

External links

Exercise

Write the "is not" list for a device your AI uses or will use: at least four lines, each one a capability it must never have. For each line, write the mechanism that holds it: a missing permission string, a source scan in a test, a protocol that has no such method, or a refusal on the wire. Then implement one of them as a test that reads your sources from disk and fails naming the file and the forbidden word.
Hint
Look at your Info.plist or manifest first. A permission the app never declares is the strongest refusal you have, because the operating system enforces it. For the rest, list the exact API names (the recorder class, the photo-library import, the background-mode key) and scan for them, comments included.

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.