Commit Graph
12 Commits
Author SHA1 Message Date
irrlichtandClaude Opus 5 c18e94e61e Podman-Netz konfigurierbar, Vorgabe pasta, auf Prod bebop-net
Prod laesst Phase 1 und Postgres in einem eigenen Netz laufen; die
Verbindung zeigt dort auf den Rechnernamen "postgres", den nur Podmans
DNS innerhalb von bebop-net aufloest. Die Unit hatte --network=pasta
fest verdrahtet - damit waere der erste Lauf an der Namensaufloesung
gescheitert, nicht an der Anmeldung.

Jetzt ${P2_NETZ}, mit Environment=P2_NETZ=pasta als Vorgabe. Die
Umgebungsdateien werden nach Environment= gelesen und ueberschreiben sie;
p2.env.beispiel setzt bebop-net.

Damit ist auch die Warnung vor host.containers.internal hinfaellig: sie
gilt nur ohne eigenes Netz. Die Checkliste sagt das jetzt so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NupWEBPzsyohVPG47HsTz8
2026-09-08 16:27:43 +02:00
irrlichtandClaude Opus 5 7cecc5c0cd Inbetriebnahme auf Prod: Checkliste und zwei Umgebungsdateien
Die Unit las bisher nur p2.env. Auf Prod steht die Datenbankverbindung
schon in ~/.config/wurzelwerk/database.env und gehoert Phase 1 mit; die
Unit liest jetzt beide, database.env zuerst. p2.env kann DATABASE_URL
ueberschreiben, falls database.env auf 127.0.0.1 zeigt - aus dem
Container heraus laeuft das ins Leere, dort muss
host.containers.internal stehen.

deploy/INBETRIEBNAHME.md haelt die Reihenfolge fest. Zwei Schritte darin
sind nicht offensichtlich und beide teuer, wenn man sie auslaesst:

  lexikon.py --laden   akteure.py liest aus den Tabellen, nicht aus den
                       JSON-Dateien. Ohne diesen Schritt laeuft Modul 4
                       durch und loest nichts auf, ohne zu scheitern.
  Erstbestand von Hand Der erste Lauf laedt 2,2 GB Modellgewichte und
                       kodiert den gesamten Korpus, ~17 min je 5000
                       Items. Aus dem Timer heraus liefe er in
                       TimeoutStartSec=1800.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NupWEBPzsyohVPG47HsTz8
2026-09-08 12:32:40 +02:00
irrlichtandClaude Opus 5 3a9c000a0e Landtage und Regierungen im Lexikon, Rang als Gleichstandsregel
Drei neue Spiegelabfragen schliessen die gemessene Luecke im
Akteurslexikon: landtage (1539), regierung (2003), sondergesandte (5).
Lexikon 5540 -> 8856 Akteure, Aufloesung 21,1 % -> 23,2 % ueber 5018
Items. Der Gewinn steckt in wenigen Personen - Siegmund 123, Witkoff
102, Kushner 93, Lawrow 21.

Drei Abfragen, weil Wikidata drei Wege verlangt:

  landtage        P31/P279*, nicht P279* - "Mitglied des Landtag
                  Sachsen-Anhalt" ist eine Instanz von Q1939559, keine
                  Unterklasse. Dazu ein schaerferer Datumsfilter: von
                  11464 je gewaehlten Personen tragen 9700 keinerlei
                  Zeitangabe, ein blosses "kein Ende gesetzt" liesse die
                  Weimarer Republik herein.
  regierung       P1308, Amt -> derzeitiger Inhaber. Ueber die Amtszeit
                  der Person faellt Lawrow (amtiert seit 2004) aus jedem
                  Datumsfenster, ohne Fenster kommen Tausende Minister
                  herein, deren Amtszeit nie zu Ende gepflegt wurde.
  sondergesandte  Der andere Weg, fuer Witkoff - sein Amt traegt kein
                  P1308. Beide Wege in einer Abfrage laufen in die
                  Zeitgrenze der WDQS.

Kushner steht in hand.json: sein Amt endete 2021, seine Rolle nicht.

