feat(2.7.0): Roadmap im DC, Testinstanz mit Testtor, Supervisor und MCP
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9d0261306c
commit
1d5ac92051
@@ -0,0 +1,185 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user