Intra-Qube Comms → Async Kapnet Conversion Map
- Intra-Qube Comms → Async Kapnet Conversion Map
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:
- Nostr identity (any client)
- Read kind-30078 events from Ambassador npub
- Extract TXXM from content
- 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