Die Erweiterung hat zuerst Schaden angerichtet. Mit den Landtagen kamen
Janine und Heiner Merz ins Lexikon, "Merz" wurde mehrdeutig, und 125
Nennungen des Bundeskanzlers fielen aus. Aus jedem "Hamburg" wurde eine
Kultusministerin (22-mal), aus "KI" ein Nachname (16-mal). Daher sieben
neue Sperreintraege und eine dritte Regel in waehle(): traegt genau ein
Kandidat den niedrigsten Rang, gewinnt er. Der Rang kommt aus der
Spiegelabfrage, Staatsfuehrung vor Bundestag vor Landtag - keine
Wichtigkeitsordnung, sondern eine Erwartung darueber, wen eine deutsche
Schlagzeile mit blossem Nachnamen meint. Abschlag 0,15, Grund steht in
der Nutzlast. Die Amtstabelle bekommt den schlechtesten Rang: sie reicht
bis 1794 zurueck, mit Rang 0 wurde aus "Teufel" ein
Ministerpraesident a. D.

Dabei fiel ein Loch im Fingerabdruck auf: NACHNAMEN_SPERRE stand nicht
in EINSTELLUNGEN_FEST. Ein Eintrag mehr aenderte das Ergebnis von 4868
auf 4820 aufgeloeste Nennungen unter derselben coder_version - genau
der Fehler, den die Version verhindern soll. Sperrliste und Rangordnung
gehen jetzt als Hash ein.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 12:11:56 +02:00
irrlichtandClaude Opus 5 a2e62a7d5e Neues Backup-Namensschema in .gitignore
Der Prod-Spiegel vom 08.09. heisst 2026-09-08_bebop-backup und faellt
nicht unter bebop_database_*. Er lag ungeschuetzt im Arbeitsverzeichnis
und traegt Rollen samt Passworthashes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 12:11:34 +02:00
irrlichtandClaude Opus 5 1ce7610e55 Akteure im Container, Kontakt im User-Agent
Das Abbild traegt jetzt spaCy und de_core_news_lg 3.8.0 mit fester Version
sowie den Wikidata-Spiegel. Es waechst dadurch von 1,28 auf 2,12 GB. Das
Modell liegt im Abbild statt im Cache-Volume: 568 MB, die sich nie aendern,
und der erste Lauf auf Prod soll nicht an einem Download haengen.

Gemessen: ein Slot-Lauf im Container erzeugt bitgleich dieselbe Nutzlast wie
die Workstation - 3407 Codings, 0 Abweichungen, gleiche coder_version.

Der User-Agent fuer die WDQS traegt jetzt die Impressumsadresse des
Projekts, wie es die Nutzungsrichtlinie erbittet.

NOTES.md haelt fest, woher die Zeichenkette "None" kommt: bei leerer
<description> faellt der Poller auf content:encoded zurueck, und die ZEIT
liefert dort einen Anker, dessen Text "None" lautet. Phase 1 schreibt
getreu mit, der Fehler ist stromaufwaerts. Am Live-Feed reproduziert,
8 von 15 Items.

Der Prod-Cluster-Dump ist per .gitignore ausgeschlossen - er enthaelt die
Rollen samt Passworthashes, auch die von gitea und hedgedoc.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NupWEBPzsyohVPG47HsTz8
2026-09-08 08:31:46 +02:00
irrlichtandClaude Opus 5 7e4c31912c Akteursmodul mit Wikidata-Spiegel
Modul 4 der Spezifikation, dazu das Lexikon, auf das es sich stuetzt.

Drei Schritte, streng getrennt: die NER liefert Kandidatenspannen, das
Lexikon entscheidet den Typ, die Amtstabelle loest Aemter gegen das Datum
des Items auf. Die Trennung ist gemessen begruendet und nicht uebernommen:
de_core_news_lg haelt "Merz" fuer einen Ort, "Landtagswahl" fuer einen Ort
und "Ukraine-Krieg" fuer eine Person. Der NER-Typ steht als ner_typ in der
Nutzlast, entscheidet aber nichts.

Modellwahl gemessen: sm und lg finden fast gleich viele Entitaeten (14249
gegen 14261), aber nicht dieselben - nur 10,7 Prozent der Items bekommen
von beiden dasselbe Ergebnis, der Jaccard ueber alle Spannen liegt bei
0,590. lg findet 170-mal zusaetzlich "AfD" sowie Merz, Putin, Trump,
Kushner, Witkoff. Zeitlich kostet das nichts (7,3 gegen 8,0 Sekunden fuer
den Gesamtbestand), an Plattenplatz 568 MB.

