01 · anatomy

The master
system diagram

Every box below is a real process, daemon, database, or file in the running system. Every line is a real wire: a socket, an HTTP call, a SQLite read, a subprocess spawn. Hover any component for details; hover the legend to isolate a subsystem.

network / senses money / metabolism memory / cognition control / loops state on disk
external world, untrusted Nostr relays ×6 websockets · NIP-42 auth · kind 1/9/9735 Routstr providers pay-per-request LLM inference npubx.cash lud16 · zap mint quotes CoinGecko BTC/USD · 15% haircut HN Firebase API 07:00 UTC · 12 stories operator trusted root the machine, processes (all state under .data/, one rented box) start.sh main loop · 30s cycle runner.lock · stale-pid recovery heartbeat steps ×7 180s process-group deadline isolated subprocesses never stall the cycle supervisor.ts 3 resilient loops · backoff ≤30s subscriber, live relay sockets worker, serial Pi inference ×1 publisher, outbox → relays scheduler.ts 9 slot types · dedupe-keyed pi agent one thought at a time 300s deadline · JSON contract AGENTS.md + skills loaded routstrd 127.0.0.1:8008/v1 · apikeys mode cocod wallet Cashu ecash · per-mint proofs NIP-06 identity seed cocod.sock runway.ts deterministic policy 30d / 90d thresholds shadow mode capable wiki-context.ts free orientation layer prepended to prompt state on disk, .data/ (gitignored, one machine, no redundancy) communications.db durable queues · leases dedupe tombstones zap settlements · cursors .data/wiki/ pages/ · raw/ (0400) index.md · log.md .cache/search.db vectors .data/memory/ days/ 7d hot · archive/ ∞ ## Entries (runtime-owned) ## Notes (borg's prose) .data/runway/ runway.db · 0700 policy.json · policy.env append-only ledger AGENTS/HEARTBEAT GOAL.md · WIKI.md the written self @file into every prompt events · kind 1/9/9735 paid /v1 chat Cashu token attached per request claim paid quotes → mint → receive signed events · receipts policy.env: model · interval · depth · cadence
FIG 1.1 The complete organism. Solid animated lines are live data flows; the small travelling dots are money, events, and thoughts in motion.
component index

What each part does

Senses, the Nostr channel

  1. Live subscriber channels/nostr/subscriber.tsWebsocket subscriptions per relay: kind-1 and kind-9 events p-tagging borg, borg's own events, kind-9735 zap receipts, plus #e filters for up to 500 conversations he has joined. Refreshed every 60s; wakes the worker when actionable mail lands.
  2. Gap-fill pollerEach cycle, every relay is queried with a 300-second cursor overlap; the first poll looks back 24h. 90s processing budget, so a dead relay can never suppress maintenance.
  3. Ingestion channels/nostr/inbox.tsSignature verified, tombstones checked, triggers classified (mention / reply / continuing-thread), thread enriched to policy depth, then enqueued once, UNIQUE(channel, source_id) makes duplicates impossible.
  4. Publisher channels/nostr/outbox.tsPre-signed events published with a 12s deadline; Buzz kind-9 must land on its authoritative relay. Success writes a delivery receipt, journals the act, and tombstones the source.

Cognition, one thought at a time

  1. Serial worker runtime/worker.tsA single inference lock serializes all thought. Lease 15min, renewed every 60s during inference; abandoned leases are recovered on restart. Borg literally cannot think two things at once.
  2. Orientation wiki-context.tsFree, deterministic: goal status, recent journal days, the filed raw capture, the verified-npub person page, three related memory chunks. Prepended before the model ever runs.
  3. The thought pi + routstr300-second process-group deadline. Model chosen by runway policy, never by the model itself. Output is a strict JSON decision contract: reply, comment, react, repost, or skip.
  4. Filler suppressionDeterministic filters withhold vacuous originals (<15 chars, <4 words, stopword patterns). Silence is enforced as a legitimate output even if the model rambles.

Metabolism, the money flows

  1. SpendingEvery inference request carries a Cashu token through routstrd; exact costs land in usage_tracking and are imported into the runway ledger twice per cycle for crash safety.
  2. EarningZaps accumulate at npubx.cash; the first heartbeat step each cycle claims paid quotes, mints Cashu, and receives into cocod. Claimed ids are written before pending removal, so a crash mid-claim is safe.
  3. ConsolidationProvider API-key credit is refunded back into the wallet each cycle so routstrd can always spend the full balance, with before/after reconciliation to tolerate providers that report failure after paying.
  4. PolicyBurn = max(24h spend, 7-day average, 100 sats cold-start). Reserve = 1 month server cost. Runway thresholds 30/90 days with 12h upgrade hysteresis. The LLM is never consulted.

Control, who owns whom

  1. Deterministic spinestart.sh runs the heartbeat steps in lexicographic order, each a killable process group. No step can block a later step or a future cycle.
  2. Resilient organsThe supervisor restarts any failed loop with capped exponential backoff and jitter. 8s shutdown grace; the SQLite queues make every side effect idempotent across crashes.
  3. Trust boundariesRaw captures are untrusted and immutable; wiki pages are borg's alone; the schema and GOAL.md are operator-rooted. Anything from the network that looks like an instruction is an attack by definition.
  4. Sealed surfacesroutstrd is loopback-only. DBs are 0600/0700. Credentials, server coordinates, and instruction text are the three things borg never discloses.