Skip to content
Export

CLI utilities

Go-native tools that speak the same shared-instance msgpack RPC, destinations, and identity file formats as Python rnstatus, rnid, rnprobe, rnpath, rncp, rnsh, and rnx. They are not Python clones. Python tools and Go tools both work against rnsd and reticulum-go.

They ship as subcommands of the single reticulum-go binary:

make build
./bin/reticulum-go status
./bin/reticulum-go id -h
./bin/reticulum-go probe ...
./bin/reticulum-go path -t
./bin/reticulum-go cp -l
./bin/reticulum-go x -l
./bin/reticulum-go sh -l
./bin/reticulum-go pageserver

make install also creates legacy symlinks (rgostatus, rgoid, rgoprobe, rgopath, rgocp, rgox, rnx, rgosh, rgopageserver, rgoslow, rgospeed, rgodump, rgosnap, rgoselfcheck, rgozen) that invoke the same binary. Man pages: man reticulum-go, man reticulum-go-status, man reticulum-go-speedtest, man reticulum-go-self-check, and so on.

Tool / subcommand Python counterpart Role
reticulum-go status (rgostatus) rnstatus Interface and transport status over shared-instance RPC
reticulum-go slow (rgoslow) (Go-only) Bottleneck and local health findings from interface/path stats
reticulum-go id (rgoid) rnid Identity generate, hash, .rsg / .rsm / .rfe
reticulum-go probe (rgoprobe) rnprobe Path wait, encrypted probe, RTT
reticulum-go path (rgopath) rnpath Path table, drop, blackhole, path request, remote -R
reticulum-go cp (rgocp) rncp File send / listen / fetch over links
reticulum-go x (rgox, rnx) rnx Remote command execution over links (rnx.execute)
reticulum-go sh (rgosh) rnsh (native + auto rnsh) Interactive remote shell over Link+Channel (PTY/pipes)
reticulum-go git (rgogit, git-remote-rns) rngit Git-over-Reticulum node and git remote helper
reticulum-go pageserver (example app) NomadNet-style page and file server
reticulum-go self-check (rgoselfcheck) (Go-only) Host OS preflight for sandbox, crypto, and interfaces
reticulum-go zen (rgozen) (Go-only) Static scan for path and link footguns in Go and optional Python sources
reticulum-go speedtest (rgospeed) Examples/Speedtest.py Loopback smoke plus cross-host / docker daemon (-daemon, -iface)
reticulum-go dump (rgodump) (Go-only) Decode RNS packets from hex or pcap to JSONL
reticulum-go snapshot (rgosnap) (Go-only) Path table, links, and health drop counters as JSON

Library code lives in pkg/rnsutil and pkg/cli. Pageserver logic lives in pkg/pageserver.

Packet capture and Wireshark docs live in packet-debug.md. The cross-stack INTEROP_EVENT timeline is in interop-timeline.md.

Mixed Python and Go tools

Python utilities and Go subcommands speak the same destinations, shared-instance RPC, and identity files. Use either tool against either daemon. Point -config at that daemon's config directory (~/.reticulum for Python rnsd, ~/.reticulum-go for reticulum-go unless you aligned them). Align rpc_key / instance_name / shared_instance_type when querying a shared instance.

