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

One Frame into a Private Socket

~14 min · unix-sockets, delivery-receipts, provenance, claude-code, adapters

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

A Door Coop Does Not Own

Every Claude Code session with cross-session messaging binds its own inbox: a Unix domain socket that other sessions on the same Mac can write to. Claude Code built it so one of your sessions could warn another one mid-task. Coop is not a Claude Code session and has no seat in that conversation, yet it still has to hand one specific chat an invitation and, later, its work. So it uses the same door the way a careful neighbor would: find exactly one live chat, check that the door really belongs to that chat, push one message through the slot, and walk away. It does not wait on the step for an answer, because the slot never gives one.

That last sentence is this whole track in miniature. A socket write has no synchronous delivery acknowledgment. Whatever Coop knows about what happened next, it learns afterward, by reading the receiver's own records. Native doors are observations.

Read the Receiver Twice, Then Once More

Claude Code keeps a small registry file for each running session: its session id, its process id, the process start time, a peer protocol number and the absolute path of its messaging socket. ClaudeDesktop.target() reads that registry and accepts exactly one live match. The pid must equal the file's name. The recorded start time must equal the live process's birth time, or the entry is an exited process's leftover. The peer protocol must be 1. The socket must pass private_socket. What comes back is four facts: pid, birth, socket path, socket inode.

send calls target() twice and refuses with Native receiver changed before send if the two readings differ. Then it hands those four expected facts to the host, which is office itself or another Mac reached through Coop's ssh helper, and the host reads the registry a third time, on the machine where the chat actually lives, and compares again. Only then does exactly one newline-terminated line go into the socket: connect, sendall, shut down the write side, close. Nothing is read back.

Why three readings? Because between "I found the chat" and "I wrote to it", a chat can exit, a new process can reuse the pid, and a socket path can come to name a different file. A reading is not free: it runs ps once for every registered chat to read that process's start time, so it costs milliseconds per chat, and the host's reading on another Mac also crosses ssh. That is still a bargain. A frame written into the wrong chat is an instruction handed to a stranger.

What Counts as Private

private_socket is four checks and one answer. The path must be a socket, not a regular file someone parked there. It must be owned by the user Coop runs as. Its mode must carry no group or other bits (mode & 0o077 is zero). And its parent directory must pass the same owner and mode test, because whoever controls a directory controls what its names point at. Pass, and you get the socket's inode, which is what the later comparison pins. Fail, and you get Native socket ownership or permissions changed, never a best guess.

Notice what is not on the list: the chat's working directory. A Claude Desktop 2.1.284 chat opened for a project starts in a scratch workspace and moves later, and a worker may cd around its checkout. On 2026-09-30 discovery filtered candidates by registry cwd and found a chat sitting at READY ten minutes late, after Dad had already told it to go ahead by hand (commit d056235, titled "cwd is data, not identity"). Identity is the session id, the live pid with its birth time, and the private socket. Everything else is description.

The Frame Itself

One JSON object. type is user; session_id names the receiver; uuid and msg_id both carry the outbox message id; from is cwkCoop; priority is next; message holds the prompt. Reusing the outbox id as the native uuid is the move that makes everything afterward possible: the id Coop stored before sending is the id it will search for in the transcript.

And notice what the frame does not claim. It asserts no permission mode for the sender. Hold that thought until the next lesson; it cost a day.

Receipts Come from the Transcript, in Two Shapes

Because the socket answers nothing, the adapter reads the chat's transcript forward from a byte offset it recorded before sending. An idle receiver starts a new turn with the frame and writes a user event whose uuid is the message id. That was the only shape Coop read until 2026-10-04. That day, todo #310's invitation reached a chat that was in the middle of a turn. Claude Code absorbed the frame into the running turn and wrote a queued_command attachment whose source_uuid was the message id, with the reason absorbed_mid_turn. The worker answered COOP_ACCEPT. The adapter, looking only for the first shape, never saw the envelope arrive, so it dropped the final that answered it, and the invitation sat there watching (commit ff2a225).

