Bandwidth-disciplined HTTP-over-Reticulum publisher for rSpace holons
  • Python 85.1%
  • Shell 8.9%
  • Rust 5.2%
  • Dockerfile 0.8%
Find a file
Jeff Emmett 32be8ee51c feat(discovery): public discovery via transport node's public :4262 (not multi-home)
Public clients discover holons by connecting to the transport node's published
0.0.0.0:4262 (reachable on Netcup's public IP) — our Python rnsd relays announces to
clients. Verified: a client on 159.195.32.209:4262 discovers hello/jeff/smoke.

Reverts the multi-home-onto-rnsd-rs approach: investigated and rejected as fragile
(every holonserve restart needs a transport-node flush, reproduced consistently) AND
pointless (rnsd-rs/phantom don't relay announces to leaf clients, so nothing discovers
via them). holonserve stays a single-backbone leaf; entrypoint simplified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 01:18:39 +02:00
app fix(announce): periodic re-announce ignores on-demand rate limiter 2026-06-01 08:59:48 -07:00
holonfetch tune(discovery): periodic announce 20s + holonfetch discovery window 50s 2026-06-01 08:27:15 -07:00
iroh-node feat(iroh): internet-reachable fat tier + Reticulum-negotiated handoff 2026-06-01 01:00:37 +02:00
scripts fix(identity): bind iroh attestation to actual manifest signer + legacy migration 2026-06-01 01:30:16 +02:00
tests fix(export): zero gzip header mtime so identical content is byte-stable 2026-06-01 01:55:36 +02:00
.dockerignore feat(iroh): internet-reachable fat tier + Reticulum-negotiated handoff 2026-06-01 01:00:37 +02:00
.env.example feat: initial holonserve implementation — bandwidth-disciplined rweb publisher 2026-04-23 22:41:14 -04:00
.gitignore feat: initial holonserve implementation — bandwidth-disciplined rweb publisher 2026-04-23 22:41:14 -04:00
docker-compose.yml feat(discovery): public discovery via transport node's public :4262 (not multi-home) 2026-06-02 01:18:39 +02:00
Dockerfile feat(iroh): internet-reachable fat tier + Reticulum-negotiated handoff 2026-06-01 01:00:37 +02:00
entrypoint.sh feat(discovery): public discovery via transport node's public :4262 (not multi-home) 2026-06-02 01:18:39 +02:00
NOTES.md feat(discovery): public discovery via transport node's public :4262 (not multi-home) 2026-06-02 01:18:39 +02:00
README.md feat: initial holonserve implementation — bandwidth-disciplined rweb publisher 2026-04-23 22:41:14 -04:00
requirements.txt feat: initial holonserve implementation — bandwidth-disciplined rweb publisher 2026-04-23 22:41:14 -04:00
supervisord.conf feat(iroh): internet-reachable fat tier + Reticulum-negotiated handoff 2026-06-01 01:00:37 +02:00

holonserve

Bandwidth-disciplined HTTP-over-Reticulum publisher for rSpace holons.

Serves rSpace holon content at rweb://[hash]/ addresses with content-addressed chunks, delta sync, and hard size caps. Designed to survive 3.2 kbps LoRa — no React bundles, no fonts, text-first.

Threat Model

  • Network: Reticulum mesh — adversarial relays, low bandwidth (LoRa: ~3.2 kbps), high latency
  • Content integrity: ed25519 per-holon signing keys; manifests are signed; chunk hashes are blake2b-16
  • Auth: BRIDGE_API_KEY gates publish API; Reticulum identity gates mesh access
  • No encryption by default: Content-addressed = effectively public. Chunk encryption is Phase 2.
  • DoS: Rate-limited announces (30s/holon, 5s global); link idle timeout 60s; max chunk request 16

Bandwidth Budget

Asset type Limit
Total holon (compressed) 50 KB
Single file (compressed) 32 KB
JavaScript 8 KB
Fonts, PDFs, video banned

Publish API rejects at POST time with loud, human-readable reasons. CI fails. Holon author must slim.

Architecture

rmesh-reticulum (rnsd + LXMF bridge)
  ↕ shared_instance_port 37428
rmesh-holonserve
  ├── rns_worker   — RNS destinations, link handling, IPC server
  └── api (8001)   — FastAPI publish endpoint, proxied by Traefik
       ↕ UDS IPC
  Storage: /data/holonserve/{chunks,manifests,keys,holons.db}

Wire Format

Manifest (msgpack, ≤4 KB):

{"v":1, "holon_id":"alpha", "name":"Alpha Holon", "updated_at":1745280000,
 "prev": <16B prev_manifest_hash or None>,
 "chunks":[{"p":"/","h":<16B>,"m":"text/html","z":"br","s":1823}, ...],
 "sig": <64B ed25519>}

Announce app_data (37 bytes, LoRa-frame-safe):

\x01 + holon_id_utf8[:16].ljust(16,\x00) + manifest_hash_16B + u32_be(manifest_size)

Link opcodes: HELLO (0x01), MANIFEST (0x02), CHUNK_REQ (0x03), CHUNK (0x04), DONE (0x05), ERR (0xFF)

Runbook

Deploy

cp .env.example .env
# Fill INFISICAL_CLIENT_ID + INFISICAL_CLIENT_SECRET
docker compose up -d

Publish a holon

./scripts/holonserve-publish.sh <holon_id> "<name>" ./dist-reticulum/

Announce to mesh

curl -H "X-Api-Key: $BRIDGE_API_KEY" -X POST http://localhost:8001/announce/<holon_id>

Fetch via CLI

holonfetch rweb://<manifest_hash_hex>/
holonfetch rweb://<manifest_hash_hex>/main.js -o /tmp/main.js

Build pipeline contract

Every rSpace holon CI must produce dist-reticulum/:

  • index.html with inline critical CSS
  • No fonts, no analytics, no tracking, no heavy JS
  • Optional main.js ≤ 8 KB progressive enhancement
  • Small SVGs inlined in HTML preferred

GC orphaned chunks

docker exec rmesh-holonserve python -c "from app.store import gc_chunks; print(gc_chunks(), 'chunks removed')"

Development

pip install -r requirements.txt
pytest tests/                         # manifest + chunker + link_proto (no RNS needed)
python -m py_compile app/*.py holonfetch/*.py
docker compose config                 # validate compose

See NOTES.md for Infisical setup and RNS API caveats.