diff --git a/README.md b/README.md index 91fe5cd..7cdf68d 100644 --- a/README.md +++ b/README.md @@ -93,12 +93,21 @@ internal/ rds/ RDS encoder (IEC 62106, CRC, differential, group scheduler) stereo/ stereo encoder (19 kHz pilot, 38 kHz DSB-SC) docs/ - config.sample.json default config - config.plutosdr.json PlutoSDR-specific config + config.sample.json default config + config.plutosdr.json PlutoSDR-specific config + pro-runtime-hardening-workboard.md living workboard for pro runtime hardening scripts/ examples/ ``` +## Planning / workboard + +For the current pro-runtime-hardening track, see: + +- `docs/pro-runtime-hardening-workboard.md` + +This document is the detailed working board for status tracking, confirmed findings, open decisions, verification notes, and implementation progress. + ## Legal note This project is intended only for lawful use within relevant license and regulatory constraints. diff --git a/docs/pro-runtime-hardening-workboard.md b/docs/pro-runtime-hardening-workboard.md new file mode 100644 index 0000000..1f46138 --- /dev/null +++ b/docs/pro-runtime-hardening-workboard.md @@ -0,0 +1,506 @@ +# Pro Runtime Hardening Workboard + +Status: living document +Branch: `feature/pro-runtime-hardening` + +Dieses Dokument ist das **Arbeitsdokument** zur schrittweisen Umsetzung des Konzepts aus `fm-rds-tx_pro_runtime_hardening_concept.json`. + +Ziel ist **nicht** nur eine hübsche Roadmap, sondern ein Ort, an dem wir konkret markieren können: +- **wo** wir im Code stehen, +- **welche Lücken** bestätigt sind, +- **welche Entscheidungen** gefallen sind, +- **welche Arbeiten** offen / in Arbeit / erledigt sind, +- **welche Risiken** noch bestehen, +- **welche Akzeptanzkriterien** wirklich nachgewiesen wurden. + +--- + +## 1. Arbeitsregeln für dieses Dokument + +### Statuswerte +- `TODO` → noch nicht begonnen +- `IN PROGRESS` → aktiv in Arbeit +- `BLOCKED` → sinnvoll erkannt, aber blockiert +- `DONE` → umgesetzt +- `VERIFIED` → umgesetzt **und** sinnvoll geprüft +- `DEFERRED` → bewusst nach hinten verschoben +- `REJECTED` → bewusst verworfen + +### Nachweispflicht +Ein Punkt gilt erst als wirklich fertig, wenn eingetragen ist: +1. **Code-Ort(e)** +2. **Was geändert wurde** +3. **Wie verifiziert wurde** +4. **Welche Restrisiken bleiben** + +### Update-Regel +Wenn wir an einem Workstream arbeiten, soll dieses Dokument mitgezogen werden. +Kein „ist im Kopf klar“. Der Stand kommt hier rein. + +--- + +## 2. Gesamtüberblick + +## Gesamtstatus +- Projektphase: `Planung / Strukturierung` +- Technischer Fokus aktuell: `noch offen` +- Nächster sinnvoller Startpunkt laut Konzept: `WS-03 Semantische Korrektheit und harte Config-/Runtime-Konsistenz` + +## Repo-bezogene bestätigte Ausgangslage + +| Thema | Status | Notiz | +|---|---|---| +| TX-Engine aktuell als synchroner Single-Loop | CONFIRMED | `internal/app/engine.go` | +| Persistenter DSP-Zustand im Generator vorhanden | CONFIRMED | `internal/offline/generator.go` | +| HTTP-Control vorhanden | CONFIRMED | `internal/control/control.go` | +| Config-Validation vorhanden, aber nicht überall semantisch konsistent | CONFIRMED | `internal/config/config.go` + Runtime-Pfade | +| Device/Capability-Modell vorhanden, aber noch nicht streng genug | CONFIRMED | `internal/platform/soapy.go` | +| Lock-freier SPSC-Audio-Ringbuffer vorhanden | CONFIRMED | `internal/audio/stream.go` | + +## Bereits bekannte bestätigte Inkonsistenzen + +| ID | Status | Beschreibung | Ort | +|---|---|---|---| +| CFG-SEM-001 | CONFIRMED | `fm.outputDrive` wird in Validation und Runtime nicht konsistent behandelt | `internal/config/config.go`, `internal/app/engine.go` | +| CTL-UX-001 | CONFIRMED | `handleAudioStream()` referenziert `--audio-http`, was CLI-seitig überprüft werden sollte | `internal/control/control.go` | + +--- + +## 3. Prioritätenmodell + +| Priorität | Bedeutung | +|---|---| +| P0 | Technische Perfektion und Determinismus | +| P1 | Betriebssicherheit und Fehlerbeherrschung | +| P2 | Hardware-Wahrheit und RF-Qualität | +| P3 | Sichere und saubere Runtime-Steuerung | +| P4 | Deployment-, Release- und Service-Reife | + +--- + +## 4. Umsetzungstracker nach Workstream + +# WS-03 — Semantische Korrektheit und harte Config-/Runtime-Konsistenz +**Priorität:** P0 +**Gesamtstatus:** TODO + +## Ziel +Ein einziger, eindeutig definierter Parameterraum. Jeder Wert hat exakt eine Bedeutung und identische Constraints in Config, HTTP-API, Runtime und Telemetrie. + +## Warum dieser Workstream zuerst +Wenn Semantik und Grenzwerte nicht sauber vereinheitlicht sind, bauen spätere Runtime- und Fault-Mechanismen auf unstabilem Fundament. + +## Aufgaben + +### WS-03-T1 — Parameterinventar erstellen +- **Status:** TODO +- **Owner:** offen +- **Code-Orte:** + - `internal/config/config.go` + - `internal/app/engine.go` + - `internal/control/control.go` + - ggf. weitere betroffene Pakete +- **Ziel:** + Alle öffentlich und intern verwendeten Parameter inventarisieren mit: + - Name + - Typ + - Einheit + - Bereich + - Default + - hot-reload-fähig ja/nein + - safety class + - Telemetrie-Name +- **Offene Fragen:** + - Wo leben heute implizite Parameter, die nicht sauber dokumentiert sind? + - Welche Runtime-Werte sind abgeleitet statt direkt konfigurierbar? +- **Nachweis:** + - Parameterinventar im Repo vorhanden + - referenzierbar für Config/API/Runtime +- **Restrisiken:** + - versteckte Semantik in Helper-Funktionen übersehen + +### WS-03-T2 — Validation vereinheitlichen +- **Status:** TODO +- **Owner:** offen +- **Code-Orte:** + - `internal/config/config.go` + - `internal/app/engine.go` + - `internal/control/control.go` +- **Ziel:** + `Config.Validate()`, Runtime-Update-Pfade und API-Patch-Validierung dürfen nicht divergieren. +- **Bereits bekannter Startpunkt:** + - `fm.outputDrive` +- **Nachweis:** + - bekannte Inkonsistenzen beseitigt + - Tests für gemeinsame Grenzwerte vorhanden +- **Restrisiken:** + - weitere Inkonsistenzen erst beim Inventar sichtbar + +### WS-03-T3 — DesiredConfig / AppliedConfig einführen +- **Status:** TODO +- **Owner:** offen +- **Code-Orte:** + - `internal/app/engine.go` + - `internal/control/control.go` + - ggf. Config-/Statusmodelle +- **Ziel:** + API und Runtime sollen trennen zwischen: + - gewünschter Konfiguration + - tatsächlich angewandter Konfiguration + - aktuellem Runtime-Zustand +- **Nachweis:** + - API kann beide Sichten getrennt ausgeben + - partielle oder abgelehnte Übernahmen werden sichtbar +- **Restrisiken:** + - unsaubere Migration bestehender Statusantworten + +## WS-03 Entscheidungslog +- Noch leer + +## WS-03 Verifikation +- Noch leer + +--- + +# WS-01 — Deterministische Echtzeit-TX-Pipeline mit entkoppeltem Writer +**Priorität:** P0 +**Gesamtstatus:** TODO + +## Ziel +Generator/Upsampler und Hardwarewriter werden als getrennte Stufen mit kleinem, kontrolliertem Frame-Puffer betrieben. + +## Aktueller Stand +- Der TX-Pfad ist laut Konzept aktuell noch synchron gekoppelt: + `GenerateFrame -> optional FMUpsampler.Process -> driver.Write` +- Das ist elegant, aber nicht pro-level-hart gegenüber Write-Spikes und Blockaden. + +## Aufgaben + +### WS-01-T1 — FrameQueue einführen +- **Status:** TODO +- **Owner:** offen +- **Code-Orte:** + - `internal/app/engine.go` + - ggf. neues internes Queue-Modul + - `internal/output/*` +- **Ziel:** + Bounded Queue mit fester Kapazität, sichtbarem Füllstand und Countern. +- **Zu entscheiden:** + - Puffern vor oder nach Upsampling? + - Referenzentscheidung im Konzept: eher Device-Frame-Ebene +- **Akzeptanzpunkte:** + - keine unbounded queue + - Fill-Level live sichtbar + - Drop/Repeat/Mute niemals ohne Counter/Log + +### WS-01-T2 — Writer-Worker einführen +- **Status:** TODO +- **Owner:** offen +- **Code-Orte:** + - `internal/app/engine.go` + - `internal/platform/*` +- **Ziel:** + Nur noch ein dedizierter Worker besitzt `driver.Write()`. +- **Akzeptanzpunkte:** + - Write-Latenz pro Frame messbar + - Timinginteraktionen klar isoliert + +### WS-01-T3 — Supervisor-Schicht einführen +- **Status:** TODO +- **Owner:** offen +- **Code-Orte:** + - `internal/app/engine.go` +- **Ziel:** + Queue-Füllstand, Late-Rate und Fehlerhäufigkeit überwachen und in Runtime-Zustände überführen. +- **Akzeptanzpunkte:** + - State-Entscheidungen sind explizit + - kein implizites Weiterwursteln bei Schieflage + +## Offene Architekturfragen +- Ist `capacity_frames = 3` ein guter Startwert oder nur Konzept-Default? +- Sollte im Fault-Fall `repeat last safe frame` erlaubt sein oder von Anfang an nur `mute`? +- Wie eng koppeln wir WS-01 mit WS-02, ohne Overengineering zu erzeugen? + +## WS-01 Entscheidungslog +- Noch leer + +## WS-01 Verifikation +- Noch leer + +--- + +# WS-02 — Explizite Runtime-State-Maschine und Fault-Handling +**Priorität:** P0 +**Gesamtstatus:** TODO + +## Ziel +Einführen eines klaren Betriebsmodells mit Fault-, Recovery- und Muted-Zuständen. + +## Zielzustände laut Konzept +- `idle` +- `arming` +- `prebuffering` +- `running` +- `degraded` +- `muted` +- `faulted` +- `stopping` + +## Aufgaben + +### WS-02-T1 — Fault-Klassifikation definieren +- **Status:** TODO +- **Owner:** offen +- **Beispiele:** + - Treiberfehler + - Write-Time-Budget überschritten + - Queue leer + - Queue dauerhaft kritisch + - Selbsttest fehlgeschlagen + - unerlaubtes Live-Update + +### WS-02-T2 — Reaktionsstrategie definieren +- **Status:** TODO +- **Owner:** offen +- **Ziel:** + Pro Fehlerklasse klar definieren: + - warn only + - degraded + - muted + - faulted + +### WS-02-T3 — Fault-Historie und Event-Log einführen +- **Status:** TODO +- **Owner:** offen +- **Ziel:** + Zustandswechsel und Faults auditierbar machen. + +## Offene Designfragen +- Wie fein granular darf die State-Maschine werden, ohne unwartbar zu werden? +- Welche Transitionen sind wirklich produktiv relevant und welche nur „theoretisch schön“? + +## WS-02 Entscheidungslog +- Noch leer + +## WS-02 Verifikation +- Noch leer + +--- + +# WS-04 — Observability, Telemetrie und Diagnosefähigkeit +**Priorität:** P1 +**Gesamtstatus:** TODO + +## Ziel +Vollständige Sichtbarkeit auf Runtime, Queue, Writer, Generator, RF-Selbsttests und API-Aktivität schaffen. + +## Aufgaben + +### WS-04-T1 — Strukturiertes Logging +- **Status:** TODO +- **Owner:** offen + +### WS-04-T2 — Prometheus-/Metrics-Schicht +- **Status:** TODO +- **Owner:** offen + +### WS-04-T3 — Debug-/Profiling-Endpunkte +- **Status:** TODO +- **Owner:** offen + +## Gewünschte Beispielmetriken +- `engine_chunks_generated_total` +- `engine_late_buffers_total` +- `engine_fault_transitions_total` +- `writer_write_duration_seconds` +- `queue_fill_ratio` +- `queue_dropped_frames_total` +- `queue_muted_frames_total` +- `driver_write_errors_total` +- `audio_stream_underruns_total` +- `audio_stream_overflows_total` +- `rf_selftest_pilot_db` +- `rf_selftest_rds_57k_db` + +## WS-04 Entscheidungslog +- Noch leer + +## WS-04 Verifikation +- Noch leer + +--- + +# WS-05 — Sichere und erwachsene Control-Plane +**Priorität:** P1 / P3-nah +**Gesamtstatus:** TODO + +## Ziel +API transport- und anwendungsseitig härten, state-aware machen und auditierbar gestalten. + +## Aufgaben + +### WS-05-T1 — Auth und Deploy-Modi definieren +- **Status:** TODO +- **Owner:** offen +- **Zielmodi:** + - localhost-only + - trusted-lan + - secured-remote + +### WS-05-T2 — HTTP-Server härten +- **Status:** TODO +- **Owner:** offen +- **Mindestpunkte:** + - ReadTimeout + - WriteTimeout + - IdleTimeout + - ReadHeaderTimeout + - Body-Size-Limits + - Content-Type-Validierung + - Method Enforcement + +### WS-05-T3 — API semantisch aufräumen +- **Status:** TODO +- **Owner:** offen +- **Ziel:** + - DesiredConfig vs AppliedConfig vs RuntimeState + - idempotente Start/Stop-Endpunkte + - transaktionsartige Apply-/Reject-Antworten + - Audit-Log pro Eingriff + +## Frühe Quick-Wins +Diese Punkte könnten ggf. vorgezogen werden, auch wenn WS-05 formal nach WS-01/02 kommt: +- HTTP-Timeouts +- Body-Limits +- sicherer Standard-Bind-Modus + +## WS-05 Entscheidungslog +- Noch leer + +## WS-05 Verifikation +- Noch leer + +--- + +# WS-06 — Hardware-in-the-loop und externe RF-Wahrheitsprüfung +**Priorität:** P2 +**Gesamtstatus:** TODO + +## Ziel +Nicht nur intern richtig rechnen, sondern extern nachweisen, dass tatsächlich korrekt gesendet wird. + +## Status +- Konzept vorhanden +- noch kein eingetragener HIL-Arbeitsstand in diesem Dokument + +## Offene Kernfragen +- Welches Referenz-Setup wird verbindlich? +- Welche Testfrequenz / Standarddauer / Schutzmaßnahmen gelten? +- Welcher externe Decoder / Empfänger gilt als Referenz? + +--- + +# WS-07 — Device-aware Capability- und Kalibrierungsmodell +**Priorität:** P2 +**Gesamtstatus:** TODO + +## Ziel +Fähigkeiten und Kalibrierungen nicht implizit, sondern explizit pro Device modellieren. + +## Noch offen +- Capability-Schema konkretisieren +- Kalibrierungsprofil definieren +- Device-aware Validation einbauen + +--- + +# WS-08 — Signal-Selbstüberwachung im Betrieb +**Priorität:** P2 +**Gesamtstatus:** TODO + +## Ziel +Pilot, Stereo, RDS und Composite-Anomalien im Betrieb erkennen. + +## Noch offen +- Goertzel/FFT-Strategie festlegen +- Schwellwerte definieren +- in Fault-Logik einspeisen + +--- + +# WS-09 — Teststrategie erweitern +**Priorität:** P3/P4-nah +**Gesamtstatus:** TODO + +## Ziel +Von Unit-Tests zu echter Qualitätsabsicherung: Golden Vectors, Long-Run, Race, Fuzzing, API-Mutation, HIL. + +## Noch offen +- Testpyramide konkretisieren +- Nightly-/CI-Fähigkeit bestimmen + +--- + +# WS-10 — Service-Reife, Packaging und Reproduzierbarkeit +**Priorität:** P4 +**Gesamtstatus:** TODO + +## Ziel +Build-, Release- und Betriebsartefakte reproduzierbar und teamtauglich machen. + +## Noch offen +- Build-Metadaten +- Service-Units +- Config-Versionierung / Migration + +--- + +## 5. Übergreifende Regeln + +### Musts +- Jeder neue Runtime-Zustand muss per API und Telemetrie sichtbar sein. +- Jede Recovery-, Drop- oder Mute-Strategie braucht Counter, Logs und Tests. +- Keine neue Config-Option ohne klaren Typ, Bereich, Einheit, Default und Hot-Reload-Klassifikation. +- Hardware-nahe Änderungen brauchen mindestens Simulations- und HIL-Validierung. +- Alle Faults müssen eine maschinenlesbare Ursache und eine menschenlesbare Zusammenfassung haben. + +### Must Not +- Keine unbounded Queues. +- Keine stillen Fallbacks ohne Telemetrie. +- Keine teilweise angewandten Live-Config-Änderungen ohne explizite Rückmeldung. +- Keine unterschiedlichen Grenzwerte zwischen Config, API und Runtime. +- Keine sicherheitsrelevanten HTTP-Endpunkte ohne Härtung im Remote-Betrieb. + +--- + +## 6. Aktuelle offene Entscheidungen + +| ID | Status | Frage | Notiz | +|---|---|---|---| +| DEC-001 | OPEN | Puffern wir auf CompositeFrame- oder DeviceFrame-Ebene? | Konzept empfiehlt Device-Frame-Ebene | +| DEC-002 | OPEN | Fault-Recovery zuerst mit `mute`, `repeat last safe frame` oder beidem? | Muss technisch und RF-seitig sauber bewertet werden | +| DEC-003 | OPEN | Ziehen wir minimale WS-05-Basis-Härtungen vor? | Timeouts/Body-Limits evtl. früher sinnvoll | +| DEC-004 | OPEN | Wie gross/simpel halten wir die erste State-Maschine? | Gefahr von Overengineering | + +--- + +## 7. Nächste sinnvolle Schritte + +### Empfohlener Start +1. **WS-03-T1 Parameterinventar erstellen** +2. **bekannte Inkonsistenzen (CFG-SEM-001, CTL-UX-001) konkret verifizieren** +3. **DesiredConfig / AppliedConfig / RuntimeState Zielmodell grob skizzieren** +4. Danach Architekturarbeit an **WS-01 + WS-02** starten + +### Vor dem ersten grossen Umbau klären +- Was ist „minimal sinnvoll“ für Milestone 1? +- Welche Dinge sind harte Must-haves und welche nur spätere Veredelung? +- Wo wollen wir bewusst nicht sofort maximal abstrahieren? + +--- + +## 8. Änderungsprotokoll + +| Datum | Änderung | Person / Agent | +|---|---|---| +| 2026-04-05 | Initiales Arbeitsdokument aus `fm-rds-tx_pro_runtime_hardening_concept.json` erstellt | Alfred |