# microReticulum Assessment Against `SPEC.md`

Date: 2026-06-09

## Executive conclusion

Chad Attermann's staged microReticulum is a useful embedded C++ implementation
of the foundational Reticulum wire protocol and ordinary transport behavior.
It has working identity, Token crypto, packet, announce, path-discovery,
transport-relay, and basic Link interoperability, with explicit memory caps and
an MCU-oriented cooperative runtime.

It is not a complete implementation of this repository's `SPEC.md`, and several
public API surfaces are present only as shells or commented Python source.
The most consequential gaps are:

1. Link lifecycle enforcement is absent: the watchdog that performs
   establishment timeout, KEEPALIVE transmission, stale detection, and timeout
   teardown is entirely unimplemented.
2. Resource and Channel are not implemented.
3. Link packet-receipt proof validation is hard-disabled, so Link packet
   receipts cannot conclude successfully.
4. GROUP destinations and ratchets are not implemented.
5. IFAC, KISS, HDLC, RNode framing/configuration, AutoInterface, and native
   shared-instance framing are absent.
6. REQUEST/RESPONSE has partial packet-path code, but request-handler
   registration is commented out and Resource-sized requests/responses cannot
   work.
7. Transport tunnels, announce-rate enforcement, announce-queue draining, and
   current per-interface path-request controls are absent.
8. Native LXMF is absent.

The practical verdict is:

- **Embedded single-hop announces and packets:** credible.
- **Basic single-hop Links:** interoperable, but application supervision is
  required for sustained operation.
- **Ordinary transport relay:** substantial, with important operational gaps.
- **Reliable Link delivery, Resource, Channel, and RPC:** 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 microReticulum commit:
  `9206f2ab63bca1fe8d3a392f70725674abba85ca`;
- Exercise 205 in
  `/usr/local/src/microreticulum/microReticulumTbeam/exercises/205_sustained_link`;
- source inspection, staged test inventory, an Exercise 205 build, and
  comparison with the normative and behavioral requirements in `SPEC.md`.

No source files in microReticulum or Exercise 205 were modified.

## Major findings

### High: Link lifecycle enforcement is absent

`SPEC.md` section 6.7 requires an active Link to send and answer KEEPALIVEs,
transition through stale state, and close on timeout. Pending and handshake
Links must also expire when establishment does not complete.

microReticulum calls `start_watchdog()` for initiator and responder Links, but
the method is empty and the complete watchdog implementation remains commented
Python pseudocode:

- `src/Link.cpp:178-179`
- `src/Link.cpp:301-302`
- `src/Link.cpp:1017-1096`

The KEEPALIVE packet send and responder paths exist, but nothing schedules the
initiator's KEEPALIVEs or stale checks:

- `src/Link.cpp:1098-1104`
- `src/Link.cpp:1632-1640`

Exercise 205 compensates at application level with a 60-second retry timer, a
three-attempt failure window, a 12-hour stale threshold, peer boot tokens, and
manual Link-state clearing:

- `exercises/205_sustained_link/src/main.cpp:746-778`
- `exercises/205_sustained_link/src/main.cpp:1107-1221`

This is strong evidence that basic Link setup and encrypted payload exchange
work. It is also evidence that sustained Link lifecycle behavior is not
provided by the library itself.

### High: Resource and Channel are API shells, not implementations

Resource constructors do not prepare or advertise a transfer.
`validate_proof()` and `cancel()` are empty, and `get_progress()` always
returns zero:

- `src/Resource.cpp:36-55`
- `src/Resource.cpp:60-82`

The Link receive cases for Resource advertisements, requests, hashmap updates,
and cancellation are inside a disabled comment block. Resource part receipt
does not call `receive_part()`:

- `src/Link.cpp:1540-1631`
- `src/Link.cpp:1642-1651`

`src/Channel.cpp` contains only includes and namespace declarations, and Link
Channel receive/get-channel code is disabled:

- `src/Channel.cpp:1-26`
- `src/Link.cpp:1257-1265`
- `src/Link.cpp:1653-1665`

Therefore `SPEC.md` sections 6.8 and 10 are not implemented.

### High: Link packet-receipt proofs cannot validate

microReticulum can emit explicit Link packet proofs, but the corresponding
receipt validator enters an unconditional explicit-proof branch and then
guards the actual signature validation with `if (false)`:

- `src/Link.cpp:391-405`
- `src/Packet.cpp:848-908`

Every Link packet receipt proof therefore returns false. This prevents reliable
delivery confirmation and also removes a prerequisite for Channel behavior.

### High: IFAC and required transport framing are absent

Both IFAC transmit and receive implementations are commented out:

- `src/Transport.cpp:797-856`
- `src/Transport.cpp:1385-1451`

The library exposes a raw `InterfaceImpl` abstraction and example raw UDP/LoRa
interfaces, but no native KISS, HDLC, RNode air-frame split/configuration,
AutoInterface, or shared-instance framing implementation was found.

As a result, `SPEC.md` section 8 is largely outside the staged implementation.
Custom applications can supply an interface, as Exercise 205 does, but that is
not equivalent to implementing the specified framing protocols.

### High: GROUP destinations and ratchets are absent

GROUP encryption is left as commented upstream pseudocode. GROUP `encrypt()`
falls through and returns plaintext; GROUP `decrypt()` returns an empty value:

- `src/Destination.cpp:441-475`
- `src/Destination.cpp:478-509`

Ratchet constants and a packet field exist, but packet ratchet selection is
commented out and the README roadmap marks ratchets unimplemented:

- `src/Packet.cpp:353-357`
- `README.md:149`

This leaves `SPEC.md` sections 1.4, 7.3, and 7.4 unimplemented.

### High: REQUEST/RESPONSE is only partially usable

