R2D2-OPS-Kuma/.settings/features
Joshua Belke 7a3d8dcb66 docs(features): F11 drone MQTT discovery & video-node association plan
Plan + shared mqtt.config.json for subscribing to the office broker's
retained node/description topics: live registry of announced UXVs with
standard-identity/liveness, manual rescan, and a bidirectional alias link
between a drone node and its video feed. Planning only; no consumer code.
2026-07-08 08:59:17 -04:00
..
01-search-and-filter.md docs: refresh monitor/group counts to 118/21 2026-07-07 13:17:22 -04:00
02-holovids-enrichment.md docs(seed): drop Gatus naming from converter + docs 2026-07-08 08:54:59 -04:00
03-alerting-and-escalation.md chore: add R2D2 deployment config (Helm chart, seed, ops, agent settings) 2026-07-06 11:54:10 -04:00
04-rollups-and-mesh-muting.md chore: add R2D2 deployment config (Helm chart, seed, ops, agent settings) 2026-07-06 11:54:10 -04:00
05-deep-probes-and-export.md chore: add R2D2 deployment config (Helm chart, seed, ops, agent settings) 2026-07-06 11:54:10 -04:00
06-native-media-detail-views.md docs(features): add F06-F10 roadmap plans 2026-07-07 10:19:23 -04:00
07-live-stream-recording.md docs(recorder): fix phantom env vars in F07 doc 2026-07-08 00:45:06 -04:00
08-klv-telemetry.md docs(features): add F06-F10 roadmap plans 2026-07-07 10:19:23 -04:00
09-c2-map-cop.md docs(features): add F06-F10 roadmap plans 2026-07-07 10:19:23 -04:00
10-reductstore-media-archive.md docs(features): add F06-F10 roadmap plans 2026-07-07 10:19:23 -04:00
11-drone-mqtt-discovery.md docs(features): F11 drone MQTT discovery & video-node association plan 2026-07-08 08:59:17 -04:00
README.md docs(features): F11 drone MQTT discovery & video-node association plan 2026-07-08 08:59:17 -04:00

R2D2 monitoring · feature roadmap

Plans for turning the seeded Kuma instance (118 monitors / 21 groups, see ../seed/README.md) into something an operator can actually run a production video fleet from. Each file is a review-first implementation plan — read it, push back, then we build. Nothing here is code you have to trust blind; every plan says exactly which existing file it touches and how you'd verify it.

The problem these solve

The public status page (../seed/status-page.png) is a 118-row wall grouped by region. It answers "is the fleet broadly healthy?" It does not answer the questions you actually ask at 2am:

  • "Is ITA.RADON01 up, and what channel/port is it on?" — no search.
  • "Show me only what's DOWN right now." — no status filter.
  • "Which Poland feeds are stalled?" — no facet by region + state.
  • "Did anyone get paged when 6 Italy feeds dropped?" — no alerting wired.
  • "Is that feed actually streaming video, or just returning HTTP 200?" — HTTP 200 ≠ live stream.

Hard constraint that shapes everything

Uptime Kuma's public status page supports Custom CSS only — no custom JS. You cannot bolt a search box onto /status/r2d2 itself. So "search" is not a status-page tweak; it's a small companion read-only app that speaks the same socket.io API the seed scripts already use (statuspage.mjs is the template). The admin dashboard has search, but it's admin-only and not the ops surface we want to hand to a duty operator. This is why Feature 01 is an app, not a CSS snippet.

Roadmap (priority order)

# Feature Headline value Touches
01 Ops Feed — searchable/filterable companion The 2am questions above. Instant search, DOWN-only filter, region/tag facets, thumbnails new ops/ app, reuses socket auth from statuspage.mjs
02 holovids CSV enrichment Exact channel/port/codec/bitrate + snapshot thumbnails on every feed. Unblocks search-by-channel convert.mjs, seed.mjs
03 Alerting & escalation Someone actually gets paged, per-region, without alert storms seed.mjs, notifications
04 SLO rollups & mesh-aware muting Meaningful "N/M live" per region; stop false-DOWN from off-mesh probes convert.mjs, seed.mjs
05 Deep stream probes & metrics export Catch stalled-but-200 feeds; Grafana/Prometheus/RSS feed for downstream probe scripts, Kuma /metrics
06 Native media detail views & GUI integration Native imagery + HLS player + metadata + copy-URL/open-in-VLC buttons per feed; type-dispatched "plugin" detail panels integrating projector/restreamer/TrailBase ops/ app (detail view, hls.js, media proxy)
07 ⚠ Live-triggered recording to disk Multi-select feeds → record to tuf8tb while LIVE; fast liveness, cut clip after 30 s dead; auto region/country/feed tree; storage monitoring ops/ app (recorder.mjs, ffmpeg, disk monitor)
08 KLV / MISB telemetry Decode MISB ST 0601 (platform/sensor/frame-centre/footprint) from the real feed's source TS → telemetry HUD; gated on discovering whether Restreamer strips the KLV data PID ops/ (misb0601.mjs, klv-agent Docker, telemetry SSE)
09 C2 map & global COP Per-feed mini-map in the theater + a global common operating picture of every live platform on offline tiles; map ⇄ video pivot ops/ (app/map.mjs, MapLibre + offline PMTiles)
10 ReductStore media archive (20 GB FIFO) Bounded, self-evicting, queryable archive of every snapshot/clip — closes F07's open retention question with a native FIFO-quota object store; battle-tested on real captured media reduct/store Docker sidecar, ops/reduct-sink.mjs (additive to F07)
11 Drone MQTT discovery & video ⇄ node association Listen to the office broker's retained node/description topics → live registry of announced UXVs (callsign/nationality/FRIEND-HOSTILE/present); manual rescan for new assets; alias + bidirectional link between a drone node and its video feed ops/ app (mqtt-consumer.mjs, node registry, associations.json, drones Page tab)

See ../ops/PLAN.md for the umbrella "C2-grade FMV console" arc tying F06 → F08 → F09 together (tested against the real feed, discovery-first: does Restreamer strip the KLV data PID?).

How to read a plan

Every feature doc has the same shape:

  1. Why — the operator question it answers.
  2. Approach — what we build and why, given the CSS-only constraint.
  3. Data model / API — the concrete Kuma events and fields involved.
  4. MVP → later — smallest useful slice first.
  5. Verify — how you confirm it works before trusting it.
  6. Open questions — decisions that are yours, not mine.

Suggested sequence

02 first (it's a convert.mjs change that enriches the data everything else reads), then 01 (the app that surfaces that data), then 03/04 in parallel, then 05 when the fleet is stable enough that "200 but stalled" is your top remaining blind spot.