peer_input now accepts both shapes and checks them alike: isMeta must be true, and origin must be exactly {kind: peer, from: cwkCoop, msg_id: <the id>}. A match with the wrong provenance is a Conflict, not a receipt, and the same envelope seen twice is a Conflict too. An absorbed envelope's answer is the final of the turn it joined, however many tool calls later.

Five Facts, Never One

Section 9 of Coop's architecture refuses to let "sent" stand in for anything else. It records five separate facts:

FactWhere Coop learns it on the Claude door
1. Coop durably stored the messageThe outbox row, committed inside the engine's own transaction
2. Host transport accepted itThe socket write returned without an error
3. The harness received itA peer entry, in either shape, with the exact id and provenance, in the transcript
4. The receiver accepted offered workA completed final carrying COOP_ACCEPT with this invitation's nonce, then the engine's one-transaction take
5. The work acquired an outcomeA report from the bound worker, or a recorded decision by Dad or the chief

An unobservable receipt stays unknown. A Coop that folded fact 2 into fact 3 would have called #310 delivered while nothing had been bound.

A successful write is fact two, and only fact two. The bytes left. Whether anyone read them, agreed to them or finished the work they describe are three more questions, and each one is answered by evidence from the far side, never by the sender's optimism.

Code

desktop.py: the privacy check and the one-frame send (verbatim excerpt)·python
def private_socket(path):
    path=Path(path)
    info=path.lstat()
    parent=path.parent.stat()
    if not stat.S_ISSOCK(info.st_mode) or info.st_uid!=os.getuid() or info.st_mode & 0o077 or parent.st_uid!=os.getuid() or parent.st_mode & 0o077:
        raise Conflict('Native socket ownership or permissions changed')
    return info.st_ino

# ... class ClaudeDesktop (SENDER='cwkCoop') ...

    async def send(self,message_id,prompt,checkpoint):
        first=self.target()
        second=self.target()
        if first!=second:
            raise Conflict('Native receiver changed before send')
        frame={'type':'user','session_id':self.session_id,'uuid':message_id,'msg_id':message_id,
               'from':self.SENDER,'priority':'next','message':{'role':'user','content':prompt}}
        # The host checks the exact receiver once more, then writes the one frame.
        self.host.send(self.registry,self.session_id,
                       {'pid':first['pid'],'birth':first['birth'],'socket':first['socket'],'inode':first['inode']},
                       json.dumps(frame)+'\n')
desktop.py: both receipt shapes, one provenance check (verbatim, docstring trimmed)·python
    def peer_input(self,event,message_id):
        """True when `event` is this delivery's peer envelope, in either transcript form.
        ... Both forms carry isMeta and the peer origin, checked alike.
        """
        if event.get('type')=='user' and event.get('uuid')==message_id:
            envelope=event
        elif (event.get('type')=='attachment' and isinstance(event.get('attachment'),dict)
              and event['attachment'].get('type')=='queued_command' and event['attachment'].get('source_uuid')==message_id):
            envelope=event['attachment']
        else:
            return False
        if envelope.get('isMeta') is not True or envelope.get('origin')!={'kind':'peer','from':self.SENDER,'msg_id':message_id}:
            raise Conflict('Claude native peer provenance changed')
        return True

External links

Exercise

Pick one place in your own code where a write to another process, queue or service gets logged as "delivered" or "sent successfully". Split that one log line into Coop's five facts. For each fact, write down where your system could actually observe it (a stored row, a response field, the receiver's own log) or write "unknown". Then change the code so it records only the facts it really saw.
Hint
Most systems can observe facts one and two directly and nothing more. If the receiver keeps any durable record of its own, such as a log, a transcript or a table, give your message an id you stored before sending and search for that id there. That is how fact three stops being a guess.

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.