fix(citation): /Title bei Dateiname-Autor-Mismatch quarantaenisieren (#234) - #256
Merged
Conversation
…— Selbst-Vergiftung durch enrich (#234) Die Pipeline quarantaenisierte den eingebetteten Info-Dict-/Author bereits (pdf_chunker: nur diagnostisch als InfoDictAuthor), vertraute dem /Title aber ungeprueft (Trust-Asymmetrie). Ein frueherer enrich(rename=True)-Lauf hatte beim Schlebbe-PDF alle eingebetteten Metadaten von Afzal 2017 zurueckgeschrieben (Selbst-Vergiftung) -> beide Schlebbe-Notes zitierten den Afzal-Titel statt Schlebbe & Greifeneder 2022. Fix (Richtung A, Dateiname-Cross-Check analog /Author): Widerspricht der eingebettete Info-Dict-Autor dem Dateiname-Autor, ist der GESAMTE Embedded-Block unglaubwuerdig -> /Title verwerfen. Damit greift die vorhandene Fallback-Kaskade (enrich-Merge / q_title / vault_writer) auf den dateinamen-abgeleiteten Titel. - _filename_contradicts_embedded_author (pdf_enrich): Gegenstueck zum bestehenden _zotero_author_matches_embedded — meldet einen POSITIVEN Widerspruch NUR bei parsbarem Dateiname UND echtem Nachname-Mismatch (kein Overreach bei fehlendem Embedded-Autor / unparsbarem Dateiname). - _quarantine_poisoned_embedded_title (orchestrator): leert pdf_meta["Title"] in place; aufgerufen im Normalpfad (vor dem Enrichment, damit der Merge-Guard einen legitim angereicherten Titel setzen kann) UND im --load-drafts-Reload-Pfad (zweiter, unabhaengiger Trust-Punkt). Tests: RED->GREEN in test_title_trust_cross_check.py (Schlebbe-Realfall + 3 Positiv-Kontrollen), 5 Guard-Unit-Tests in test_pdf_enrich.py, Reload-Poison-Test in test_load_draft_state_roundtrip.py (Bestandstest-Kommentar an neues Verhalten angepasst). Voll-Suite gruen.
…s-Check (#234) Review von PR #256 fand einen HIGH-Bug in _filename_contradicts_embedded_author, an 4 realen Literatur-PDFs verifiziert: Der beidseitige Nur-letztes-Token-Vergleich brach in zwei Klassen und quarantaenisierte korrekte Titel faelschlich: 1. Mehrautoren: Bei "Autor1 und Autor2 - Jahr - Titel" wurde nur Autor2 geprueft; ein legitimer Embedded-ERSTautor (= Autor1) erzeugte einen falschen Widerspruch (Ebner und Gegenfurtner / Klingenberg und Weber / Deci und Ryan / Ayaz und Yanartaş). 2. Diakritika: Reine Diakritik-Differenz brach den Match auch bei Ein-Autor (Yanartaş vs. Yanartas). Fix (Vergleichs-Heuristik, kein Kern-Umbau): - Neuer Helper _author_surnames: zerlegt Autor-String an _AUTHOR_SEP_RE (';'/'und'/'and'/'&') in Einzelautoren, Nachname = letztes Token (bzw. Teil vor Komma bei "Nachname, Vorname" — Deci-Fall), diakritik-gefaltet. - Widerspruch nur noch, wenn KEIN Embedded-Nachname zu IRGENDEINEM Dateiname- Nachnamen passt (Mengen-isdisjoint). Grosszuegig gegen Overreach. - Diakritik-Fold in Helper _strip_diacritics extrahiert (aus _significant_tokens, verhaltensgleich) und beidseitig genutzt. Schlebbe/Afzal bleibt korrekt Widerspruch (True): 'Afzal' passt zu weder 'Schlebbe' noch 'Greifeneder'. Neue Tests: 5-fach parametrisierte Overreach-Faelle + Diakritik- Ein-Autor + Regressions-Erhalt; RED->GREEN. Voll-Suite 5807 passed, ruff sauber.
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Befund (Scout-verifiziert)
Trust-Asymmetrie: Die Pipeline quarantaenisiert den eingebetteten Info-Dict-
/Authorbereits (pdf_chunker._parse_pdfinfo_output: nur diagnostisch alsInfoDictAuthor), vertraute dem/Titleaber ungeprueft._TITLE_LOOKS_BADfaengt nur Zahlenmuell, keine plausiblen Falsch-Titel.Schlebbe-Afzal-Poisoning: Ein frueherer
enrich(rename=True)-Lauf hatte beim Schlebbe-PDF ALLE eingebetteten Metadaten von Afzal 2017 (aus dem Literaturverzeichnis) zurueckgeschrieben. Folge: beide Schlebbe-Notes zitierten „Conceptualisation and Measurement of Information Needs" (Afzal) statt Schlebbe & Greifeneder 2022. Die finale Zitation liestpdf_meta.get("Title")direkt (citation.py:126) — ein reiner q_title-Filter haette die Fehlattribution NICHT behoben.Gewaehlter Ansatz (Richtung A: Dateiname-Cross-Check analog /Author)
Titel lassen sich nicht per Nachname matchen; das robusteste vorhandene Signal ist der Embedded-Autor. Widerspricht
InfoDictAuthordem Dateiname-Autor, ist der GESAMTE eingebettete Block unglaubwuerdig — inkl./Title._filename_contradicts_embedded_author(pdf_enrich.py): Gegenstueck zum bestehenden_zotero_author_matches_embedded. Meldet einen positiven Widerspruch NUR bei parsbarem Dateiname UND echtem Nachname-Mismatch. Fehlender Embedded-Autor / unparsbarer Dateiname →False(kein Overreach auf sauberen Bestand)._quarantine_poisoned_embedded_title(orchestrator.py): leertpdf_meta["Title"]in place. Aufgerufen im Normalpfad (vor dem Enrichment, damit der Merge-Guardorchestrator.py:1993einen legitim angereicherten Titel setzen kann) UND im--load-drafts-Reload-Pfad (zweiter, unabhaengiger Trust-Punkt). Danach greift die vorhandene Fallback-Kaskade (Merge-Guard /q_title/vault_writer:167) auf den dateinamen-abgeleiteten Titel „Information Need, Informationsbedarf und -bedürfnis".Locus-Begründung: Der Titel wird direkt in
pdf_metaquarantaenisiert (nicht nurq_title), weilbuild_citation_metapdf_meta["Title"]direkt liest — nur so wird die tatsaechliche Zitation korrigiert.TDD RED → GREEN
test_title_trust_cross_check.py—AttributeError/AssertionError;test_without_quarantine_citation_carries_poison_titlereproduziert die Fehlattribution (cite.title == POISON_TITLE). Reload-Poison-Test schlug fehl (Gift-Titel ueberlebte Resume).test_pdf_enrich.py; Reload-Poison-Test gruen.test_load_draft_state_roundtrip.py:172-177— Clean-Input-Assertion bleibt gueltig (kein widersprechenderInfoDictAuthor→ Verhalten unveraendert); Kommentar an neue Ableitung angepasst + neuer Poison-Reload-Test ergaenzt.Abnahme
pytest generative lib/decision_engine/tests shared/tests -q: 5800 passed, 3 skipped, 4 deselected, 0 failed.ruff check+ruff format --check: sauber.Schlebbe-PDF-Bereinigung (einmalig, ausserhalb Repo)
Backup ZUERST:
C:/tmp/schlebbe-2022-bak-vor-234-cleanup.pdf(106760 bytes, verifiziert identisch). Korrigiert via_write_pdf_metadatamit dateinamen-abgeleiteten Werten (kein Raten; Afzal-DOI entfernt, Schlebbe-DOI unbekannt → leer).Pipeline-Gegencheck auf der korrigierten Datei:
_quarantine_poisoned_embedded_title→False(self-consistent, korrekter Titel bleibt).Hinweis: Die zwei bereits generierten Schlebbe-Notes im Vault tragen weiterhin die alte Afzal-Zitation — Neu-Generierung ist ein separater Pipeline-Lauf (ausserhalb dieses Issues).
Closes #234