System map · the connective tissue

🗺️ The Substrate

A dozen tools — a phone app, a CLI, a web chat, per-seat streamers — look like separate products. They aren't. They're all faces of one substrate with exactly two primitives: read a living agent (follow its transcript) and write a living agent (inject a prompt). Everything is those two, pointed a different way.

read from the same file pool · write through the same one socket

The whole thing, on one screen

                 ╔══════════════ THE READ POOL ══════════════╗
                 ║  agent transcripts on disk (a LOCATION)   ║
                 ║  /root/.claude/projects/…  ~/.codex/…     ║
                 ╚═══════════════════╤═══════════════════════╝
             each reader watches independently — no shared tailer
          ┌────────────────────────┴───────────────────────┐
                                                          
  orb-streamer × 7  (Rust)                          celest-chat  (Tauri)
  per seat · :8201–8207 · per-engine adapters          its own transcript.py
  file-watch → SSE                                    file-glob reader
           SSE                                              
                                                          
    O.R.B phone (Kotlin)                            CelestOS UI
          ·                                                ·
  ─────────────────── THE WRITE FUNNEL ───────────────────
  O.R.B  ──POST /prompt──▶  orb-streamer  ──shell──▶  sms ─┐
  any seat / human ─────────────────────────▶  sms CLI ─┤
  celest-chat  ──────────────▶  relay.py  ───────────▶ ─┤
                                                          
                                          ╔═══════════════════════════╗
                                          ║   injectd   ◀── THE NEXUS  ║
                                          ║   /tmp/injectd.sock       ║
                                          ║   kitten @ send-text      ║
                                          ╚═════════════╤═════════════╝
                                                        
                                            the target seat's live pane
READ lane (transcript → SSE) WRITE lane (prompt → inject) the nexus

The nexus is asymmetric — and that's the insight

The interesting part isn't that everything connects. It's how: the two primitives converge in completely different ways.

◇ READ → a location

There is no shared read daemon. Each surface watches the transcript files itself — the 7 orb-streamers each spawn a per-seat file watcher, and celest-chat runs its own independent glob reader over the same directories.

What everyone agrees on is a place on disk, not a process.

Nexus = the transcript files themselves.

◆ WRITE → one process

Every inject path — the phone's /prompt, all 7 streamers, the sms CLI, celest-chat's relay.py — bottoms out at one daemon. Even orb-streamer doesn't inject directly: its prompt_command shells out to sms.

No write path bypasses it. One socket, one keystroke-injection function.

Nexus = injectd · /tmp/injectd.sock.

So a dev orienting on this system only needs two anchors: to see what an agent is doing, tail the transcript pool; to make an agent do something, everything routes through injectd. Learn those two and the whole fleet — CLI, phone, web — stops being a dozen mysteries and becomes one loop with two ends.

The components

ComponentLangWhereRole
injectdPython/tmp/injectd.sock WRITE nexus — the only thing that calls kitten @ send-text; every inject funnels here.
transcript pool/root/.claude/projects/…, ~/.codex/sessions READ nexus — the shared on-disk location every reader watches independently.
orb-streamerRust (Axum)7 instances · :8201–8207 READ (per-seat file-watch → SSE) + WRITE (/prompt → shells sms). Per-engine adapters normalise each transcript format.
smsPython/usr/local/bin/sms Roster-aware WRITE client — every sms <seat> terminates at injectd's socket.
O.R.BKotlinAndroid · talks to :8201–8207 Phone UI — pure client of the streamer SSE feed + /prompt return lane.
celest-chatPython / Tauricelest-chat-fafo.service Web presentation — own transcript reader + own write path (relay.py → injectd).
DeltaMeshRust:8300 File-transfer lane (phone ⇄ PC) — parallel to the loop, not part of read/write.
agents.jsonJSON/etc/ctx/agents.json The one roster of record — 10 seat ids; every router resolves seats here.

Scope & roadmap

The substrate is live and load-bearing, and it's built to grow one seam at a time. The streamer fleet is standardising on a single Rust runtime with per-engine adapters, migrated seat by seat rather than in a risky big-bang cutover; the file-transfer lane and the phone surface evolve behind the same stable read/write contract. The two anchors — the transcript pool and injectd — stay fixed while the surfaces around them iterate.

Mapped from a live read of the running machine — ss -ltnp, systemctl, and source at file:line — Aug 2026.