aussensensor kuratiert externe Informationsquellen (Newsfeeds, Wetter, Lagebilder) und stellt sie in einem konsistenten Ereignisformat für die Chronik zur Verfügung. Die aktuelle Implementierung besteht aus einfachen Bash-Hilfsskripten, die den Feed in export/feed.jsonl pflegen und manuell an die Chronik übertragen. Langfristig ist eine Migration zu einem dauerhaften Daemon geplant (siehe docs/adr).
-
Zielgruppe: Operatoren und Analysten, die ein konsolidiertes Lagebild benötigen.
-
Einordnung: aussensensor dient als vorgelagerter Kurationspunkt für externe Quellen und beliefert die Chronik über die
/v1/ingest-Schnittstelle. -
Datenfluss: Zielbild (Standard): aussensensor → nur chronik
/v1/ingest; Zustellung erfolgt via Plexer/Chronik gemäßcontracts/consumers.yaml. Legacy (deprecated): aussensensor → direkt heimlern (wird abgeschaltet).Hinweis: Der direkte Heimlern-Pfad ist deprecated. Bevorzugter Pfad: chronik. Architekturentscheidungen, die zu diesem Design führten, sind in den ADRs dokumentiert.
| Komponente | Beschreibung |
|---|---|
scripts/append-feed.sh |
Fügt dem Feed ein neues Ereignis im JSONL-Format hinzu und erzwingt Contract-Konformität. |
scripts/validate.sh |
Validiert eine JSONL-Datei gegen das Schema. |
scripts/jsonl-compact.sh |
Kompaktifiziert JSONL-Dateien, indem jede Zeile als einzelnes JSON-Objekt formatiert wird. |
scripts/push_chronik.sh |
Überträgt den kompletten Feed an die Chronik-Ingest-API oder führt einen Dry-Run aus. |
scripts/push_heimlern.sh |
(Deprecated) Stößt den Push des Feeds an die Heimlern-Ingest-API an. |
contracts/aussen.event.schema.json |
JSON-Schema des Ereignisformats (Contract). |
export/feed.jsonl |
Sammeldatei aller kuratierten Ereignisse. |
Hinweis:
export/feed.jsonlenthält initial eine minimale Beispielzeile, damit die CI-Validierung sofort grün läuft. Ersetze/erweitere die Datei bei echter Nutzung.
- POSIX-kompatible Shell (getestet mit
bash) jq≥ 1.6 für JSON-Verarbeitungcurlfür HTTP-Requestsajv-cli(Node.js) für Validierung (npm i -g ajv-cli@5.0.0)- Zugriff auf die Chronik-Umgebung inkl. gültigem Token
- Repository klonen und in das Projektverzeichnis wechseln.
- Environment-Variablen setzen:
CHRONIK_INGEST_URL: Basis-URL der Chronik-Ingest-API (z. B.https://chronik.example/ingest/aussen).HEIMLERN_INGEST_URL: Endpoint der Heimlern-Ingest-API (z. B.http://localhost:8787/ingest/aussen).- Optional:
CHRONIK_TOKENfür einen statischen Token (Headerx-auth).
- Sicherstellen, dass
jq,curlsowienode/npminstalliert sind. - Dependencies installieren:
npm ci(installiertajvundajv-formatsfür die Streaming-Validierung). ajv-cli(nur für manuelle Einzeltests):npm install -g ajv-cli@5.0.0- Optional: Pre-commit Hooks für lokale Validierung installieren:
Die Hooks führen automatisch shellcheck, YAML/JSON-Validierung und weitere Checks vor jedem Commit aus.
pip install pre-commit pre-commit install
- (Für GitHub Actions) Repository-Secrets
CHRONIK_INGEST_URLundCHRONIK_TOKENsetzen, damit der WorkflowPush feed to Chronikfunktioniert.
Siehe docs/runbook.md. CI validiert export/feed.jsonl gegen den Contract.
./scripts/append-feed.sh -t news -s rss:demo -T "Test" -S "Kurz" -u "https://example.org" -g "tag1,tag2"
# Für Positional-Mode siehe ./scripts/append-feed.sh -hsource: Menschlich lesbarer Bezeichner (z. B.heise,dwd).type: Vonappend-feed.shakzeptierte Kategorien:news|sensor|project|alert|link. Das Schema hälttypegrundsätzlich frei; die Einschränkung ist Script-Policy, kein Contract-Enum.title,summary,url: Inhalte des Ereignisses (summary≤ 2000 Zeichen).summarywird bei fehlender Angabe als leerer String geschrieben;urlist optional und wird nur gesetzt, wenn übergeben.tags: optionale Liste einzelner Tags (z. B.rss:demo,topic:klima). Das Skript serialisiert sie immer als JSON-Array ([], wenn keine Tags übergeben wurden) und schreibt jede Zeile als kompaktes JSON-Objekt (NDJSON).- Das Skript erzwingt Pflichtfelder, validiert Typen und prüft die Summary-Länge mit dem JSON-Schema, bevor der Eintrag in
export/feed.jsonlangehängt wird.
Bei Eingabefehlern bricht das Skript mit einem nicht-null Exit-Code ab. Bereits vorhandene Einträge bleiben unverändert.
Standard: scripts/push_chronik.sh (Zielarchitektur).
Legacy (Deprecated): scripts/push_heimlern.sh.
Achtung: Dieses Skript ist deprecated und erfordert
ALLOW_HEIMLERN_MVP=1. Es beendet sich mit Exit Code 2, wenn das Gate nicht explizit geöffnet ist.
Optional steht ein kleines Binary aussensensor-push bereit (Rust),
das NDJSON korrekt an /v1/ingest sendet. Die Skripte nutzen es,
falls vorhanden; sonst wird auf curl zurückgefallen.
-
Lokale Schema-Validierung (AJV, Draft 2020-12):
./scripts/validate.sh export/feed.jsonl
-
JSONL-Kompaktifizierung: Falls eine JSONL-Datei mehrzeilige oder unformatierte JSON-Objekte enthält, kann sie mit dem Kompaktifizierungs-Skript normalisiert werden:
./scripts/jsonl-compact.sh export/feed.jsonl
Dies stellt sicher, dass jede Zeile ein einzelnes, kompaktes JSON-Objekt ist (NDJSON-konform).
-
Beim Append erzwingt das Skript Pflichtfelder, erlaubte Typen und die Summary-Länge laut Contract. Contract-required sind
typeundsource;ts,title,summaryundtagswerden vom Skript ergänzt;urlwird nur gesetzt, wenn übergeben. -
GitHub Actions Workflows:
shellcheckprüft alle Bash-Skripte auf häufige Fehler und Best Practices.testsführt die automatisierte Testsuite (bats-core) aus.Push feed to Chronikvalidiert jede Zeile mit AJV (mittels temporärer Kopie der Datei) und stößt manuell einen Push (optional als Dry-Run) an.validate (aussensensor)prüft jede Feed-Zeile automatisiert gegen das Contract-Schema (inklusive Format-Checks) bei Pushes, Pull Requests und manuellen Runs.validate (aussen fixtures)deckt Edge-Cases anhand der Beispiel-JSONL-Dateien untertests/fixtures/aussen/**ab.
# Optional: Feed leeren, um nur den Test-Eintrag zu prüfen
# > export/feed.jsonl
./scripts/append-feed.sh -s heise -t news -T "Testtitel" -S "Kurztext" -u "https://example.org" -g "urgent,topic:klima,Berlin"
./scripts/validate.sh export/feed.jsonl
tail -n1 export/feed.jsonl | jq .- Demonstriert, dass freie Tags (z. B.
topic:klima) korrekt verarbeitet werden. - Validiert den Feed direkt im Anschluss (siehe Schleife oben) und zeigt die zuletzt geschriebene Zeile einschließlich leerer Standardfelder.
This project uses bats-core for automated testing. The tests are located in the tests/ directory. To run the test suite, execute the following command:
./tests/run.shcd tools/aussensensor-push
cargo build --release
sudo install -m 0755 target/release/aussensensor-push /usr/local/bin/Die Push-Skripte verwenden das Binary automatisch, wenn vorhanden (sonst curl).
- Pflichtfelder laut Contract:
type,source. Wenntype == "link", ist zusätzlichurlerforderlich.ts,title,summaryundtagswerden vom Append-Skript ergänzt und sind für gute Nutzbarkeit empfohlen.summarywird bei fehlender Angabe als leerer String geschrieben;urlwird nur gesetzt, wenn übergeben.tags[]wird immer als JSON-Array geschrieben ([], wenn keine Tags übergeben wurden), damit Downstream-Services fixe Spalten haben. - Keine zusätzlichen Felder erlaubt (
additionalProperties: false). - Tags sind freie Strings (z. B.
rss:demo,topic:klima). Sie werden als JSON-Array geschrieben. - Das Append-Skript setzt
tsautomatisch, serialisiert fehlende Tags als leeres Array und schreibt pro Ereignis eine NDJSON-Zeile. - Fehlerhafte Zeilen können mit
jqkorrigiert und erneut validiert werden. - Für NDJSON/JSONL empfiehlt sich
application/x-ndjson. Einige Systeme akzeptieren auchapplication/jsonl; bei Bedarf kann der Push per Flag oderCONTENT_TYPEdarauf umgestellt werden.
Für kontraktnahe Beispiele kannst du unter tests/fixtures/aussen/*.jsonl einzelne Ereignisse ablegen.
Ein dedizierter GitHub-Workflow validiert jede Datei einzeln gegen das Contract-Schema:
- Workflow:
.github/workflows/validate-aussen-fixtures.yml - Trigger: Änderungen unter
tests/fixtures/aussen/**oder manueller Start - Schema:
contracts/aussen.event.schema.json(per Raw-URL aus dem metarepo gespiegelt)
Beispiel (lokal):
npx -y ajv-cli@5 validate --spec=draft2020 --strict=false --validate-formats=false -s contracts/aussen.event.schema.json -d tests/fixtures/aussen/deinfall.jsonl
- Logging: Beide Skripte loggen in STDOUT/STDERR; für automatisierten Betrieb empfiehlt sich eine Umleitung nach
logs/(z. B. via Cronjob). - Überwachung:
- Erfolgs-/Fehlercodes der Skripte in einen Supervisor (Systemd, Cron) integrieren.
- GitHub Actions Workflow als manueller Run (z. B. nach größeren Änderungen) nutzen: Dry-Run prüfen, anschließend echten Push ausführen.
- Feed-Größe und Alter der neuesten Einträge regelmäßig prüfen (
jq -r '.ts'). - Chronik-API-Responses lokal sichern (Follow-Up:
export/last_push_response.json).
- Ereignislebenszyklus: Erfassung → Kuratierung im Feed → Push an Chronik → Archivierung der verarbeiteten Zeilen (Rotation über zukünftigen Daemon).
- Automatisierte Validierung – umgesetzt via GitHub Actions (
Push feed to Chronik) als manueller Einstiegspunkt. - Daemonisierung gemäß ADR-0002: persistente Queue, Retry-Mechanismus, Backoff, Health Endpoint.
- Telemetrie: strukturierte Logs und Metriken (z. B. Prometheus) für Anzahl/Alter der Ereignisse.
- Self-Service-Dokumentation: Beispiele für neue Quellen, Onboarding-Checkliste.
Eine detaillierte Evaluation und Optimierungsplan findet sich in docs/evaluation.md.
Weitere Details und Entscheidungen sind in den Architecture Decision Records dokumentiert.
- Legacy:
scripts/push_heimlern.sh(Direkt-Push) – DEPRECATED. - Ziel:
scripts/push_chronik.sh(nur chronik ingest) – Standard.
Dieses Repository ist Teil des Heimgewebe-Organismus.
Single Source of Truth: heimgewebe/metarepo (contracts/ + contracts/consumers.yaml). ADRs dokumentieren Entscheidungen, sind nicht SSOT.
aussensensor agiert als reiner Producer von Events; die Zustellung und das Routing an Consumer (wie Heimlern, Heimgeist etc.) obliegt dem Plexer/Chronik-Subsystem basierend auf den zentralen Contracts.
Die übergeordnete Architektur, Achsen, Rollen und Contracts sind zentral beschrieben im
👉 metarepo/docs/heimgewebe-organismus.md
sowie im Zielbild
👉 metarepo/docs/heimgewebe-zielbild.md.
Alle Rollen-Definitionen, Datenflüsse und Contract-Zuordnungen dieses Repos sind dort verankert.