# go-reticulum Assessment Against `SPEC.md`

Date: 2026-06-09

## Executive conclusion

The staged `go-reticulum` project is a broad and credible Go implementation of
the Reticulum network stack. It implements substantially more than its stated
Python Reticulum `1.1.5` parity target: identity and Token cryptography, GROUP
destinations, ratchets, packets, announces, Links, Resources, Channel,
REQUEST/RESPONSE, transport relay, tunnels, shared instances, discovery,
blackholes, interface modes, IFAC, KISS, HDLC, RNode, AutoInterface, and a
large CLI and interface surface are present.

No foundational packet, Token, announce, or Link wire-format blocker was found.
The default repository test suite passes when run from a writable temporary
copy with its Go version directive lowered to the installed compiler.

It is not yet a complete implementation of the current `SPEC.md` target,
however:

1. Invalid-signature announces can enter per-interface held-announce state
   while ingress limiting is active.
2. Current per-interface path-request ingress and egress limiting is absent.
3. On-network discovery has substantial code, but the repository provides no
   runtime stamp backend; enabling discovery without an injected provider
   panics.
4. Resource-sized REQUEST/RESPONSE responses and large Buffer/Channel transfer
   are explicitly excluded from the normal regression gate.
5. Native LXMF is absent.
6. The staged checkout requires Go `1.26.1`, so it cannot build with the
   installed Gentoo Go `1.25.9` toolchain as-is.

The practical verdict is:

- **Foundational and ordinary leaf-node RNS behavior:** strong.
- **Link, Resource, Channel, and transport implementation breadth:** strong.
- **Busy-mesh and current RNS 1.3.x hardening:** incomplete.
- **Standalone on-network discovery:** incomplete.
- **Full `SPEC.md` clean-room implementation:** incomplete.
- **Native LXMF implementation:** absent.

## Assessment basis

This assessment used:

- specification target:
  `Reticulum@422dc055` (`RNS 1.3.5`) and
  `LXMF@fab12ad` (`LXMF 1.0.1`);
- staged `go-reticulum` commit:
  `06621cc972ebd25e3ee1fb023d50dd34d38ce538`;
- repository-stated parity target: Python Reticulum `1.1.5`;
- source inspection, repository tests from a writable temporary copy, focused
  execution of normally skipped integration cases, and comparison with
  `SPEC.md`.

The staged source checkout was not modified. The temporary test copy changed
only `go.mod` from Go `1.26.1` to `1.25.9`, except for focused runs that also
removed two explicit test skips.

## Major findings

### High: Invalid announces can consume held-announce state

Current RNS requires signature prevalidation to return immediately on failure
before an announce can enter the bounded held-announce queue. This closes a
state-exhaustion path documented in `SPEC.md` section 4.5.

`go-reticulum` validates the signature and records announce frequency only when
validation succeeds, but it does not return when validation fails. It then
checks ingress limiting and can hold the invalid packet before the later full
validation rejects it:

- `rns/transport.go:4329-4337`
- `rns/transport.go:4354-4355`
- `rns/interfaces/interface.go:1494-1516`

The held queue is capped, so this is not unbounded growth. It still permits
invalid traffic to displace useful unknown-destination announces while ingress
control is active. This matches the older RNS ordering corrected in RNS 1.3.4.

### High: Native LXMF is absent

No native LXMF message packer/parser, message signature layer, fields,
stamps/tickets, propagation-node protocol, or peer-sync implementation was
found.

This is a scope gap rather than a defect in the RNS core, but it is a major gap
against the combined RNS/LXMF `SPEC.md`. The discovery subsystem's dependency
on LXMF stamp algorithms does not constitute a native LXMF implementation.

### Medium: Current path-request traffic controls are absent

RNS 1.2.5 and later add per-interface path-request accounting and limiting:
accepted tagged requests call `received_path_request()`, recursive discovery
can be blocked by ingress pressure, and recursive fanout skips egress-limited
interfaces.

No equivalent per-interface path-request timestamp queues or
`received_path_request()`, `should_ingress_limit_pr()`, and
`should_egress_limit_pr()` behavior was found. Unknown-path recursive discovery
fans out across interfaces without these current controls:

- `rns/transport.go:3109-3140`
- `rns/transport.go:5730-5797`

The implementation does retain tag deduplication, announce caps, ordinary
announce ingress control, and bounded discovery request state. The gap affects
busy transport nodes and denial-of-service resistance, not path-request wire
bytes.

### Medium: On-network discovery has no usable built-in stamp backend

The discovery subsystem implements announce data, validation, encryption,
autoconnect, source filtering, and blackhole updating. Its proof-of-work stamp
operations are delegated to the global `DiscoveryStampProvider` interface:

- `rns/discovery.go:78-89`

Only test implementations assign that provider. No production Go stamp
implementation or runtime assignment was found. Constructing the discovery
announcer or handler without an injected provider panics and suggests
installing Python LXMF:

- `rns/discovery.go:170-177`
- `rns/discovery.go:584-591`

