# ADR-0001: Bridge and extend — the gateway/extension seam

- **Status:** Accepted
- **Date:** 2026-05-24
- **Context source:** ARCHITECTURE.md §1

## Context

We are building a Rust implementation of the Reticulum protocol that must
participate in the existing Reticulum network *and* serve as a vehicle for
protocol extensions (post-quantum link handshakes, hardware-backed identity,
modern observability, foreign-protocol adapters). These two goals pull in
opposite directions:

- Network participation demands **byte-exact** compatibility with a protocol
  defined, in practice, by a Python reference implementation.
- Extensions demand **design freedom** — and, critically, the freedom to land
  them *without* coordinating with the Reticulum maintainer or network, given
  that the reference maintainer withdrew from public engagement in December 2025
  and the reference license now blocks standard distribution channels.

If extension concerns were allowed to bleed into the wire-compatible code, every
extension would risk breaking interop, and the licensing/derivation story would
become muddy.

## Decision

Split the stack into two layers separated by a **Rust API seam, not a wire
format**:

1. **Gateway layer** (`plexus-core`, `plexus-crypto`, `plexus-codec`,
   `plexus-gateway`): implements the Reticulum wire format — Announce, Path,
   Link, Resource — and is byte-exact with the network. Built clean-room from
   the public-domain protocol spec and observed wire behavior.

2. **Extension layer** (`plexus-ext`): original work layered *above* the gateway
   API. Extension-aware peers discover each other via a TLV carried in the
   announce `app_data` field (which the reference treats as opaque), behind an
   `0xEE 0xEE` sentinel. Extensions are negotiated; absent negotiation, behavior
   falls back to gateway-native framing.

**The invariant:** extension data never appears in Reticulum-compatible packets
unless explicitly negotiated by both peers. Reticulum-only peers see our nodes
as ordinary Reticulum nodes.

This seam is enforced structurally by the crate dependency graph
(ARCHITECTURE.md §2.2): the gateway crates do not depend on `plexus-ext`, so
extension types are not even *in scope* when emitting compatible wire output.
The conformance suite (ARCHITECTURE.md §7) verifies it.

## Consequences

**Benefits**

- Extensions land with **no network coordination** required.
- **Clean licensing**: the gateway is derived only from the public-domain spec;
  the extension layer is original. No post-April-2025 reference code, no AGPL.
- **Embedded-friendly**: the gateway core is `no_std + alloc`; `std`/`tokio`
  live only in the interface and extension/daemon crates.
- **Future-proof**: when the protocol evolves under community stewardship, the
  gateway layer absorbs the change; the extension layer is unaffected.

**Costs (accepted)**

- **More crates** (~9 instead of one). Judged the right trade.
- **Discipline at the seam**: extensions must never leak onto compatible wire
  output. Enforced by crate boundaries and verified by tests.
- **A negotiation mechanism** is required for extension-aware peers to find each
  other (the announce `app_data` TLV; ARCHITECTURE.md §6.1).

## Alternatives considered

- **Single monolithic crate.** Rejected: blurs the licensing boundary, prevents
  a `no_std` core, and entangles extension churn with interop-critical code.
- **A new wire format for extensions.** Rejected: would fork the network and
  forfeit compatibility, which is goal #1.
- **Upstreaming extensions into the reference.** Not viable given the reference
  maintainer's withdrawal and licensing posture.

## References

- ARCHITECTURE.md §1 (the seam), §2 (crate layout enforcing it), §6 (extension
  negotiation), §10 (licensing chain).
