Explorer
/tmp/fast-repeat-50.json
← Zurück ↓ Download
{"queue_id": 50, "relative_path": "Solutions/SOL_006_REPAIRABILITY_REPORT.md", "title": "SOL_006_REPAIRABILITY_REPORT", "import_key": "8bcaaf134201fe2154213ad37739a85e7e32a25f1fd0888aaf8acb5673d21824", "chunk_count": 52, "created_nodes": 0, "created_relationships": 0, "body": null, "chunks": [{"chunk_key": "2e9bc684175d7e4d43863046282d920fd8b0a1e16baeaa0bf83e909c92442563", "chunk_index": 0, "heading": "SOL_006_REPAIRABILITY_REPORT", "text": "# SOL_006_REPAIRABILITY_REPORT\nReparierbarkeits-Analyse der in SOL-006 identifizierten Probleme\nErstellt: 2026-05-28 | Keine Änderungen durchgeführt\n\n---", "text_hash": "3595a17eaa0428b6149aabd04fa005f8d0a6aac23896d436108d048bbeaef732"}, {"chunk_key": "f3b622008250a2d304dbd372373f791b18cd3c65a7aaa1a5b4cddc65aa944da9", "chunk_index": 1, "heading": "REGEL-01: Lebensmittel-Schimmel vs. Immobilien-Schimmel", "text": "OL_006_REPAIRABILITY_REPORT\nReparierbarkeits-Analyse der in SOL-006 identifizierten Probleme\nErstellt: 2026-05-28 | Keine Änderungen durchgeführt\n\n---\n## REGEL-01: Lebensmittel-Schimmel vs. Immobilien-Schimmel", "text_hash": "840eb27a23359ab2b6d03439e2faec0edacbc77f5f02b77b4695985c23dbdbd2"}, {"chunk_key": "b12707e5b1e6de12bee22015a835175f5a78d1dad203bec1fc00403f8fcdb3f1", "chunk_index": 2, "heading": "Ursache (präzise)", "text": "## REGEL-01: Lebensmittel-Schimmel vs. Immobilien-Schimmel\n### Ursache (präzise)\n\n`signal_classifier.py`, Funktion `score_signal()`, Kategorie-Zuweisung ca. Zeile 307:\n\n```python\nif core_hits > 0 and (\"schimmel\" in t or \"mold\" in t or \"moho\" in t):\n    signal_category = \"schimmel_risiko\"\n```\n\n`CORE_DE` enthält \"schimmel\" als erstes Keyword. Jeder Text mit \"Schimmel\" triggert `core_hits > 0`. Die Bedingung prüft dann erneut auf \"schimmel\" in t — was bei Lebensmittel-Titeln wie \"Schimmel-Essen\" oder \"Schimmel auf dem Schinken\" genauso zutrifft wie bei Gebäudeschimmel.\n\nEs gibt keine Kontextprüfung. Lebensmittel-Keywords fehlen in `IRRELEVANT_KW` vollständig (vorhanden: \"restaurant\", \"gastronomie\" — aber nicht \"Lebensmittel\", \"Schinken\", \"Essen\" als Food-Kontext, \"abgelaufen\", \"Gammel\").\n\nDer `topic_class`-Mechanismus hilft hier nicht: `topic_class = \"irrelevant\"` greift nur wenn `irrelevant_hits >= 2 AND core_hits == 0 AND main_geo == 0`. Da \"schimmel\" aber in `CORE_DE` steht, ist `core_hits > 0` — die irrelevant-Logik greift nie.", "text_hash": "41f6d0e245c0a74141be661972a811e45eefb85e7ca9832d6e02c698c34adcd4"}, {"chunk_key": "8d1f3887c6923e93ffe0af741dec98d128280b997d038585cdde8c951bda35f6", "chunk_index": 3, "heading": "Betroffene Datei", "text": "elevant_hits >= 2 AND core_hits == 0 AND main_geo == 0`. Da \"schimmel\" aber in `CORE_DE` steht, ist `core_hits > 0` — die irrelevant-Logik greift nie.\n### Betroffene Datei\n\n`/opt/struktur/social-media-radar/classification/signal_classifier.py`", "text_hash": "0ab48257f9c02b6c8600168833458af08f266a8aba8f6e66f7e2c4b3c09fc4db"}, {"chunk_key": "b2a9188c96867391de743662f83b8d0486eda667c28c6f6c56e6dc4126d411f8", "chunk_index": 4, "heading": "Konkrete Funktion", "text": "### Betroffene Datei\n\n`/opt/struktur/social-media-radar/classification/signal_classifier.py`\n### Konkrete Funktion\n\n`score_signal()` — Abschnitt \"Signal-Kategorie\" (ca. Zeile 297-307)", "text_hash": "461431b788aa7e06fb6fa46832443a627eda61d1f07dcbd2dcf0af8324c65e82"}, {"chunk_key": "ff2bc034dcfaa4839b53273097be50defd9b7842e58ef689205fb177c46889ba", "chunk_index": 5, "heading": "Änderungsumfang", "text": "### Konkrete Funktion\n\n`score_signal()` — Abschnitt \"Signal-Kategorie\" (ca. Zeile 297-307)\n### Änderungsumfang\n\n**Klein** — 1 neue Keyword-Liste `FOOD_CONTEXT_KW` (ca. 6-8 Keywords), 1 Guard-Bedingung in der schimmel_risiko-Zuweisung.\n\nÄnderung in 2 Stellen:\n1. Neue Liste im Keyword-Abschnitt: `FOOD_CONTEXT_KW = [\"lebensmittel\", \"schinken\", \"fleisch\", \"gammel\", \"abgelaufen\", \"speise\", \"mahlzeit\", \"schulessen\", \"lebensmittelkontrolle\"]`\n2. Guard in der Kategorie-Logik: `food_hit = _hits(text, FOOD_CONTEXT_KW)` + zusätzliche Bedingung `and food_hit == 0` in der schimmel_risiko-Zuweisung.", "text_hash": "8a0618352079465793cb2c65413b2624edffa656ebbc48c889f85071bcf462d9"}, {"chunk_key": "798034f69a18095a7113ad9275c34e2b86ba1bbdc450edc5bb8d450b71efcf43", "chunk_index": 6, "heading": "Risiko der Änderung", "text": " Guard in der Kategorie-Logik: `food_hit = _hits(text, FOOD_CONTEXT_KW)` + zusätzliche Bedingung `and food_hit == 0` in der schimmel_risiko-Zuweisung.\n### Risiko der Änderung\n\nNiedrig. Die vorgeschlagenen Keywords sind lebensmittelspezifisch und kommen in Gebäude-/Immobilienkontexten nicht vor. Keine bekannten False-Negatives im bestehenden Datensatz. Erfordert Rescore der betroffenen Signale (~50-100 Stück mit \"schimmel\" im Titel).", "text_hash": "591e1a8963298e346bcbecf9980f33958972a286cbe24383d02a884d6fa9dbec"}, {"chunk_key": "0c0b58ec8638c4d031efbe070385f6a613951740d52538b2ace1b94066c8be93", "chunk_index": 7, "heading": "Empfohlene Lösung", "text": "icht vor. Keine bekannten False-Negatives im bestehenden Datensatz. Erfordert Rescore der betroffenen Signale (~50-100 Stück mit \"schimmel\" im Titel).\n### Empfohlene Lösung\n\n```", "text_hash": "10f59f8f61b997d1ac8a8de7c8033d9e526f2084b67a778aec3d0def08f00bfb"}, {"chunk_key": "f5a8f490e817c64ca26c740f3426795fbe956b366f65e66fa1caecd1f9489658", "chunk_index": 8, "heading": "Neue Liste hinzufügen (im Keyword-Abschnitt):", "text": "### Empfohlene Lösung\n\n```\n# Neue Liste hinzufügen (im Keyword-Abschnitt):\nFOOD_CONTEXT_KW = [\"lebensmittel\", \"schinken\", \"fleisch\", \"gammel\",\n                   \"abgelaufen\", \"speise\", \"mahlzeit\", \"schulessen\",\n                   \"lebensmittelkontrolle\", \"gammelfleisch\"]", "text_hash": "83b2d77e7e1cfb19e268499786774aed91e4edf41cd5b732e6d93810bab4af86"}, {"chunk_key": "37513851640103d24909bac8ef7365b502e0e44f004a9f0dd513fbc3b09c9c53", "chunk_index": 9, "heading": "In score_signal(), vor der Kategorie-Zuweisung:", "text": "\"fleisch\", \"gammel\",\n                   \"abgelaufen\", \"speise\", \"mahlzeit\", \"schulessen\",\n                   \"lebensmittelkontrolle\", \"gammelfleisch\"]\n# In score_signal(), vor der Kategorie-Zuweisung:\nfood_hit = _hits(text, FOOD_CONTEXT_KW)", "text_hash": "d6fa4b1740ab009a3a1154bc07dc6b59caf5f867fd2567391848f810bd3f852f"}, {"chunk_key": "f564939be4996f7b5b1808c1a8d316565fee1aa160769ccc5d9a935d5df1c087", "chunk_index": 10, "heading": "Kategorie-Logik anpassen:", "text": "# In score_signal(), vor der Kategorie-Zuweisung:\nfood_hit = _hits(text, FOOD_CONTEXT_KW)\n# Kategorie-Logik anpassen:\nif core_hits > 0 and (\"schimmel\" in t or \"mold\" in t or \"moho\" in t) and food_hit == 0:\n    signal_category = \"schimmel_risiko\"\n```", "text_hash": "3071c51e51a21a79f59c733688c5848eed1b55cee2afda1dfa2c188441f6e220"}, {"chunk_key": "0ae6cbe392324a4f560aafc0f70632874b5822b1146a321c1ef2287c64e8d05b", "chunk_index": 11, "heading": "Reparierbarkeit", "text": "ie-Logik anpassen:\nif core_hits > 0 and (\"schimmel\" in t or \"mold\" in t or \"moho\" in t) and food_hit == 0:\n    signal_category = \"schimmel_risiko\"\n```\n### Reparierbarkeit\n\n**EINFACH** — lokale Änderung, kein Architektureingriff, minimal invasiv.\n\n---", "text_hash": "442d829711401e41c8dfbe923c2206c5effe1a193c100b8a832c3ed437da806f"}, {"chunk_key": "2c004a51616a734350e9bb75301f55406a75202e5fdf789b9800c8c4ff17fd5a", "chunk_index": 12, "heading": "REGEL-02 + UI-01: Director/Briefing-Widerspruch", "text": "### Reparierbarkeit\n\n**EINFACH** — lokale Änderung, kein Architektureingriff, minimal invasiv.\n\n---\n## REGEL-02 + UI-01: Director/Briefing-Widerspruch", "text_hash": "710d8dc985fa6c4ba7ce5419658da6ed5d7d91c7172be1bddcd3bb0dab61ad53"}, {"chunk_key": "c00ddf03bba4c7591332eecce414cd75963f49643ba2efa9d704c96fc4c31c08", "chunk_index": 13, "heading": "Ursache (präzise)", "text": "## REGEL-02 + UI-01: Director/Briefing-Widerspruch\n### Ursache (präzise)\n\n**Architektonisch:** Director und Briefing sind seitlich parallel, nicht hierarchisch. Director läuft zuerst und setzt `director_action`. Briefing filtert dann auf `director_action = 'pruefen'` und setzt `briefing_freigabe`. Es gibt keine Rückkopplung.\n\n**Im Director** (`content_director.py`, `compute_director_score()`):\n\n```python\nif publish_blocks and publishing_value < 30:\n    action = \"beobachten\"\nelif director_score >= 70 and not publish_blocks:\n    action = \"veroeffentlichen\"\nelif director_score >= 55:\n    action = \"pruefen\"   # <-- wetter_klima landet hier (Score 56-65)\n```\n\nDer Director kennt `briefing_freigabe` nicht — er schaut nur auf `publish_blocks` und `director_score`. wetter_klima ohne `publish_blocks` + Score ≥55 → immer `pruefen`.\n\n**Im Briefing** (`content_briefing.py`, `_get_freigabe()`):\n\n```python\nif cat == \"wetter_klima\" and topic_cls == \"sekundaer\":\n    return \"zurueckstellen\"   # <-- explizite Regel, unabhängig vom Director\n```\n\nBriefing liest `director_score` (Zeile: `dir_score = sig.get(\"director_score\", 0)`), aber überschreibt nie `director_action`. Director liest nie `briefing_freigabe`.\n\n**Keine Hierarchie definiert** — beide Outputs stehen gleichrangig im UI nebeneinander.", "text_hash": "8fd399b9715cae80a5fa5544cf742a006a80e0b7b88f39656b0ad7fce65332ad"}, {"chunk_key": "3a5bbef8dac6b1589a49376b6560b3e57e26611811608de4af8173c6a1b0d79c", "chunk_index": 14, "heading": "Betroffene Dateien", "text": "ie `director_action`. Director liest nie `briefing_freigabe`.\n\n**Keine Hierarchie definiert** — beide Outputs stehen gleichrangig im UI nebeneinander.\n### Betroffene Dateien\n\n- `/opt/struktur/social-media-radar/content_director.py` — `compute_director_score()`\n- `/opt/struktur/social-media-radar/content_briefing.py` — `_get_freigabe()`, `run()`\n- `/opt/struktur/social-media-agent/templates/cockpit.html` — Director-Block-Rendering (Zeile ~708-732)", "text_hash": "4a5504898ce26e57465b37cf712df6888c7cac9b321ff3cb3e33fa42c3cb6b21"}, {"chunk_key": "8a76823ceaa4d92850602b4ae73687556d12e3141c486ff49f6c9f3415140126", "chunk_index": 15, "heading": "Konkrete Funktionen", "text": "tent_briefing.py` — `_get_freigabe()`, `run()`\n- `/opt/struktur/social-media-agent/templates/cockpit.html` — Director-Block-Rendering (Zeile ~708-732)\n### Konkrete Funktionen\n\n- `content_director.py`: Action-Entscheidungsbaum (letzte ~10 Zeilen von `compute_director_score()`)\n- `content_briefing.py`: `_get_freigabe()` (gibt Briefing-Freigabe zurück), `run()` (schreibt in DB)\n- `cockpit.html`: `dirHtml`-Rendering-Block (~Zeile 708-732)", "text_hash": "bd77a7563a04f3e1b82ec9f0ba68e59c09fe9d9dbb4056e38264ad23b3dcb601"}, {"chunk_key": "0f8af8d299758cf3e04014f10cc54b579b853af26a2cc9e5a2ae7a16ceaa49b3", "chunk_index": 16, "heading": "Wer hat finale Autorität?", "text": "briefing.py`: `_get_freigabe()` (gibt Briefing-Freigabe zurück), `run()` (schreibt in DB)\n- `cockpit.html`: `dirHtml`-Rendering-Block (~Zeile 708-732)\n### Wer hat finale Autorität?\n\nDas Briefing ist redaktionelle Entscheidungsebene (prüft MAS-Kernbezug, Risiko, Plattform-Fit). Der Director ist ein numerischer Publishing-Score. Semantisch sollte das Briefing Vorrang haben — aber das ist nirgendwo in Code definiert.", "text_hash": "ffb6c3274b1e0cb7281bf7cc34dfc9a56e658f14afb76ed8a24798006caa5ed6"}, {"chunk_key": "338b1f37303e5a60387d83c820902cf78435e55733b971f837fb16667ca59563", "chunk_index": 17, "heading": "Minimale Änderung — zwei Optionen", "text": "form-Fit). Der Director ist ein numerischer Publishing-Score. Semantisch sollte das Briefing Vorrang haben — aber das ist nirgendwo in Code definiert.\n### Minimale Änderung — zwei Optionen\n\n**Option A — Briefing schreibt Director zurück (Datenebene, empfohlen):**\n\nIn `content_briefing.py`, `run()`, nach dem DB-UPDATE des Briefings:\n\n```python\nif result[\"briefing_freigabe\"] in (\"zurueckstellen\", \"verwerfen\"):\n    if sig[\"director_action\"] in (\"pruefen\", \"veroeffentlichen\"):\n        conn.execute(\n            \"UPDATE signals SET director_action = 'beobachten' WHERE signal_id = ?\",\n            (sig[\"signal_id\"],)\n        )\n```\n\nUmfang: ~5 Zeilen. Effekt: `director_action` in DB stimmt mit `briefing_freigabe` überein. Kein UI-Konflikt mehr.\n\nRisiko dieser Option: Wenn Director danach erneut standalone läuft (`python3 content_director.py`), überschreibt er den Wert wieder. Die Reihenfolge Director → Briefing muss stabil sein. Im Scheduler muss Briefing immer nach Director laufen — das ist aktuell bereits so.\n\n**Option B — UI-Overlay (Sichtbarkeitsebene, ergänzend):**\n\nIn `cockpit.html`, im `dirHtml`-Block (~Zeile 712):\n\n```javascript\n// Nach: const dColor = DA_COLORS[s.dir_action] || '#64748b';\nconst dirOverridden = s.b_freig === 'zurueckstellen' || s.b_freig === 'verwerfen';\n// Im dirHtml-Template: border-color zu grau wenn overridden, + Overlay-Text\n```\n\nUmfang: ~8 Zeilen JS. Effekt: Director-Block wird visuell zurückgestellt wenn Briefing widerspricht.", "text_hash": "1408deb4fedc32fddffd3f29ba46a92b961e851e4477c5c563847e861ec720cf"}, {"chunk_key": "bc31e376266139865a2146fa4e3fb6c6b9e1823530d1d7644e95527570b0cc1d", "chunk_index": 18, "heading": "Risiko der Änderung", "text": "olor zu grau wenn overridden, + Overlay-Text\n```\n\nUmfang: ~8 Zeilen JS. Effekt: Director-Block wird visuell zurückgestellt wenn Briefing widerspricht.\n### Risiko der Änderung\n\nMittel. Option A verändert die Kanonizität von `director_action` in der DB. Wenn Director-Run und Briefing-Run zeitlich auseinanderlaufen (z.B. Director nochmal manuell), kommt der Widerspruch zurück. Option B ist UI-only und damit stabiler, aber löst das Datenproblem nicht.\n\n**Empfehlung: Beide Optionen kombinieren** — A für Datenkonsistenz, B für sofortigen UI-Effekt ohne Warten auf nächsten Run.", "text_hash": "7c7b7349aac9879d561fa1c30869f1bc4ee6ad3b9e15395051f22214f2978788"}, {"chunk_key": "8cffb8fea57e036a3b5be506f18a0348ba429d2de2a097c3d5aebf2e345b4c96", "chunk_index": 19, "heading": "Reparierbarkeit", "text": " das Datenproblem nicht.\n\n**Empfehlung: Beide Optionen kombinieren** — A für Datenkonsistenz, B für sofortigen UI-Effekt ohne Warten auf nächsten Run.\n### Reparierbarkeit\n\n**REPARABEL** — architektonisch nicht trivial (Modulkopplung), aber lokal lösbar in ~13 Zeilen ohne strukturellen Umbau.\n\n---", "text_hash": "29460d3bab0ea642d129cd7226fd692bb7c7b0849b6628887c170107b7dbe282"}, {"chunk_key": "e38744c522c993688484a219a1c064374a1f1c38e506e5580066f9ca587d0fba", "chunk_index": 20, "heading": "UI-02: Post-Button trotz negativer Freigabe", "text": "### Reparierbarkeit\n\n**REPARABEL** — architektonisch nicht trivial (Modulkopplung), aber lokal lösbar in ~13 Zeilen ohne strukturellen Umbau.\n\n---\n## UI-02: Post-Button trotz negativer Freigabe", "text_hash": "8999d1ebb858a8883ecadda5d76aa38a6163f63e7a69731f423f1e1e2273c11b"}, {"chunk_key": "02179a88167bd0d4999ef39e4e1d30178a8d2da265f6be1d1698f4308d04ef74", "chunk_index": 21, "heading": "Ursache (präzise)", "text": "## UI-02: Post-Button trotz negativer Freigabe\n### Ursache (präzise)\n\n`cockpit.html`, im `acts`-Template-String (Zeile 841-842):\n\n```javascript\n<div class=\"act\" onclick=\"createPostFromSignal('${s.id}','${x(s.topic_de||s.title)}','${s.apl||'facebook'}')\">\n  <span><div>Post erstellen</div>...\n</div>\n```\n\nDer Button hat keinerlei Bedingung. `s.b_freig` ist bereits im JS-Signal-Objekt (Zeile 295: `b_freig: {{(s.briefing_freigabe or \"\")|tojson}}`) — die Variable ist vorhanden, wird aber im Button-Rendering nicht ausgewertet.", "text_hash": "06c37e4d54f5395d792367425c8e54fbc9963347e2cfc63ad29f42381f533207"}, {"chunk_key": "981243144f2a60760e65dfdf1d8f6ad5e2a9a3c6334fab05fcfaeb8e027a8c44", "chunk_index": 22, "heading": "Betroffene Datei", "text": "l-Objekt (Zeile 295: `b_freig: {{(s.briefing_freigabe or \"\")|tojson}}`) — die Variable ist vorhanden, wird aber im Button-Rendering nicht ausgewertet.\n### Betroffene Datei\n\n`/opt/struktur/social-media-agent/templates/cockpit.html`", "text_hash": "86b6dfe8a4faf91309a7a9a024d9074776966076e409d5d5c6be6c164445e8f3"}, {"chunk_key": "f4e8f0374337b149995d523496e0d1216f2385dbfc5acd4f01101ec17d217614", "chunk_index": 23, "heading": "Konkrete Funktion", "text": "### Betroffene Datei\n\n`/opt/struktur/social-media-agent/templates/cockpit.html`\n### Konkrete Funktion\n\n`acts`-Konstante im Signal-Detail-Rendering (Zeile ~836-845)", "text_hash": "b111e04d0dc9f82db237aaa76e9c0739a87e68e8a96cba64ab494bd4c1603164"}, {"chunk_key": "b8855ed8ff6be1502863212796173ec77fe32e0ed0865aad42af938111638e77", "chunk_index": 24, "heading": "Ist rein UI-seitig möglich?", "text": "### Konkrete Funktion\n\n`acts`-Konstante im Signal-Detail-Rendering (Zeile ~836-845)\n### Ist rein UI-seitig möglich?\n\n**Ja.** Backend-Validierung ist nicht notwendig, da `createPostFromSignal()` keinen automatischen Publish-Prozess auslöst — es öffnet ein Draft-Formular. Die Sperre ist eine UI-Schutzmaßnahme, kein Sicherheitsmerkmal.", "text_hash": "5c37a9c7ab7fe6d7e088494a1dae6a19469c2ba9ebaba544b1ed26b462db1d71"}, {"chunk_key": "8b2d789fbea3c97dee354d22c5e4e614c3be244edd43ee577c39b3ee2f6d8d45", "chunk_index": 25, "heading": "Empfohlene Lösung", "text": "Signal()` keinen automatischen Publish-Prozess auslöst — es öffnet ein Draft-Formular. Die Sperre ist eine UI-Schutzmaßnahme, kein Sicherheitsmerkmal.\n### Empfohlene Lösung\n\n```javascript\n// Vor dem acts-String:\nconst canPost = !(s.b_freig === 'zurueckstellen' || s.b_freig === 'verwerfen');\nconst postBtnTitle = canPost ? '' : `title=\"Freigabe: ${s.b_freig} — Signal zuerst prüfen\"`;\n\n// Im acts-String ersetzen:\n// ALT:\n<div class=\"act\" onclick=\"createPostFromSignal(...)\">\n// NEU:\n<div class=\"${canPost ? 'act' : 'act dis'}\" ${canPost ? `onclick=\"createPostFromSignal(...)\"` : ''} ${postBtnTitle}>\n```", "text_hash": "434addc5c98586ab0247989fac4a64c5ad05dbed787e25862f3fb26a1263b910"}, {"chunk_key": "a6bf135af48e03a5872c698562d7469d4d8fef0b7e5077713b6a0e538694023d", "chunk_index": 26, "heading": "Änderungsumfang", "text": "PostFromSignal(...)\">\n// NEU:\n<div class=\"${canPost ? 'act' : 'act dis'}\" ${canPost ? `onclick=\"createPostFromSignal(...)\"` : ''} ${postBtnTitle}>\n```\n### Änderungsumfang\n\n**Klein** — 2 neue Variablen + 1 Zeile geändert. Keine Backend-Änderung.", "text_hash": "f19da73938c735de7dba344956a2315195b8cd20d74a4ff45820f2e523f5a9aa"}, {"chunk_key": "ac31f688179ee7c7bad658669a51e876a078ff996e7a93327e89aef9528c5b6a", "chunk_index": 27, "heading": "Risiko der Änderung", "text": "### Änderungsumfang\n\n**Klein** — 2 neue Variablen + 1 Zeile geändert. Keine Backend-Änderung.\n### Risiko der Änderung\n\nNiedrig. Der `class=\"act dis\"` Stil ist bereits im CSS definiert (für \"Veröffentlichen / Planen\"). Keine neuen Stile nötig.", "text_hash": "4d0f5ffe6a9a986dbdafc5b846e11f570fc707d7a2a14ed00c3ab92ecb9cdca3"}, {"chunk_key": "236b3824cdac38ad94182842f50d1641ce35fbf242f5673e48c038300cce8ece", "chunk_index": 28, "heading": "Reparierbarkeit", "text": "### Risiko der Änderung\n\nNiedrig. Der `class=\"act dis\"` Stil ist bereits im CSS definiert (für \"Veröffentlichen / Planen\"). Keine neuen Stile nötig.\n### Reparierbarkeit\n\n**EINFACH** — rein UI-seitig, keine Abhängigkeiten.\n\n---", "text_hash": "714cf6d77b139e98c54a2645536d4392f99511ff8fa7277310c4cee8499feb3e"}, {"chunk_key": "8ca985b155c68e1fc7143ecac10ac62450a75f925f7be317235109f7ea13d229", "chunk_index": 29, "heading": "REGEL-03: Todesfall-/Ethik-Flag", "text": "### Reparierbarkeit\n\n**EINFACH** — rein UI-seitig, keine Abhängigkeiten.\n\n---\n## REGEL-03: Todesfall-/Ethik-Flag", "text_hash": "ad3eb4d42e14b44f9a8f415e55b69c06fac03eb2a425b4dde9c9884bf8de1580"}, {"chunk_key": "632364e0e3831b3d56f6802eb109d0c5d25be5f267fb8a91266147fa654d0061", "chunk_index": 30, "heading": "Ursache (präzise)", "text": "## REGEL-03: Todesfall-/Ethik-Flag\n### Ursache (präzise)\n\n`content_briefing.py`, Funktion `_get_risiko()`:\n\n```python\ndef _get_risiko(sig: dict, hits: dict) -> str:\n    # ... prüft PR-Treffer, Wetter-Bezug, Konkurrenz\n    if not risiken:\n        return \"Kein erhöhtes Risiko identifiziert\"\n```\n\nEs gibt keine Prüfung auf Todesfall-Keywords. Die Funktion erhält das vollständige `sig`-Dict (DB-Row) — `sig.get(\"topic\")` ist verfügbar und enthält den Signaltitel (z.B. \"Derrumbe mortal en Manacor...\").\n\nDie `_get_freigabe()` liest `director_score`, `director_blocks`, `topic_cls` — aber nicht den Titeltext. Ein Todesfall-Signal kann dadurch `briefing_freigabe: pruefen` statt `pruefen` (mit Pflicht-Warntext) erhalten.\n\nBestehende Risikostruktur ist vorhanden — der Code-Pfad existiert, nur die Todesfall-Erkennung fehlt.", "text_hash": "de0435c8f5f70a8f48c680660d226618f8d60e1b1b19c3332556a286be79caf7"}, {"chunk_key": "9209a08cacadc6ab7d9933ead56c43e975ea47e7bd8ff8468d2c723502b7acee", "chunk_index": 31, "heading": "Betroffene Datei", "text": "tatt `pruefen` (mit Pflicht-Warntext) erhalten.\n\nBestehende Risikostruktur ist vorhanden — der Code-Pfad existiert, nur die Todesfall-Erkennung fehlt.\n### Betroffene Datei\n\n`/opt/struktur/social-media-radar/content_briefing.py`", "text_hash": "b73e53afc1ac4a5e340472d9b180e7532ec25a8e5fce6eedafd5586fdc2378f9"}, {"chunk_key": "60ca21364985f6cb248809c3e9ee6f66de7a1798eed4b31870b5d2c88f8db7d4", "chunk_index": 32, "heading": "Konkrete Funktion", "text": "### Betroffene Datei\n\n`/opt/struktur/social-media-radar/content_briefing.py`\n### Konkrete Funktion\n\n`_get_risiko()` — am Anfang, vor PR-Check", "text_hash": "9aa39afbc1d3cb4b1361f8a1f5bdcc7c0d6010faef53eb4ab3546659cbfe4cc6"}, {"chunk_key": "81bde66d4a7a02b33d03370a36eea039dce7c010eb0e9a407f0c5f6e26bfead5", "chunk_index": 33, "heading": "Gibt es bereits Safety-Strukturen?", "text": "### Konkrete Funktion\n\n`_get_risiko()` — am Anfang, vor PR-Check\n### Gibt es bereits Safety-Strukturen?\n\nJa. `_get_risiko()` prüft bereits: PR-Treffer, schwacher Mallorca-Bezug, Konkurrenz-Ton, Alarmfakten. Das Muster existiert. Eine neue Bedingung fügt sich sauber ein.", "text_hash": "25d79394fd383071a07e71763d816bc9ac3ca27da27a5633bb01566052fc4e3a"}, {"chunk_key": "f17a9092ae749c71c2d7703f7806fd3ff0640cfe2ba62426d933631e8026fe78", "chunk_index": 34, "heading": "Empfohlene Lösung", "text": "o()` prüft bereits: PR-Treffer, schwacher Mallorca-Bezug, Konkurrenz-Ton, Alarmfakten. Das Muster existiert. Eine neue Bedingung fügt sich sauber ein.\n### Empfohlene Lösung\n\n```python", "text_hash": "974b7f44e9b9cd53ac0764b9d444fed32484bf623a53dbe5241a5d8b6bfbf122"}, {"chunk_key": "977f1928e302b807b286dd5d6486a1e7cc81178f237548f7b5fe8641ea7c620b", "chunk_index": 35, "heading": "Am Anfang von _get_risiko(), neue Konstante (einmalig außerhalb der Funktion):", "text": "### Empfohlene Lösung\n\n```python\n# Am Anfang von _get_risiko(), neue Konstante (einmalig außerhalb der Funktion):\nDEATH_KW = [\"mortal\", \"toedlich\", \"todefall\", \"gestorben\", \"ums leben\",\n            \"getoetet\", \"verstorben\", \"fatale\", \"fatal\", \"fallecido\",\n            \"fallecimiento\", \"victima mortal\", \"muerto\"]", "text_hash": "715c7683e8c7512ab12cd82d5142e2b8a77a5fd6c3ead1f22bce3149c71fa138"}, {"chunk_key": "ee85f8b18ba63b0d6b2ea1b80fe7bb433fc43c4e1a1074d2ca88e62e6d8e46c7", "chunk_index": 36, "heading": "In _get_risiko(), als erste Prüfung:", "text": "estorben\", \"ums leben\",\n            \"getoetet\", \"verstorben\", \"fatale\", \"fatal\", \"fallecido\",\n            \"fallecimiento\", \"victima mortal\", \"muerto\"]\n# In _get_risiko(), als erste Prüfung:\ntopic_text = (sig.get(\"topic\") or \"\").lower()\nif any(kw in topic_text for kw in DEATH_KW):\n    risiken.append(\"Achtung: Todesmeldung — sensitives Thema, kein direkter CTA, sachlichen Abstand halten\")\n```\n\nOptional: In `_get_freigabe()` dieselbe DEATH_KW-Prüfung → wenn Todesfall, mindestens `pruefen` erzwingen (auch wenn director_score ≥ 60).", "text_hash": "bf052bf65bb7c17bd651e1e0b236e7648514bf655e36f3bedd40c39223445cd4"}, {"chunk_key": "3ce0c91e566c4b10a4832a44b1f9754a15ca1b1601bc22994a2cf3106ad284a6", "chunk_index": 37, "heading": "Änderungsumfang", "text": "lten\")\n```\n\nOptional: In `_get_freigabe()` dieselbe DEATH_KW-Prüfung → wenn Todesfall, mindestens `pruefen` erzwingen (auch wenn director_score ≥ 60).\n### Änderungsumfang\n\n**Klein** — 1 neue Konstante (~10 Keywords), 3-4 Zeilen in `_get_risiko()`, optional 3 Zeilen in `_get_freigabe()`.", "text_hash": "b4269c592a8315312fa87a843938277255c5954351da5a34b42c348b2d5684b6"}, {"chunk_key": "e9788b747febb46c22e3f1cf2b237d6cb1090f3ba7f827c432866689a0f080bf", "chunk_index": 38, "heading": "Risiko der Änderung", "text": "### Änderungsumfang\n\n**Klein** — 1 neue Konstante (~10 Keywords), 3-4 Zeilen in `_get_risiko()`, optional 3 Zeilen in `_get_freigabe()`.\n### Risiko der Änderung\n\nNiedrig. Todesfall-Keywords sind spezifisch. Kein bekannter Konflikt mit bestehender Logik. Keine Seiteneffekte auf Director-Score.", "text_hash": "b5c2828bf875c5c9ed1a5aaa789493af49ea0484bd1d043c86e168a4f4339c97"}, {"chunk_key": "819e04e43b5dca70df2cd517814f398553dc7162d952a3d631b715eccb9b8792", "chunk_index": 39, "heading": "Reparierbarkeit", "text": "siko der Änderung\n\nNiedrig. Todesfall-Keywords sind spezifisch. Kein bekannter Konflikt mit bestehender Logik. Keine Seiteneffekte auf Director-Score.\n### Reparierbarkeit\n\n**EINFACH** — lokaler Eingriff in bestehende Struktur.\n\n---", "text_hash": "76d55f9fc4491d75ec31989107d861f8f62bb0ef32971b289d02b3a690204df6"}, {"chunk_key": "7177ef6c4c65eddba176804f60096fc411df12d3c53da93adabf1c6a9b9ec7b3", "chunk_index": 40, "heading": "REGEL-04: Mallorca-Relevanz zu weich", "text": "### Reparierbarkeit\n\n**EINFACH** — lokaler Eingriff in bestehende Struktur.\n\n---\n## REGEL-04: Mallorca-Relevanz zu weich", "text_hash": "7b7000c365c6931aa84522d3c1196c86552bcacb853e4a4d1464b34e491614fe"}, {"chunk_key": "a04ac11d54574a486acee4431cf6001aa1e85628bc3236ca90984f1adad83555", "chunk_index": 41, "heading": "Ursache (präzise)", "text": "## REGEL-04: Mallorca-Relevanz zu weich\n### Ursache (präzise)\n\n`signal_classifier.py`, Funktion `score_signal()`:\n\n```python\nGEO_KEYWORDS_MAIN = [\"mallorca\", \"majorka\", \"baleares\", \"balearen\"]\nmain_geo = _hits(text, GEO_KEYWORDS_MAIN)\nmallorca_bonus_raw = 25 if main_geo >= 1 else (15 if spec_geo >= 1 else 0)\n```\n\n`_hits()` ist ein reiner Keyword-Match — Wortebene, keine Positionsgewichtung. Ein einzelnes \"Mallorca\" irgendwo im Text gibt den vollen Bonus von 25 Punkten.\n\nSignal \"Rostocker Kinder bekommen Schimmel-Essen + Karls expandiert nach Mallorca\": \"Mallorca\" steht im letzten Drittel des Titels als Zusatz-Info. Der `main_geo`-Hit ist 1 → Bonus 25 → Score landet bei 61.\n\nDer `text`-Parameter in `score_signal()` enthält `topic` (Titel, oft 80-150 Zeichen). Da die Texte kurz sind, ist ein Position-Check nach Zeichenanzahl gut handhabbar.", "text_hash": "25246d4dfa7c3c46989acb35d6bf3a65ac00511a89496852e6365704ccee6b74"}, {"chunk_key": "fc64f78580654fab359976229054f303030c5e46cc5c6503b557c3823b2bd6a3", "chunk_index": 42, "heading": "Betroffene Dateien", "text": "ter in `score_signal()` enthält `topic` (Titel, oft 80-150 Zeichen). Da die Texte kurz sind, ist ein Position-Check nach Zeichenanzahl gut handhabbar.\n### Betroffene Dateien\n\n- `/opt/struktur/social-media-radar/classification/signal_classifier.py` — `score_signal()`\n- Downstream: Alle Signale in `signals.db` müssen nach Änderung neu gescort werden (`rescore.py`)", "text_hash": "fb9d3d71028f1afbf99215f85219a485a1d4801e42faad15ddeab7f5586f2549"}, {"chunk_key": "4b395b74f3b8ce6eca4e1448cc210d3513ae2cba5a5522473b9f8f70cc0caf28", "chunk_index": 43, "heading": "Konkrete Funktion", "text": "ssification/signal_classifier.py` — `score_signal()`\n- Downstream: Alle Signale in `signals.db` müssen nach Änderung neu gescort werden (`rescore.py`)\n### Konkrete Funktion\n\n`score_signal()` — Schritt 3 \"BASIS-KEYWORD-RELEVANZ\", Variable `mallorca_bonus_raw`", "text_hash": "687bc33afa4831b16cc06e38168ff00b7bb69db0e0dca2a8f6c6b140bc289fc8"}, {"chunk_key": "55b10a4979ffd79b861ef64b875966eddd7487e12cd10071c100fbb04f62a4a7", "chunk_index": 44, "heading": "Welche Schwellen existieren?", "text": "### Konkrete Funktion\n\n`score_signal()` — Schritt 3 \"BASIS-KEYWORD-RELEVANZ\", Variable `mallorca_bonus_raw`\n### Welche Schwellen existieren?\n\n- `main_geo >= 1` → Bonus 25 (sofort, ohne Gewichtung)\n- `spec_geo >= 1` (Palma, Manacor etc.) → Bonus 15\n- `GEO+KATEGORIE-FLOOR`: Wenn Mallorca + MAS-Kategorie → Score mindestens 35\n\nKeine bestehende Positionsgewichtung.", "text_hash": "933443924ce5c5a6fb7ba11074fe65357073f968cbc332293545ef7ef5406a2a"}, {"chunk_key": "7ca698bb1c0cfc3efaffe5f7efcaebfbf30aa7d6bde01379c650856efb7d82e5", "chunk_index": 45, "heading": "Empfohlene Lösung", "text": "` (Palma, Manacor etc.) → Bonus 15\n- `GEO+KATEGORIE-FLOOR`: Wenn Mallorca + MAS-Kategorie → Score mindestens 35\n\nKeine bestehende Positionsgewichtung.\n### Empfohlene Lösung\n\n**Option A — Position-Check (empfohlen):**\n\n```python", "text_hash": "dd7fe79dcc71068b9043e6ca1339e493e3a977f5e3f1a277b92961a2a4e1e932"}, {"chunk_key": "237f80a0b88191aa24c75eb1a36aa8b8e35aebe69dd55688374804e7550263ab", "chunk_index": 46, "heading": "Nach main_geo-Berechnung:", "text": "### Empfohlene Lösung\n\n**Option A — Position-Check (empfohlen):**\n\n```python\n# Nach main_geo-Berechnung:\nfirst_half = t[:max(len(t) // 2, 40)]   # erstes Titeldrittel oder min. 40 Zeichen\nmain_geo_primary = _hits(first_half, GEO_KEYWORDS_MAIN)", "text_hash": "4dd25505afd9aaee9ac06d46873b615b3fe48c5c3551836ffcb5fc0d7021679a"}, {"chunk_key": "bda706da4dcf566ea30dccddcce8c3d2c065b3c3bdc5129ad2c6993452adfaac", "chunk_index": 47, "heading": "Mallorca-Bonus gestaffelt:", "text": "Berechnung:\nfirst_half = t[:max(len(t) // 2, 40)]   # erstes Titeldrittel oder min. 40 Zeichen\nmain_geo_primary = _hits(first_half, GEO_KEYWORDS_MAIN)\n# Mallorca-Bonus gestaffelt:\nif main_geo_primary >= 1:\n    mallorca_bonus_raw = 25        # Mallorca im ersten Textteil = Kernthema\nelif main_geo >= 1:\n    mallorca_bonus_raw = 10        # Mallorca nur im hinteren Teil = Randerwähnung\nelif spec_geo >= 1:\n    mallorca_bonus_raw = 15\nelse:\n    mallorca_bonus_raw = 0\n```\n\nErgebnis für \"Rostocker Kinder...+Karls nach Mallorca\": `main_geo_primary = 0` (Mallorca hinten), `main_geo = 1` → Bonus 10 statt 25 → Score ca. 46 statt 61.\n\n**Option B — Non-Mallorca-Geo-Exclusion (nicht empfohlen):** Keyword-Liste für andere Städte/Regionen pflegen (brittle, Wartungsaufwand).", "text_hash": "c95313101e13c9a83b871f35e052547d4c05ad921779b218c364e8f97a03f4fc"}, {"chunk_key": "6c5312c50742fe19db34b7660c114e1753e9a6f2be5568a14ed75ac984e927a2", "chunk_index": 48, "heading": "Änderungsumfang", "text": "6 statt 61.\n\n**Option B — Non-Mallorca-Geo-Exclusion (nicht empfohlen):** Keyword-Liste für andere Städte/Regionen pflegen (brittle, Wartungsaufwand).\n### Änderungsumfang\n\n**Klein** im Code (3-4 Zeilen). **Mittel im Effekt** — alle Signale in der DB müssen neu gescort werden. `rescore.py --live` vorhanden und funktionsfähig.", "text_hash": "bca37fa9285ad45180921e7b791f4781218ba23feeed1b6d587de30f90236d09"}, {"chunk_key": "8aacd615caa41049d5abeb1a032d0b0c0ffed4127fce58f4a52b1d5bdf9bc27d", "chunk_index": 49, "heading": "Risiko der Änderung", "text": "ein** im Code (3-4 Zeilen). **Mittel im Effekt** — alle Signale in der DB müssen neu gescort werden. `rescore.py --live` vorhanden und funktionsfähig.\n### Risiko der Änderung\n\nMittel. Sehr kurze Titel (z.B. \"Mallorca: Feuchte\") haben `len(t) < 40` → `first_half = t[:40]` würde den gesamten Text einschließen → kein Problem. Für lange Artikel-Zusammenfassungen könnte \"Mallorca\" am Ende eines ersten Satzes nicht erfasst werden → `//2` (Hälfte statt Drittel) als Schwellenwert empfohlen.\n\nVor Produktiv-Einsatz: Testlauf auf 10-20 bekannte Signale, Score-Diff prüfen.", "text_hash": "7211a7c9e88cfe801183aee07eb9adf89922b7c3e90a0e87810db793c283c94a"}, {"chunk_key": "0525c40b185712a042c377aed4cd54359263a123bfdc266e5c7812b3f9f91bb3", "chunk_index": 50, "heading": "Reparierbarkeit", "text": "sst werden → `//2` (Hälfte statt Drittel) als Schwellenwert empfohlen.\n\nVor Produktiv-Einsatz: Testlauf auf 10-20 bekannte Signale, Score-Diff prüfen.\n### Reparierbarkeit\n\n**REPARABEL** — Code-Änderung minimal, aber Auswirkung erfordert Rescore der gesamten DB und anschließenden Director + Briefing Run.\n\n---", "text_hash": "539e3633b211ed60ee1e3b0eac02f42348fd8b937c943dc033f67fef54c54b82"}, {"chunk_key": "3e2caf5619b3f68991dad99ea7d4e0237fccd066a0d6dc37e93c0d63d1b55199", "chunk_index": 51, "heading": "Zusammenfassung", "text": "rierbarkeit\n\n**REPARABEL** — Code-Änderung minimal, aber Auswirkung erfordert Rescore der gesamten DB und anschließenden Director + Briefing Run.\n\n---\n## Zusammenfassung\n\n| Problem | Datei | Funktion | Umfang | Risiko | Reparierbarkeit |\n|---|---|---|---|---|---|\n| REGEL-01: Lebensmittel-Schimmel | signal_classifier.py | score_signal() | Klein | Niedrig | **Einfach** |\n| REGEL-02/UI-01: Director/Briefing-Widerspruch | content_briefing.py + cockpit.html | run() + dirHtml | Klein | Mittel | **Reparabel** |\n| UI-02: Post-Button gesperrt | cockpit.html | acts-String | Klein | Niedrig | **Einfach** |\n| REGEL-03: Todesfall-Flag | content_briefing.py | _get_risiko() | Klein | Niedrig | **Einfach** |\n| REGEL-04: Mallorca-Relevanz | signal_classifier.py | score_signal() | Klein/Code + Rescore | Mittel | **Reparabel** |\n\n**Alle 5 Probleme sind reparabel. Kein strukturelles Architekturproblem.**\n\nDie Fixes sind unabhängig voneinander — jeder kann einzeln umgesetzt und validiert werden.\n\n**Empfohlene Reihenfolge:**\n1. UI-02 — sofort, null Risiko, sofortiger Nutzen\n2. REGEL-01 — schnell, niedrige Risiko, beseitigt Lebensmittel-Noise\n3. REGEL-03 — schnell, wichtig für Qualitätssicherung\n4. REGEL-02/UI-01 — zwei Teilschritte, erfordert Koordination Briefing-Run-Reihenfolge\n5. REGEL-04 — letzter Schritt, da Rescore der gesamten DB notwendig\n\n---\n\n*Erstellt: 2026-05-28 | Analyse-only, keine Änderungen durchgeführt | Autor: AG (Claude Sonnet 4.6)*", "text_hash": "6237b1291fe79e6e0f347bc3416cc767f690e1f7b1628f309dc5ff825fe3e276"}], "elapsed_s": 0.082}