Neue Anfrageart rescue-tunnel im bestehenden Update-Postkasten (kein
zweiter Weg): UpdateChannel::requestRescueTunnel(), der Agent fuehrt
deploy/rescue-tunnel.sh mit Frist aus, die Konsole zeigt Ergebnis,
Waechter-Stand und Wirt-Helfer-Vertrag in der Update-Karte, Bestaetigung
im Modal (R23) nach dem Muster von ConfirmReleaseUpdateLock.
Zusatzfix in deploy/watchdog.sh: der wg0-Block meldete geheilt=true
schon, bevor geprueft war, ob wg-quick up wg0 wirklich gewirkt hat --
ein fehlgeschlagener Tunnelaufbau haette der Konsole "healed" vorgemacht.
geheilt wird jetzt erst nach der zweiten wg-show-Probe gesetzt, mit
Regressionstest in WatchdogVisibilityTest.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Waechter redete bisher nur ins Journal auf dem Wirt — die Konsole
im Container sieht ihn also nicht. Er schreibt jetzt zusaetzlich
storage/app/deploy/watchdog-last-run.json (atomar, .tmp + mv) mit
Ausgang (idle/healed/stood_down) und den say()-Meldungen des Laufs.
WatchdogLog::lastRun() liest das robust (fehlend/kaputt -> null,
stale-Erkennung nach 5 Minuten).
Die mitgelieferte Testvorlage hatte selbst einen Fehler: die
docker-Attrappe setzte ihren mehrzeiligen Vorgabewert ungequotet in
generierten Shell-Code ein, wodurch die "ps"-Antwort einen Dienst
verschluckte und der idle-Test faelschlich "healed" sah. Behoben
durch Anfuehrungszeichen um den eingesetzten Wert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>