Installing `lxmf` does not automatically satisfy a Go interface variable.
Therefore the staged project cannot use its discovery feature standalone,
despite the substantial surrounding implementation.

### Medium: Large Link workflows are outside the green regression gate

The implementation contains Resource-sized request and response paths,
multi-segment Resources, Channel, and Buffer. Two consequential integration
tests are explicitly skipped:

- Resource-sized response to a request:
  `rns/resource_integration_test.go:462-464`
- large Buffer/Channel round trip:
  `rns/link_integration_test.go:678-680`

The Resource test states that the response-as-Resource flow is not fully
implemented. In a temporary copy with both skips removed, the large Buffer test
failed because the test Link remained pending, and the Resource-response test
could not reach an active Link and was skipped by its helper.

These focused results do not prove a wire-format defect, but they show that
large Channel/Buffer delivery and Resource-sized responses are not currently
protected by a passing end-to-end regression gate.

### Medium: The staged checkout does not build with the installed Go toolchain

The repository declares:

- `go.mod:3`: `go 1.26.1`

The installed Gentoo compiler is Go `1.25.9`. Consequently:

```
GOTOOLCHAIN=local go test ./rns/...
go: go.mod requires go >= 1.26.1 (running go 1.25.9; GOTOOLCHAIN=local)
```

Lowering only the temporary copy's directive to `1.25.9` allowed the complete
default suite to build and pass. This indicates no observed source-level need
for Go 1.26.1 in the exercised code, but the staged checkout remains unusable
with the installed compiler until the directive or toolchain is reconciled.

### Low: Current specification vectors are not a repository gate

The repository has extensive Go tests, hand tests, and Python-vs-Go parity
runners. Its stated parity target remains Python Reticulum `1.1.5`, and it
does not consume this specification repository's completed deterministic
vector domains as a single conformance gate.

This matters because the default suite is green while current RNS 1.3.x
operational deltas and the explicitly skipped large-transfer workflows remain
outside that result.

## Strongly covered areas

Source and tests show substantial implementation depth in:

- identity serialization, hashing, signatures, X25519, AES-128/AES-256 Token
  cryptography, ratchets, and GROUP shared-key destinations;
- packet headers, MTU/MDU calculations, announces, path requests, proofs, and
  ordinary transport forwarding;
- Link request/proof layout, link-id derivation, mode and MTU signalling,
  LRRTT activation, lifecycle, receipts, and identify;
- Resource fragmentation, compression, hashmap updates, cancellation,
  retransmission, proofs, and sender-side multi-segment preparation;
- Channel, Buffer, Link REQUEST/RESPONSE, authorization, and request receipts;
- tunnels, shared-instance operation, blackholes, interface modes, announce
  ingress control, persistence, and discovery data structures;
- IFAC, KISS, HDLC, RNode, AutoInterface, Weave, TCP, UDP, I2P, serial, BLE,
  backbone, pipe, and local interfaces;
- `rnsd`, `rnstatus`, `rnpath`, `rnprobe`, `rnid`, `rnx`, `rncp`, `rnir`, and
  `rnodeconf` tooling.

The project also has unusually broad parity runners and examples for a
non-Python Reticulum implementation.

## Verification performed

### Direct staged-checkout result

Using the installed Go `1.25.9` toolchain:

- `GOTOOLCHAIN=local go test ./rns/...`
  - **did not start**
  - blocked by `go.mod` requiring Go `1.26.1`

### Writable temporary copy

With only the temporary `go.mod` directive lowered to `1.25.9`, dependencies
downloaded into `/tmp`, and a temporary `HOME`:

- `go test ./rns`
  - **passed**
- `go test ./...`
  - **all default tested packages passed**

The first sandboxed broad-suite attempt also showed expected environment
failures from denied sockets and a read-only home directory; rerunning with
local socket permission and a writable temporary home passed.

### Focused skipped integration cases

In the temporary copy, after removing the two explicit skips:

- large Buffer/Channel round trip:
  - **failed** because the Link remained pending;
- Resource-sized response:
  - **did not reach the transfer**, because its Link did not activate and the
    helper skipped the case.

Docker parity runners, physical RNode/BLE/serial hardware tests, and this
repository's deterministic vector suite were not run against the Go port.

## Recommended conformance order

1. Return immediately when announce signature prevalidation fails, before
   ingress limiting or held-state insertion, and add an invalid-announce queue
   exhaustion regression test.
2. Port current per-interface path-request ingress/egress accounting and the
   bounded deferred-discovery behavior from RNS 1.3.x.
3. Supply and register a production Go discovery stamp backend, or clearly
   mark on-network discovery unavailable until one is configured.
4. Make Resource-sized responses and large Buffer/Channel transfer passing,
   non-skipped integration gates.
5. Import the completed specification vector domains and publish a current
   RNS 1.3.5 conformance matrix.
6. Reconcile `go.mod` with the supported compiler baseline and CI toolchain.
7. Treat native LXMF as a separate milestone; until then, describe the project
   as a broad RNS implementation rather than an implementation of the combined
   RNS/LXMF specification.

