Antigravity-Review-Fixes: Traversal-Guard, Client-Pooling, Cache-Lock, Doku

Vier verifizierte Befunde aus dem externen Review (Gemini 3.1 Pro):
- app.py: SPA-Fallback gegen Path-Traversal gehaertet (resolve + is_relative_to,
  liefert nur noch Dateien INNERHALB von frontend/dist aus).
- app.py/gateway_proxy.py: geteilter httpx.AsyncClient im lifespan statt neuer
  Client pro /v1-Anfrage (Keep-Alive/Pooling, spart Sockets unter parallelen Agent-Stroemen).
- system.py: check_versions_cached() mit threading.Lock + Double-Check gegen Scan-Stampede.
- AGENTS.md: Zeitzonen-Drift korrigiert (Box laeuft Europe/Berlin, nicht UTC).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-05 10:21:32 +02:00
parent ff1b9a085f
commit 12c387a6de
4 changed files with 51 additions and 30 deletions
+21 -12
View File
@@ -9,6 +9,7 @@ der Box, daher sysfs). Verschachtelte Struktur wie v1 (cpu.percent, ram.used Byt
import glob
import os
import subprocess
import threading
import psutil
@@ -157,6 +158,7 @@ def get_engine_version() -> dict:
_VERSION_CACHE = {"ts": 0.0, "data": {}}
_VERSION_LOCK = threading.Lock()
def check_versions_cached() -> dict:
@@ -164,18 +166,25 @@ def check_versions_cached() -> dict:
now = time.time()
if now - _VERSION_CACHE["ts"] < 30.0:
return _VERSION_CACHE["data"]
mc2_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
data = {
"mc2": get_git_info(mc2_path),
"engine": get_engine_version(),
"hermes_ui": get_git_info("~/hermes-webui"),
"hermes_agent": find_hermes_agent_git()
}
_VERSION_CACHE["ts"] = now
_VERSION_CACHE["data"] = data
return data
# Lock gegen Scan-Stampede: FastAPI führt sync-Routen im Threadpool aus → ohne Lock würden
# parallele Dashboard-/Agent-Aufrufe die git-/Versions-Scans mehrfach gleichzeitig anwerfen.
# Doppelt geprüft, damit ein zweiter Thread den frisch gefüllten Cache nimmt statt neu zu scannen.
with _VERSION_LOCK:
now = time.time()
if now - _VERSION_CACHE["ts"] < 30.0:
return _VERSION_CACHE["data"]
mc2_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
data = {
"mc2": get_git_info(mc2_path),
"engine": get_engine_version(),
"hermes_ui": get_git_info("~/hermes-webui"),
"hermes_agent": find_hermes_agent_git()
}
_VERSION_CACHE["ts"] = now
_VERSION_CACHE["data"] = data
return data
def system_status() -> dict: