hermes-erkenntnisse/portal-fixes/portal-token-idle-fix-2026-07-24.md

5.2 KiB

Portal cp.go-ki.eu: Token-Anzeige vereinheitlicht + Idle-Auto-Aus-Schalter (2026-07-24)

Auftrag 1: Widerspruch "Token: Expired" vs Session-Watchdog gruen

Ursache (belegt)

  • GPU-Shadow-Karte las token_valid/token_ok aus Hub :4099 Endpoint /api/shadow/status. Dieser Endpoint liefert token_valid:false, token_min_left:0, expires_at:1782171222, next_renew_at: "23.06.2026 19:01" - ein veralteter/toter Tracker, der seit Wochen nicht mehr rennt (next_renew liegt in der Vergangenheit ggue. heute 24.07.2026).
  • Der Session-Watchdog (shadow.php?action=session_health, echte Cookie-Daten aus dem nas2-Container) zeigte kratos 29.4d, cf_clearance 364.4d, oauth 55-57min TTL mit auto-refresh - sah "gesund" aus.

KORREKTUR waehrend der Arbeit (Baer, nach Live-Befund eines zweiten Workers)

Erste Annahme "Watchdog-TTLs = Wahrheit" war FALSCH. Tatsaechliche Wahrheit: Shadow.tech lehnt die Kratos-Session serverseitig ab, obwohl das Cookie laut Ablaufdatum noch Wochen gueltig aussieht. Beleg im Adaptive-Starter-Log auf dem Hub (/opt/shadow-bulletproof/logs/starter.log):

[14:31:32]   Login-Page without kratos - redirecting to https://pc.shadow.tech/login?login_hint=...

Mehrfach reproduziert (14:24, 14:26, 14:29, 14:31 Uhr), VM bleibt offline (vm_online:false).

Neue einheitliche Wahrheitsquelle

Neuer PHP-Endpoint shadow.php?action=login_status (jump_control, 100.91.98.15:8480) tailt starter.log auf dem Hub (100.87.20.94) per SSH und meldet session_accepted: true/false anhand des letzten "Login-Page without kratos"-Treffers.

Backend /opt/gpu1-status/app.py (VM201), Funktion _gpu_token_health():

  • token_ok kommt jetzt aus login_status (session_accepted), NICHT mehr aus Cookie-TTLs.
  • Cookie-TTLs (kratos/cf/oauth) werden weiter als cookie_info mitgeliefert - reine Zusatzinfo, beschriftet als "Cookie-Ablauf", NICHT als "Session gueltig".
  • Der kurzlebige OAuth-Access-Token (~1h, auto-refresh) beeinflusst token_ok nicht mehr.

Frontend: Token-Badge auf der GPU-Shadow-Karte zeigt jetzt bei session_accepted:false klar "Expired" + Grund-Text mit Login-Link (http://100.111.0.111:6070); bei session_accepted:true "gueltig" inkl. OAuth-TTL als Zusatzinfo.

Live-Beleg (24.07.2026, ueber Portal-API, eingeloggt als matthias)

GET /api/shadow/gpu/status
{
  "vm_online": true,
  "token_ok": false,
  "token_reason": "Shadow lehnt die Login-Session ab (Login-Page without kratos) - einmalig einloggen: http://100.111.0.111:6070",
  "cookie_info": {"kratos_ttl_days":29.38,"cf_ttl_days":364.38,"oauth_ttl_min":55.7,"oauth_has_refresh_token":true}
}
GET /api/shadow/gpu/session_health
{"kratos_session_ttl_days":29.38,"cf_clearance_ttl_days":364.38,"oauth_ttl_min":55.7,...}

Beide Stellen zeigen jetzt denselben abgeleiteten Zustand (rot/Login-noetig), die Cookie-TTLs werden separat als Zusatzinfo mitgeliefert. Kein Widerspruch mehr.

Hinweis Bildschirmfoto: Browser-Pane in dieser Session zeigte die SPA nicht zuverlaessig (App-Div blieb trotz bestaetigtem /api/check -> authenticated:true unsichtbar, vermutlich Automatisierungs-/Session-Artefakt bei parallel geoeffneten Tabs). Verifikation daher direkt ueber die Portal-eigenen Fetch-Aufrufe (identischer Code-Pfad wie die UI-Badges) im Seiten-Kontext, nicht per Screenshot.

Auftrag 2: Idle-Teardown Pause-Schalter je Knoten

Neue PHP-Actions idle_pause (GET) / idle_pause_set (POST, value=on|off) in shadow.php, video-shadow.php, monster.php (jump_control, 100.91.98.15) - lesen/schreiben direkt /opt/idle-teardown/state/.paused (www-data hat jetzt Schreibrechte auf das state-Verzeichnis, chgrp www-data + chmod 775).

Portal-Backend: /api/shadow/{node}/idle_pause (GET) und /api/shadow/{node}/idle_pause_set (POST, JSON {"value":"on"|"off"}) fuer node in gpu, video, monster.

Portal-Frontend: Auf der GPUPCs/#shadow-Seite je Knotenkarte ein Toggle "Auto-Aus nach 60 Min Idle" (an/aus), Zustand kommt live aus der Flag-Datei (kein Raten), inkl. letzter Idle-Log-Zeile als Zusatzinfo.

Live-Beleg Toggle (ueber Portal-API)

POST /api/shadow/monster/idle_pause_set {"value":"on"}  -> {"ok":true,"paused":true}
GET  /api/shadow/monster/idle_pause                     -> {"paused":true, "last_log_line":"..."}
POST /api/shadow/monster/idle_pause_set {"value":"off"} -> {"ok":true,"paused":false}

Flag-Datei auf dem Hub nachgewiesen erschienen/verschwunden (/opt/idle-teardown/state/monster.paused). Video-shadow Default-Zustand (pausiert = VM bleibt an) unveraendert wiederhergestellt.

Ablauf (Portal-Skill befolgt)

Backup (app.py.bak-token-idle-, app.py.bak-truthfix-) -> py_compile -> Testinstanz :9092 (HTTP 200) -> systemctl restart gpu1-portal.service -> systemctl is-active = active -> https://cp.go-ki.eu/ HTTP 200. PHP-Dateien auf jump_control ebenfalls gesichert (.bak-idlepause-, .bak-loginstatus-), php -l sauber.

Geaenderte Dateien

  • VM201 /opt/gpu1-status/app.py (Backend _gpu_token_health(), neue Endpoints /api/shadow/{node}/idle_pause[_set], /api/shadow/gpu/login_status; Frontend Token-Badge + 3x Idle-Toggle-Zeilen + JS loadIdlePause()/toggleIdlePause())
  • jump_control (100.91.98.15) shadow.php, monster.php, video-shadow.php (neue Actions idle_pause, idle_pause_set, login_status in shadow.php)
  • /opt/idle-teardown/state/ Gruppe auf www-data, chmod 775 (reversibel)