Link REQUEST and RESPONSE packet parsing, msgpack encoding, authorization
checks, and receipt state are substantially present. However, the public
destination methods that register and deregister request handlers are entirely
commented out:

- `src/Destination.cpp:356-395`

Requests or responses larger than the Link MDU instantiate the Resource shell,
which cannot transfer data:

- `src/Link.cpp:1141-1155`
- `src/Link.cpp:1201-1253`

The packet-sized receive path is promising, but the staged API cannot expose a
working server handler and Resource-sized forms cannot work. `SPEC.md` section
11 is therefore incomplete.

### Medium: Transport operational controls are incomplete

Ordinary packet forwarding, reverse tables, Link tables, path discovery,
interface-mode decisions, announce replay tracking, and bounded path/announce
tables are implemented. Important control behavior remains absent:

- tunnel synthesis, receive handling, restoration, and persistence are stubs:
  `src/Transport.cpp:2671-2775`, `src/Transport.cpp:4006-4137`;
- announce-rate enforcement is commented out:
  `src/Transport.cpp:2031-2067`;
- queued announces can be added, but `process_announce_queue()` is empty and no
  timer is started:
  `src/Interface.cpp:91-136`, `src/Transport.cpp:1089-1151`;
- IFAC is absent as noted above;
- current RNS per-interface path-request ingress/egress limiting is absent;
- packet-hashlist and known-destination persistence are stubs:
  `src/Transport.cpp:226-242`, `src/Transport.cpp:3716-3752`,
  `src/Identity.cpp:282-371`.

These gaps matter most for transport nodes, busy meshes, restart recovery, and
untrusted interfaces.

### Medium: Exercise 205 exposed and patched inbound Link callback binding

The staged microReticulum head is a recent fix that asks the owner destination
to bind callbacks when an inbound encrypted payload arrives without a Link
packet callback:

- microReticulum commit `9206f2a`
- `src/Link.cpp:1337-1357`

Exercise 205 contains matching callback rebinding and documentation:

- `exercises/205_sustained_link/src/main.cpp:821-824`
- `exercises/205_sustained_link/src/main.cpp:936-946`
- `exercises/205_sustained_link/README.md`

The fix addresses a real application-visible loss mode. Its recency and the
amount of Exercise 205 supervision indicate that basic Link behavior is still
stabilizing and should not yet be treated as a complete section 6
implementation.

### Medium: Native LXMF is absent

No LXMF packer/parser, message signature layer, fields, stamp/ticket support,
or propagation protocol was found. microReticulum is explicitly an RNS
library, so this is a scope gap rather than a defect in its stated network-stack
scope, but it remains a major gap against the combined `SPEC.md`.

## Strongly covered areas

Source, tests, examples, and Exercise 205 show useful implementation depth in:

- identity key serialization, hashing, signing, X25519 exchange, HKDF, Token
  crypto, and private-key file compatibility;
- destination/name hashing and SINGLE destination encryption;
- HEADER_1/HEADER_2 packet packing, parsing, hop handling, and ordinary
  originator transport insertion;
- announce generation and validation, including the corrected five-byte random
  plus five-byte timestamp form;
- path requests, path responses, replay blobs, path tables, ordinary DATA
  forwarding, reverse proofs, and transport-relayed Links;
- Link request, LRPROOF, link-id derivation, key derivation, MTU/mode
  signalling, LRRTT activation, identify, payload encryption, and close;
- cooperative MCU operation, custom interface integration, configurable
  bounded tables, low-memory handling, and path persistence through
  microStore.

The project also has 98 enabled `RUN_TEST` declarations, concentrated in
utility, persistence, msgpack, memory, receipt, hashlist, packet-cycle, and
announce-table behavior. It does not consume this specification repository's
thirteen deterministic vector domains.

## Exercise 205 comparison

Exercise 205 is a valuable integration harness rather than an independent RNS
implementation. It links directly to the staged microReticulum checkout and
demonstrates:

- real ESP32/LoRa SINGLE announces and Links;
- Link MTU negotiation and encrypted Link payload exchange;
- multi-peer operation with scheduled traffic;
- the need for application-level retry, stale cleanup, reboot detection, and
  callback rebinding around the current library.

It does not exercise Resource, Channel, REQUEST/RESPONSE, IFAC, framing
protocols, tunnels, ratchets, GROUP destinations, or LXMF. Its successful build
therefore supports a narrow but important conclusion: microReticulum is a
credible foundation for embedded Link experiments, not a full conformance
demonstration.

## Verification performed

Results:

- Exercise 205 `bob` firmware:
  `source /home/jlpoole/rnsenv/bin/activate && pio run -d exercises/205_sustained_link -e bob`
  - **build passed**
- staged native test suite:
  - **not run**
  - PlatformIO refused the read-only staged project directory. From a writable
    temporary copy, it attempted to install the native platform into an
    isolated core and terminated with `HTTPClientError` before running tests.

The Exercise 205 build emitted an existing compiler warning in
`src/Bytes.h:368`: `Bytes::collection() const` can return a reference to a
temporary when the object has no backing data. That is a C++ correctness risk,
but it is not itself a `SPEC.md` conformance finding.

## Recommended conformance order

1. Implement Link watchdog/lifecycle behavior and enable Link receipt proof
   validation; add deterministic Link lifecycle and proof tests.
2. Implement Resource fully, then REQUEST/RESPONSE Resource forms.
3. Implement Channel on top of proven Link receipts.
4. Implement IFAC and the required framing/interface protocols for intended
   deployments.
5. Implement GROUP and ratchet behavior.
6. Close transport-node gaps: tunnels, queue draining, announce/path-request
   ingress controls, and restart persistence.
7. Consume this repository's deterministic vectors as a release gate.