Task Python tool Go tool Against rnsd Against reticulum-go
Interface status (local RPC) rnstatus reticulum-go status Yes Yes
Path table / drop / blackhole (local RPC) rnpath reticulum-go path Yes Yes
Remote status (-R) rnstatus reticulum-go status Yes, if remote has enable_remote_management Yes, same
Remote path table / rates (-R) rnpath reticulum-go path Yes, if remote has enable_remote_management Yes, same
Probe rnprobe reticulum-go probe Yes Yes
File transfer (rncp.receive) rncp reticulum-go cp Yes Yes
Remote exec (rnx.execute) rnx reticulum-go x Yes Yes
Shell on dest app rnsh rnsh reticulum-go sh (auto) Yes Yes (Go listener announces rnsh as well)
Shell on dest app rgosh (no) reticulum-go sh n/a Go native only
Git clone/fetch/push (rns://) rngit / git-remote-rns reticulum-go git, git-remote-rns Yes Yes

Remote drop, path-request, and blackhole mutate over -R exit 255 on both stacks. rnir, rnpkg, and rnodeconf stay Python-only. rgoslow, rgodump, rgosnap, rgoselfcheck, and rgozen stay Go-only.

Shared-instance RPC (required for rgostatus and rgopath table modes)

rgostatus and rgopath -t / drop / blackhole modes dial a running shared instance (Python rnsd or reticulum-go) over the same multiprocessing.connection + msgpack protocol Python uses.

RPC is fully supported on both transports:

shared_instance_type Listen / dial address
tcp 127.0.0.1:<instance_control_port> (default 37429)
unix Abstract socket @rns/<instance_name>/rpc (Linux)
unset Platform default: unix on Linux, tcp elsewhere (matches Python RNS)

Go implements both server and client for TCP and Unix. When the type is unset, utilities try the platform default first, then the other transport, so stock Linux Python rnsd works without forcing TCP.

Why connection refused is common

Issues that usually stack:

  1. Wrong config directory. Python uses ~/.reticulum. Go defaults to ~/.reticulum-go. Point -config at the directory of the daemon you are querying.
  2. Explicit transport mismatch. If one side sets shared_instance_type = tcp and the other unix, dials miss. Leave the key unset on Linux, or set the same value on both.
  3. Daemon not sharing. The process that owns interfaces must have share_instance = yes and be running.
  4. Auth key mismatch. Align rpc_key, or share the same derived transport_identity.

Working config for Python rnsd + Go tools (Unix on Linux)

Stock Linux Python already uses abstract Unix sockets. Point Go tools at that config directory:

./bin/reticulum-go status -config ~/.reticulum
./bin/reticulum-go status -config ~/.reticulum -json
./bin/reticulum-go path -config ~/.reticulum -t -json

Optional shared auth key in both configs (recommended when mixing stacks):

[reticulum]
share_instance = yes
instance_name = default
shared_instance_type = unix
rpc_key = <64 hex characters>

Generate a key once:

python3 -c 'import secrets; print(secrets.token_hex(32))'

Restart rnsd after editing rpc_key. Go tools with unset or unix type dial @rns/default/rpc.

TCP RPC (all platforms)

Use TCP when you want the same recipe on every OS, or when mixing with an older Go daemon that bound TCP:

[reticulum]
share_instance = yes
instance_name = default
shared_instance_type = tcp
shared_instance_port = 37428
instance_control_port = 37429
rpc_key = <64 hex characters>

Restart the daemon after editing so it binds TCP 127.0.0.1:37429.

Auth key rules

Config Authkey used
rpc_key set (64 hex chars) That exact 32-byte key
rpc_key empty SHA-256 of the daemon storage/transport_identity private key

Go and Python must agree. Prefer an explicit shared rpc_key when mixing stacks so you do not depend on identical transport identity files.

Query a Go daemon instead

Run reticulum-go with share_instance = yes under ~/.reticulum-go. Unset type follows the platform default (Unix on Linux):

./bin/reticulum-go status -config ~/.reticulum-go -json
./bin/reticulum-go path -config ~/.reticulum-go -t

Only one process should own the shared instance ports (or Unix RPC name) at a time.

rgostatus

rgostatus [flags] [filter]
Flag Meaning
-config dir Config directory (default: ~/.reticulum-go)
-json Emit JSON (bytes as hex, same field names as Python where populated)
-a Include all interfaces (less filtering of local/client peers)
-n substr Filter interface names (positional filter also accepted)
-l Include link count
-A Show announce byte and count stats
-P Show path-request byte and count stats
-B Only interfaces with active bursts
-b List blocked IPs per interface
-t Show transport traffic totals
-T Show path topology: path table grouped by receiving interface with hops, next-hop hash, age (Go-only)
-p Show packets per second in totals
-Q Show inbound queue pressure (use -Q rather than -q, which is quiet)
-z Show profiling results when the instance provides them
-m Continuously monitor status
-I sec Monitor refresh interval (default 1)
-d / -D List discovered interfaces (details with -D)
-show-stale Include stale discovery entries when listing discovered interfaces
-show-unknown Include discovery entries without implementation/version info
-attach name Attach interface by name via shared-instance RPC (RNS 1.5.5)
-detach name Detach interface by name via shared-instance RPC
-reload name Detach and re-attach interface by name
-s key Sort by rate, rx, tx, rxs, txs, traffic, announce, arx, atx, prx, ptx, held, queue
-r Sort ascending (default descending)
-timeout dur RPC timeout (default 10s)
-R hash Transport identity hash of remote instance
-i path Identity file for remote management
-W / -w sec Timeout for remote queries (0 = adaptive)

JSON includes per-interface announce and path-request frequencies, held announces, outgoing announce queue, burst flags, and traffic counters when the daemon provides them. Totals include rxpps/txpps when available.

Against a Go daemon, human and JSON output also include local mesh health fields when counters are non-zero: ifac_fail, hmac_fail, announce_sig_fail, unpack_fail, integrity_fail_rate, stale_closes, keepalive_timeout, and related totals. Python rnsd does not populate these keys. Missing fields mean zero or unknown, not a protocol error.

Go daemons report announce reject-reason counters per interface (announce_malformed, announce_dest_type, announce_blackholed, announce_key_mismatch, announce_max_hops, announce_held, announce_suppressed) plus per-endpoint dial health on outbound client interfaces (endpoint_dial_failures, endpoint_flaps, endpoint_quarantined, endpoint_quarantine_s). The endpoint fields render as an Endpoint line when non-zero. An endpoint that keeps failing or flapping is quarantined with an escalating cooldown instead of being redialed forever.

Discovered interface listings show the announced implementation and version in the Stack field. Entries that stopped being announced go stale, and entries whose announce carries no implementation or version are hidden by default. Pass -show-stale / -show-unknown to include them (same defaults as Python rnstatus 1.5.7).

Interface attach/detach/reload requires enable_interface_management = yes (the default) on the owning instance and only works against a running shared instance. I2P and local shared-instance interfaces cannot be detached, matching Python.

rgoslow

reticulum-go slow [flags]
# legacy: rgoslow

Ranks congestion and local health signals that commonly explain stalled transfers or noisy interfaces. Uses the same shared-instance RPC as status (interface_stats plus path table).

Flag Meaning
-config dir Config directory (default: ~/.reticulum-go)
-json Emit full JSON report
-a Include all interfaces
-n substr Filter interface names
-l Include link count
-dest hash Focus analysis on a destination (32 hex)
-top n Max interfaces to rank (default 12)
-high-hop n Hop count treated as high (default 6)
-m Continuously refresh
-I dur Monitor interval (default 2s)
-timeout dur RPC timeout (default 10s)

Bottleneck findings cover bitrate utilization, announce/PR bursts, held announces, outgoing announce queues, bandwidth gates, socket RTT, and high-hop paths.

When talking to a Go daemon, health findings can also appear:

Kind Meaning
integrity_burst Elevated IFAC/HMAC/unpack fail rate vs accepted frames
auth_pressure Announce signature or link proof rejects clustered on an iface
link_degraded Rising stale closes or keepalive timeouts
ingress_pressure Held announces or burst limiters active
announce_queue Outgoing announces waiting for announce_cap

Counters stay local to the node. slow only observes and scores. It does not change ingress policy or blackhole tables.

rgospeed

reticulum-go speedtest [flags]
# legacy: rgospeed

Link throughput test modeled on Python Examples/Speedtest.py.

Mode Command
Loopback smoke (default / CI) reticulum-go speedtest or -loopback
Server (oneshot) reticulum-go speedtest -l
Daemon (VPS / docker) reticulum-go speedtest -daemon
Client (cross-host) reticulum-go speedtest <server_dest_hash>

Destination is speedtest.server. Server and client must use the same -bytes size. After the transfer the server sends a SPEEDOK ack with the confirmed RX count. Networked clients pace sends (100 us per packet by default) so UDP sockets are not overrun. Loopback does not pace.

Every run prints a grep-friendly speedtest_result ... line on stdout (visible in docker logs). With -json, a JSON object follows on stdout as well.

Use a real config with UDP/TCP (or a shared path). share_instance is forced off so the tool owns its interfaces. Python-style forward_ip / forward_port are accepted as aliases for target_host / target_port.

Flag Meaning
-loopback In-process pipe (CI liveness, default when no args)
-l Listen as server (one client then exit)
-daemon Listen forever (implies -l -m, default announce every 120s)
-m Listen: serve multiple clients
-iface all (default) or comma-separated config section names
-p Print identity / destination hash and exit
-config dir Config directory (default ~/.reticulum-go)
-identity path Persistent identity for listen mode
-bytes n Plaintext bytes to transfer (default 2 MiB)
-min-bps n Fail below this rate (0 disables, loopback defaults to 1e6)
-timeout sec Overall timeout (default 60)
-announce sec Listen announce interval (0 once, <0 never)
-json Emit JSON after each speedtest_result line
-q Quieter debug

Cross-host example (two machines / configs with a shared path):

# server
reticulum-go speedtest -daemon -iface tcp -bytes 4194304
# client (paste the 32-hex hash printed by the server)
reticulum-go speedtest -iface tcp -bytes 4194304 <hash_from_server>

Docker VPS reference

Build and run a persistent public TCP listener:

docker build -f docker/Dockerfile.speedtest -t reticulum-go:speedtest .
docker run -d --name rgo-speedtest -p 4242:4242 \
  -e SPEEDTEST_IFACE=tcp \
  -v reticulum-go-speedtest:/data \
  reticulum-go-speedtest:latest
docker logs -f rgo-speedtest

Env knobs: SPEEDTEST_IFACE (all or names), SPEEDTEST_BYTES, SPEEDTEST_ANNOUNCE, SPEEDTEST_PORT, SPEEDTEST_JSON, RNS_CONFIG. Persist /data so the identity (and thus dest hash) stays stable for CI secrets.

CI client config needs a TCPClientInterface to the VPS host:port and the printed dest hash. Treat measured rates as a path floor (runner to VPS), not a lab loopback number.

Nightly CI runs make test-link-speed (TestLinkSpeedSmoke) with a 512 KiB loopback cap and a 1 MB/s floor.

rgoid

Identity and signing tool. Files are wire-compatible with Python:

Extension Format
.rid 64 raw bytes (X25519 private + Ed25519 seed)
.rsg 64-byte Ed25519 signature + msgpack envelope (hashtype, hash, meta)
.rsm Same as .rsg with embedded message
.rfe Chunked identity encrypt (same token layout as Python)

Examples:

./bin/reticulum-go id -g ~/.reticulum-go/id.rid -p
./bin/reticulum-go id -i ~/.reticulum-go/id.rid -H rns.id
./bin/reticulum-go id -i id.rid -s file.bin -f
./bin/reticulum-go id -i id.rid -V file.bin
./bin/reticulum-go id -i id.rid -S "hello" -w note -f
./bin/reticulum-go id -i id.rid -S @inventory.txt -w reticulum-go.rsm -f
./bin/reticulum-go id -V note.rsm
./bin/reticulum-go id -i e318cbc04468bd574db2b4523dddd710 -V reticulum-go.rsm -extract
./bin/reticulum-go id -i id.rid -e secret.txt -f
./bin/reticulum-go id -i id.rid -d secret.txt.rfe -f

-S @path reads the message body from a file (needed for large tree inventories). -extract prints only the embedded RSM message after a successful verify. -i may be a 32-character identity hash when verifying (no private key required).

Go-signed .rsg / .rsm / .rfe validate with Python rnid, and the reverse also works.

rgoprobe

rgoprobe [flags] <full_name> <destination_hash_hex>

Attaches as a shared-instance client (or starts local transport), waits for a path, sends encrypted probes, and prints RTT. Default path wait follows the slowest online interface bitrate instead of a flat 15s. Example:

./bin/reticulum-go probe -config ~/.reticulum -n 3 -v app.aspect aabbccddeeff00112233445566778899

rgopath

Path table and blackhole management over shared-instance RPC, plus a default path-request mode that attaches like rgoprobe.

rgopath [flags] [destination_hash]
Flag Meaning
-config dir Config directory
-t Show path table (optional hash filter)
-r Show announce rate info
-json / -j JSON for -t / -r / -b
-m N Max hops filter for path table
-d Drop path to hash
-D / -q Drop announce queues (Python -D, Go also accepts -q)
-x Drop all paths via transport hash
-w sec Path request timeout (0 = adaptive from slowest online bitrate, default)
-R hash Transport identity hash of remote instance
-i path Identity file for remote management
-W sec Timeout for remote queries (default 15)
-b / -blackholed List blackholed identities
-B / -blackhole Blackhole identity hash
-U / -unblackhole Lift blackhole
-p View published blackhole list for a remote transport identity
-duration / -for hours Blackhole duration (0 = indefinite)
-reason str Blackhole reason
-filter substr Filter blackhole list lines

Go extras (compat preserved): -json on path and blackhole lists, drop-via count in the success line, clearer path-found summary after a successful request.

Remote table and rates use the same rnstransport.remote.management destination as Python rnpath, so rnpath -t -R works against a Go daemon and rgopath -t -R works against Python rnsd. Enable it on the remote daemon with enable_remote_management = yes and remote_management_allowed = . Remote drop, path-request, and blackhole mutate are not implemented (Python also exits 255).

rgopath -t -R <transport_identity_hash> -i ~/.reticulum-go/storage/identities/rgosh

rgocp

File transfer over links. Destination name is rncp.receive so Go and Python peers interoperate.

rgocp [flags] <file> <destination_hash>     # send
rgocp -l [flags]                            # listen
rgocp -f [flags] <remote_path> <hash>       # fetch
Flag Meaning
-config dir Config directory
-i / -identity path Identity file (default storage/identities/rncp)
-l Listen for pushes
-f Fetch remote file (-f <remote_path> <dest>)
-a hash Allowed identity (repeatable, listen)
-n / -no-auth Accept requests from anyone (listen)
-F / -allow-fetch Enable fetch_file requests (listen)
-j / -jail dir Restrict fetch paths
-s / -save dir Save directory for received files
-O / -overwrite Overwrite on receive
-C / -no-compress Disable auto compression
-b / -announce sec Announce interval (0 once, <0 never)
-w sec Path/link timeout (0 = adaptive, default)
-S / -silent Silent progress
-P / -phy-rates Show physical-layer style rates in progress
-p Print identity and destination hash

Allow lists are loaded from /etc/rncp/allowed_identities, ~/.config/rncp/, ~/.rncp/, plus Go-specific ~/.config/rgocp/ and ~/.rgocp/.

Go extras: cleaner progress lines on stderr, -json is not used (transfer is binary), unique .N rename when not overwriting.

rgox / rnx

Remote command execution over links. Destination name is rnx.execute, request path command (wire-compatible with Python rnx).

reticulum-go x -l [flags]                         # listen
reticulum-go x [flags] <destination_hash> <cmd>   # execute
reticulum-go x -x [flags] <destination_hash>      # interactive
Flag Meaning
-config dir Config directory
-i path Identity file (default storage/identities/rnx)
-l Listen for commands
-x Interactive REPL
-a hash Allowed identity (repeatable, listen)
-n Accept from anyone (listen)
-N Do not identify to listener
-b Skip announce on listen start
-m Mirror remote exit code
-d Detailed timing/size summary
-w sec Path/link/command timeout (0 = adaptive path and link)
-W sec Max result download time
--stdin str Remote stdin
--stdout N / --stderr N Max returned bytes
-json Structured JSON result (Go)
-p Print identity and destination hash

Allow lists: /etc/rnx/, ~/.config/rnx/, ~/.rnx/, plus ~/.config/rgox/ and ~/.rgox/.

Exit codes match Python rnx (241-249 for client failures, -m mirrors remote).

rgosh

Interactive remote shell over Link + Channel. Native protocol uses destination app rgosh. Connecting to a Python rnsh destination hash selects that protocol automatically. --compat forces the rnsh dest and wire types. Listen without --compat accepts both rgosh and rnsh on the same identity.

Interactive sessions stay up until the remote process exits. Ctrl-C is forwarded to the remote PTY. Disconnect with ~. (tilde then period, right after a newline). ~L toggles line mode. ~~ sends a literal tilde. -w is path/link handshake only.

Unix listeners (Linux, macOS, FreeBSD, OpenBSD, NetBSD, Dragonfly) use a PTY. Windows listeners fall back to pipes (ComSpec / cmd.exe) and cannot host vim-style TTY programs. A Windows client can still attach to a Unix listener. Console resize is polled on Windows (no SIGWINCH).

reticulum-go sh -l [flags] [command...]                 # listen (rgosh + rnsh)
reticulum-go sh [flags] <destination_hash> [command...] # connect (auto-detect)
reticulum-go sh --compat -l                             # rnsh dest only
Flag Meaning
-config dir Config directory
-i path Identity file
-s name Service name (identity file suffix)
-l Listen for sessions
-a hash Allowed identity (repeatable, listen)
-n Accept from anyone (listen)
-N Do not identify to listener
-b PERIOD Announce interval seconds (default 900, 0 once at start)
--no-announce Never announce (listen)
-A Append remote cmdline to the default command
-C Reject a remote cmdline. Empty cmdline still runs the default command
--compat Force Python rnsh dest and wire protocol
--line / --raw Force line-buffered or raw stdin
-m Mirror remote exit code
-w sec Path/link handshake timeout (0 = adaptive, default)
-p Print identity and destination hash

Allow lists: /etc/rgosh/, ~/.config/rgosh/, ~/.rgosh/, plus Python rnsh paths. Files are re-read on each new link. Auto line mode engages when link RTT is high unless --raw. Stream sends wait for the channel window and compress to MDU so slow links do not flood.

Live interop:

RUN_LIVE_INTEROP=1 PYTHON_INTEROP=python3 RETICULUM_PATH=/path/to/reticulum \
  go test -v ./tests/interop/ -run 'Rgosh|Rnsh'

rgozen

reticulum-go zen [flags] [packages...]
# legacy: rgozen

Static source checker for Reticulum path and link footguns. Think go vet or go fix for common mistakes that lead to throttling, handshake storms, or path resolved but link never opens. No daemon or network access is required.

Default scan is ./... from the current module. Pass package patterns the same way as go test.

Flag Meaning
-fix Apply safe automatic fixes (today: check RequestPath errors in functions that return error)
-json Emit a JSON report
-list-rules Print all rule IDs, severity, and hints, then exit
-plain Plain output without colors
-test Include *_test.go files
-python Also scan .py files under the module root
-C dir Module root directory (default: cwd)

Exit code is 0 when clean, 1 when errors are present or warnings remain without -fix, 2 on flag errors.

What it catches

Go rules cover spinning on RequestPath, HasPath, or AwaitPath, Establish or NewLink inside loops, link use before the established callback, announce bursts, hard-coded 15 second timeouts, RequestPath with on_interface overrides, and Recall before a path wait.

With -python, the same anti-patterns are checked in RNS Python apps: has_path and request_path loops, await_path inside retry loops, link_ready and link.status polling, request_path followed by has_path spin, Recall before await_path, on_interface overrides, and require_shared_instance without a running rnsd.

Each finding prints file, line, rule ID, why it fails, a fix hint, and doc references. Run -list-rules for the full catalog.

Example:

reticulum-go zen ./pkg/myapp/...
reticulum-go zen -python -C ~/my-rns-app
reticulum-go zen -fix ./...
reticulum-go zen -json ./pkg/... | jq .

Use this during development and in CI before shipping apps that talk to shared instances or slow radios. See also API reference path and link guidance and Development and testing.

reticulum-go git (rngit)

reticulum-go git runs an rngit-compatible repository node. The git protocol destination is git.repositories on the node identity and handles list, fetch, push, delete, create, fork, mirror, sync, permissions, releases, and work documents.

When serve_nomadnet = yes is set in the [pages] section of the server config, a second destination nomadnetwork.node serves the browseable page surface that NomadNet clients load:

  • /page/index.mu, group.mu, repo.mu, tree.mu, blob.mu, commits.mu, commit.mu, refs.mu, stats.mu, releases.mu, release.mu, work.mu, work_doc.mu
  • /file/artifact, /file/download, /file/workdoc for release artifacts, raw blobs, and work document downloads
  • /media is a Reticulum-Go extension for repository blobs with optional WebP conversion (media_conversion config). The reference implementation has no such route

Page requests carry NomadNet var_* fields (var_g, var_r, var_ref, var_path, var_scope, var_id, var_t, var_a, var_thanks, var_page, var_type, var_h, var_raw, var_render). Unidentified peers resolve as the null identity d7db22f63b453c23bb0688dde565b7c1 and can be refused entirely by listing it under blocked_identities.

Templates come from <configdir>/templates/<name>.mu with defaults compiled in. Supported names: base, front, group, repo, tree, blob, commits, commit, refs, stats, releases, release, work, work_doc, no_ident. Placeholders: {PAGE_CONTENT} in every template, plus {NODE_NAME}, {VERSION}, {NAVIGATION}, and {GEN_TIME} in base. A template file with the executable bit set is run and its stdout becomes the template, bounded by a 5 second timeout and a 1 MiB output cap.

Markdown files (README, work documents) are converted to Micron, and blob pages apply syntax highlighting unless syntax_highlight = no. With record_stats = yes the node persists Python-compatible daily counters and renders a stats page with activity scoring. stats_ignore_identities and stats_push_ignore_identities exclude identities from counting.

Deliberate differences from the Python reference:

  • Git subprocesses for pages are bounded by an 8 second timeout and blob display is capped at 256 KiB, same limits, but executable templates and blob head reads are bounded where the reference is not
  • stats_push_ignore_identities is honored. The reference parses it but never applies it
  • rperms rechecks repository admin permission, not group permission (reference bug)
  • Work document delete on a missing document returns Not Found instead of failing
  • Missing release artifacts return no response instead of slipping through a no-op guard

Troubleshooting

Symptom Fix
dial tcp 127.0.0.1:37429: connection refused Start the daemon. If type is explicit tcp, the daemon must also be TCP. With unset type, utilities also try Unix. Use -config for that daemon's config dir.
dial unix @rns/...: connection refused Daemon is on TCP only, or instance_name differs. Align shared_instance_type and instance_name, or leave type unset so tools try both.
rpc auth failure Align rpc_key, or use the same storage/transport_identity when keys are derived.
Empty or missing announce rates from Python Field is present but may be 0 until traffic accumulates. Sorting and JSON keys still work.
Top-level rxb/txb are 0 while interfaces show traffic Python aggregate totals often omit some parent interfaces. Prefer per-interface counters.
Identity load log lines on stderr Harmless debug from loading transport_identity for derived auth when resolving keys. Prefer explicit rpc_key to avoid that path when possible.
rgocp transfer ignored Listener needs -n or an allow-list entry (-a) matching the sender identity hash. Metadata (name) is required on the wire.

Debugging

Tool Role
reticulum-go status Interface stats over shared-instance RPC (-json, -q), including Go integrity counters when present
reticulum-go slow Bottleneck and local health findings (integrity_burst, auth_pressure, link_degraded, ...)
reticulum-go path -t Path table dump
reticulum-go debug Effective config path, log level, platform, RPC reachability (-rates, -json)
reticulum-go self-check Host OS preflight checklist (--json, --quick, --full, --strict)
reticulum-go zen Static path and link footgun scan (-fix, -json, -list-rules, -python)
reticulum-go probe Connectivity / RTT (-json)
Control API HTTP /v1/health (liveness), /v1/status (iface stats plus integrity fields), /v1/paths when enable_control_api = yes
Daemon -debug N Override config loglevel for one run (0 silent through 7 packets)

TTY colors (status Up/Down, probe/path/cp/id outcomes, pageserver banner, daemon text log levels) honor NO_COLOR (off) and FORCE_COLOR / CLICOLOR_FORCE (on). JSON output and file logs stay plain.

Related documents