Der Spiegel ist eine Abschrift, keine Auslegung: lexikon/*.json enthaelt
die Wikidata-Antworten unveraendert, mit MANIFEST.json als Beleg. Jede
Ableitung geschieht in lexikon_laden.py. Nur lexikon.py --spiegeln fasst
das Netz an, und es laeuft von Hand - die WDQS ist ein spendenfinanzierter
Dienst, kein Endpunkt fuer eine Pipeline im Viertelstundentakt.

p2-005 legt akteure und amtsinhaber an, dazu zwei Betriebssichten. Keine
Ausschlussbeschraenkung gegen ueberlappende Amtszeiten: Doppelspitzen sind
im deutschen Parteiensystem der Normalfall, und Bremen fuehrt
"Buergermeister" als kollegiales Amt. Die Sicht
amtsinhaber_ueberschneidungen macht Ueberlappungen sichtbar, statt sie zu
verbieten. Amtszeiten sind halboffen - der Tag der Uebergabe gehoert dem
Nachfolger, sonst waere jeder Amtswechsel eine Ueberschneidung.

Messung ueber den Gesamtbestand: 3407 Items in 21,1 Sekunden, 14652
Nennungen, 2889 aufgeloest. Ein Slot-Lauf erzeugt bitgleich dieselbe
Nutzlast wie der Gesamtlauf, 0 Abweichungen. spaCy ist stapelunabhaengig
(Stapelgroesse 64, 7, 1 und rueckwaerts: identische Spannen), der
Kunstgriff mit der festen Tokenlaenge aus dem Embeddingmodul ist hier
nicht noetig.

Zwei Fallen sind in NOTES.md festgehalten: eine geratene QID haengt einen
Eintrag an ein fremdes Objekt (Q157617 ist die Commerzbank, nicht der
Bundesrat), und FILTER (lang(?name) = "de") verliert lautlos alles ohne
deutsches Label - Apple, Microsoft und Meta.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NupWEBPzsyohVPG47HsTz8
2026-09-08 08:27:05 +02:00
irrlichtandClaude Opus 5 cf89e012b2 Revisionsmodul, Embeddings und Container
Drei Schritte, die zusammen Phase 2 lauffaehig machen.

Revisionen (migrations/p2-004, revisionen.py)
    Ingest schreibt jede geaenderte Fassung eines Items nach
    raw_item_versionen fort. Daraus faellt ein Befund ab, den die
    Spezifikation nicht vorsehen konnte: welches Haus seine Schlagzeile
    nachtraeglich umschreibt, und wie. 206 von 3407 Items, acht
    Einstufungen von 'formal' bis 'neufassung'. Kein Modell, kein Lexikon,
    kein Netzzugriff - nur ein Wortvergleich zweier Fassungen.

    Fortschreibungen sind ueber ticker_markiert und kopf_stabil abziehbar,
    absichtlich als zwei Merkmale statt einer Kategorie: das eine ist eine
    Selbstauskunft des Hauses, das andere eine Beobachtung am Satzbau.

Embeddings (embeddings.py)
    multilingual-e5-large, 1024 Dimensionen, MIT. Jede Zeile wird auf feste
    128 Token aufgefuellt, nicht nur bis zur laengsten des Stapels - sonst
    haengt ein Vektor davon ab, mit welchen Nachbarn er kodiert wurde, und
    ein Slot-Lauf liefert andere letzte Stellen als ein Backfill.
    Nachgewiesen: 64/64 bitgleich einzeln wie im vollen Stapel, groesste
    Abweichung 0.00e+00, und im Betrieb 26 Slot-Vektoren unveraendert
    gegen den 3407er-Backfill.

    Darum transformers statt sentence-transformers: letzteres kapselt genau
    diese Stelle weg.

Container (Containerfile, phase2.py, deploy/)
    Debian trixie wie der Postgres-Container, torch aus dem CPU-Index.
    Die regelbasierten Module liefern darin fuer alle 3407 Items bitgleich
    dieselbe Nutzlast wie auf der Entwicklungsmaschine - Portabilitaet
    gemessen, nicht behauptet.

version.py bekommt den Schluessel 'revision'. Weil der Hash ueber den ganzen
Komponentensatz laeuft, aendert das auch die Version des Dublettenmoduls,
obwohl an dessen Verfahren nichts anders ist. Das ist die in version.py
beschriebene Semantik der Spezifikation, kein Versehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NupWEBPzsyohVPG47HsTz8
2026-09-08 07:41:27 +02:00
irrlicht 50d497925f Dublettenprüfung 2026-09-07 14:30:02 +02:00
irrlicht 861caae57c database migrations 2026-09-07 12:40:12 +02:00
irrlicht c42db46973 Readme 2026-09-07 12:40:02 +02:00
irrlicht d1bd1016f7 Database connection 2026-09-07 12:25:07 +02:00
irrlicht 91931a47b0 Initial 2026-09-07 12:25:02 +02:00