Explorer
/tmp/fast-one-56.json
← Zurück ↓ Download
{"queue_id": 56, "relative_path": "Solutions/REGEL_04_SOURCE_SUFFIX_FIX_PLAN.md", "title": "REGEL_04_SOURCE_SUFFIX_FIX_PLAN", "import_key": "0f76ed9dae1e7ac766f8f668b82244787de407787ca4e348d1ca79924a237ced", "chunk_count": 36, "created_nodes": 37, "created_relationships": 71, "body": null, "chunks": [{"chunk_key": "2f451f82b9d4899b21890bcb2b019146595087965087e6781747f084d5c09f42", "chunk_index": 0, "heading": "REGEL_04_SOURCE_SUFFIX_FIX_PLAN", "text": "# REGEL_04_SOURCE_SUFFIX_FIX_PLAN\nMallorca-Bonus aus Publisher-Suffix entfernen — minimale Aenderung, kein globaler Rescore\nDatum: 2026-05-28 | Status: Plan (kein Patch) | Ziel: 49 Source-Suffix-Signale korrigieren\n\n---", "text_hash": "64343e5e69971f4a775206e13af88fc5f5e7a6f86d39a8c9ad0c5368064d5b69"}, {"chunk_key": "0a8e56680588ea45fbff8bdafacd4c6fde88cffec289f6465d0e0f3cd9032dc1", "chunk_index": 1, "heading": "1. Exakte Fundstelle im Code", "text": " entfernen — minimale Aenderung, kein globaler Rescore\nDatum: 2026-05-28 | Status: Plan (kein Patch) | Ziel: 49 Source-Suffix-Signale korrigieren\n\n---\n## 1. Exakte Fundstelle im Code", "text_hash": "a2634b805857c090b436118114ed867b20ecef511413e48a61f3865529180da6"}, {"chunk_key": "5c61dbc342dce44a506b811d6513be481751d100651d06f67973b787a7d00b45", "chunk_index": 2, "heading": "Wo main_geo berechnet wird", "text": "## 1. Exakte Fundstelle im Code\n### Wo main_geo berechnet wird\n\n**Datei:** `/opt/struktur/social-media-radar/classification/signal_classifier.py`\n\n```\nZeile 217: def score_signal(text: str, language: str = \"de\", base_category: str = \"\",\nZeile 218:                  source_url: str = \"\", timestamp: str = \"\") -> dict:\n...\nZeile 224: t = text.lower()\n...\nZeile 229: main_geo  = _hits(text, GEO_KEYWORDS_MAIN)   ← PROBLEM\nZeile 230: spec_geo  = _hits(text, GEO_KEYWORDS_SPECIFIC)\n...\nZeile 300: mallorca_bonus_raw = 25 if main_geo >= 1 else (15 if spec_geo >= 1 else 0)\n```", "text_hash": "5376ce7348e353019e84971bb918e12769e8d4dcea85acf422669cec8224fd65"}, {"chunk_key": "7a193da9fd95d96cd8b54dbb2d797651d5b58253b7aa9426a3f2aa92ab9947bd", "chunk_index": 3, "heading": "Wie der Text zusammengesetzt wird", "text": "eile 230: spec_geo  = _hits(text, GEO_KEYWORDS_SPECIFIC)\n...\nZeile 300: mallorca_bonus_raw = 25 if main_geo >= 1 else (15 if spec_geo >= 1 else 0)\n```\n### Wie der Text zusammengesetzt wird\n\n**rss_intake.py (Zeile ~170):**\n```python\ntitle = item[\"title\"]\ndesc  = item.get(\"description\", \"\")\ntext  = f\"{title} {desc}\"        # <- titel + beschreibung, einfach konkateniert\nsd = score_signal(text, language=..., ...)\n```\n\n**rescore.py (Zeile ~63):**\n```python\ntopic    = row[\"topic\"] or \"\"\ntext = f\"{topic} {clean_summary}\".strip() if clean_summary else topic\nsd = score_signal(text, language=lang, base_category=cat)\n```", "text_hash": "eade3f367138dff8054c003f9870697cc1c4ffef7c73cbbaa0036a0a39fd6cca"}, {"chunk_key": "13a9969aeb6e49aacbd185559c85309518684d087ed9d1c9ed92d6b7c5cc30d2", "chunk_index": 4, "heading": "Das Problem", "text": "row[\"topic\"] or \"\"\ntext = f\"{topic} {clean_summary}\".strip() if clean_summary else topic\nsd = score_signal(text, language=lang, base_category=cat)\n```\n### Das Problem\n\nRSS-Feeds wie \"Diario de Mallorca\" und \"Mallorca Zeitung\" stellen ihren Namen ALS SUFFIX in den Titel-Feed:\n```\ntitle: \"La biblioteca de Es Pont d'Inca cerrada por humedad - Diario de Mallorca\"\n```\n\n`_hits(text, GEO_KEYWORDS_MAIN)` findet \"mallorca\" im Suffix \"Diario de Mallorca\".\n`main_geo = 1` → `mallorca_bonus_raw = 25` → voller Bonus — obwohl der Inhalt kein Mallorca-Keyword enthaelt.\n\n---", "text_hash": "28bf8d168c88d7deece374f3b1f400ca68fd7751a2440bd829851c8ff02b0575"}, {"chunk_key": "d262a97127e696d9ec4cec469585f8ac03bc89bca97ce773fbfd9d7d7432803c", "chunk_index": 5, "heading": "2. Vorgeschlagene minimale Aenderung", "text": "ca\" im Suffix \"Diario de Mallorca\".\n`main_geo = 1` → `mallorca_bonus_raw = 25` → voller Bonus — obwohl der Inhalt kein Mallorca-Keyword enthaelt.\n\n---\n## 2. Vorgeschlagene minimale Aenderung\n\n**Einzige Datei die geaendert wird:** `signal_classifier.py`\n\n**Schritt 1: Hilfsfunktion `_geo_text()` hinzufuegen** — direkt nach der `_hits()`-Funktion (nach Zeile ~202):\n\n```python\ndef _geo_text(text: str) -> str:\n    \"\"\"\n    SOL-006 REGEL-04: Source-Suffix-Entfernung fuer Geo-Erkennung.\n\nWenn GEO-Keywords ausschliesslich im Publisher-Suffix stehen\n    (nach letztem ' - ', Suffix <= 40 Zeichen), wird der Suffix\n    aus dem Geo-Text entfernt. Alle anderen Keyword-Hits sind unberuehrt.", "text_hash": "e3e452b8858985b878efe1caa86c6351f571108a16f37aed069ef310a60ba8b6"}, {"chunk_key": "3f29831eb8b03d56bd9c1b2332f089854405a6f3c477972b08a743f745f1834b", "chunk_index": 6, "heading": "2. Vorgeschlagene minimale Aenderung", "text": "uffix stehen\n    (nach letztem ' - ', Suffix <= 40 Zeichen), wird der Suffix\n    aus dem Geo-Text entfernt. Alle anderen Keyword-Hits sind unberuehrt.\nBeispiele:\n      \"Humedad en casa - Diario de Mallorca\"  -> \"Humedad en casa\"       (strip)\n      \"Mallorca: Schimmel in Wohnung\"         -> unveraendert             (Mallorca im Content)\n      \"Schimmel in Palma - Diario de Mallorca\" -> unveraendert            (Palma im Content)\n      \"Feuchte Kälte auf Mallorca warm - Mallorca Magazin\" -> unveraendert (Mallorca im Content)\n    \"\"\"\n    GEO_MAIN_LOCAL = ('mallorca', 'majorka', 'baleares', 'balearen')\n    t_lower = text.lower()\n    idx = t_lower.rfind(' - ')\n    if idx == -1:\n        return text\n    suffix = t_lower[idx + 3:]\n    # Nur kurze Suffixe sind Quellennamen — Saetze sind laenger als 40 Zeichen\n    if len(suffix) > 40:\n        return text\n    if not any(kw in suffix for kw in GEO_MAIN_LOCAL):\n        return text\n    content = t_lower[:idx]\n    if any(kw in content for kw in GEO_MAIN_LOCAL):\n        return text  # Mallorca auch im Content-Teil -> Bonus bleibt\n    return text[:idx]  # Original-Gross-/Kleinschreibung erhalten\n```\n\n**Schritt 2: In `score_signal()` — nach `t = text.lower()` (Zeile ~225):**\n\n```python\n    t = text.lower()\n\n# SOL-006 REGEL-04: Geo-Erkennung auf Source-Suffix-bereinigten Text anwenden\n    _gtext = _geo_text(text)", "text_hash": "5d6703897bd0446b1afa2967bda4c552252f05c1a2314c5f310afc07cd34dea1"}, {"chunk_key": "70c7f42500f8a367dae7d14d756bda98704ac7bf1e08af188dc81f4418d77163", "chunk_index": 7, "heading": "2. Vorgeschlagene minimale Aenderung", "text": "e ~225):**\n\n```python\n    t = text.lower()\n\n# SOL-006 REGEL-04: Geo-Erkennung auf Source-Suffix-bereinigten Text anwenden\n    _gtext = _geo_text(text)\n# ========================================================================\n    # STEP 1: KEYWORD COUNTS\n    # ========================================================================\n    main_geo  = _hits(_gtext, GEO_KEYWORDS_MAIN)    # war: _hits(text, ...)\n    spec_geo  = _hits(_gtext, GEO_KEYWORDS_SPECIFIC) # war: _hits(text, ...)\n```\n\n**Alle anderen Zeilen bleiben unveraendert** — nur `main_geo` und `spec_geo` verwenden `_gtext`.\nCore-, Prop-, Weather-, Risk- und alle anderen Keyword-Hits weiterhin auf vollem `text`.\n\n---", "text_hash": "b48b72644a0d3f35770ef72aa744a2df6bbb854bf2f6caa243431f0a0644f54a"}, {"chunk_key": "c1f01078807df16462e5cec6f2f3a7ee0c734a3b6d1c91b3aa4a84f020961efa", "chunk_index": 8, "heading": "3. Warum nur 2 Zeilen geaendert werden — Designentscheidung", "text": "rt** — nur `main_geo` und `spec_geo` verwenden `_gtext`.\nCore-, Prop-, Weather-, Risk- und alle anderen Keyword-Hits weiterhin auf vollem `text`.\n\n---\n## 3. Warum nur 2 Zeilen geaendert werden — Designentscheidung\n\nDie Funktion `_geo_text()` berechnet einen bereinigten Text nur fuer die Geo-Erkennung.\nKeine anderen Scores sind betroffen. Kein UI. Kein Director. Kein Briefing.\n\nDie 40-Zeichen-Heuristik fuer \"ist es ein Quellenname oder ein Satz?\" funktioniert weil:\n- \"Diario de Mallorca\" = 18 Zeichen\n- \"Mallorca Zeitung\" = 16 Zeichen\n- \"Mallorca Magazin\" = 16 Zeichen\n- \"Ultima Hora\" = 11 Zeichen\n- Ein typischer Satz mit \" - \" ist laenger als 40 Zeichen\n\n---", "text_hash": "e08282d15aace3fbf0416d23a11aa87e8cbf8e9ebbbd974362c6258161a06860"}, {"chunk_key": "3cdc129bdd46e9fc73c3ff9176a81236e409323be291747d4629d9b8d02c55bd", "chunk_index": 9, "heading": "4. Testfaelle mit Signal-IDs", "text": "ca Zeitung\" = 16 Zeichen\n- \"Mallorca Magazin\" = 16 Zeichen\n- \"Ultima Hora\" = 11 Zeichen\n- Ein typischer Satz mit \" - \" ist laenger als 40 Zeichen\n\n---\n## 4. Testfaelle mit Signal-IDs", "text_hash": "8d2dca0e231a904df19c6044a1c66ce17e8b5bbb8ce48d4b74c7a3212abccd3d"}, {"chunk_key": "3a321afa02a9037a83d319fabc2d538f3ccb3689b73949f688be69f5165bc1cf", "chunk_index": 10, "heading": "TC-01: Klarer Source-Suffix, kein Summary (erwarteter Hauptfall)", "text": "## 4. Testfaelle mit Signal-IDs\n### TC-01: Klarer Source-Suffix, kein Summary (erwarteter Hauptfall)\n\n```\nSignal-ID:  cbaaed9b-3df9-4507-96f2-144e568fcb2e\nTopic:      \"La biblioteca de Es Pont d'Inca continua cerrada por problemas de humedad - Diario de Mallorca\"\nSource:     Google News: Humedad Vivienda Mallorca (ES)\nSummary:    None\nScore IST:  68.0  mallorca_relevance=29\n\nAnalyse:\n  text = topic (kein Summary)\n  rfind(' - ') findet \" - Diario de Mallorca\"\n  suffix = \"Diario de Mallorca\" (18 Zeichen <= 40)\n  suffix_has_geo = True (mallorca)\n  content = \"La biblioteca de Es Pont d'Inca continua cerrada por problemas de humedad\"\n  content_has_geo = False\n  -> geo_text = content\n\nmain_geo SOLL = 0 (Mallorca nicht im Content)\n  spec_geo SOLL = 0 (Palma/Manacor etc. nicht im Content)\n  mallorca_bonus_raw SOLL = 0\n\nScore SOLL: ca. 48 (beobachten statt interessant)\n```", "text_hash": "8c1945177bf07c211308994c40f7bdf09fcfd4b53c346ada3aa1a207aff2ac18"}, {"chunk_key": "fe8c2f87217251416188a34b0058ce77d9e7f24e6c5873771e3ddc1894b542c2", "chunk_index": 11, "heading": "TC-02: Mallorca auch im Content — Suffix-Strip darf NICHT feuern", "text": "ontent)\n  spec_geo SOLL = 0 (Palma/Manacor etc. nicht im Content)\n  mallorca_bonus_raw SOLL = 0\n\nScore SOLL: ca. 48 (beobachten statt interessant)\n```\n### TC-02: Mallorca auch im Content — Suffix-Strip darf NICHT feuern\n\n```\nSignal-ID:  (beliebiges Signal mit \"auf Mallorca\" im Inhalt und \" - Diario de Mallorca\" Suffix)\nBeispiel Topic: \"Feuchte Kaelte: So bekommen Sie Ihre Wohnung auf Mallorca warm - Mallorca Magazin\"\n\nAnalyse:\n  rfind(' - ') findet \" - Mallorca Magazin\"\n  suffix = \"Mallorca Magazin\" (16 Zeichen <= 40)\n  suffix_has_geo = True\n  content = \"Feuchte Kaelte: So bekommen Sie Ihre Wohnung auf Mallorca warm\"\n  content_has_geo = True (mallorca im Content!)\n  -> Kein Strip, geo_text = unveraenderter text\n\nmain_geo SOLL = 1+ (Mallorca im Content)\n  mallorca_bonus_raw SOLL = 25 (bleibt unveraendert)\n  Score SOLL: unveraendert (65.0)\n```", "text_hash": "c59f471e7f9545ff71fdceea4290a6b6c05feea94658f14a6ba72e5590e35830"}, {"chunk_key": "acbc0e4d3677e890c90aaa18479939e886f6ab9df9100c06fa7e4b2d53e4bc84", "chunk_index": 12, "heading": "TC-03: Source-Suffix, aber Summary enthaelt ebenfalls Geo (bekannte Einschraenkung)", "text": "veraenderter text\n\nmain_geo SOLL = 1+ (Mallorca im Content)\n  mallorca_bonus_raw SOLL = 25 (bleibt unveraendert)\n  Score SOLL: unveraendert (65.0)\n```\n### TC-03: Source-Suffix, aber Summary enthaelt ebenfalls Geo (bekannte Einschraenkung)\n\n```\nSignal-ID:  3c3031ab-03b3-4528-9202-81a993075d9a\nTopic:      \"Wetter Llubi: 7-Tage-Prognose - Feuchte Aussichten (23.4.2024) - Mallorca Zeitung\"\nSummary:    \"Wetter Llubi: 7-Tage-Prognose Feuchte Aussichten (23.4.2024) Mallorca Zeitung\"\nScore IST:  64.0  mallorca_relevance=25\n\nAnalyse:\n  text = topic + \" \" + summary\n  rfind(' - ') im Gesamttext: findet letztes ' - ' — je nach Zusammensetzung\n  Selbst wenn Titel-Suffix gestrippt wird: summary enthaelt \"Mallorca Zeitung\" (kein Dash)\n  main_geo bleibt 1 (aus Summary)\n  -> Kein Score-Effekt fuer diesen Fall\n\nDiese Einschraenkung ist dokumentiert (siehe Abschnitt 7).\n```", "text_hash": "bd84cf5dd69c2d6fe7889378d05331359463beed7ea5dfcb2314b589931a55fd"}, {"chunk_key": "5e3d85586b4907ce58b4c6c7c7aaedea92e84fc4a36517afe5f8fb8daf4e4878", "chunk_index": 13, "heading": "TC-04: Spezifischer Ort im Content, Mallorca nur im Suffix", "text": " (kein Dash)\n  main_geo bleibt 1 (aus Summary)\n  -> Kein Score-Effekt fuer diesen Fall\n\nDiese Einschraenkung ist dokumentiert (siehe Abschnitt 7).\n```\n### TC-04: Spezifischer Ort im Content, Mallorca nur im Suffix\n\n```\nSignal-ID:  20d5e5d2-32a0-4b88-adc1-f28c4b609bc3\nTopic:      \"Humedad en ocho pisos de Cala Major: Se nos caen trozos de pared - Diario de Mallorca\"\nSource:     Google News: Moho Mallorca (ES)\nSummary:    None (oder kurz)\nScore IST:  61.0  mallorca_relevance=25\n\nAnalyse:\n  suffix = \"Diario de Mallorca\" (18 Zeichen <= 40)\n  content = \"Humedad en ocho pisos de Cala Major: Se nos caen trozos de pared\"\n  content_has_geo(main) = False (kein mallorca/baleares im Content-Teil)\n  -> Strip angewandt\n\nspec_geo: \"Cala Major\" ist in GEO_KEYWORDS_SPECIFIC?\n    -> Nein, \"cala major\" ist NICHT in GEO_KEYWORDS_SPECIFIC (nur palma, manacor, alcudia, soller, inca, llucmajor, felanitx, santanyi, mittelmeer)\n  -> spec_geo = 0\n\nmain_geo SOLL = 0, spec_geo SOLL = 0\n  mallorca_bonus_raw SOLL = 0\n  Score SOLL: ca. 36-41 (beobachten)\n\nACHTUNG: Cala Major IST ein Stadtteil von Palma. Falls \"palma\" im Topic vorkaeme,\n  wuerde spec_geo=1 und mallorca_bonus=15 greifen.\n  Dieses Signal verliert den Lokalitaetsbezug im Score, obwohl es lokal ist.\n  (Dokumentierter Tradeoff — kein REGEL-04-Fix-spezifisches Problem)\n```", "text_hash": "e717b3c9d4ef7ef8572189598fabac61d2fbfdb6150884d2e25d3cb85aec2faa"}, {"chunk_key": "bc86a92e77dc13a2194bd3d29e604d24374204550942cbc9d0fb6f8b9cfb232f", "chunk_index": 14, "heading": "TC-05: Kontroll-Signal — kein Source-Suffix, unveraendert", "text": "\n  Dieses Signal verliert den Lokalitaetsbezug im Score, obwohl es lokal ist.\n  (Dokumentierter Tradeoff — kein REGEL-04-Fix-spezifisches Problem)\n```\n### TC-05: Kontroll-Signal — kein Source-Suffix, unveraendert\n\n```\nBeispiel Topic: \"Mallorca: Schimmelbefall in Apartmentanlage Cala Major\"\n(Mallorca steht AM ANFANG, kein ' - Quellenname' Suffix)\n\nAnalyse:\n  rfind(' - ') = -1 (kein Separator)\n  -> geo_text = unveraenderter text\n  -> main_geo unveraendert\n  -> Score unveraendert\n```\n\n---", "text_hash": "f6aca09d64c510b9c19de9d6458dd05a3c191fb13347d92f3f339a70713f134d"}, {"chunk_key": "23e0021ec8cd66c192cf809803f33e1d2dbb9f845c232847b01f77e2e8622fe6", "chunk_index": 15, "heading": "5. Score-Effekt auf die 49 Source-Suffix-Signale", "text": "Suffix)\n\nAnalyse:\n  rfind(' - ') = -1 (kein Separator)\n  -> geo_text = unveraenderter text\n  -> main_geo unveraendert\n  -> Score unveraendert\n```\n\n---\n## 5. Score-Effekt auf die 49 Source-Suffix-Signale", "text_hash": "5a60a4c86f637a314034aff2ef7f4a595ef76811337d161eda09cc9109b661f5"}, {"chunk_key": "161cfc54840db8062a1ddc1fa9d31a998674578d624cee80a245d4be6165391c", "chunk_index": 16, "heading": "Kategorisierung nach Fix-Wirksamkeit", "text": "## 5. Score-Effekt auf die 49 Source-Suffix-Signale\n### Kategorisierung nach Fix-Wirksamkeit\n\n| Typ | Anzahl | Fix-Wirkung |\n|-----|--------|-------------|\n| Kein Summary (text = topic) | 37 | Vollstaendig: main_geo = 0 nach Fix |\n| Summary ohne Geo-Keyword | 4 | Vollstaendig: main_geo = 0 nach Fix |\n| Summary mit Geo-Keyword (RSS-Artefakt) | 8 | Eingeschraenkt: main_geo bleibt 1 aus Summary |\n| **Gesamt** | **49** | **41 vollstaendig, 8 eingeschraenkt** |", "text_hash": "66c3196223727f80a1de1b46192901d37a8249cddd86e3ef8b901f6ad8da84a0"}, {"chunk_key": "153b480a05e7cc5f0bee03ecca37b282e7d941c73aebff734a8b34db6588f594", "chunk_index": 17, "heading": "Erwartete Score-Aenderung fuer die 41 vollstaendig betroffenen Signale", "text": "y mit Geo-Keyword (RSS-Artefakt) | 8 | Eingeschraenkt: main_geo bleibt 1 aus Summary |\n| **Gesamt** | **49** | **41 vollstaendig, 8 eingeschraenkt** |\n### Erwartete Score-Aenderung fuer die 41 vollstaendig betroffenen Signale\n\n```\nmallorca_bonus_raw: 25 -> 0\nmallorca_relevance: ~25-29 -> 0\nScore-Reduktion: -20 bis -25 Punkte (je nach anderen Faktoren)\n\nAktuelle Verteilung der 49:\n  68-69 (interessant): 2\n  61-67 (interessant): 11\n  41-57 (interessant/beobachten): 16\n  35-40 (beobachten): 20\n\nNach Fix (ca.):\n  > 51 (interessant): 0-2 (nur wenn starke Content-Scores kompensieren)\n  35-50 (beobachten): ~30\n  < 35 (irrelevant): ~10-15\n```\n\n---", "text_hash": "688c9192ab37182347867b42ead47d7016bcead01beec25611564522ce7046ed"}, {"chunk_key": "34dec2df09c99e20fa6ea8b43b2f120128b4cdee05329c7058182f67228a2c6b", "chunk_index": 18, "heading": "6. Risikoanalyse", "text": "Nach Fix (ca.):\n  > 51 (interessant): 0-2 (nur wenn starke Content-Scores kompensieren)\n  35-50 (beobachten): ~30\n  < 35 (irrelevant): ~10-15\n```\n\n---\n## 6. Risikoanalyse", "text_hash": "b439024cf93edb817aed3c6418db1f4a18e41e67e1e19c59ae8c58593ab99485"}, {"chunk_key": "cdd36bd8616ffecc619f5f348e434b5d75f6116a3e645800a330a4cb735a94c9", "chunk_index": 19, "heading": "Risiko 1: Genuine lokale Signale verlieren Score", "text": "## 6. Risikoanalyse\n### Risiko 1: Genuine lokale Signale verlieren Score\n\n**Einschaetzung: Mittel — akzeptierbar**\n\nEinige der 49 Signale sind genuine Mallorca-Lokalnachrichten (z.B. \"La biblioteca de Es Pont d'Inca cerrada por humedad - Diario de Mallorca\"). Diese verlieren den Geo-Bonus, weil ihr Titel-Content kein \"Mallorca\" erwaehnt. Der Bonus entstand durch den Quellennamen, nicht durch den Inhalt.\n\nTradeoff: Score-Reduktion ist korrekt — der Titel-Content ist lokal, aber nicht explizit Mallorca-markiert. Andere Score-Dimensionen (core_hits, prop_hits, urgency etc.) bleiben unveraendert.\n\n**Guard:** Signale mit spec_geo-Treffer (Palma, Manacor, etc. im Content) behalten ihren spec_geo-Bonus (15 Punkte). Nur main_geo (25 Punkte) wird bereinigt.", "text_hash": "938902f036a8491c8d9396b302e40def710aac057b05c4498ec55d5fde113456"}, {"chunk_key": "b89ef2902f594a2d2f5497be18bc338b4828707c5d1830233b4fc8723087ff98", "chunk_index": 20, "heading": "Risiko 2: False Negatives bei der Suffix-Erkennung", "text": ":** Signale mit spec_geo-Treffer (Palma, Manacor, etc. im Content) behalten ihren spec_geo-Bonus (15 Punkte). Nur main_geo (25 Punkte) wird bereinigt.\n### Risiko 2: False Negatives bei der Suffix-Erkennung\n\n**Einschaetzung: Gering**\n\nWenn der letzte \" - \" im Text kein Quellenname-Separator ist (sondern Teil der Beschreibung), und der Pseudo-Suffix <= 40 Zeichen und GEO-haltig ist: falsche Strippung.\n\nBeispiel: `\"Schimmel in der Wohnung - auch auf Mallorca ein Problem\"`\n- rfind(' - ') findet \" - auch auf Mallorca ein Problem\"\n- suffix = \"auch auf Mallorca ein Problem\" (28 Zeichen <= 40)\n- suffix_has_geo = True, content_has_geo = False\n- -> Faelschlicherweise gestrippt\n\n**Mitigation:** In der Praxis selten. RSS-Titel folgen der Konvention \"Content - Quellenname\", nicht \"Behauptung - Gegenargument in 28 Zeichen\". Bei Bedarf Suffix-Laenge auf 25 Zeichen reduzieren.", "text_hash": "714a66fc59fb1b468f17bc7ba93144dcc75084ae8982bbf41dd41074b70d5804"}, {"chunk_key": "e673c4f48c7dfe3a7ad972c551bcf68c0b7f420d7fa860acce47737c3293e730", "chunk_index": 21, "heading": "Risiko 3: 8 RSS-Artefakt-Signale (Summary-Geo)", "text": "l folgen der Konvention \"Content - Quellenname\", nicht \"Behauptung - Gegenargument in 28 Zeichen\". Bei Bedarf Suffix-Laenge auf 25 Zeichen reduzieren.\n### Risiko 3: 8 RSS-Artefakt-Signale (Summary-Geo)\n\n**Einschaetzung: Gering — kein Regressionspfad**\n\n8 Signale haben \"Diario de Mallorca\" / \"Mallorca Zeitung\" auch im Summary-Text (ohne \" - \" Separator, Google News RSS-Artefakt). Diese werden durch den Fix nicht veraendert. Ihr Score bleibt unveraendert (=IST-Zustand). Keine Verschlechterung, keine Verbesserung.", "text_hash": "fef38c1e7e9b0e92fb5d73a7646a0edbc3d20972c67fa729222c1eaba7c50f4a"}, {"chunk_key": "c741970f37646d9cab63c7c4e8076ff8e6cca660c69a0520f7092a7093bf81b2", "chunk_index": 22, "heading": "Risiko 4: Unbeabsichtigte Wechselwirkung mit spec_geo", "text": " RSS-Artefakt). Diese werden durch den Fix nicht veraendert. Ihr Score bleibt unveraendert (=IST-Zustand). Keine Verschlechterung, keine Verbesserung.\n### Risiko 4: Unbeabsichtigte Wechselwirkung mit spec_geo\n\n**Einschaetzung: Kein Risiko**\n\n`spec_geo` wird ebenfalls auf `_gtext` angewendet. GEO_KEYWORDS_SPECIFIC enthaelt Palma, Manacor, Alcudia, Soller, Inca, Llucmajor, Felanitx, Santanyi, Mittelmeer. Diese Woerter erscheinen NIE in typischen Quellennamen (\"Diario de Mallorca\", \"Mallorca Zeitung\"). Kein Einfluss auf spec_geo fuer Source-Suffix-Faelle.", "text_hash": "98f261c14ee71b986c484415b727a4d18040d2171437dfe57b9b6515044de0ec"}, {"chunk_key": "483fa7dcb4ee1e6825828f429f217d28f5d533b1b0d63101335fa2ce63166329", "chunk_index": 23, "heading": "Risiko 5: Rueckwaertskompatibilitaet bei rescore.py", "text": "ese Woerter erscheinen NIE in typischen Quellennamen (\"Diario de Mallorca\", \"Mallorca Zeitung\"). Kein Einfluss auf spec_geo fuer Source-Suffix-Faelle.\n### Risiko 5: Rueckwaertskompatibilitaet bei rescore.py\n\n**Einschaetzung: Kein Risiko**\n\n`rescore.py` ruft `score_signal(text, ...)` ohne Aenderung auf. Die Funktion `_geo_text()` ist intern. Kein API-Bruch. rescore.py profitiert automatisch vom Fix.\n\n---", "text_hash": "ae7d96aa0b15857629592b3306d10c3b6f0edb59e68e422a93447f0abeed4776"}, {"chunk_key": "e502de6fc5a1cfbfd40029cb816d20a731be3ea9952e6950d9769b8836587cdf", "chunk_index": 24, "heading": "7. Bekannte Einschraenkung: 8 RSS-Artefakt-Signale", "text": "t `score_signal(text, ...)` ohne Aenderung auf. Die Funktion `_geo_text()` ist intern. Kein API-Bruch. rescore.py profitiert automatisch vom Fix.\n\n---\n## 7. Bekannte Einschraenkung: 8 RSS-Artefakt-Signale\n\n8 der 49 Source-Suffix-Signale haben das Google News RSS-Muster, bei dem der Quellenname AUCH im Summary-Text steht (ohne \" - \" Separator):\n\n```\ntopic:   \"Archiv. Nachrichten des Tages 25. Januar 2026 - Mallorca Magazin\"\nsummary: \"Archiv. Nachrichten des Tages 25. Januar 2026 Mallorca Magazin\"\n```\n\nFuer diese Signale bleibt main_geo=1 aus dem Summary-Text, auch nach Titel-Suffix-Strip.\n\n**Optionale Folgeanpassung** (nicht im Scope dieses Fixes, separater Plan noetig):\n- `source_name` Parameter zu `score_signal()` hinzufuegen\n- Quellennamen aus geo_text entfernen (nicht nur Titel-Suffix, auch Summary-Inline)\n\n---", "text_hash": "784714b06ef7e0d8041e4f8e5d90e3be0b1a7b0cf7922abe43c229b0b6b7b57c"}, {"chunk_key": "a4db04379f1ddbb61ab90e35ca22cf40b6cb8207d2a0fc97b2820bb444a75237", "chunk_index": 25, "heading": "8. Gezielter Rescore: reicht fuer 49 Signale", "text": "g):\n- `source_name` Parameter zu `score_signal()` hinzufuegen\n- Quellennamen aus geo_text entfernen (nicht nur Titel-Suffix, auch Summary-Inline)\n\n---\n## 8. Gezielter Rescore: reicht fuer 49 Signale\n\n**Kein Voll-Rescore notwendig.**\n\nNach dem Patch genuegt ein gezielter Rescore der 49 Source-Suffix-Signale:\n\n```python", "text_hash": "18fa3ac312417ac5da2aff7c4f6a031f8503f011fd72cbe1e8b5160a961211a1"}, {"chunk_key": "876ed3a64b9042dd18f743fc636fb2d7e9068bc02915d251e5e48fe00a8a7c62", "chunk_index": 26, "heading": "Identifikation der 49 Signale (SQL-Filter fuer rescore):", "text": "score: reicht fuer 49 Signale\n\n**Kein Voll-Rescore notwendig.**\n\nNach dem Patch genuegt ein gezielter Rescore der 49 Source-Suffix-Signale:\n\n```python\n# Identifikation der 49 Signale (SQL-Filter fuer rescore):", "text_hash": "310b5f5240b68d69c02656934d55b0e6c63ea69b2afaf15ca4597005790ef823"}, {"chunk_key": "e657eccae3734218e13413df1ea1b622cdd11515087d4c75b2b2275e837b5dbf", "chunk_index": 27, "heading": "WHERE signal_id IN (<liste der 49 IDs>)", "text": "# Identifikation der 49 Signale (SQL-Filter fuer rescore):\n# WHERE signal_id IN (<liste der 49 IDs>)", "text_hash": "6a05eaac630b730168a0bd426c6df7f11a96f7b999a075d5311b7529cbb5322e"}, {"chunk_key": "11d8859a0fb651fe84107ec0e7b267aebee281736e2278d6853cc9d34a5ffa84", "chunk_index": 28, "heading": "ODER via Python-Filter: is_source_only(topic) == True", "text": "# WHERE signal_id IN (<liste der 49 IDs>)\n# ODER via Python-Filter: is_source_only(topic) == True\n```\n\n`rescore.py` liest topic + summary aus DB und berechnet text intern. Nach dem Fix in `signal_classifier.py` wird `score_signal()` fuer diese Signale automatisch kleinere main_geo zurueckgeben.\n\n**Empfohlener Rescore-Aufruf:**\n\n```bash", "text_hash": "46b3b1aa2fb026fef8f21de6cf916c8bb830a21a09600d7886953c0a9e1a0930"}, {"chunk_key": "1f949d2af33978d2abe0d287306321556b7095259071f47daa7e32d10cf9cc3a", "chunk_index": 29, "heading": "Option A: Voll-Rescore (sicher, aber breiter)", "text": " `signal_classifier.py` wird `score_signal()` fuer diese Signale automatisch kleinere main_geo zurueckgeben.\n\n**Empfohlener Rescore-Aufruf:**\n\n```bash\n# Option A: Voll-Rescore (sicher, aber breiter)\npython3 /opt/struktur/social-media-radar/rescore.py --live", "text_hash": "4216961e9df9028cb98da94368db306762a2c34542c7040d5fda49c5f6620c19"}, {"chunk_key": "610a0c13a9da9291b393020bb6fba2f31d2f16626e98f2fed358d2525a4f37c5", "chunk_index": 30, "heading": "Option B: Gezielter Rescore der 49 IDs (nach Erstellung eines filter-scripts)", "text": "# Option A: Voll-Rescore (sicher, aber breiter)\npython3 /opt/struktur/social-media-radar/rescore.py --live\n# Option B: Gezielter Rescore der 49 IDs (nach Erstellung eines filter-scripts)\npython3 /opt/struktur/social-media-radar/rescore.py --filter source_suffix --live\n```\n\nFuer Option B muesste `rescore.py` eine `--filter`-Option erhalten oder ein separates Script erstellt werden.\n\n**Empfehlung: Option A (Voll-Rescore)** — bei 341 Signalen schnell (< 30s), kein Mehraufwand. Alle anderen Signale: Score unveraendert (Patch greift nur wenn source-suffix-Bedingung erfuellt).\n\n---", "text_hash": "3011f0773adf0c0ad80b66b3423029dedf8219c19e42fcc0d7a3706a80a928e6"}, {"chunk_key": "b9542e652b7593237aa0e5fcc935c173ac579aceac1bfb878a05b8a6c2577107", "chunk_index": 31, "heading": "9. Backup und Rollback", "text": "41 Signalen schnell (< 30s), kein Mehraufwand. Alle anderen Signale: Score unveraendert (Patch greift nur wenn source-suffix-Bedingung erfuellt).\n\n---\n## 9. Backup und Rollback\n\n```bash", "text_hash": "2973ef815a9fc88a7136abb99a624f761ef3fa7d224b025e07a7aa393ee43ede"}, {"chunk_key": "a501f232c86b3c38568447687c910efda7a939c10cac1e3cf75583bfd9c62b61", "chunk_index": 32, "heading": "Backup vor Patch:", "text": "## 9. Backup und Rollback\n\n```bash\n# Backup vor Patch:\ncp /opt/struktur/social-media-radar/classification/signal_classifier.py \\\n   /opt/struktur/social-media-radar/classification/signal_classifier.py.bak.regel04", "text_hash": "71910717d1c04910382fc60f7475cb72e49d95a175973c6ee3b8cc9154c44252"}, {"chunk_key": "ab8ca01edb7f6ca12144b66191853cf594f6226cf7aa2ec4b4e6a41da2fbc0b3", "chunk_index": 33, "heading": "Rollback wenn noetig:", "text": "/struktur/social-media-radar/classification/signal_classifier.py \\\n   /opt/struktur/social-media-radar/classification/signal_classifier.py.bak.regel04\n# Rollback wenn noetig:\ncp /opt/struktur/social-media-radar/classification/signal_classifier.py.bak.regel04 \\\n   /opt/struktur/social-media-radar/classification/signal_classifier.py\npython3 /opt/struktur/social-media-radar/rescore.py --live\n```\n\n---", "text_hash": "3dfd99841a0744498c6b50b0069d42603819757cee5f80d409e58ff582f23e90"}, {"chunk_key": "bb11194e01ebb58d5e022bbc2cede5c0b5557cdd4c11f55e70279501f83e78a5", "chunk_index": 34, "heading": "10. Implementierungs-Checkliste (fuer Freigabe)", "text": ".regel04 \\\n   /opt/struktur/social-media-radar/classification/signal_classifier.py\npython3 /opt/struktur/social-media-radar/rescore.py --live\n```\n\n---\n## 10. Implementierungs-Checkliste (fuer Freigabe)\n\n- [ ] 1. Backup: `signal_classifier.py.bak.regel04` anlegen\n- [ ] 2. `_geo_text()` Funktion nach `_hits()` einfuegen (ca. Zeile 203)\n- [ ] 3. `_gtext = _geo_text(text)` in `score_signal()` nach `t = text.lower()` einfuegen\n- [ ] 4. `_hits(text, GEO_KEYWORDS_MAIN)` -> `_hits(_gtext, GEO_KEYWORDS_MAIN)`\n- [ ] 5. `_hits(text, GEO_KEYWORDS_SPECIFIC)` -> `_hits(_gtext, GEO_KEYWORDS_SPECIFIC)`\n- [ ] 6. Syntax-Check: `python3 -m py_compile signal_classifier.py`\n- [ ] 7. Unit-Test TC-01 bis TC-05 manuell verifizieren\n- [ ] 8. `rescore.py --live` ausfuehren\n- [ ] 9. Score-Verteilung pruefen: wie viele Signale unter 51? Kein operatives Signal verloren?\n- [ ] 10. SOL-006 Phase-3-Report erstellen\n\n---", "text_hash": "3c8dbcf08b26fcc8aea937f360c6abeb77321c9b9a9e503d12d0319382cb9063"}, {"chunk_key": "ffe7b13accd874e4ac27faa3a2997cfc7653feedde17b652fd93c3890034c2d2", "chunk_index": 35, "heading": "11. Zusammenfassung", "text": "uehren\n- [ ] 9. Score-Verteilung pruefen: wie viele Signale unter 51? Kein operatives Signal verloren?\n- [ ] 10. SOL-006 Phase-3-Report erstellen\n\n---\n## 11. Zusammenfassung\n\n| Punkt | Wert |\n|-------|------|\n| Betroffene Datei | `signal_classifier.py` — nur diese |\n| Code-Aenderung | 1 neue Funktion (_geo_text) + 3 Zeilen in score_signal |\n| Signale betroffen | 49 Source-Suffix-Signale |\n| Vollstaendig gefixt | 41 (37 ohne Summary + 4 mit geo-freiem Summary) |\n| Eingeschraenkt (RSS-Artefakt) | 8 (Summary enthaelt Geo auch ohne Dash) |\n| Kollateralschaden | 0 (genuine middle-Signale unveraendert) |\n| Rescore-Aufwand | Voll-Rescore (341 Signale, < 30s) |\n| Freigabe-Voraussetzung | TC-01 bis TC-05 manuell bestaetigent |\n| Kein Voll-Rescore ohne Freigabe | Bestaetigt |\n\n---\n\n*Erstellt: 2026-05-28 | Autor: AG (Claude Sonnet 4.6)*\n*Kein Code veraendert — nur Plan*", "text_hash": "0145b7bd554d0d62d596decc717d24abdf691bc2b43e03b20180db73cc40c1fe"}], "elapsed_s": 0.097}