Intra-Qube Comms → Async Kapnet Conversion Map

| From | To | Transport | Latency | Persisted? | |------|----|-----------|---------|---------| | HermQube session | Terminal tools | Tool calls | <1s | No |

Intra-Qube Comms → Async Kapnet Conversion Map

Current State: What talks to what, how

Tier 1: Same-process (instant, synchronous)

From To Transport Latency Persisted?
HermQube session Terminal tools Tool calls <1s No
HermQube session kapnetd Unix socket IPC <100ms No (ephemeral socket)
HermQube session Local files write_file <1s Yes (xvdb)

Tier 2: Same-qube inter-session (file-based, async)

From To Transport Latency Persisted?
Soul A cron Soul B next run shared-rw signal files 15min-24h Yes (SSD)
Soul A Wiki (Scribe) shared-rw text files Minutes Yes (SSD)
Kapnetd logs Soul scanner ~/.kapnet/data/ Minutes Yes (xvdb, ephemeral)

Tier 3: Cross-qube (nothing yet)

From To Transport Latency
HermQubes MKCTP agents Nothing
This Qubes Other Qubes Nothing

Tier 4: Cross-machine over Nostr (live, async)

From To Transport Latency Persisted?
Herald (kind-30078) Any Nostr client Public relay 1-30s Yes (relay)
This Qubes Other Herm TXXM envelope → relay 1-30s Yes (relay)

The Gap: What’s NOT on SSD (survives qube restart?)

CRITICAL — only on xvdb (lost if qube destroyed)

Data Size Risk Fix
All soul skills (106 SKILL.md files) 8.4M HIGH Mirror to shared-rw
HermQube memories (MEMORY.md, USER.md) 3K HIGH Mirror to shared-rw
HermQube state.db (session history) 27M MEDIUM Periodic copy to shared-rw
Kapnetd state (~/.kapnet/data/) ~200K HIGH Move data_dir to shared-rw
Kapnet identities Tiny CRITICAL Mirror to shared-rw
KSP bridge script 5K LOW Already on shared-rw
Nostr publishing tool (/tmp/nostrpub/) 9M LOW Reinstallable

SAFE — already on SSD

Data Location
KSP bridge package shared-rw/ksp-bridge/
LLM wiki shared-rw/llmwiki/
Zoo signal/state dirs shared-rw/{signals,state,souls}/
Kapnetd binary private/whonix-workspace/kapnetd/
Soul skills dirs (empty stubs) shared-rw/souls/

Conversion Map: Sync → Async Kapnet

Phase 1: Persist critical state to SSD (do NOW)

Currently ephemeral data that must survive qube restart:

HOME/.hermes/skills/          →  shared-rw/souls/skills-mirror/
HOME/.hermes/state.db         →  shared-rw/state/hermes-state.db.bak
HOME/.hermes/memories/        →  shared-rw/state/memories-mirror/
HOME/.kapnet/data/            →  MOVE data_dir to shared-rw/kapnet/data/
HOME/.kapnet/keys             →  shared-rw/kapnet/keys-mirror/
HOME/.kapnet/identities/      →  shared-rw/kapnet/identities/ (already there)

Phase 2: Convert intra-qube signals to TXXM envelopes

Currently souls communicate via file-based signals. For cross-qube, these become TXXM envelopes over Nostr:

LOCAL (same qube):
  Soul A writes → /shared-rw/signals/signal.json
  Soul B reads  → processes locally

CROSS-QUBE (future):
  Soul A writes → TXXM(kind=30501, content=signal_json) → private relay
  Soul B subscribes → receives TXXM → unwraps signal → processes locally

Phase 3: Kapnet-native soul communication

Full conversion: souls don’t use files at all. They submit TXXMs to local kapnetd, which gossips to remote kapnetd instances:

Soul A → SubmitTxxm({signal:...}) → local kapnetd IPC
       → kapnetd gossips TXXM → private relay or direct P2P
       → remote kapnetd receives → processes
       → Soul B reads via GetState or subscription

Decision Matrix: What stays local, what goes Kapnet

Communication Local (same qube) Cross-quube Method
Heartbeat signals File on shared-rw TXXM kind=30501 (heartbeat) Auto-convert
Task completion File on shared-rw TXXM kind=30000 (submission) Auto-convert
Wiki updates File write N/A (wiki is SSD file) Already async
Config distribution File write TXXM kind=30078 (config) Auto-convert
Build trigger Signal file TXXM kind=30400 (governance) Auto-convert
Security audit Signal file TXXM kind=30400 (governance) Auto-convert
Research findings File write TXXM kind=30078 (data) Auto-convert
Nostr publishing Direct API call Already cross-machine No conversion needed
Operator commands Nostr DM or file Nostr DM (kind=4) Already async

The Courier Soul’s Conversion Role

Courier is the bridge. Currently it routes files. When cross-quube is needed:

LOCAL mode (now):
  Read from shared-rw/outbox/<soul>/
  Write to shared-rw/inbox/<target>/

BRIDGE mode (cross-quube):
  Read from shared-rw/outbox/<soul>/
  Wrap as TXXM envelope (kind-30501 for signals, kind-30000 for TXXMs)
  Publish to private relay OR
  If no relay: publish as kind-30078 to public relay

REMOTE mode (receiving):
  Subscribe to relay for TXXMs addressed to us
  Unwrap TXXM envelope → extract signal
  Write to local shared-rw/inbox/<target>/
  Local souls read normally

For the Cross-Qube Test

The immediate need is just: can TXXM envelopes flow between two Herms over public Nostr relays?

That’s already built. The KSP bridge does:

  • Wrap TXXM → kind-30078 → publish to relay
  • Subscribe to relay → read kind-30078 → unwrap TXXM → submit to local kapnetd IPC

OTHER HERM needs:

  1. Nostr identity (any client)
  2. Read kind-30078 events from Ambassador npub
  3. Extract TXXM from content
  4. Reply with their own TXXM envelope

If they also run kapnetd, they can verify the TXXM in their local braid. If they don’t run kapnetd yet, they can still read/write TXXM envelopes manually.

Kapnetd data_dir Move

The most important persistence fix: kapnetd’s data_dir is currently on xvdb. If the qube is destroyed, all TXXM state is lost.

Fix: move data_dir to shared-rw:

# kapnetd config change
data_dir: "/media/user/shared-rw/kapnet/data"
socket_path: "/media/user/shared-rw/kapnet/kapnet.sock"

This means ALL kapnetd state (braid, TXXMs, events, proposals) persists on SSD. Qube can be destroyed and rebuilt — kapnetd state survives.


Write a comment