Offline-first gateway between devices running Latch and one or more Trace backends. Relay accepts LEP envelopes (serial, TCP, HTTP, MQTT, adapters, or files), validates them, stores them on disk, ACKs the device only after the write, optionally analyzes crashes locally, and forwards events with retries and idempotency.
- Persist before ACK —
LSAK ACK_STOREDonly after object write + SQLite commit - At-least-once delivery — duplicates possible after a lost response; stable IDs make retries safe
- Works offline — outages do not block collection
- Raw kept locally — original LEP bytes stay exportable and checksummed
- No cloud lock-in — talks only to the Trace HTTP contract
- LEP v1/v2 validation/encode (v2 is the current wire version; v1 accepted), CRC-32/IEEE, optional HMAC + ChaCha20-Poly1305, zstd payloads
- Latch stream and COBS framing with resync
- Sources: serial, TCP/TLS, UDP, HTTP/TLS, directory, MQTT, subprocess adapters
- Delivery: mirror / priority / route / local-only, JSON or binary batch, zstd
- Privacy filters per destination (local raw untouched)
- ELF catalog, build-id match, DWARF + external symbolizers, Cortex-M and multi-arch basics
- CLI/TUI, Prometheus, Grafana dashboard template, backup/restore
- Packaging: Docker, systemd, deb/rpm templates, Windows service, launchd, Homebrew
go test ./...
go build -trimpath -ldflags "-s -w \
-X main.cliVersion=v0.4.0 \
-X main.gitCommit=$(git rev-parse --short HEAD) \
-X main.buildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o bin/laststate-relay ./cmd/laststate-relayNeeds Go 1.26.1+.
cp relay.yaml.example relay.yaml
laststate-relay config validate relay.yaml
laststate-relay run --config relay.yamlSerial collect:
laststate-relay collect \
--serial COM5 \
--baud 115200 \
--framing latch-stream \
--ack lsak-v1 \
--data-dir ./dataOffline analysis (explicit ELF or auto-match from the artifact catalog):
laststate-relay analyze crash.lep --elf build/firmware.elf
laststate-relay analyze crash.lep --data-dir ./dataAdmin and ingest are separate. Do not expose admin publicly without TLS and a strong token.
Admin
GET /v1/status | /v1/health | /v1/ready
GET /v1/events | /v1/events/{id}
GET /v1/destinations
POST /v1/events/{id}/replay
POST /v1/destinations/{id}/pause|resume
POST /v1/spool/prune|reconcile
Ingest
GET /v1/ingest/capabilities
GET /v1/relay/capabilities
POST /v1/ingest
POST /v1/events:batch
Trace (as destination)
GET /v1/relay/capabilities
POST /v1/ingest
POST /v1/events:batch
Batching is per destination. Relay discovers limits, sends JSON or binary batches (optionally zstd), retries only failed items, and falls back to single-event POST for older servers.
run · collect · info · inspect · analyze
import · export · replay · status · doctor
artifacts · destinations · bundle · spool
backup · restore · config · version
| Doc | Topic |
|---|---|
| docs/architecture.md | How the pieces fit |
| docs/durability.md | ACK / write path |
| docs/production.md | Deploy checklist |
| docs/v1-release-gate.md | v1.0.0 tagging gate |
| docs/hil-matrix.md | CAN/BLE/LoRa/Probe HIL evidence |
| docs/compatibility-matrix.md | What is ready vs draft |
| spec/ | Wire drafts (crypto, batch, TLVs, …) |
| ROADMAP.md | What is left |
Native CAN (SocketCAN/CAN FD/USB-CAN/TCP), BLE GATT, and LoRa/LoRaWAN sources
are implemented (internal/source/can.go, ble.go, lorawan.go) with unit
coverage (go test ./internal/source/). Not tagged v1.0.0 yet — that waits
on the executable gate in docs/v1-release-gate.md:
protocol freeze, durability soak, Latch+Trace E2E, the
HIL matrix, and an external security review.
Apache-2.0 — LICENSE.md