Bridge

MeshSat Bridge changelog: standalone gateway releases.

Generated from the commit history of meshsat: features and fixes, newest first, one section per tag. Untagged work on the main branch is listed under Unreleased. MeshSat is a prototype and has never been deployed to a real user.

Unreleased (main, last change 2026-09-15)

Features

  • relay: serve the bridge API to the tenant’s phones through the Hub relay (07d3750f)
  • ttc: both kits pair a T-Deck Pro, captioned (A) on tesseract and (B) on parallax (172fdd5a)
  • aprs: report a serial TNC that has sent nothing since its link opened as silent, with a PTT hint on the panel (c01f719f)
  • ups: battery events on the event stream when the pack changes state (43d783e1)
  • health: show device health beside the link state for gateways, the modem and the booth screen (124ce57e)
  • oob: follow a peer kit’s radio to its new node number (908dae33)
  • time: establish the clock before the bridge starts, and never export one we cannot trust (4b94bd19)
  • web: the kiosk poster is an interlude in the attract loop, not a lid: 20 s every 4 min after 3 min idle (0c5a7e73)
  • web: kiosk poster screensaver after 30 s idle, any touch or a live message wakes the panel (063521e1)
  • web: TTC handhelds are the T-Deck Pro on tesseract and a T-Deck Plus without the SMA stub (6e98e32b)
  • ttc: the four routes become one row each, riding their own lane (6a3d6842)
  • oob: the Hub can pair as a management peer, by its own key or the kit’s (1d813987)
  • ttc: fourth booth path, kit to kit over Iridium IMT, with a satellite lane on the panel and satellite traffic in the packet feed (0d6802a5)
  • ttc: the island with the kit and the handheld is the hero of the booth screen, the message strip is one row (d1278695)
  • hub: wire the satellite fallback uplink, position/health/SOS frames to the Hub over IMT/SBD or SMS when MQTT is down (0d3c1609)
  • cellular: plaintext peers for the Hub SMS leg, [origin] prefix parsed, the Hub’s echo of a kit’s own SMS dropped (0597731f)
  • ttc: booth flow selector, three paths drawn on the panel, tap a lane to choose this kit’s way out (dad90ac3)
  • aprs: beacons carry the same repeat copies as messages (f9c9a24d)
  • api: POST /api/messages/simulate-mesh-rx feeds a text through the radio-receive path for relay pre-flight without a handheld (ca9f8b9f)
  • aprs: tx_repeat sends each message twice on the air; the far kit dedups (9d28e3bc)
  • aprs: status beacon, Direwolf timing keys, watchdog rungs gated on a hung Direwolf; relayed texts travel as text on text bearers (41f3ee98)
  • failover: groups skip a member whose receiver is deaf, for the APRS-first booth relay (41fad9a3)
  • api,web: nodes carry other_mesh, the dashboard lists this mesh first and counts only it as peers (bf99aeaa)
  • web: TTC composer, double-tap the kit to type a message on the panel and send it to the local or the remote mesh (390f884b)
  • web: leaving TTC mode is an easter egg, three taps on the mark then one on the QR (2259905e)
  • web: TTC device drawings are the real T-Deck Plus and T-Echo, photos with a live screen overlay (29ea75ad)
  • web: TTC island line counts only decrypted LoRa, shows unreadable frames from other meshes (0d0bc6c5)
  • web: TTC mode islands are mesh A msat-ttc-01 on tesseract, mesh B msat-ttc-02 on parallax (538c0336)
  • power: power widget on the left of the clock in both headers (95c108b9)
  • power: power widget sits next to the clock in both headers (60fc13bf)
  • power: power widget in the top bar, host poweroff action, POST /api/system/power (cccb4971)
  • web: TTC mode follows the table, tesseract left of parallax (a65f397e)
  • web: TTC mode audit pass, kit name in the header, honest labels (df91f9b5)
  • web: TTC mode for the visitor, diptych layout, tap cards, replay, QR (8c0fa8a4)
  • web: TTC mode device art from the real hardware, kit CAD render and LilyGO drawings (6bf3ff7d)
  • kiosk: panels never dim on mains power, AC-aware --idle mode for meshsat-backlight (c803f365)
  • engine: live packet feed for TTC mode, packet SSE events, /api/packets, delivery events carry their row (02695705)
  • web: brand re-skin and TTC mode booth screen replacing Run Full Demo (3b150e09)
  • web: ?pointer=1 keeps the kiosk profile but shows the mouse cursor (b02210c5)
  • aprs: serial KISS TNC path for the PicoAPRS V4, gateway fan-out to ax25_0, TNC receive health (493e8c3c)
  • health: RTL-SDR, GPS, IMT and SBD probes, spectrum scan serialisation, health on the dashboard (bb0fa67d)
  • health: ZigBee and cellular heal ladders, live zigbee_0 binding, cellular quiet window (c7782ef2)
  • health: device health watchdog with a heal ladder for the mesh radio (aa65ed4a)
  • scripts: DMR858M UART configuration tool for the bench swap (0053bc15)
  • aprs: receive-health signal and a receive watchdog that walks the recovery ladder (5513f983)
  • scripts: kit installers ship the RTL-SDR blacklist and the Goodix touch rebind unit (81f7dcb5)
  • oob: RESET level 3 cuts USB port power on a per-port switchable hub (39c065d3)
  • web: Remote Mgmt settings tab for OOB management frames (1d94dcc2)
  • api: OOB routes, Prometheus counters, Hub mgmt commands, key-import peer registration (0ac4109a)
  • deploy: OOB host agent, socket-activated units, tmpfiles and installer (55fa70d2)
  • oob: management frame service, executor, classifier hooks and bridge wiring (d8bee7ce)
  • dispatch: per-delivery destination and class, verbatim SMS, directed APRS, SMS sender address (a72d7890)
  • keystore: mgmt channel type 0x08 and CreateBundleFromEntries (676cbac7)
  • database: v54 OOB peers and log, per-delivery destination and class (0b2d047a)
  • oob: frame codec, replay window, key derivation, command and target tables (8790b1a3)
  • kit: kit-to-kit P2P bearer over the MT7612U dongle (ec126885)
  • kit: codify field kit WiFi provisioning, disable firmware roaming (e90e9dbd)
  • sdd-tier6: customer-facing CHANGELOG.md generated from git history (e3829ee7)
  • sdd-tier5: per-tag release notes generated from outcomes (3e26456a)
  • sdd-tier4: CI gate + retrospective outcomes (0b5a6199)
  • sdd-tier3: acceptance test mappings + worker dispatch packets (9f1459ee)
  • sdd-tier2: observability blocks on every task (5e845d4e)
  • dashboard: demo polish: run-all button, sparklines, channel matrix, map marker pulse (8d71905d)
  • ble: host-side systemd unit pins BT adapter flags pre-bluetoothd (b9ae8f67)
  • ble: pin advertising identity to hostname-derived static random MAC (0b7031bf)
  • ble: resilience for bridge↔bridge Reticulum peer link (3c1d03a6)
  • compose: plumb DCF77 env vars through standalone compose (07c09217)
  • timesync: DCF77 longwave stratum-1 time source (bb2c3cc0)
  • hemb: persist bond-decrypted payloads to the message store (6df793c3)
  • hemb: MESHSAT_MESH_MTU env var for bond mesh bearer MTU (26e5e1f8)
  • dashboard: APRS widget shows E2E encryption state (d6047dcf)
  • web: 9603 GPIO status + power-cycle button in Iridium card (46b30279)
  • iridium: OnOff GPIO + HardPowerCycle API (bd0afc29)
  • iridium: RI GPIO input: hardware ring-alert path (40d55364)
  • iridium: NetAv GPIO input: SBDIX veto + status exposure (42bb98b4)
  • hemb: bond-level end-to-end encryption (encrypt-then-code) (179b7aec)
  • keys: POST /api/keys/import: bridge-side bundle ingestion (f544dc78)
  • aprs: end-to-end encryption over AX.25 using existing transform pipeline (3c10a054)
  • spectrum: detail view opens as full-screen modal, not a route (e4002628)
  • spectrum: persist scan history + per-band detail view (5515feaf)
  • p2p: overlay-IP reconciler: bulletproof WiFi-Direct TCP anchoring (267648a4)
  • wifi-p2p: auto-wire peer into Reticulum TCP + HeMB bond (4e89c27f)
  • wifi-p2p: WiFi-Direct kit-to-kit link over USB dongles (bb8a75be)
  • ui: WiFi adapter picker + dashboard Links widget (fc0165de)
  • federation: capability manifest + trusted peers + BLE exchange (92b97a98)
  • ble,wifi: GATT client + WiFi peer-link (bf04a7cf)
  • hub: BT/WiFi command dispatcher over Hub MQTT (e6364fe4)
  • bluetooth: detect + label MeshSat kits by advertised GATT UUID (2b588a15)
  • system-wifi: merge iw-dev signal dBm into WiFi status (25e1820d)
  • ui: Bluetooth peers + WiFi manager in Settings (69cc309c)
  • kiosk: long-running-renderer defences in depth (07a83775)
  • image: add BT + WiFi + namespace tooling to runtime (6fb8c000)
  • api: port BT + WiFi host-ops from HAL: standalone-mode pragma (45d1ef57)
  • api: port BT + WiFi management from cubeos/hal (99ab827d)
  • dashboard: Active Comms tile speaks HeMB: bond label + per-bearer dots (7c103a90)
  • web: bundle-hash polling auto-reloads kiosk after deploy (95a5961b)
  • kiosk: swayidle backlight dim + sudoers-scoped wrapper (a264fe01)
  • system: wire X1202 UPS battery into bridge + operator tile (ac7b24e7)
  • kiosk: one-shot Pi 5 kiosk provisioner (eb2e81a7)
  • web,api: Phase-9: /pair/scan browser wizard + directory health envelope (14e9329c)
  • web: Settings > Devices: Arm pair mode + paired-clients list (b91f35ff)
  • pair,api,database: pair-mode protocol v1: arm/claim/refresh/list/revoke (09cf29b8)
  • web: PWA + touch keyboard + SPA fitness polish (b85b9cd8)
  • web: team broadcast + clustered map + USMTF library + FieldHelp (ea720693)
  • web,api: SOS panic button + USMTF templates (b812672f)
  • directory,web: QR contact cards + trust levels + FLASH hard-block (4e7f130d)
  • directory,web: SIDC on contacts + milsymbol Map pins (911a7db6)
  • web: Engineer keyboard shortcuts composable (085367d9)
  • web: IQ-70 i18n dictionaries + useLabel composable (32650fb0)
  • web,api: NVIS night theme + backlight sysfs bridge (65591f51)
  • web: Settings: 5 Operator tabs + Engineer drawer (5b75240c)
  • web: Radios view + persistent StatusStrip (b04a34c0)
  • web: People view: directory browser + trust dots + verify flow (4b598144)
  • web: Inbox: unified view, bearer-coloured bubbles, delivery ticks (33c0c563)
  • web: Compose view: contact-first, precedence-second (52b317bc)
  • web: primary nav reshape: 5 items + More + mobile bottom bar (010c55c4)
  • web: Operator/Engineer mode toggle with localStorage (6aa2b551)
  • engine,api: SendToRecipient + POST /api/messages/send-to-contact (84d5cffd)
  • database,engine: precedence-aware queue + FLASH preemption (e7a4be34)
  • directory,api: vCard 4.0 + CSV import/export (Bridge) (e8a1d8e1)
  • hubreporter: directory_push + trust_anchor_rotate handlers (5af92044)
  • api: retire legacy SMS-contacts endpoints (25fa0513)
  • types,database: STANAG 4406 precedence on every delivery (f3091f7e)
  • engine: per-contact AES traffic key resolution (31f46197)
  • directory: internal/directory package: Store + SQLStore (463ca2a3)
  • database: unified directory schema v44-v48 (ebd56668)
  • aprs: bundle Direwolf as supervised subprocess (24b0327d)
  • spectrum: MIL-grade operator UX + technical-debt closure (D1-D12) (1516e55d)
  • spectrum: add always-visible ECCM quick-reference table (50ad18d1)
  • spectrum: MIL/ITU compliance: MIJI-9 metrics + ECCM guidance (56833753)
  • spectrum: replace waterfall widget with scannable 5-band status list (7e5c0b8e)
  • spectrum: true connected/disconnected detection: USB sysfs check (00c056d3)
  • spectrum: multi-feature classifier: kills false-positive alerts (ecaf1f78)
  • spectrum: auto-retry calibration for bands that failed Phase 1 (every 60s) (1d2362fa)
  • spectrum: calibration progress bar + countdown in widget and page (15cfc1de)
  • spectrum: paint waterfall from t=0 (publish during calibration) + 512-col upsampled smooth heatmap (SDR#-style) (6f9b8225)
  • spectrum: pause/play button + proper mini waterfall strips in widget (2c4ef2d3)
  • spectrum: real spectrum-analyzer look: FFT trace + Turbo waterfall + axes + hover cursor (5bdffa8f)
  • spectrum: compact dashboard widget + /spectrum page + popup toggle + ACK mute (ff4624f0)
  • spectrum: Phase 2: waterfall widget + sticky jamming ACK modal (59af4129)
  • spectrum: Phase 1: SSE stream + TAK CoT + hub alert relay (a4ce0504)
  • spectrum: monitor GPS L1 + LTE Band 20/8 + install rtl_power (4791e927)
  • zigbee: all four follow-ups: staggered reads, leave req, level/color, IAS Zone (c91f9dc0)
  • zigbee: ZCL Read Attributes: pull sensor values on demand (ce871d30)
  • zigbee: complete device manager: DB, API, UI, TAK CoT bridge (827af3e3)
  • zigbee: BDB commissioning fallback + notification decode (aa58af36)
  • zigbee: permit-join, ZCL temp/humidity decode, dashboard widget (91287d36)
  • zigbee: add permit-join API + dashboard widget (45a76597)
  • aprs: 4-layer Direwolf self-healing system (0f60119b)
  • aprs: add APRS dashboard widget with heard stations and activity (809c42c3)
  • deploy: add tesseract01 field kit to CI deploy matrix (7ab15a70)
  • deploy: support field kit layout and per-target SSH user (913b4085)
  • hubreporter: add spectrum monitoring to Hub telemetry (c425de97)
  • spectrum: RTL-SDR jamming detection with auto transport failover (d5bb3662)
  • routing: add BLE Reticulum interface via BlueZ D-Bus (11f27638)
  • keystore: complete v2 key bundle support with signing pubkey endpoint (5ba8b65e)
  • api: add per-IP HTTP rate limiting middleware (9f3c5e31)
  • api: add Prometheus metrics endpoint at /metrics (a738bd98)
  • map: show TAK-relayed positions alongside mesh nodes (80efbe54)
  • tak: close data loop: bridge receives TAK CoT from Hub MQTT relay (584dd17b)
  • tak: show ‘Via Hub’ when bridge relays CoT through Hub to OTS (7260ff39)
  • tak: 100% compliance: protobuf inbound, team filter, GeoChat, 9-line (695d306f)
  • map: bearing/distance measurement tool + team group filter (97f3135b)
  • tak: Mission Browser + Certificate Lifecycle + Monitor polish (f1837c9b)
  • tak: add Missions, Data Packages, and SA Snapshot tabs to TakView (2c72ea46)
  • dashboard: enhance TAK widget with connection status dot and rate (d02de639)
  • tak: CoT event stream SSE + TakView page + dashboard widget (b5531c3f)
  • map: TAK/CoT-compliant markers with MIL-STD-2525 SVG icons (ce25f661)
  • tak: DataPackage + Mission API: Marti REST client (bb1d8777)
  • tak: auto-enrollment via TAK Server port 8446 (2f75d1b5)
  • tak: multicast SA: serverless peer-to-peer LAN discovery (b8fbf392)
  • tak: certificate auto-enrollment via TAK Server port 8446 (3c2961be)
  • tak: TAK Protobuf v1 wire format + stream framing (415723b1)
  • tak: expanded CoT types: waypoints, circles, route/map types (d0274265)
  • tak: position enrichment: GPS accuracy, velocity, coalescing, takv (2aa6195a)
  • ui: add TAK Settings tab for CoT gateway configuration (d38949f7)
  • hemb: wire cellular_0 as HeMB bearer + SMS peer API (971b0454)
  • cellular: add /api/cellular/at debug endpoint (2ef2dc46)
  • keys: Hub-driven key rotation + key_ref in transforms (3cd88fb6)
  • hemb: add fault injection API + decode latency percentiles to stats (50076109)
  • hemb: adaptive reassembly timeout + decode latency tracking (9c1060c1)
  • hemb: receive-side reassembly bonder + POST /api/hemb/send endpoint (61553c5e)
  • hemb: add Reticulum packet sender as bearer for bond groups (55029250)
  • ui: Hubble v3: fix flow table, lighter cards, port rows, timestamps (37d6824a)
  • ui: Hubble v2: left-accent cards, MTU info, connection dots, rule badges (ad66bf49)
  • ui: Hubble-inspired visual overhaul of ObservabilityGraph (255773fb)
  • ui: replace Topology + HeMB tabs with Hubble-inspired observability dashboard (8fbf4aa7)
  • hemb: add RLNC matrix inspector + hemb_events persistence (e9c3af0c)
  • hemb: add TUN/TAP adapter for IP-over-HeMB bonding (fe4dd604)
  • hemb: add observability dashboard: event bus, SSE, bearer graph, flow table (47b5115e)
  • api: add bond group CRUD + HeMB stats REST endpoints (a24cfee0)
  • hemb: implement HeMB core protocol + MeshSat integration (75adb692)
  • hemb: add frame format, CRC-8, header detection and promotion (52a1ae4d)
  • routing: add ZigBee Reticulum interface for CC2652P coordinator routing (7dfcf599)
  • routing: add SMS Reticulum interface for cellular packet routing (a6254de9)
  • routing: add mTLS support to MQTT Reticulum interface for Hub relay (0f30f068)
  • hub: sign birth messages with ECDSA-P256-SHA256 for MQTT anti-spoofing (946315fa)
  • hub: use shared MQTT username ‘meshsat’ + NATS password for Hub auth (f30147f9)
  • dtn: wire custody transfer into delivery pipeline: point-to-point, not broadcast (1c771abf)
  • wire: wire DTN fragmentation + RLNC coding + FEC into live pipelines (f8d5b36a)
  • wire: wire TimeService + mesh consensus into main.go startup (04c2ce55)
  • protocol: implement 4 protocol enhancements: FEC, Time Sync, DTN, RLNC (ce5400de)
  • e2e: add live E2E validation tooling for full-stack testing (e7275b39)
  • hub: mTLS client certificate via UI: paste PEM in Settings (e766e3b6)
  • hub: TLS CA config for hub reporter + routing handler updates (3512f181)
  • api: add bridge restart button: POST /api/system/restart (39fe6611)
  • routing: wire AX.25 and MQTT Reticulum interfaces in main.go (f4522aeb)
  • hub: UI-managed Hub MQTT credentials: paste from Fleet page (2a2260bd)
  • hub: populate all health fields: CPU, memory, disk, interfaces, Reticulum, burst (8e034f86)
  • dashboard: Reticulum network widget: peers, nodes, links, interfaces (42be5d0c)
  • routing: UI-managed TCP peers, listen port, and announce interval (b2d315a6)
  • routing: wire TransportNode + PathFinder + InterfaceRegistry in main.go (4dd2f1c6)
  • proto: adopt official Meshtastic protobuf bindings (d7fe0f5b)
  • dashboard: credential management tab in Settings (a5ecc865)
  • hubreporter: credential_push/revoke command handlers (b33f7e78)
  • credentials: centralized cert/credential management for bridge (d5206699)
  • keystore: cross-platform key exchange with QR bundles and envelope encryption (c2b75eae)
  • resources: add resource transfer API and DB persistence (8f847cd0)
  • routing: wire resource transfer and all transport interfaces (84a3686f)
  • routing: add Astrocast, MQTT, and AX.25 Reticulum interfaces (e5a695b0)
  • routing: wire Iridium SBD and IMT as Reticulum interfaces (fb12f4eb)
  • gateway: pass scheduler works for both SBD and IMT (75ee47fe)
  • routing: wire Reticulum routing subsystem into processor (9ff45151)
  • hub: wire real command handlers for send_text, send_mt, flush_burst (e1be2de9)
  • routing: wire TCP/HDLC Reticulum interface in main.go (2b3b9152)
  • gateway: multi-instance gateway support for xN modems of same type (290c259e)
  • api: async message send: queue instead of blocking on satellite (c459102d)
  • imt: integrate jspr-helper C binary into meshsat (9de6f5fc)
  • imt: add jspr-helper C binary for RockBLOCK 9704 serial I/O (4306348a)
  • imt: add checkProvisioning JSPR call and /api/iridium/provisioning endpoint (ce7aa7d8)
  • hub: bridge-to-hub uplink protocol: HubReporter, device streaming, offline queue, satellite fallback (0d076cb3)
  • gateway: add TLS client certificate and CA support to MQTT gateway (c58bb7ba)
  • ci: add bananapi01 as deploy target + Playwright project (229ea923)
  • transport: parse ROUTING_APP, request_id, reply_id, via_mqtt (181163f2)
  • api: add /api/cellular/signal/fast cached endpoint (4ee054d9)
  • transport: full zero-config auto-detection: remove all device port env vars (8b6f81a1)
  • gateway: wire device supervisor events into gateway manager for hot-swap (472f6dae)
  • transport: add firmware version, MSSTM time, sleep/wake, power profile (0da68d8d)
  • deploy: replace bananapi01 with pifour01 in deploy pipeline (ac98f602)
  • transport: wire DeviceSupervisor to API server and dashboard (421c43ac)
  • transport: add USB tty recovery to DeviceSupervisor, remove debug logging (73829dd7)
  • transport: add SetPort methods and gateway IMT support for DeviceSupervisor (7788dc9b)
  • transport: add DeviceSupervisor for stable device discovery and auto-reconnect (50fda8a1)
  • deploy: source per-device env overrides from /cubeos/config/meshsat.env (d471ba8a)
  • ui: dynamic Iridium widget: auto-detect SBD vs IMT, show modem info (3a7d0292)
  • transport: add JSPR protocol and DirectIMTTransport for RockBLOCK 9704 (119fd968)
  • transport: add RockBLOCK 9704 IMT auto-detect and wire into startup (3401d9b6)
  • transport: auto-request NodeInfo from unnamed mesh nodes (43ec25ae)
  • api,ui: add RequestNodeInfo to refresh peer names from mesh (78fb9de6)
  • ui: rename Radio to Meshtastic, add channel summary to Dashboard and Peers (83272992)
  • ui: add webhook log + dedup mesh msgs in dashboard widget (9e16e019)
  • ui: add mesh text messages to dashboard unified message widget (21fa31ad)
  • radio: add Meshtastic radio configuration page (59dd84d5)
  • api: add radio setup detection endpoint (965369da)
  • cell: add SIMCom AT+CPSI? cell info parser for A7670E (9ec9281c)
  • cell: add T-Call A7670E detection and auto-PIN-unlock (94f7f304)
  • routing: wire TCP/HDLC Reticulum interface into app lifecycle (0150014a)
  • routing: chunked resource transfer with segment bitmap and SHA-256 verification (9029be09)
  • routing: HDLC framing and TCP Reticulum interface for RNS interop (c5d6b684)
  • routing: path request/response flooding for dynamic route discovery (4494a034)
  • astrocast: implement missing Astronode S binary protocol commands (c87d53cf)
  • routing: register Iridium and Astrocast as Reticulum interfaces (67c57b82)
  • routing: wire Transport Node into app.go, add InterfaceRegistry (102ca0dd)
  • routing: Transport Node with forwarding table and cross-interface relay (5920b425)
  • link: 2-packet handshake, HKDF-SHA256 keys, AES-CBC+HMAC encryption (d5dcbdb0)
  • routing: switch announces to Reticulum wire format (bd82d69e)
  • routing: switch Identity to Reticulum 3-stage dest hash computation (f8401bb9)
  • reticulum: port Hub wire format library, replace custom packet.go (65ddcdf8)
  • routing: add Reticulum wire format packet header library (9010ae5a)
  • compat: protocol version byte, cert pinning, canned codebook, docs (a90dbb24)
  • ui: Hub auth UI, API key management, RBAC visibility, E2E tests (dcb2c197)
  • ratelimit: add per-device SBD credit budget limits (d677514a)
  • auth: API keys with RBAC role enforcement (055e1a67)
  • auth: tenant isolation layer with per-table filtering (8de37dc8)
  • auth: harden OAuth2/OIDC with PKCE, RP logout, refresh token rotation (b9d6e79d)
  • hub: add Cloudloop credit balance polling (9c6710ba)
  • deploy: add production deployment guide with Caddy, MQTT, and backup tooling (4578ee57)
  • api: device registry enhancements: status, IMEI validation, MQTT hub publish (5f5f49ae)
  • channel: register TAK and APRS channels in registry and gateway factory (d007590b)
  • gateway: APRS adapter: Direwolf KISS TCP with AX.25 encode/decode (3e9696d1)
  • gateway: TAK/CoT adapter: bidirectional CoT XML over TCP/TLS (63752053)
  • database: device config versioning: delete method and full tests (5688fe9c)
  • api: add device registry CRUD with IMEI key (dbe577d3)
  • web: fix audit log viewer and add map enhancements (b297419b)
  • ui: wire all field intelligence features into frontend (e9a43519)
  • field intelligence features: 8 new capabilities (b5ce7c96)
  • api: complete MESHSAT-41: enable/disable, reorder, stats, failover update (8bbd5791)
  • api: add /api/config/diff endpoint for preview-before-import (ff78fef9)
  • compress: add MSVQ-SC rate-adaptive lossy semantic compression (56d31031)
  • engine: wire QoS levels, sequence numbers, and ACK tracking (001614e8)
  • routing: wire routing package into main app event loop (7e92392a)
  • routing: add path discovery, link establishment, and bandwidth limiting (4360a399)
  • routing: implement Reticulum-inspired announce broadcasting and delivery confirmations (121d1f2d)
  • transport: implement AES-256-CTR encrypted passthrough relay (cf4a8e17)
  • web: add loop prevention metrics to Bridge view (f392e7e8)
  • delivery: store-and-forward workers with pre-wake prep and priority eviction (f684c28b)
  • contacts: unified contact book with multi-transport conversation view (f986e861)
  • cellular: enable SMS encryption + improve SMS format (b1820e3f)
  • meshsat: add Cloudflare DynDNS provider, rewrite README for v0.3.0 (375a8386)
  • meshsat: per-rule SMS contacts, Dynu DynDNS, Huawei ICCID fix (0b29efe4)
  • meshsat: direct node/portnum pickers in access rule form (ace0f950)
  • meshsat: auto-bind interfaces to unambiguous USB devices, auto-online (09c3f428)
  • meshsat: SIM card management with ICCID auto-detect and phone lookup (54ad779a)
  • meshsat: dashboard widget dropdowns, queue height fix, deploy HAL coexistence (586110e5)
  • meshsat: RSRP/RSRQ display, roaming status, data usage tracking (9e709739)
  • web: SMS inbox, cell broadcast archive, signal quality labels (ab515db9)
  • meshsat: SMS contact groups in access rules + contact manager UI (1c489505)
  • meshsat: add mobile data auto-reconnect and multi-APN failover (1b9bfbb7)
  • web: interface selector dropdowns on widget titles (006e64da)
  • meshsat: operator refresh, phone number, unified queue, map fix, gateway SSE events (656f1798)
  • web: complete LOW priority audit items: geolocation, deliveries, channels, factory reset (e6b0f238)
  • web: frontend audit: audit log, config export, structured editors (1d62c9f6)
  • web: add ZigBee settings tab with paired device list (a5cf3cb4)
  • gateway: add ZigBee 3.0 gateway with Z-Stack coordinator management (60d7d841)
  • meshsat: ZigBee 3.0 transport channel with Z-Stack ZNP codec (cf956529)
  • meshsat: transport-aware transform validation (2476f1c5)
  • meshsat: AES-256-GCM payload encryption transform (74162553)
  • meshsat: SMAZ2 compression with Meshtastic dictionary (ea3934f8)
  • meshsat: transform pipeline + Ed25519 signing + audit log (b796ab08)
  • meshsat: failover group runtime resolution (705ba8d0)
  • meshsat: YAML config export/import (show running-config) (f5af6526)
  • meshsat: loop prevention, TTL expiry, QoS propagation (c9fe6b60)
  • meshsat: worker lifecycle, HELD deliveries, drop forwarding_rules (cf9dfb9b)
  • web: add Interfaces view for v0.3.0 interface management (f29518a9)
  • meshsat: wire v0.3.0 access rules into processor dispatch path (1ef5294a)
  • meshsat: add v0.3.0 access rule evaluation engine (fde5d0b5)
  • meshsat: add interface-aware gateway routing (78cbcdfa)
  • meshsat: add v0.3.0 interface model schema + InterfaceManager (af5767e2)
  • meshsat: complete cellular modem frontend integration (9a4bcd28)
  • meshsat: full cellular modem support: PIN unlock, CBS alerts, SMS history, cell info (a5b00ff4)
  • meshsat: fix AT-MSGEO ECEF parsing + multi-pass Iridium geolocation (75179b34)
  • meshsat: add GPS reader and time sync to Meshtastic radio (2c8f792e)
  • meshsat: add serial health watchdog for stale CDC sessions (d4094f08)
  • meshsat: add per-priority message expiration policy (5430d1d1)
  • astrocast: direct transport, config wiring, and settings UI (0cfd1916)
  • Astrocast LEO pass prediction: TLE manager, API, and dashboard tab (d0d32759)
  • any-to-any RuleEditor + cross-bridge tab (1ca3d11d)
  • v0.2.0 any-to-any routing: channel registry, delivery ledger, unified rules engine (b636464e)
  • SMS contacts CRUD, webhook activity log, full UI wiring (198058f2)
  • UX overhaul: top bar labels, chart sizing, tabs, pages (91498ee6)
  • top bar redesign, activity log telemetry values, queue/signal UX (279cc713)
  • UX polish: activity log clarity, delete queue API, top bar fixes (1d9eae4f)
  • frontend renovation: widget sizing, node modal, unified chart, SBD history, map themes (81fbab76)
  • full Meshtastic device management: config reads, position, S&F, range test, canned messages, neighbors (30c6c024)
  • smart scheduling intelligence: use custom elevation, GSS history, and MO counters (52402355)
  • configurable min elevation filter with environment presets (b1abb999)
  • GSS registration history tracking + pass/signal/GSS mini-charts (d067026b)
  • configurable mailbox polling mode + manual check button (71cd76bf)
  • dashboard UX overhaul: drag-and-drop widgets, stats modals, activity persistence (009308a6)
  • add stats-for-nerds debug panels to Bridge view (7dc5f63e)
  • cellular dashboard, unified location, activity log events, infinite DLQ retry (abece25d)
  • add 4G/LTE cellular gateway with 3-way bridge and cost risk analyzer (80394777)

Fixes

  • oob: BEARER on for a running bearer and off for a stopped one answer ok, as the spec promises (483d1f63)
  • ttc: satellite lane and chip name the modem that is present; visitor line measure (6913a829)
  • relay: fetch the bridge CA from the Hub instead of the MQTT root store (b104f47c)
  • cellular: the SMS bundle PUT applies every field under one lock before the thresholds run (e5552ac6)
  • engine: a gateway restarting under a delivery in flight is a retry, not a bridge crash (a1875b5d)
  • aprs: hold the status beacon while this kit waits for an ack (6b581b87)
  • mesh: serial watchdog off by default and never reopens a radio that still answers (2bc88920)
  • engine: drop inbound frames that fail the decrypt chain on an encrypted interface (232970d2)
  • aprs: keep third-party frames out of the message pipeline, only messages to us and MeshSat relays are forwarded (007b45a7)
  • oob: let the host agent power-cycle a Meshtastic 2.8 radio on its HWCDC identity (83ff614a)
  • failover: copy the stored plaintext, not the mutated ciphertext, when a no-ack message moves bearers (4fc4b300)
  • aprs: send an ack-requested frame once per attempt, without a blind repeat copy (30d100b3)
  • mesh: tell the radio before closing its port, and pace writes like the official client (bd6c8163)
  • aprs: an unacknowledged relayed text is sent again and then moves to SMS (da5401fc)
  • cellular: a modem command can only act on the session it was queued to (bb7da1ae)
  • mesh: keep DTR up when the radio’s port closes, and report the radio’s reboot count (df1d1add)
  • mesh: retry the handshake until the radio sends its node info (89cb4a7c)
  • mesh: count a silent handshake as a silent radio so the hub-port cut comes first (5c9d9e90)
  • ui: keep the compact battery chip its width when the pack drains on mains (da01f5e4)
  • aprs: listen before talking on every APRS transmission (c4bcc9d1)
  • ups: halt before the X1202 cuts out and flag a pack draining on mains (f1b869aa)
  • mesh: cut a silent radio’s hub port at once and stop zeroing the radio’s own node entry (24b61a97)
  • kiosk: rebind the touch controller when its probe misreads the config (5337b5cd)
  • time: drop docker.socket from the clock guard ordering, it was deleting Docker’s start job (424fa40b)
  • deploy: pass MESHSAT_API_RATE_LIMIT through compose so it can actually be set (c5eacaf2)
  • aprs: the beacon and the message no longer keep the same cadence (37f4a3b6)
  • health: a probe that never returns can no longer freeze the heal ladder (3f4f4798)
  • hub: keep retrying a first MQTT connect that failed, and stop paying for the fallback afterwards (215c024b)
  • kiosk: the booth screen survives a recycle, and no recycle fires at power-on (09a7d61c)
  • ci: read the pushed digest from buildx’s metadata file, not from imagetools (b72eb035)
  • delivery: a bearer that is down for a moment no longer kills the message queued to it (58fbe0f7)
  • deploy: a deploy is green only when the kit runs the image the pipeline built, and it survives a dropped SSH session (d7caf601)
  • time: the modem’s unset clock reads as 2070, not 1970, and the unit’s Documentation line was not a URL (73778e82)
  • spectrum: LTE bands scan in one hop and calibration is sample-driven, so cellular jamming detection calibrates instead of burning a core forever (e3eb692e)
  • web: booth route tap times out and says “failed” instead of hanging; kiosk idle dim after 3 min (be6c92a7)
  • web: T-Deck Plus photo under a new name so the kiosk browser drops the cached SMA version (5ee788fa)
  • aprs: keep a KISS frame the PicoAPRS closes with a stray FESC, count it as repaired (0392aa74)
  • aprs: a bad KISS frame is dropped and logged, the TNC port stays open, and the beacon wait is jittered (0f8ea2c0)
  • x1202: the battery reads 100 % on mains, the monitor learns the pack’s own full point from the fuel-gauge plateau (da4cd6c6)
  • ttc: the booth screen draws a relayed text from the inbound event, not from the encrypted frame (c563581e)
  • spectrum: an RTL-SDR that appears after startup is attached without a restart, and its hard reset tries the hub port cut first (f275ecc4)
  • mesh: the two kit radios no longer loop NodeInfo requests across the split channels (ccad4d9a)
  • sos: the dead man’s switch was never wired into the shipped binary (8371faf0)
  • zigbee: the interface scan no longer re-probes ports a transport already owns (38a03edc)
  • kiosk: the bridge comes back after a power-on, and the kiosk follows it (06ebbe3f)
  • ttc: the route rows fit the panel, and every glyph sits on its wire (6ad829d7)
  • kiosk: one autostart for both kits, and stop the installer flipping the panels (124aab43)
  • ttc: shorter satellite lane text so it fits the right-hand kit’s lane (f04fa41c)
  • ttc: the booth flow rules are ingress rules on mesh_0, the relay convention the dispatcher evaluates (41deb0f6)
  • gateway: shutdown skips a gateway still being created instead of crashing on the nil sentinel (a6bc9c8c)
  • failover: a member served by a connected gateway counts as online; the booth group picked SMS over a healthy APRS (b265c06f)
  • aprs: status beacons are liveness only, never an inbound message or a booth-screen trip (eab9283f)
  • gateway: inbound receivers run under the manager’s context, not the restarting caller’s (56e2f9b8)
  • web: TTC panel audit round two, composer journeys, housekeeping frames, replay caption, spectrum skip (2d385983)
  • web: TTC message box never squeezes the drawing on the panel, three lines at most (30882d63)
  • web: operator dashboard’s four glance rows fit above the bottom nav on the 7 inch panel (4bf72736)
  • web: TTC mode designed for the panel’s real viewport, 853x480 CSS px at scale 1.5, and immune to the NVIS theme (eadfabd3)
  • web: TTC outbound dot takes the lane of the delivery that actually carried it, SMS lane lights (2c5d6d72)
  • imt: Subscribe stops the previous loops and each loop closes its own done channel (7f00015c)
  • imt: JSPR reader stop is idempotent, Close drops the connection; bridge died with close of closed channel (bc570c8c)
  • cellular: SMS history stores the decoded text of encrypted inbound SMS (ab3816de)
  • database: apply SQLite pragmas with modernc syntax, kits ran a rollback journal (f78ef651)
  • cellular: open the T-Call with DTR and RTS low and equal; the old DTR-only clear held the ESP32 in reset (ff4e487d)
  • health: manual rungs outlive the HTTP request, USB reset hits the device not its hub, ZigBee ladder covers a missing gateway and a dongle off the bus (4281b6ca)
  • health: GPS liveness on any NMEA sentence, RTL-SDR warm-up tolerance and real recovery (fa172635)
  • aprs: receive watchdog survives a bridge restart, gateway list carries the receive fields (7e452cf5)
  • aprs: preflight sets the AIOC capture gain at every Direwolf start (default 94 %, MESHSAT_AIOC_CAPTURE) (0bf00145)
  • gateway: StopGatewayInstance leaves a starting instance alone instead of dereferencing the nil sentinel (8151189c)
  • oob: a level-3 reset of an interface restarts that interface itself 10 s after the power cycle (5718ac64)
  • oob: host agent addresses hubs by exact location so the USB 3 half of a dual hub is switched too (d01ab8f8)
  • transport: mark every serial, USB and GPIO descriptor close-on-exec (84be51be)
  • cellular: refresh the registration state on every signal poll (b84af42d)
  • oob: e2e driver never resends a mutating request after a lost response (c0177267)
  • oob: target levels as JSON ints; deploy never removes the bridge for a missing image (75994831)
  • sdd: reword CGO prohibitions so they stop tripping the CGO gate (4362a73e)
  • sdd: recount PROJECT.md metrics and pin the SDD validator (34a5d5f2)
  • claims: remove dead interfaces and correct capability statements (bcfd7c38)
  • bond: startup self-heal for stale auto bond labels (25db776a)
  • bond: preserve human-authored bond labels across member changes (8a70e266)
  • dashboard: 5 Active Comms audit fixes (79f502fb)
  • demo: hard 28s deadline on iridium dispatch so demo run always completes (064594e5)
  • dashboard: clean up mesh widget state + drop misplaced Channel Health (75facb41)
  • routing,transform,keystore: three demo-follow-up defects (f88c9a06)
  • dashboard: gate touch drag-reorder to grip handle only (7f4fdf27)
  • dashboard: count bridge publishes that Hub converts to CoT as TAK msgs_out (d697788d)
  • dashboard: TAK/CoT widget shows live Hub-relayed counters (fd42256f)
  • ble: meshsat-ble-addr-pin systemd unit was hanging on btmgmt without TTY (a7a86750)
  • ble: accept LE-only peripherals in bluetooth connect handler (f5399469)
  • web: persist kiosk flag in localStorage so reloads after route nav stay kiosk (4b88eb60)
  • mesh: make Meshtastic config handshake timeout configurable, default 60s (7e00b9c9)
  • transport: 3-way probe cascade with DTR guard on all probes (b19ad79d)
  • cellular: read live connection state from transport in Status() (e988161b)
  • hemb: ax25 bearer recognised as free so HeMB bond allocates symbols to it (52e467ca)
  • routing: TCPInterface.Send errors when no peers (8c8595d3)
  • hemb: document mesh MTU=100 as the field-verified working value (5dd7dbe0)
  • hemb: length-prefix bond payload to survive RLNC zero-pad (07bfd165)
  • iridium: open OnOff as tri-state input, pulse via Reconfigure (5a66c397)
  • hemb: TUN bonder mustn’t overwrite the bond-decrypt bonder (e047b23f)
  • hemb: mesh bearer MTU 237→230 so LoRa SF7 doesn’t silently drop (c59b60bd)
  • iridium: omit unset NetAv/RI timestamps from API response (e2b58d13)
  • aprs: show regulatory notice before enabling encryption (dd15102a)
  • spectrum: classic SDR palette + aligned legend, dark noise floor (e2720bf3)
  • shell: kiosk session ignores localStorage shell override (dc4a8663)
  • spectrum: per-band crop pad + 20 dB gain stops sidebars and saturation (fa4fd226)
  • spectrum: waterfall palette uses fixed dB offsets, not MAD scaling (ca14a429)
  • spectrum: band-level waterfall palette, 1 dB gridlines (7038a7ab)
  • spectrum: bump scan context timeout 30s → 90s (44243230)
  • spectrum: scanner never demotes to legacy rtl_power (78f07e7b)
  • spectrum: seed waterfall from latest N rows, not last 5 min (b856670b)
  • spectrum: persistence retries forever, no permanent self-disable (a24ab9da)
  • spectrum: widen scan to crop Hann edges + swap trace Y-axis to row min/max (a0964526)
  • spectrum: stop rendering per-bin FFT noise as rainbow snow (3060e16a)
  • hemb: trim RLNC zero-padding to IP tot_len before TUN write (5c56f6d0)
  • hemb: default non-zero LossRate per iface so bonder includes every bearer (d6ab6c52)
  • hemb: route all bearers through Reticulum registry, size by real MTU (9617fc26)
  • dashboard: iridium_0 short label SBD not Sat (43af9183)
  • dashboard: HeMB tile: dynamic subtitle + count-aware sizing (6e12968a)
  • dashboard: ifaceOK consults Reticulum registry for tcp_/ble_/mqtt_rns_ (369da520)
  • hemb: unblock multi-bearer send + auto-rebind on bond change (70eca2ae)
  • tcp: link-local-aware dialer for WiFi-Direct IPv6 peers (af4b87af)
  • tcp-iface: default listen :4242 in standalone mode (3714194c)
  • wifi-p2p: bind role → go_intent deterministically (8d5075ce)
  • wifi-p2p: pass WPS display/keypad role to p2p_connect (6378e828)
  • wifi-p2p: PIN-only pairing, PBC disabled (d1dc20cc)
  • ui: auto-probe WiFi capabilities so P2P Find button enables (d13feb7d)
  • wifi-p2p: retry p2p_peers for fresh-supplicant race (331f1bd5)
  • wifi-p2p: ensureWpaSupplicant before wpa_cli on USB dongles (78f8f7e9)
  • wifi-p2p: exclude p2p-dev-* mgmt iface from active-group detection (638a4890)
  • ifacemgr: device_type ↔ channel_type alias unblocks auto-bind (940295c9)
  • devices: merge supervisor+bindings lists, filter Pi 5 BT UART (85fc630b)
  • ui: bind dropdown + scan dedup + mode selector (599e9c51)
  • devices: ambiguous VID:PID + WiFi scan auto-up + Devices→WiFi surface (f9c0b8a2)
  • ui: Settings tabs wrap, main nav shows scrollbar (ba36c029)
  • wifi-enum: classify USB via device/subsystem, not path scan (ccc26400)
  • federation: return [] not null for empty peers list (ec1fbddc)
  • ui: match WiFi + BLE handler response shapes (84a9cfee)
  • image: add standalone-mode pragma to Dockerfile apt block (254c775c)
  • dashboard: operator mesh tile keys off radio state, not peer activity (9c6f8e0f)
  • kiosk: remove duplicate swayidle in session launcher (00f10277)
  • dashboard: touch-event drag-reorder for widgets (3e92ef7c)
  • spa: inputmode + enterkeyhint hints on every input (4ea7b91f)
  • spa: 40/48 dp tap-target floor for buttons (b4cbbf8b)
  • spa: checkbox row-as-target in InterfacesView (88972e90)
  • spa: narrow-screen textarea defaults (8340d525)
  • install-kiosk: escape & in sed replacement for BRIDGE_URL (39ef35de)
  • x1202: in-place write preserves inode for bind mount (24c9f185)
  • dashboard: compact mission tile + inline orange TEST SOS (60b0cfdd)
  • dashboard: tighten operator tile padding for 480px viewport (d9a06224)
  • dashboard: operator row 1 (state+SOS) + row 3 (GPS/Batt/Queued) (389eed71)
  • dashboard: include APRS in operator channel count (6e1cf10c)
  • dashboard: operator-specific glanceable view (b1b9a0f3)
  • kiosk: 7" polish pass: bump chrome labels + nav tap targets (1d7014f5)
  • kiosk: bottom tab bar overlap + quote autostart URL (648961b6)
  • kiosk: decouple kiosk chrome from shell role (66285abb)
  • kiosk: generate blank xcursor binary with python, drop xcursorgen dep (e42b7228)
  • kiosk: install blank xcursor theme: compositor draws 0 visible pixels (6f36dfd0)
  • kiosk: restore @media(pointer:coarse) cursor rule + force touch-events on (856fdf74)
  • kiosk: hide Wayland compositor cursor via labwc cursorSize=1 (62f87872)
  • kiosk: wait for bridge /health before chromium + tighter scrollbar hide (1882cc18)
  • web: hide cursor + scrollbars via html.shell-kiosk class (284fe3dd)
  • web: hide scrollbars on touch-primary devices (alongside the cursor) (796d4b14)
  • web: hide mouse cursor on touch-primary devices (f3665437)
  • kiosk: labwc + wlr-randr + udev touch matrix: working on Pi Touch Display 2 (86643f48)
  • kiosk,web: Raspberry Pi Touch Display 2 (720×1280) support (6953a480)
  • web: engineer mode uses new views + Pi 7" touchscreen compat (6c4104a7)
  • aprs: track every AX.25 source, not only APRS-formatted payloads (5181ba40)
  • spectrum: auto-demote rtl_power_fftw → rtl_power on sustained failure (4c756243)
  • web: service worker: network-first for SPA shell + SSE passthrough (ee6a8012)
  • web: Operator ‘…’ overflow menu: teleport out of nav clip rect (49e5e45a)
  • map: load leaflet.markercluster after leaflet resolves (688fe45e)
  • deps: pin go.mod to 1.24 + downgrade x/crypto x/sys x/sync x/text (b2d82792)
  • web: modal max-width full on mobile, constrained on sm+ (d7b4d7df)
  • web: dedupe NVIS toggle: keep only the StatusStrip copy (3ad50457)
  • app: pass empty precedence to QueueDirectSend in Hub cmd handler (f4f58e46)
  • transport: add Precedence field to SendRequest (9292f174)
  • api: plumb precedence through /api/messages/send (44463fe5)
  • signing: wrap Ed25519 private key at rest under master key (ce23e339)
  • ax25: auto-reconnect to KISS TNC after read error (24f94749)
  • aprs: Option-B provider, OTA TX/RX counters, richer connected (935eaea6)
  • aprs: detach supervisor ctx from HTTP request + SIGINT on stop (6d68cbcc)
  • aprs: use PTT CM108 + ARATE/TXDELAY/TXTAIL to match field kits (93bb2c52)
  • aprs: KISS loopback-only + surface supervisor state (82e14076)
  • dispatcher: add WaitGroup so tests can drain workers before db.Close (37a4773a)
  • Dockerfile: install libtclap-dev:arm64 (not native) for cross-compile (a962d74b)
  • hemb: de-flake TestGF256Consistency: retry on rank deficiency (7e5ff77f)
  • spectrum: skip NaN/Inf in stats + floor std to 0.5 dB (149921b7)
  • Dockerfile: install librtlsdr to /usr/local so pkg-config+RPATH match runtime (465d6f2b)
  • Dockerfile: pass explicit -I/-L for rpfftw cross-compile (fde5e393)
  • Dockerfile: point rpfftw pkg-config at /out/usr/local/lib/pkgconfig (cbe18ebb)
  • spectrum: switch to rtl_power_fftw: async multi-URB read works on V4 where rtl_power’s single-URB sync read hangs (79c05d90)
  • Dockerfile: correct patch sanity check grep pattern (84978cff)
  • spectrum: correct rtl_power patch: unified-diff blank line needed leading space (026249af)
  • spectrum: patch rtl_power to call rtlsdr_reset_buffer: fixes V4 hang (8f770192)
  • spectrum: bump scan timeout 12s->30s for Blog V4 driver cold start (3d7ca7ea)
  • Dockerfile: point pkg-config at arm64 multiarch dir for cross libusb (049eb924)
  • Dockerfile: build rtl-sdr-blog in Debian c-builder (native cross) + Debian runtime (816e4ad6)
  • Dockerfile: serial rtl-sdr-blog build: QEMU GCC segfaults under parallel make (0f41f76b)
  • spectrum: build rtl-sdr-blog fork: stock librtlsdr hangs on RTL-SDR Blog V4 (ce60a875)
  • spectrum: bump rtl_power scan timeout 5s->12s (GPS+LTE were SIGKILLed) (dce52419)
  • zigbee: gwmgr restart retry ladder + silence sysfs-RO unbind noise (cfdffff9)
  • spectrum: seed store from /api/spectrum/status so UI shows bands during calibration (17bb9421)
  • zigbee: unbind/rebind cp210x driver: deeper recovery than USB reset (3c590305)
  • zigbee: use unicast self-permit-join: broadcast rejected with 0xC2 (4c1332af)
  • zigbee: supervisor → manager rebind race + re-enable watchdog (15f388dd)
  • zigbee: disable stuck-read watchdog: recovery race breaks gateway (511491bd)
  • zigbee: watchdog false-positive: track readLoop iterations not bytes (9a1bf6f5)
  • zigbee: humidity scale: Tuya /10 quirk fallback (75c27625)
  • zigbee: stuck-read watchdog: auto-USBDEVFS_RESET when cp210x wedges (1383dbc0)
  • zigbee: e2e spec polish + history endpoint normalises empty slice (dc8b3c2d)
  • zigbee: USBDEVFS_RESET to escape stuck cp210x state on re-init (9c7cc1f8)
  • zigbee: close+reopen serial port on re-init to escape stuck read (8baae9d5)
  • hemb: de-flake TestEncodeDecodeRoundtrip: retry on rank deficiency (7d7d9596)
  • zigbee: poll UTIL_GET_DEVICE_INFO during init (AREQ-less firmware) (c95c5fa2)
  • zigbee: release z.mu around initCoordinator to unbreak startup (c5a39f38)
  • zigbee: wait for DEV_ZB_COORD + cache port probes to stop dongle resets (3aa4d639)
  • zigbee: show permit-join errors in UI instead of silent swallow (b1ca25c0)
  • zigbee: skip unsolicited AREQs when waiting for permit-join SRSP (eb4502f4)
  • zigbee: serialMu prevents readLoop from stealing ZNP responses (db0727cf)
  • aprs: filter Reticulum frames from APRS parser + add APRS badge (e2a64d1d)
  • aprs: count RX/TX at KISS connection level, not per-consumer (33dc5e3f)
  • cellular: IMEI URC leak + SMS counters in dashboard (fcc0555f)
  • aprs: wire RecordTX() into sendMessage for TX counter (4a8bb1b1)
  • web: remove leftover constellation refs breaking Passes page (577ad60a)
  • cellular: retry PIN verify for 30s instead of fixed 5s wait (98fc6ae7)
  • cellular: permanently disable SIM PIN after first unlock (7c93df45)
  • imt: use GPIO chardev ioctl for I_EN reset (no gpioset binary) (2cb35e45)
  • imt: cycle I_EN GPIO to reset JSPR state on connect (dc414210)
  • imt: flush JSPR state via direct serial before starting helper (1295f4ff)
  • imt: flush modem JSPR state before handshake on reconnect (f6dd4ce6)
  • cellular,zigbee: increase AT timeout to 60s, add ZNP probe retries (689ec875)
  • zigbee: increase ZNP probe settle delay to 1.5s for DTR-triggered boot (50bd86ff)
  • supervisor: fix gateway startup ordering and ZNP probe DTR reset (265ee5a0)
  • supervisor: fix startup race and skip JSPR on ACM devices (3ce266ec)
  • supervisor: fix device detection for all field kit transports (230130fe)
  • supervisor: add Seeed XIAO ESP32-S3 VID:PID to Meshtastic auto-detect (f1159b37)
  • cellular: wait 30s for T-Call ESP32 cold boot before AT check (273ed7a1)
  • web: repair duplicate class attrs in PassesView after Astrocast removal (6513b1cf)
  • api: increase API rate limit default from 300 to 600 rpm (198432dc)
  • mqtt: add ResumeSubs and OrderMatters for QoS 1+ in-flight persistence (435ac349)
  • hemb: skip TUN tests in CI environment (88c23f1f)
  • hemb: skip TUN tests when device unavailable in CI (a660a302)
  • mqtt: persist sessions and retry subscriptions on broker reconnect (520521f2)
  • tak: import api client in DashboardView for Via Hub detection (e0ea50b4)
  • tak: restore missing Vue imports in TakView (useMeshsatStore, ref, computed) (1b1f1750)
  • tak: add GeoChat + 9-Line tabs, fix Playwright test labels (209fc16c)
  • tak: remove extra </div> breaking Vue SFC template (771615ac)
  • tak: clean up duplicate GeoChat/9-Line template injections (4d4f64fb)
  • test: E2E mock TAK server skips version negotiation messages (f9f7de44)
  • resolve 3 pre-existing test failures (26f3cf04)
  • cellular: A7670E SMS ME storage + polling fallback (b1494672)
  • cellular: reduce AT+CSQ timeout to 3s: unblock I/O loop for URCs (2a9f6d23)
  • cellular: extract +CMTI URCs from AT response buffer (77ccce40)
  • hemb: re-inject decoded HeMB payload into DispatchAccess (8eab9796)
  • db: KeyBundleRow.ExpiresAt nullable: prevents key lookup failure (c2a841f8)
  • processor: apply ingress transforms before messages DB persist (5e64c3a2)
  • imt: improve L4 Reticulum classifier: reject ASCII plaintext (023fa15a)
  • imt: L4 payload classification: split Reticulum vs app MT queues (8a20dce6)
  • imt: persist MT messages to DB and forward to inbound channel (35e7e271)
  • imt: MT receive pipeline verified working: keep INFO logging (daf3632d)
  • sms: apply egress transforms on SMS send API (fa48bf6d)
  • keystore: use MaxKeyVersion to avoid UNIQUE constraint on StoreKey (3e1f99ab)
  • transport: wake mesh processor immediately on port assignment (2a3e061e)
  • transport: probe serialization + auto-PIN unlock for Huawei E220 (4c2f74d8)
  • hemb: widen stream ID to 8-bit + clean up decoded generations (1832e4f5)
  • hemb: use global stream sequence to prevent generation ID collisions (f8c0e475)
  • hemb: fix SendViaBondGroup bearer priority to match DispatchAccess (15871a1d)
  • hemb: detect HeMB frames inside Reticulum data packets (51c7bf50)
  • hemb: route mesh bearer via Reticulum transport node, not raw PRIVATE_APP (f353e29f)
  • hemb: commit linter additions: GaussStep, arrival tracking, matrix inspector (732a36ba)
  • hemb: global stats aggregator, bearer contributions, N=1 regression (c450de32)
  • ui: adjust viewport offset to 90px for nav + status bar height (804f0849)
  • ui: constrain topology view to viewport with calc(100vh - 48px) (36b04bac)
  • ui: use flex ratio for graph/table split to prevent viewport overflow (f106124f)
  • ui: fix layout overflow + inline flow table with bridge events (7fdb8db6)
  • ui: fix undefined template refs in ObservabilityGraph bridge node (5ae67b23)
  • ui: add null guards to all computed array accesses in ObservabilityGraph (8a097839)
  • ui: null safety in ObservabilityGraph computed properties (d678cf74)
  • hemb: fix ref unwrapping in bearer graph and flow table (6f4735bc)
  • hemb: fix ref unwrapping in bearer graph computed property (7cc98728)
  • hemb: dynamic bearer resolution for any interface type (97fb92bd)
  • hemb: add mesh_0 fallback in bond group bearer resolution (dc5ae655)
  • docker: add libc6-dev-arm64-cross for aarch64 cross-compilation headers (9eb5ce09)
  • docker: cross-compile C helper to avoid QEMU GCC segfault on ARM64 (30fa6b13)
  • channel: update test for IPoUGRS channel descriptor (10 channels) (1f619059)
  • build: commit local fixes: MQTTReticulumPrefix renamed, announce relay signature (19c5a6ea)
  • rlnc: trim padded segments to actual size during RLNC reassembly (512ab3e2)
  • critical: stop time sync flooding satellite SBD: exclude paid interfaces (5a5e34b7)
  • routing: dispatch time sync packets before Reticulum header parser (c823c974)
  • hub: remove CA PEM from bridge UI, fix clearing logic (a034dc61)
  • hub: include Meshtastic in health + birth interface list (07588ba6)
  • mesh: synthesize user_id from node number when NodeInfo is unavailable (8f3d67ea)
  • mesh: merge config-download nodes instead of full-replace to preserve OTA-learned identity (b3caac80)
  • routing: DB-persisted listen port overrides env var on startup (bdf85f22)
  • ui: bridge UI polish: error parsing, responsive badges, settings forms (18207a3f)
  • ui: suppress raw JSON error on Interfaces health scores (b154dda2)
  • transport: probe ACM ports before claiming as Meshtastic (ddb3fdfd)
  • dashboard: show pending DLQ items and label SBD/IMT separately (9458228a)
  • iridium: track last mo_status in DLQ to prevent false-positive sent marking (0a94c654)
  • hub: wire command handler and burst queue in main.go (c2cdd680)
  • gateway: align supervisor instance IDs with gateway type naming (b7fd3d6b)
  • gateway: prevent duplicate instances when fewer transports than DB configs (e6566bd4)
  • ci: make HAL recreation non-fatal in deploy script (3d0b9ce6)
  • ci: scope migration lint to migrations.go diff section (5b2bc699)
  • imt: fix consecutive MO: remove aggressive buffer reset, add early timeout (dd767a94)
  • imt: rewrite jspr_helper.py to single-thread event loop with bulk reads (d503debe)
  • imt: use USBDEVFS_RESET ioctl for USB reset inside Docker (628624c9)
  • imt: add USB device reset when JSPR handshake fails (4e848ab3)
  • imt: fix MT receive: persistent rx buffer + mt_received event handler (c49c7bef)
  • gateway: give iridium_imt its own interface ID for delivery routing (247677a1)
  • imt: fix bridge serial connection to RockBLOCK 9704 (a6ba1535)
  • imt: only block stdin_thread writes during active MO, not all sends (026d06ca)
  • imt: block serial writes during MO flow in jspr_helper.py (241d65ec)
  • gateway: map iridium_imt gateway to iridium interfaces in syncIfaceMap (503a4ef2)
  • api: resolve gateway type to correct interface ID from DB (17c526dc)
  • api: route /api/messages/send through delivery ledger, not outCh (de688743)
  • imt: increase helper MO timeout from 120s to 240s (35267026)
  • imt: touch lastRead before MO send to prevent watchdog kill (d1c8f165)
  • ui: show IMT messages in queue widget, fix satellite label (f44696e6)
  • ui: use live modem type for Iridium widget title, not stale DB label (ebd04453)
  • imt: production cleanup: API/UI wiring, MT flow fix, debug removal (fb565a22)
  • imt: proper threading.Lock for serial read coordination (80ac63b9)
  • imt: fix MO helper serial thread race + code 0 rejection (fcfaf828)
  • imt: move MO segment exchange into Python helper for inline response (51ac3e4b)
  • imt: chmod 755 jspr_helper.py in Dockerfile (f7107a26)
  • imt: add execute permission to jspr_helper.py (001a6f98)
  • imt: add jspr_helper.py to repo for Docker build (74be93eb)
  • imt: restore helper subprocess, fix watchdog + write timeout + Python helper (145a2094)
  • imt: replace jspr-helper subprocess with direct Go serial I/O (50a2b673)
  • imt: O_NONBLOCK + select() + read() with TCSETS2: C library pattern (4e46e31c)
  • imt: probeJSPR uses raw fd + TCSETS2 for correct 230400 baud (f99fca7d)
  • imt: use VMIN=1 VTIME=0 like minicom: block in read() permanently (9ec7101a)
  • imt: stop calling TCSETS2 on every read: set termios once like minicom (e88aebe6)
  • imt: use blocking read() with VTIME: FIONREAD polling breaks URB chain (352167ba)
  • imt: use TCGETS2/TCSETS2 for 230400 baud: TCSETS silently fails on ARM64 (8b7eef53)
  • imt: FTDI workarounds: latency 1ms, autosuspend off, serial watchdog (235e8530)
  • imt: use FIONREAD polling for reads: select/poll/epoll all fail on ftdi_sio (ed38e551)
  • imt: match C library read timeout (500ms) and fix readOneLine early exit (735bca56)
  • imt: match official RockBLOCK 9704 C library serial exactly (9f3a0393)
  • imt: switch from poll() to ioctl(FIONREAD) for serial reads (c53a0abe)
  • imt: switch rawSerialPort from epoll to poll() syscall for serial reads (c8c066f2)
  • imt: replace go.bug.st/serial with rawSerialPort for JSPR to fix reader hang (bdcacbc8)
  • imt: restore active GET constellationState signal polling (44091171)
  • imt: re-set serial read timeout after each write in reader goroutine (22224000)
  • imt: single-goroutine serial I/O: write via channel to reader (d0010bc6)
  • imt: serialize serial port R/W via writeMu to prevent reader hang (356b6777)
  • imt: persist partial line buffer across readOneLine calls (dd0e4e98)
  • imt: use correct JSPR target ‘messageProvisioning’ (not ‘checkProvisioning’) (09ada64d)
  • api: route /api/messages/send to satellite gateway when gateway field specified (f322b6f8)
  • hub: wire HubReporter into main.go startup path (1abae276)
  • imt: event-driven signal polling per official RockBLOCK 9704 C library (3bc40cf9)
  • cell: increase AT+CPIN timeout to 30s for ATdebug firmware (142ed985)
  • transport: JSPR probe retries, signal recorder transport selection, IMT signal preservation (ddd9c18f)
  • main: signal recorder wired to IMT transport in main.go, not just app.go (ad2daeb6)
  • transport: 2s timeout for constellationState, record 0 bars on timeout (d71dd4bc)
  • engine: signal recorder polls GetSignalFast instead of Subscribe (85353540)
  • engine: signal recorder uses active satellite transport, not hardcoded SBD (ee0d11f6)
  • dashboard: Iridium widget finds either SBD or IMT gateway (48287320)
  • api: /api/iridium/* endpoints auto-select active satellite transport (d143d798)
  • transport: match official C library JSPR JSON format with spaces (4f9b8d05)
  • transport: JSPR handshake retry + accept error responses with generic targets (606c0281)
  • gateway: auto-create config on device_connected, not just at startup (c378ae70)
  • ci: deploy job fails when device is unreachable instead of faking success (968340c4)
  • transport: accept any JSPR response as proof of 9704 device (7f6a7f8e)
  • api: prefer cached signal in /api/cellular/signal too (1559a418)
  • transport: use ‘supervisor’ sentinel to fully disable transport auto-detect (fc3b7015)
  • transport: disable transport auto-detect when supervisor is active (c02e352f)
  • gateway: reconcile DB configs with actual hardware at startup (0a8be9f1)
  • transport: always register both satellite transports for dynamic hot-swap (2bab7402)
  • gateway: wire device event watcher in main.go and fix swap event gap (9f4bc7c9)
  • transport: fix critical device hot-swap detection in supervisor (40b9e4f7)
  • gateway: prevent false-positive MO buffer check on first DLQ attempt (95025f0b)
  • transport: include ttyAMA* in device supervisor scan patterns (fe2853f2)
  • transport: check cellular VID:PID before ambiguous handler in supervisor (9a1b72f0)
  • transport: don’t hold mu during JSPR connect to prevent Subscribe deadlock (27928e30)
  • engine: skip initial scanDevices() to prevent startup hang (fe1c6cf8)
  • deploy: stop meshsat before HAL recreation to prevent stale serial fds (2456b6b3)
  • transport: prefer unambiguous VID:PID in Meshtastic auto-detect (4c956471)
  • deploy: use sudo for compose file sed injection (a6ac6675)
  • deploy: force-stop HAL container before recreate to prevent removal error (cf40ff8e)
  • transport: make GetStatus and GetSignalFast non-blocking on IMT (858631ea)
  • deploy: add mule per-device env for RockBLOCK 9704 IMT port (6b23ae6c)
  • deploy: inject env vars directly into compose environment section (6340a3ac)
  • deploy: always regenerate meshsat.env per device, not just on first run (1a554cca)
  • deploy: pass DEPLOY_TARGET to ci-deploy.sh for device identification (d3e31977)
  • deploy: auto-create per-device meshsat.env and inject into compose (efd4552d)
  • transport: retry IMT probe at startup with 2s delay (8be3be8d)
  • transport: probe for 9704 at startup, fall back to 9603 SBD (0633b2f2)
  • proto: add from field and remove empty payload in RequestNodeInfo (32a57e08)
  • ui: show node/contact names instead of raw IDs in Comms view (22422b75)
  • proto: correct ChannelSettings field numbers to match proto spec (e012a468)
  • proto: use correct AdminMessage field 33 for SetChannel (1b24cc71)
  • cell: strip ATdebug ANSI output from AT responses (f0cd9516)
  • cell: correct T-Call VID:PID and add multi-device deploy (e795cd4d)
  • astrocast: rewrite Astronode S codec to match official ASCII hex protocol (2cbebdff)
  • routing: correct HDLC escape byte to 0x7D per RNS spec (d8009ea7)
  • mqtt: fix subscribe error handling and add retry on reconnect (063c56d5)
  • db: restore append-only migrations (v30-v35) removed by revert (fe818fdf)
  • geofence, health score, and MSVQ-SC codebook fixes (2f9b99a5)
  • api: add missing rockblock webhook handler and device tests (1c980ffe)
  • add PDU mode fallback decoder for SMS reception (3c63bede)
  • apply ingress transforms before dispatching forwarded messages (1f7309a1)
  • wire HealthScorer, DeadManSwitch, BurstQueue, GeofenceMonitor into app startup (49ab464d)
  • ci: install nodejs in build stage for web frontend compilation (b1b113ec)
  • ci: eliminate QEMU arm64 Go build from Docker: use pre-built binaries (c30092b7)
  • delivery: remove legacy workers, fix TTL reaper for held deliveries (1894f35e)
  • web: double-height queue widget, 6h cell signal history, contact name priority (d6bc6f55)
  • iridium: sane retry limits and startup cleanup for runaway deliveries (0e3f022b)
  • iridium: custom SBDIX response reader to skip binary preamble (5845e6b7)
  • iridium: prevent duplicate SBD sends from serial bus contention (979f5c4a)
  • web: SMS conversation view, dashboard queue fix, dedup (729c5788)
  • cellular: encrypt only message text for SMS, not full JSON payload (9590ba4b)
  • cellular: select correct USB interface for Huawei AT commands (512586a0)
  • transport: reset t.running on ioLoop exit to allow serial reconnect (264a3095)
  • cellular: add SMS raw function debug logging (1cc0c2df)
  • cellular: add GSM 7-bit SMS text sanitizer (13a51a5f)
  • transport: set AT+CMGF=1 before each SMS, improve SBDWB drain (40871fe3)
  • dispatch: fix 4 bugs in delivery pipeline (118e292d)
  • cellular: prevent goroutine leak when transport not ready (b820e1bb)
  • cellular: improve SMS CMGS response handling for Huawei E220 on 2G (17009f12)
  • cellular: force serial reconnect on command timeout (631193cb)
  • cellular: robust SMS send with AT probe and post-send settle (acdc1f9d)
  • iridium: drain serial buffer between SBDWB and SBDIX (80d6e0bb)
  • cellular: fix SMS sending: plaintext, sync delivery, 2G timeout (ebd1bf52)
  • dashboard: show all channel deliveries in message queue widget (0478fd52)
  • meshsat: expose transform fields in interface status API (caef1392)
  • meshsat: properly drain Swarm stack before compose deploy (9ed1bee2)
  • meshsat: detect ISU autonomous transmit via SBDSX MO buffer pre-check (8f43d428)
  • meshsat: add timeout to cellular AT command/SMS execution, prevent ioLoop hang (784501ac)
  • meshsat: add 5s timeout to cellular/iridium signal API endpoints (85783f7f)
  • meshsat: cellular widget bugs, remove SMS section, fix map rendering (b1573485)
  • web: remove undefined rules export, delete orphaned components, fix node.id in messages (610faf04)
  • web: remove dead /api/rules, fix map node IDs, migrate Bridge to access-rules (7ec74d93)
  • transport: iridium auto-detect prefers VID:PID over AT probe, skips cellular (eeb1e6fd)
  • ci: deploy always uses standalone docker-compose, never Swarm (992492cd)
  • meshsat: enrich cellular status DB fallback with cell_info and signal data (4738f7c2)
  • meshsat: cellular API fallback to DB when transport unavailable (36cd9209)
  • meshsat: add immediate first signal poll and remove debug logging (a3593a8e)
  • meshsat: use AT+COPS? for Huawei E220 cell info (MCC/MNC/AcT) (1e93d48a)
  • meshsat: enrich CREG cell info with cached network type (83337806)
  • meshsat: add AT+CREG? fallback when AT+QENG unsupported (787dbcc4)
  • meshsat: persist SMS, CBS, cell_info events without CellularGateway (763ad720)
  • meshsat: separate stateMu from serial mu for non-blocking GetStatus (08c99f74)
  • meshsat: skip AT+COPS? when SIM locked + harden readATResponse (1bae2704)
  • meshsat: prevent cellular API deadlock with TryLock + diagnostic logging (f3089e53)
  • meshsat: use wall clock for iridium geolocation observation timestamp (ff9e8344)
  • meshsat: expose GPS satellite count in location widget (2ac063b5)
  • meshsat: time sync all mesh nodes + remove Iridium geolocation (1fb06c3c)
  • ci: false positive in migration append-only check (9a210743)
  • meshsat: signal history clock skew, DLQ max_retries, SBDIX parser (33d8f3aa)
  • use NAME=ASTROCAST Celestrak query (GROUP=astrocast not found) (06193d62)
  • ui: About page: subtitle and all 6 transport channels (31a16bef)
  • ui: update Help and About pages with accurate content (de64e176)
  • 17 bugs from codebase review: backend and frontend (56084ed1)
  • complete HardwareModel enum (126 models) + last message timestamp per node (7d48ad93)
  • remove_by_nodenum was field 96 (exit_simulator), correct is field 38 (41157b5d)
  • protobuf field number mismatches: NodeInfo, Telemetry, User, Position (3629fea0)
  • map color differentiation and Iridium accuracy circle (9f92983b)
  • change AUTO location priority to GPS > Custom > Iridium (54b8340a)
  • clamp AT-MSGEO altitude to prevent broken pass predictions (f9dfb6cf)
  • navbar logo visibility: optimized icon for small display (1b97b39f)
  • resolve high & medium audit issues across dashboard (66977e0c)
  • smart DLQ backoff based on ISU mo_status codes (82034c86)
  • DLQ retry mechanism stops retrying after signal-triggered drain fails (6491d0ba)
  • update GSS sync timestamp on attempt, not just success (149e75f9)
  • restore SBDSX gate to stop empty-MO SBDIX credit burn (5cd8a860)
  • always clear MO buffer after SBDIX attempt, not just on success (553c2b0d)
  • always run SBDIX in MailboxCheck to discover queued MT messages (225d5709)
  • clear MO/MT buffers on connect to prevent stale resend loops (d2ebc697)
  • clear MO buffer after successful SBDIX to prevent stale resend loop (c846e0d7)
  • trigger SBDIX on outbound MO buffer during mailbox poll (3150b642)
  • add mesh reconnect loop, dynamic port exclusion, proper Close() wait (3d5f3432)
  • SSE subscribers return on disconnect event to trigger reconnect (6df62228)
  • revert stty context timeout (causes signal:killed during port contention) (9545f576)
  • restore SBDSX disconnect on timeout (safe now without channel close) (20f70ad0)
  • standalone direct transport 24-bug parity fix with HAL (95ce0621)
  • prevent gateway→mesh→gateway feedback loop on inbound SBD messages (db152fd0)
  • force serial reconnect on SBDIX/SBDSX timeout to prevent stuck connection (3462527c)
  • close SBDSX parse failure fallback that bypassed empty-MO guard (1efa0936)
  • remove stale SBDIX check that sent empty SBD messages every 15min (058c7699)

v0.1.0 (2026-03-04)

Features

  • mode-aware CI deploy (direct vs Swarm) (487527f2)
  • direct serial transport for standalone mode (no HAL required) (89516f11)
  • pass-aware smart scheduler + multi-source location management (fd9b4b93)
  • encoding fix, logo, map messages, node mailboxes, signal overlay (8d2046d8)
  • Iridium operational dashboard + bridge pipeline builder (048e8a64)
  • tactical operations dashboard with 7-panel grid (5bdb5232)
  • node management, message stats breakdown, logo (6e541b39)
  • forwarding rules engine, presets, SOS, delivery tracking, standalone mode (fcc7c80a)
  • Iridium priority queue + offline compose (Priority 3d) (9912bdd5)
  • opportunistic DLQ drain on Iridium signal SSE events (edfde6a3)
  • Iridium signal display with 10s fast poll + refresh in MeshSat SPA (6b8e6fec)
  • MeshSat SPA UX overhaul: dashboard, channels, config forms (f93c3769)
  • add default_destination to Iridium gateway config (a231f07a)
  • Iridium dead-letter queue for failed SBD sends (cab7c718)
  • Phase 4: MQTT gateway, Iridium satellite bridge, gateway management API + UI (72242125)
  • Phase 3: standalone web UI with embedded SPA (f43b069b)
  • Phase 2: admin commands, radio config, waypoints, signal quality (6b8ee491)
  • MeshSat coreapp Phase 1: scaffold, persistence, event ingestion (424a112a)

Fixes

  • parseSBDIX tolerates 5-field responses (mtQueued optional) (ab044f7d)
  • ringAlertListener retry + prevent stale SBDIX on fresh connect (4f199e3c)
  • match HAL’s serial mutex pattern exactly: eliminate SBDIX binary garbage (2533d82f)
  • Iridium gateway shows disconnected despite working transport (492cecad)
  • SBDIX serial race + SBDSX gating in direct transport (bb81063a)
  • pollWorker initial timer race: start with 5s instead of idle interval (1bb80f56)
  • reduce serial contention + deduplicate ring alert handlers (65cb9c99)
  • handle plain-text MT messages from external senders (3f3f67f4)
  • detect piggybacked MT from outbound sends + add mailbox result logging (f102eae9)
  • inbound SBD messages silently dropped when forwarding rules exist (a45e2831)
  • opportunistic DLQ drain bypasses backoff, ring alert retries on failure (c90e1e9f)
  • chart pass colors indigo, Last TX/RX from queue, bulk stale removal (471cfa89)
  • portnum filter on all rule types, historical pass prediction (36b48b8a)
  • check MOSuccess after SBD send, redesign signal-vs-passes chart (5a816577)
  • plaintext SBD for text messages, reduce poll waste (17617e3f)
  • 6 UX/bug fixes: signal, queue direction, inbound SBD, config, message stats, comms (70035ab3)
  • queue UI clarity: sent items show as ‘delivered’ with dimmed style (cd927f44)
  • queue not displaying: API returns {queue:[]} not raw array (885afac9)
  • inbound node selector, queue shows sent messages (11273d45)
  • bridge rules single authority, inbound evaluation, clear UI (43f285f1)
  • overhaul Messages view into tactical comms panel (c4b99651)
  • message flow Y-fork layout for MQTT and Iridium gateways (3b1c8dbb)
  • Iridium SSE backoff: reset on successful connection, lower cap to 5s (2510552b)
  • SSE backoff: reset on successful connection, lower cap to 5s (d3e7973b)
  • processor forwards to live gateway instances via GatewayProvider (6e814397)
  • read HAL_CORE_KEY directly instead of HAL_API_KEY (14ba7013)
  • ci-deploy.sh sources secrets.env for compose variable substitution (2822a3ca)
  • CI dual-IP failover for deploy target resolution (24675666)
  • CI deploy: use service update --force for existing services (fc607c41)
  • add placeholder index.html for go:embed in CI builds (f8ebc903)