Sammelcommit fuer den ueber mehrere Sitzungen gewachsenen, bisher nicht
eingecheckten Stand. Getrennte Commits waeren ehrlicher gewesen, sind es
nachtraeglich aber nicht mehr: BugRepo, changelog.json und die Doku tragen
Aenderungen aus allen Straengen gleichzeitig, und keine Zwischenstufe waere
lauffaehig.
ROADMAP IM DEPLOYMENTCENTER (2.7.0)
Planungsstand, Reihenfolge und Zustaendigkeit lagen in handgepflegten
Markdown-Dateien neben einem Bugtracker, der genau diese drei Dinge bereits
fuehrt. Zwei Pfleger fuer dasselbe Feld - Drift war eine Frage der Zeit.
Ab jetzt: Zustand im DC, Begruendung in der Datei. Kein Feld hat zwei Pfleger.
- Migration 016: epic, roadmap_rank, target_build, defer_trigger,
doc_anchor, Status "deferred", Tabelle roadmap_epics.
KEINE Roadmap-Tabelle - ein Eintrag ist ein bugtracker_item.
- Zugehoerigkeit ist ein Feld: Ein Item steht auf der Roadmap, wenn es ein
epic hat. Ein zweites Kennzeichen daneben koennte auseinanderlaufen.
- Kennung ist die Item-ID. Handvergebene Kuerzel ("A12") erzeugen die
schlimmste Fehlerart: Beide Seiten stimmig, Verschiedenes gemeint, weil
die Kennung nach einer Loeschung neu vergeben wurde.
- Zurueckstellen verlangt defer_trigger. Ohne benannten Anlass ist ein
Vorhaben nicht zurueckgestellt, sondern vergessen. Die Regel sitzt im
Repository, damit sie auf allen drei Schreibwegen gleich greift.
- Modules/Bugtracker/Roadmap.php, /api/bugtracker/v1/roadmap.php,
WebUI-Modul mit Filtern, cli/roadmap.php --write/--check,
dc_roadmap und dc_roadmap_set im MCP-Adapter.
- cli/roadmap.php --write ERZEUGT den Zustandsteil der Markdown-Datei;
--check prueft nur die Prosa. Was erzeugt wird, kann nicht driften.
- docs/ROADMAP_MIGRATION.md: Uebernahme fuer die anderen Projekte.
TESTINSTANZ UND TESTTOR
- dc-dev.mhdf.de: zweite Installation, eigene DB, eigene Schluessel,
Basic-Auth davor, Rocket.Chat aus.
- 124 Testfaelle in tests/e2e gegen API, Rechte, Migrationen, Sperre.
- scripts/deploy.py bringt vor jedem Upload erst den anstehenden Stand auf
die Testinstanz und laesst dann den Testlauf laufen. Erst bei
Rueckgabewert 0 geht etwas auf die Produktion (--ohne-test als Notausgang).
Andersherum prueft der Lauf aelteren Code als den, der gleich hochgeht.
- tests/ ist aus dem Produktiv-Deploy ausgeschlossen; testctl.php kann
nicht versehentlich auf dc.mhdf.de landen.
- Ein Lauf mit mehr uebersprungenen als geprueften Faellen endet mit
Rueckgabewert 2 statt 0. Nichts ist kaputt, geprueft wurde es aber auch
nicht - der Unterschied darf nicht am Rueckgabewert verschwinden.
SUPERVISOR, PROJEKTLANDSCHAFT, NACHPRUEFUNG (2.6.0/2.6.1)
- Migration 013: projektuebergreifend melden (dev_agent, evidence,
triage_external, affects).
- Migration 014: supervisor_findings, Katalog, fuenf serverseitige
Detektoren im Tick.
- Migration 015: Nachpruefung als Arbeitsschlange statt Benachrichtigung.
- DEV-Lizenzschluessel zur Selbstbedienung, dc-testkit fuer die Test-VM.
- MCP-Adapter: 15 Werkzeuge, ohne Fremdabhaengigkeiten, mit Abgrenzung
von Fremddaten gegen Prompt-Injektion.
BEHOBEN
- observe und status im Supervisor legten den Zustand des Befundes als
"status" in die Antwort. Http::ok() merged ['status' => 'success']
darunter, also gewann der Befundzustand - eine angenommene Meldung kam
als status="open" an. Heisst jetzt finding_status. War Item #59.
Migrationen 013-016 sind auf dem Produktivserver noch NICHT ausgefuehrt.
Ohne sie bricht das WebUI, weil die Roadmap-Ansicht bei jedem Seitenaufruf
gegen bugtracker_items.epic abfragt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
186 lines
7.8 KiB
Markdown
186 lines
7.8 KiB
Markdown
# Supervisor — Befunde und Rückbau
|
|
|
|
Der Supervisor sieht nach, ob etwas ungewöhnlich ist, und legt Befunde ab.
|
|
|
|
Er beantwortet die Frage **„ist das ungewöhnlich?"** — nicht „ist das
|
|
schlimm?". Die zweite Frage beantwortet ein Mensch oder ein Agent bei der
|
|
Sichtung, mit Verlauf, Flotte und Quelltext vor Augen.
|
|
|
|
Gültiger Stand aller Vorhaben: **[ROADMAP.md](ROADMAP.md)**<br>
|
|
Ausführliche Begründung (archiviert): [archiv/SUPERVISOR_MCP_DESIGN.md](archiv/SUPERVISOR_MCP_DESIGN.md)
|
|
|
|
---
|
|
|
|
## Wichtig: es gibt nichts einzubauen
|
|
|
|
> **Ein Supervisor im ausgelieferten Programm ist verworfen.** Er hätte in
|
|
> jeder Anwendung Einbau, Rückbau, eigenen Zustand auf Kundenhardware, ein
|
|
> weiteres Token im Binary und eine zweite Fassungspflege gebraucht — und dabei
|
|
> überwiegend gemeldet, was Error-Reporting und Bugtracker ohnehin abdecken.
|
|
>
|
|
> **Für Anwendungen ändert sich damit nichts.** Wer Fehler an den Bugtracker
|
|
> meldet, ist fertig. Die Detektoren laufen im Deploymentcenter auf den Daten,
|
|
> die dadurch ohnehin hereinkommen.
|
|
|
|
Diese Anleitung beschreibt deshalb zweierlei: **was der Supervisor findet und
|
|
wie man es ansieht** — und **wie begonnene Vorbereitungen zurückgebaut werden.**
|
|
|
|
---
|
|
|
|
## Woher Befunde kommen
|
|
|
|
**Serverseitig, von selbst.** Fünf Detektoren laufen im minütlichen Tick
|
|
(gedrosselt auf zehn Minuten) und brauchen keine Änderung an irgendeiner
|
|
Anwendung:
|
|
|
|
| Detektor | Findet |
|
|
|---|---|
|
|
| `novel.error_signature` | Fehlersignatur, die es in dieser Fassung noch nie gab |
|
|
| `silence.heartbeat` | Instanz meldet sich nicht mehr |
|
|
| `deviation.self` | Abweichung vom eigenen Verlauf der letzten Tage |
|
|
| `deviation.fleet` | Ausreißer gegenüber anderen Installationen derselben Fassung |
|
|
| `regression.build` | Kennzahl verschiebt sich nach einem Update |
|
|
|
|
Keiner davon muss den gesuchten Fehler vorher kennen. Der Maßstab kommt nicht
|
|
aus einem Kopf, sondern aus dem eigenen Verlauf, aus der Vorversion oder aus
|
|
den anderen Installationen — deshalb finden sie Dinge, an die niemand gedacht
|
|
hat.
|
|
|
|
**Von außen eingeliefert**, über `POST /api/supervisor/v1/observe` mit dem
|
|
Scope `supervisor:report`. Heute nutzen das Prüfwerkzeuge und Testläufe. Der
|
|
[Katalog](../src/Modules/Supervisor/Catalog.php) legt die Namen fest, unter
|
|
denen gemeldet wird — abrufbar über `GET /api/supervisor/v1/catalog`.
|
|
|
|
Dass die Namen stabil sind, ist der ganze Zweck: Befunde aus verschiedenen
|
|
Projekten müssen vergleichbar bleiben. Ein umbenannter Detektor zerreißt jede
|
|
Auswertung, die über den Zeitpunkt der Umbenennung hinausgeht.
|
|
|
|
---
|
|
|
|
## Befunde ansehen
|
|
|
|
Über MCP in Claude Code:
|
|
|
|
```
|
|
dc_finding_summary → Zählung je Detektor
|
|
dc_findings detector: "deviation" → die Einzelbefunde
|
|
dc_metrics source: "app-01" metric: … → der Verlauf dahinter
|
|
```
|
|
|
|
Ohne MCP:
|
|
|
|
```
|
|
GET /api/supervisor/v1/summary
|
|
GET /api/supervisor/v1/findings?detector=deviation&status=active
|
|
GET /api/supervisor/v1/catalog
|
|
```
|
|
|
|
Befunde tragen ihre Umgebung. Was außerhalb von `production` auffällt, ist eine
|
|
Stufe niedriger eingestuft — nicht weil es unwichtig wäre, sondern weil auf
|
|
Testmaschinen systematisch mehr Rauschen entsteht.
|
|
|
|
**Ob ein Befund aus einem Testlauf ein Artefakt des Prüfstands ist oder auch
|
|
beim Kunden aufträte, ist die schwierige Frage.** Sie ist offen; die Ansätze
|
|
stehen in der [Roadmap unter G8](ROADMAP.md). Der brauchbarste Gedanke daraus:
|
|
Fehlende Zugangsdaten sind ein Artefakt — *wie die Software darauf reagiert*,
|
|
ist keines. Ein Wiederholungssturm, ausgelöst durch fehlende Zugangsdaten, ist
|
|
ein echter Befund, denn auch beim Kunden laufen Zugangsdaten ab.
|
|
|
|
---
|
|
|
|
## Vorbereitungen in den Projekten zurückbauen
|
|
|
|
In mehreren Projekten wurde bereits von Hand etwas in Richtung Supervisor
|
|
begonnen — UI-Steuerelemente, teilweise ein lokaler KI-Agent. Das fällt
|
|
**ersatzlos** weg; es tritt nichts an seine Stelle.
|
|
|
|
### Erkennen
|
|
|
|
```bash
|
|
grep -rniE "supervisor|healthcheck|selfcheck|anomal" --include=*.cs --include=*.php .
|
|
```
|
|
|
|
Typisch: eine eigene Timer-Schleife, ein Verzeichnis mit Zählern, ein eigener
|
|
`HttpClient`-Aufruf gegen das Deploymentcenter, eine JSON-Datei mit Zustand,
|
|
eine Klasse namens `HealthCheck` oder ähnlich.
|
|
|
|
### Was verschwindet
|
|
|
|
- **Lokal laufender KI-Agent** samt API-Schlüssel. Der Schlüssel läge auf
|
|
Kundenhardware, der Kontext im Speicher fremder Maschinen.
|
|
- **UI-Listen, -Tabellen und -Schaltflächen für Befunde.** Es gibt lokal keine
|
|
Befundhistorie anzuzeigen, und Abhaken wäre `supervisor:manage` — ein Recht,
|
|
das kein Laufzeit-Token trägt.
|
|
- **Eigene Warteschlangen** für nicht zugestellte Meldungen. Eine wachsende
|
|
Warteschlange in einer ohnehin auffälligen Anwendung ist genau der Schaden,
|
|
den man vermeiden wollte.
|
|
- **Eigene Alarmierung** je Auffälligkeit. Wer bei jeder Kleinigkeit alarmiert,
|
|
hat nach einer Woche einen Kanal, den niemand mehr liest.
|
|
- **Feste Schwellwerte je Kennzahl.** Die tragenden Detektoren vergleichen
|
|
gegen eigenen Verlauf, Vorversion oder Flotte. Ein Schwellwert findet nur,
|
|
woran vorher jemand gedacht hat.
|
|
- **Timer-Schleifen, Zustandsdateien, eigene POSTs** an das Deploymentcenter.
|
|
|
|
Was bleiben darf, wenn es schon gebaut ist: eine **einzelne Statuszeile** im
|
|
Administrationsbereich — meldet die Anwendung Fehler, wann zuletzt. Das ist die
|
|
einzige lokal beantwortbare Frage.
|
|
|
|
### Was übrig bleibt und wertvoll ist
|
|
|
|
Wo in der Vorbereitung schon überlegt wurde, **worauf** zu achten wäre, ist
|
|
diese Überlegung das Wertvollste am ganzen Bestand. Sie wandert nicht ins
|
|
Nichts, sondern:
|
|
|
|
| Überlegung | Neuer Ort |
|
|
|---|---|
|
|
| „Hier darf nie ein negativer Saldo entstehen" | Prüfung im Testlauf |
|
|
| „Dieser `catch` verschluckt etwas Wichtiges" | Fehlermeldung an den Bugtracker, statt zu schlucken |
|
|
| „Diese Warteschlange kann volllaufen" | Kennzahl im Heartbeat — `deviation.self` sieht den Rest |
|
|
| „Dieser Job stirbt manchmal still" | Heartbeat-Monitor — `silence.heartbeat` sieht den Rest |
|
|
|
|
Die letzten beiden sind der Punkt: Was als Kennzahl im Heartbeat landet, wird
|
|
serverseitig ohnehin überwacht. Dafür braucht es keinen Beobachter im Programm,
|
|
nur einen Wert mehr im Ping.
|
|
|
|
### Auftrag für den Agenten im Projektverzeichnis
|
|
|
|
Zum Einfügen in eine frische Sitzung im jeweiligen Projekt:
|
|
|
|
```text
|
|
In diesem Projekt wurde eine Supervisor-Vorbereitung begonnen. Sie wird
|
|
ersatzlos zurückgebaut — ein Supervisor im ausgelieferten Programm ist
|
|
verworfen. Es tritt nichts an seine Stelle.
|
|
|
|
1. Bestandsaufnahme. Suche:
|
|
grep -rniE "supervisor|healthcheck|selfcheck|anomal" .
|
|
Berichte, was du findest, bevor du etwas änderst.
|
|
|
|
2. Ersatzlos entfernen:
|
|
- lokal laufender KI-Agent samt API-Schlüssel
|
|
- UI-Listen, -Tabellen und -Schaltflächen für Befunde
|
|
- eigene Warteschlangen, eigene Alarmierung, feste Schwellwerte
|
|
- eigener POST ans Deploymentcenter, eigene Zustandsdatei
|
|
- eigene Timer-/Hintergrundschleife
|
|
Behalten: höchstens eine Statuszeile im Administrationsbereich.
|
|
|
|
3. Die Überlegungen retten. Wo jemand notiert hat, WORAUF zu achten wäre,
|
|
überführe das:
|
|
- fachliche Zusicherung -> Prüfung im Testlauf
|
|
- verschluckter Fehler -> Fehlermeldung an den Bugtracker statt Schlucken
|
|
- Wert, der volllaufen kann -> Kennzahl im Heartbeat
|
|
|
|
4. Sicherstellen, dass Fehler gemeldet werden: globaler Exception-Handler an
|
|
POST /api/errors/v1/report, mit build_version. Ohne diese Angabe kann der
|
|
Tracker eine Regression nicht von einem veralteten Prüfstand unterscheiden.
|
|
|
|
5. Fassung festhalten: dc_link_project mit to_slug "deploymentcenter",
|
|
integrated_version "2.6.1". Ohne MCP: POST /api/bugtracker/v1/projects.
|
|
|
|
Fällt dir dabei ein Fehler im Deploymentcenter selbst auf, melde ihn mit
|
|
dc_report gegen project_slug "deploymentcenter" samt evidence.
|
|
```
|
|
|
|
Schritt 4 ist der wichtigste. Er ersetzt den ganzen verworfenen Beobachter:
|
|
Kommen Fehler mit Fassungsangabe herein, arbeiten die serverseitigen Detektoren
|
|
darauf — ohne eine Zeile Beobachtercode in der Anwendung.
|