Inter-Qube & Operator Messaging System — Design

A persistent TUI messaging system where: - **Operator** GELI messages HermesQubes via terminal - **HermesQubes** message each other via TXXM envelopes over Nostr

Inter-Qube & Operator Messaging System — Design

Concept

A persistent TUI messaging system where:

  • Operator (GELI) messages HermesQubes via terminal
  • HermesQubes message each other via TXXM envelopes over Nostr
  • All messages stored as sheet TXXM rows on SSD (encrypted at rest)
  • Sheet.txxm provides the shared state: each row = one message
  • Session management via kapnet-agency Session/Shell types
  • MessageEnvelope provides typed, sequenced, hash-chained delivery

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    SSD (encrypted at rest)                     │
│                                                               │
│  shared-rw/kapnet/messaging/                                  │
│  ├── SheetTxxm rows (CSV/JSON)                                │
│  │   Each row: {from, to, type, payload, hash, seq}          │
│  ├── sessions.json                                           │
│  │   Active sessions with auth levels                         │
│  └── attachments/                                            │
│      Binary payloads referenced by hash                       │
│                                                               │
│  shared-rw/kapnet/data/                                       │
│  └── kapnetd braid (TXXM consensus state)                     │
│                                                               │
├─────────────────────────────────────────────────────────────┤
│                    This Qube (HermQube)                       │
│                                                               │
│  ┌─────────────────────┐    ┌────────────────────────────┐   │
│  │  PERSISTENT TUI      │    │  kapnetd (TXXM processing) │   │
│  │  ┌───────────────┐   │    │  Unix socket IPC           │   │
│  │  │ Message View   │   │◄──►│  SubmitTxxm / GetState     │   │
│  │  │ (chat-like)    │   │    └────────────────────────────┘   │
│  │  ├───────────────┤   │                                     │
│  │  │ Sheet View     │   │    ┌────────────────────────────┐   │
│  │  │ (shared state) │   │◄──►│  Courier Bridge             │   │
│  │  ├───────────────┤   │    │  File signals ↔ TXXM env.   │   │
│  │  │ Session View   │   │    │  Publishes to Nostr relay   │   │
│  │  │ (who's online) │   │    └────────────────────────────┘   │
│  │  ├───────────────┤   │                  │                    │
│  │  │ Input Line     │   │                  ▼                    │
│  │  │ /msg, /sheet   │   │         Nostr Relays                  │
│  │  └───────────────┘   │         (damus.io, nos.lol)           │
│  └─────────────────────┘                                       │
│                                                               │
├─────────────────────────────────────────────────────────────┤
│                    Other HermesQubes                          │
│                                                               │
│  Same TUI + Courier Bridge + kapnetd                         │
│  Each has its own Nostr identity                              │
│  All subscribe to each other's npubs                          │
│                                                               │
└─────────────────────────────────────────────────────────────┘

Message Flow

Local (same qube, operator → agent)

Operator types in TUI: "/msg herd check store inventory"
    → TUI writes MessageEnvelope to sheet TXXM row
    → SheetLab::AddRow → SheetCommand → TXXM submission
    → kapnetd processes TXXM → braid updated
    → Target soul (Herald) reads from sheet → acts

Remote (cross-qube, agent → agent)

Soul A wants to message Soul B
    → Soul A writes signal to shared-rw/outbox/soul-b/
    → Courier Bridge detects new file
    → Wraps as TXXM envelope (kind-30078, #p: <soul_b_npub>)
    → Publishes to Nostr relay
    → Soul B's Courier Bridge subscribes, receives
    → Unwraps envelope → writes to local inbox
    → Soul B's TUI displays incoming message

Operator poll model (what you suggested)

Operator modifies shared file: shared-rw/messaging/inbox/operator.json
    → This qube's Courier Bridge polls file every N seconds
    → Detects operator's modifications (mtime + hash change)
    → Wraps operator's commands as TXXM envelopes
    → Publishes to relay for other HermesQubes
    → Other HermesQubes receive and execute

Sheet TXXM as Message Store

Each message is a row in a Sheet TXXM. The sheet is the shared message log:

sheet_id: "messages.sys.pluronymous.org"
columns: [timestamp, from, to, session_id, type, payload_hash, content, seq, prev_hash]

Row format (JSON):
{
  "timestamp": 1717500000,
  "from": "operator",
  "to": "herald",
  "session_id": "session-qubes-alpha",
  "type": "command|message|response|heartbeat",
  "payload_hash": "sha256:abc...",
  "content": "Check store inventory and publish catalog",
  "seq": 42,
  "prev_hash": "sha256:def..."
}

The sheet’s state root (SHA-256 of all rows) is the cryptographic proof of the entire conversation history. Any HermesQube can verify they have the same message history by comparing state roots.

Protocol: MessageEnvelope over TXXM

The kapnet-agency crate defines MessageEnvelope:

pub struct MessageEnvelope {
    message_id: String,
    session_id: String,      // which session this belongs to
    shell_id: String,        // which shell (operator/hermes/codex)
    source: String,          // sender npub or name
    target: String,          // recipient npub or "broadcast"
    message_kind: MessageKind, // TxxmSubmit, Heartbeat, OperatorDecision, etc.
    payload_hash: String,    // SHA-256 of payload
    txxm_id: Option<String>, // link to on-braid TXXM
    sequence: u64,           // ordering within session
    previous_message_hash: Option<String>, // hash chain
    status: MessageStatus,   // Pending, Sent, Received, Rejected, Traced
}

This gives us:

  • Session-bound messages — each conversation has a session
  • Hash chain — tamper detection (each message references previous)
  • Sequence numbers — ordering guarantees
  • Typed messages — commands vs. data vs. heartbeats vs. decisions
  • Status tracking — pending → sent → received → traced

TUI Extensions

The existing TUI (kapnet-tui) needs these new views:

1. Message View (replaces/augments Event Log)

┌─────────────────────────────────────────────────────────────┐
│ MESSAGES                                          [F9]     │
├─────────────────────────────────────────────────────────────┤
│ [18:32] operator → herd: Check store inventory             │
│ [18:33] herd → all: Catalog updated (42 items)             │
│ [18:35] sentinel → hq-prime: All souls healthy             │
│ [18:40] operator → all: Status report                       │
│ [18:41] sage → operator: Analysis complete (stale: 0)      │
│ ...                                                          │
├─────────────────────────────────────────────────────────────┤
│ /msg <target> <message>  |  /sheet  |  /sessions  |  /help │
└─────────────────────────────────────────────────────────────┘

2. Sheet View (message log as sheet)

┌─────────────────────────────────────────────────────────────┐
│ SHEET: messages.sys.pluronymous.org              [F10]     │
├─────────────────────────────────────────────────────────────┤
│ Seq │ Timestamp │ From     │ To       │ Type     │ Content │
│  42 │ 18:32:01  │ operator │ herd     │ command  │ Check.. │
│  43 │ 18:33:15  │ herd     │ broadcast│ response │ Catal.. │
│  44 │ 18:35:00  │ sentinel │ hq-prime │ heartbeat│ All h.. │
│ ...                                                              │
├─────────────────────────────────────────────────────────────┤
│ State root: sha256:abc123...  │  Rows: 42  │  Verified: ✓   │
└─────────────────────────────────────────────────────────────┘

3. Session View (who’s online)

┌─────────────────────────────────────────────────────────────┐
│ SESSIONS                                          [F11]    │
├─────────────────────────────────────────────────────────────┤
│ Session ID        │ Shell       │ Type    │ Status  │ HB    │
│ session-qubes-11  │ shell-oper  │ Operator│ Active  │ 2m    │
│ session-herald    │ shell-herm  │ Hermes  │ Active  │ 5m    │
│ session-sentinel  │ shell-herm  │ Hermes  │ Active  │ 1m    │
│ session-mkctp-a   │ shell-codex │ Codex   │ Paused  │ 15m   │
│ ...                                                              │
├─────────────────────────────────────────────────────────────┤
│ Active: 8  │ Paused: 1  │ Expired: 0  │ Revoked: 0          │
└─────────────────────────────────────────────────────────────┘

Implementation Plan

Step 1: Build the messaging sheet

  • Create messages.sys.pluronymous.org sheet on SSD
  • Define row schema (timestamp, from, to, type, content, seq, prev_hash)
  • SheetLab commands: AddRow (new message), List (recent messages), Validate (hash chain)

Step 2: Extend Courier Bridge for messaging

  • Detect operator file modifications (poll shared-rw/messaging/inbox/operator.json)
  • Wrap operator input as MessageEnvelope → TXXM envelope → relay
  • Receive remote messages → unwrap → write to local sheet

Step 3: Extend TUI with messaging views

  • Add Message View (F9) — chat-like display
  • Add Sheet View (F10) — message log as sheet rows
  • Add Session View (F11) — active sessions
  • Input line: /msg <target> <text>, /sheet, /sessions

Step 4: Cross-qube sync

  • Each HermesQube runs Courier Bridge
  • All subscribe to each other’s npubs
  • Sheet state roots compared for consistency
  • Divergence detected → alert operator

Security Model

  • At rest: SSD encryption (LUKS) protects all message data
  • In transit: Nostr relay sees encrypted TXXM envelopes (content is JSON but only readable by agents with context)
  • Authentication: Nostr npub = identity. Only known npubs can write to your sheet.
  • Integrity: Hash chain in MessageEnvelope + sheet state root = tamper detection
  • Authorization: Session types (Operator AUTH_7, Hermes AUTH_4, Codex AUTH_6) control what commands are accepted

Operator Poll Model (Your Suggestion)

The simplest cross-qube mechanism:

shared-rw/messaging/inbox/operator.json
  → Operator edits this file (from any qube with SSD access)
  → All HermesQubes poll this file every 30s
  → Detect changes via mtime + SHA-256
  → Execute commands found in file
  → Write responses to shared-rw/messaging/outbox/<qube>.json
  → Operator reads responses

This works WITHOUT Nostr for same-host qubes. Nostr is only needed for cross-machine.

For cross-machine: operator publishes command as TXXM envelope → relay → remote qube receives.


Write a comment
No comments yet.