From 6b1cc975c0fbdbdef8373578d705e8961562a514 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Sat, 9 May 2026 03:28:22 +0000 Subject: [PATCH] Phase 7: sync_shared.py - Mojibake-fail-safe + Doku MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- CLAUDE.md | 5 +++++ scripts/sync_shared.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2069d17..74d7e1f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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" diff --git a/scripts/sync_shared.py b/scripts/sync_shared.py index 91ba107..ab8761b 100755 --- a/scripts/sync_shared.py +++ b/scripts/sync_shared.py @@ -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 ""