Phase 7: sync_shared.py - Mojibake-fail-safe + Doku

- has_mojibake_markers Heuristik: erkennt Doppel/Triple-Encoded UTF-8
  (typische Latin-1-Sicht-Sequenzen wie ä ö ¤ Æ).
- fix_mojibake raises RuntimeError wenn ftfy fehlt UND Mojibake erkannt
  ist - verhindert Mojibake-Reimport durch Sync.
- main() faengt RuntimeError und exit 2 mit klarer Fehlermeldung.
- CLAUDE.md: Voraussetzung ftfy + fail-safe-Erklaerung erganzt.
Dieser Commit ist enthalten in:
claude-dev
2026-05-09 03:28:22 +00:00
Ursprung a5f2c1d59e
Commit 6b1cc975c0
2 geänderte Dateien mit 31 neuen und 2 gelöschten Zeilen

Datei anzeigen

@@ -183,6 +183,11 @@ shared:
grund: "Verwaltungs-Fork mit tenant_id-Filter weg + Historie + Config-Konstanten"
hinweis: "Auto-Sync schreibt NICHT. Drift wird gemeldet, manuell entscheiden."
voraussetzung:
ftfy installieren: "pip install ftfy" (im venv des Repos)
grund: "Sync-Skript fixed Mojibake aus Monitor-Originalen automatisch."
fail_safe: "Ohne ftfy bricht das Skript ab wenn Mojibake erkannt - schuetzt vor Mojibake-Reimport."
beim_drift:
nicht_locked: "einfach --apply, dann committen"
locked: "diff anschauen, ueberlegen ob die Monitor-Aenderung im Verwaltungs-Fork sinnvoll ist"

Datei anzeigen

@@ -51,11 +51,31 @@ DEFAULT_MONITOR = Path("/home/claude-dev/AegisSight-Monitor")
DEFAULT_VERWALTUNG = Path(__file__).resolve().parent.parent
def has_mojibake_markers(text: str) -> bool:
"""Heuristik: Doppel/Triple-Encoded UTF-8 erkennen.
Echte deutsche Umlaute kommen als "ü" / "ä" / "ö" / "ß" - Single-Byte-Zeichen
aus latin-1-Sicht ("Ã", "Â", "Æ") sind ein starkes Mojibake-Indiz.
"""
return any(seq in text for seq in ("ä", "ö", "ü", "ß", "Ä", "Ö", "Ü", "¤", "Æ"))
def fix_mojibake(text: str) -> tuple[str, bool]:
"""Repariert Doppel-Encoded UTF-8 falls vorhanden. Gibt (text, fixed?) zurück."""
"""Repariert Doppel-Encoded UTF-8 falls vorhanden. Gibt (text, fixed?) zurück.
Raises RuntimeError wenn Mojibake erkannt wird aber ftfy nicht installiert ist
(dann würde ein Sync den Mojibake unrepariert ins Verwaltungs-Repo schreiben -
dagegen schützt fail-fast).
"""
try:
import ftfy # type: ignore
except ImportError:
if has_mojibake_markers(text):
raise RuntimeError(
"Monitor-Source enthält Mojibake (Doppel-Encoded UTF-8) und ftfy "
"ist nicht installiert. Sync würde Mojibake ins Verwaltungs-Repo "
"schreiben.\n Lösung: pip install ftfy (im venv des Repos)"
)
return text, False
fixed = ftfy.fix_text(text)
return fixed, fixed != text
@@ -126,7 +146,11 @@ def main() -> int:
return 2
src_text = src_path.read_text(encoding="utf-8")
src_text, fixed_mojibake = fix_mojibake(src_text)
try:
src_text, fixed_mojibake = fix_mojibake(src_text)
except RuntimeError as e:
print(f"FEHLER beim Verarbeiten von {monitor_rel}:\n {e}", file=sys.stderr)
return 2
src_text = patch_imports_for_shared(src_text)
existing = dst_path.read_text(encoding="utf-8") if dst_path.exists() else ""