Inter-Qube & Operator Messaging System — Design
- Inter-Qube & Operator Messaging System — Design
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-agencySession/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.orgsheet 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