# Novaberg — Faktengedächtnis (Bauplan) **Teil 3 von 5 — Bauplan.** Absicht und Kopfblock: [`novaberg-memory-fakten_k.md`](novaberg-memory-fakten_k.md) · Diskussion und Ergänzungen: [`novaberg-memory-fakten_e.md`](novaberg-memory-fakten_e.md) · Ausarbeitung und Messungen: keine (`_k`, Kopfblock). Die Abschnittsnummer §6 ist die des Konzepts. **Stand:** 26. Oktober 2026, 07:51 UTC (`date -u`; §6 F7: die Commit-Kennung des Subjekttyps nachgetragen — Code-Tree `47256bf` ist `a4997ac`). Davor 23. Oktober 2026, 20:11 UTC (`date -u`; F7 auf `_e` A Nr. 41–43 nachgezogen — der Typ ist ein Fakt aus der Liste der sechs in der Faktentabelle, nicht `entitaeten.typ`; Tabelle der Bauteile, *Die angenommene Bauart* und *Reihenfolge* Schritt 11). Davor 22. Oktober 2026, 23:00 UTC (`date -u`; Teil H und der Kanal von C5 am Modell gemessen, zwei Bugs daraus — *Der Erinnerungsanker*, *Das Angebot der Sachlage*, *Reihenfolge* Schritte 6 und 7). Davor 22. Oktober 2026, 22:24 UTC (`date -u`; am Code geprüft und berichtigt — die Schemaänderungen und der Erzeuger gebaut, F2 mit seinen gebauten Ausgängen und ohne Rückfrage, der Kanon in `agents/fakten/beziehungen.py`, F1 als `load_mappe`, F7 und der Typ einer Entität nicht gebaut, S3 ohne Vorgabewert, das Plugin committet; *Reihenfolge* Schritte 4 und 5; die Ampeln; die Stilllegung der Tabelle aufgehoben; die Kopfzeile von Schritt 4 markiert). Davor 22. Oktober 2026, 20:29 UTC (`date -u`; Teil H und C5 gebaut, getestet und committet, Code-Trees `d810399`, `0d5f633`, `04f823e` — das Angebot der Sachlage mit den Fakten, Regel (c) nach `_e` A Nr. 44, der Kalender im Angebot mit eigener Grenze; der Erinnerungsanker mit Kanal, Suche und Knoten — *Die angenommene Bauart*, F1 *Ihre Leser*, *Der Erinnerungsanker*, *Das Angebot der Sachlage*, *Reihenfolge* Schritte 6 und 7). Davor 22. Oktober 2026, 06:12 UTC (`date -u`; F6, die Zeit eines Ereignisses: das Jahr eines Ausdrucks ohne Jahr kommt aus der Zeitlage des Satzes, gebaut, getestet und am Modell gemessen — F6, *Reihenfolge* Schritt 10). Davor 22. Oktober 2026, 06:06 UTC (`date -u`; F6, die Schritte 5–6 gebaut und getestet, im Betrieb nicht gemessen — das Ereignis gekennzeichnet in `[TERMINE]`, die Leser des Monats, die Mappe mit *ab*/*bis* über `aktive_zeile`, die Klärung eines Tages verschiebt die Monatszeile; F6 und *Reihenfolge* Schritt 10). Davor 22. Oktober 2026, 05:27 UTC (`date -u`; F6, die Schritte 3–4 gebaut, getestet und am Modell gemessen — der Weg über Planner und Clipboard als überholt markiert, gebaut ist der passive Weg über den Dispatcher; S6 ohne DDL als `month`; S5 und S7 committet, die DDL am 21.10.2026 angewandt und gemessen — F6, *Die Schemaänderungen*, *Reihenfolge* Schritt 10). Davor 21. Oktober 2026, 20:11 UTC (`date -u`; F6, die Grundlage: S5, die Typquelle mit dem Typ `ereignis` und das Verschieben in einer Transaktion gebaut und getestet, nicht committet, die DDL am Betrieb nicht angewandt; der Weg im Turn fehlt — F6, *Die Schemaänderungen*, *Reihenfolge* Schritt 10). Davor 21. Oktober 2026, 19:47 UTC (`date -u`; S7, die Timeline je Paar: gebaut und getestet, nicht committet, die DDL am Betrieb nicht angewandt — F6, *Die Schemaänderungen*, *Reihenfolge* Schritt 10). Davor 21. Oktober 2026, 07:10 UTC (`date -u`; F6 Grenze und Umfang, F3 Rückverweis). Davor 21. Oktober 2026, 06:13 UTC (`date -u`; M2: die Tiefe bleibt 2, `_e` A Nr. 40). Davor 21. Oktober 2026, 06:05 UTC (`date -u`; F6 und S7: das Ereignis gehört dem Paar, `_e` A Nr. 38). Davor 21. Oktober 2026, 05:48 UTC (`date -u`; *Der Erinnerungsanker*: sucht immer, `_e` A Nr. 36). Davor 21. Oktober 2026, 04:56 UTC (`date -u`; F7: der Typ aus der Klassifikation; dazu seit dem 20.10. nachgetragen: F1 gebaut, M2 gemessen, das Plugin gelöscht). Davor 20. Oktober 2026, 21:30 UTC (`date -u`; F1: Leser, Ort und Endpunkt der Mappe, `_e` A Nr. 29–32). Davor 20. Oktober 2026, 18:55 UTC (`date -u`; F2 und F4: der passive Agent, `_e` A Nr. 24–28). Davor 20. Oktober 2026, 05:32 UTC (`date -u`; §6 *Reihenfolge*: Schritt 4, der Schreibweg des Fakten-Agenten, gebaut; der Empfang über den Router zurückgehalten; F2 ohne Objekt-Merkmal, `_e` A Nr. 23; der Agent ist passiv, `_e` A Nr. 24). Davor 18. Oktober 2026, 14:58 UTC (`date -u`; §6 *Reihenfolge*: Schritt 3, das Schema S1 bis S4 und das Repository, gebaut). Davor 17. Oktober 2026, 21:50 UTC (`date -u`; die Bauart angenommen und je Bauteil beschrieben, *Die angenommene Bauart*; die Schemaänderungen S1 bis S6 im Grundsatz freigegeben, nicht gebaut; F5 und F7 nach den Entscheidungen berichtigt; die Reihenfolge in elf Schritten; nichts gebaut außer dem gemeinsamen Leseweg der Termine). Davor 17. Oktober 2026, 17:05 UTC (`date -u`; M1 gemessen, M2 hinter F1 gestellt, weil er einen Bau braucht; nichts gebaut). Davor 17. Oktober 2026, 15:40 UTC (`date -u`; angelegt, nichts gebaut). --- ## 6. Die Bauteile Jedes Bauteil ist eine Zeile der Featureliste ~~mit ⚫~~ → mit ihrer Ampel (§3.1, *Faktengedächtnis*; seit dem 20.10.2026 nicht mehr alle ⚫). Die Beispiele sind synthetisch. **Vorbedingung für alle:** ~~Die Tabelle `fakten` ist stillgelegt, bis ein Fakten-Agent gebaut wird (entschieden am 06.10.2026). F2 hebt die Stilllegung auf.~~ → Die Stilllegung vom 06.10.2026 ist mit F2 aufgehoben: Seit dem 21.10.2026 schreibt der passive Fakten-Agent in `fakten` (`7bde8d7`; am Code geprüft am 22.10.2026, `FaktenRepository.schreiben` über `agents/fakten/dispatch.py::process_fact_orders`). Jede Schemaänderung (eine Spalte für die Herkunft, ein Verweis auf die Timeline, eine Verfallsgröße) wird vor dem Bau angekündigt und wirkt erst nach dem Neustart des Dienstes. → Die sechs Schemaänderungen der Bauart (S1 bis S6, unten) sind am 17.10.2026 im Grundsatz freigegeben, ~~nicht gebaut~~ → gebaut: S1 bis S4 am 18.10.2026, S5 am 21.10.2026, S6 am 22.10.2026 ohne DDL, dazu S7 am 21.10.2026 (*Die Schemaänderungen*, unten; am Code geprüft am 22.10.2026); **jede wird vor ihrem Bau einzeln angekündigt** (`_e` A, Nr. 20). ~~Die Fragen der Bauart (`_k` §5, Punkte 1 bis 5) sind vor dem Bauteil zu entwerfen, das sie berührt.~~ → Die Fragen der Bauart (`_k` §5, Punkte 1 bis 5) sind am 17.10.2026 entschieden; was daraus je Bauteil folgt, steht unten unter *Die angenommene Bauart*. | Bauteil | ZIEL | TEST | MESSUNG | Gegenprobe | |---|---|---|---|---| | **F1 — die Mappe lesen** | Zu einer Entität liefert eine einzige Lesefunktion ihre Fakten bis zum zweiten Grad in beide Richtungen: Referenz- und Wert-Fakten, nur aktive, nur die des Paares, gekappt. Alle Leser benutzen sie | Entität mit Fakten als Subjekt und als Objekt, Nachbarn mit eigenen Fakten → erster und zweiter Grad geliefert, dritter nicht; ein Wert-Fakt ist dabei; ein Fakt eines anderen Paares nie; über der Kappung wird gekürzt und gesagt, dass gekürzt wurde; ohne Fakten → leer und als *keine Fakten* erkennbar, nicht als Ausfall | Simulation an einem Prüf-Nutzer: Eine Frage zu einer Person mit gespeicherten Fakten wird mit ihnen beantwortet, auch mit einem Fakt des zweiten Grades. Dazu M2 | Nur die Subjekt-Richtung gelesen → die Fakten, in denen die Entität Objekt ist, fehlen; nur Entität→Entität verbunden → der Wert-Fakt fehlt | | **F2 — der Fakten-Agent** | Der Fakten-Agent ist eine Fachabteilung ~~am Empfang~~ → ohne Empfang, ein passiver Dienst (20.10.2026, `_e` A Nr. 24–28), nach dem Muster der Timeline. Er meldet sich an mit Aushang, Negativfällen ~~und dem Objekt-Merkmal, das er bedient~~ → ohne Objekt-Merkmal (19.10.2026, `_e` A Nr. 23) → seit dem 20.10.2026 ohne Aushang und Negativfälle, er meldet sich nicht am Empfang an (`_e` A Nr. 28). Er prüft einen Auftrag gegen seinen Bestand, schreibt deterministisch und verifiziert, ~~antwortet auf einem der vier Ausgänge, veranlasst Rückfragen über den Klärfall am Objekt~~ → meldet je Auftrag und je Tripel einen Ausgang, ohne Rückfrage: Zwei gleichnamige Entitäten ergeben `mehrdeutig`, und nichts wird geschrieben; die Frage gehört an das Objekt der Lage (F3, nicht gebaut; am Code geprüft am 22.10.2026, `agents/fakten/suche.py`), und schreibt sein Audit selbst. Das Plugin `FaktenManager` geht in ihm auf | Zeugen auf die vier Ausgänge; *identisch* → keine Zeile, kein Fehler; *widerspricht* → Ablösung (F5); ein geschriebener Fakt trägt Paar und Herkunft; ein verifizierter Schreibschritt wird als solcher gemeldet, ein gescheiterter ist `fehler` und nie `abgeschlossen`; das Repository filtert nach dem Paar (`FAKTEN-PAIR-IGNORED`) | Simulation an einem Prüf-Nutzer: Ein ausdrücklicher Auftrag (*„Merk dir, dass Lena in Kassel lebt“*) legt genau eine Zeile an. Die Antwort sagt es, und die Prüfung der Speicherbehauptung meldet keine unbelegte Behauptung | Die Verifikation nach dem Schreiben entfernt → ein gescheitertes Schreiben meldet `abgeschlossen`, und die Prüfung der Speicherbehauptung hält es für gedeckt | | **F3 — Entitäten klären** | Passt ein Name eines Objekts der Sachlage auf zwei Entitäten, steht ein Klärfall mit den Kandidaten am Objekt ([`novaberg-klaerung_k.md`](novaberg-klaerung_k.md) §2.3). Gefragt wird nach den Regeln der Klärung, die Kandidaten stehen als nummerierte Liste. Nach der Antwort ist das Objekt an genau eine Entität gebunden. Erzeuger ist der vorhandene `EntityResolutionService` mit `braucht_klärung` | Zwei Entitäten *Lena* → ein Klärfall mit beiden Kandidaten in fester Liste; eine Entität → kein Klärfall, Bindung wie heute; die Antwort *„die zweite“* bindet die zweite; ein neuer Auftrag zum selben Objekt ersetzt den Klärfall; die Sachlage verfällt → der Klärfall verfällt, nichts wird gebunden | Simulation an einem Prüf-Nutzer mit zwei gleichnamigen Personen im Bestand: *„Lena kommt morgen“* → Rückfrage mit beiden (bei Haltung oder Auftrag), danach ist das Objekt gebunden, und die Mappe stimmt | Klärfall abgeschaltet → das Objekt bleibt ungebunden, es kommt keine Frage, die Mappe fehlt. Das ist das heutige Verhalten des Magnet-Pfads | | **F4 — lernen ohne Auftrag** | Eine neue, dauerhafte Aussage über eine Entität mit Salienz über der Grenze stellt Nova dem Fakten-Agenten ohne Auftrag zu, und er legt sie als Fakt mit Herkunft ab. Unter der Grenze bietet Nova nach Pflichtbewusstsein und Nähe an oder fragt, und erst die Zustimmung wird ein Auftrag. Weltwissen aus Modell oder Recherche ist lernbar, mit seiner Herkunft | Salienz über der Grenze → Zustellung ohne Bitte, ein Tripel mit Herkunft *Mensch*; darunter mit hohem Pflichtbewusstsein → ein Angebot und kein Tripel bis zur Zustimmung; darunter mit niedrigem → nichts; eine Anweisung an die Figur, ein Rollenspielsatz, eine Metapher → kein Tripel; ein Weltwissens-Satz aus einer Recherche → Tripel mit Herkunft *Recherche* | Simulation an einem Prüf-Nutzer über zwei Gespräche: eine Aussage über eine nahe Person im ersten, eine Frage danach im zweiten → gewusst. Dazu die Zählung je Herkunft und der Anteil abgelegter Aussagen gegen angebotene | Grenze über jede Salienz gesetzt → kein Tripel ohne Zustimmung; Herkunft weggelassen → die Zählung je Herkunft fällt aus | | **F5 — ablösen statt überschreiben** | Ein neuer Wert zu Subjekt und ~~Beziehung~~ → einer einwertigen Beziehung löst den alten bi-temporal ab, ohne Rückfrage: Der alte wird invalidiert, der neue angelegt, beide bleiben. → Bei einer mehrwertigen Beziehung kommt der neue Wert dazu (entschieden am 17.10.2026, `_e` A, Nr. 17). Die aktiven beantworten die Gegenwart, alle zusammen die Historie | *Lena lebt in Kassel* → *Lena lebt in Hamburg*: der alte mit `aktiv = FALSE` und `t_invalid`, der neue aktiv; derselbe Wert → keine neue Zeile; die Historie liefert beide in zeitlicher Folge; höchstens ein aktiver Wert je Subjekt und ~~Beziehung~~ → einwertiger Beziehung, von der Datenbank erzwungen (S4). → Zwilling: zwei Haustiere (mehrwertig) bleiben beide aktiv. Scheitert das Anlegen, bleibt der alte Wert aktiv | Im Labor gegen eine Wegwerf-Datenbank: zwei Ablösungen hintereinander, danach die Historie gelesen | Das Invalidieren entfernt → zwei aktive Werte für dieselbe Beziehung | | **F6 — Zeit über die Timeline** | Ein Fakt, der durch ein Ereignis entsteht, gilt ab dem Ereignis; sein Beginn verweist auf den Eintrag der Timeline. Kein Fakt trägt einen Monat oder ein Datum als Wert, und ein Monat wird keine Entität | *„Lena zieht im November nach Kassel“* → keine Entität *November*, kein Fakt mit dem Wert *November*; ist der Tag geklärt, gilt *Lena lebt in Kassel* ab ihm, und der Beginn verweist auf den Eintrag; eine Spanne (*den ganzen November*) bleibt ein Termin der Timeline mit Anfang und Ende. → Seit der Bauart (17.10.2026): Der Eintrag `ereignis` steht schon vor der Klärung mit der Genauigkeit *Monat* da, und nach dem Verschieben führt der Verweis über `timeline.nachfolger_id` zur aktiven Zeile | Zählung am Bestand nach einer Simulation: Fakten mit einem Zeitwort im Wert (Soll 0), Entitäten, deren Name ein Monat ist (Soll 0), Fakten mit Beginn und Verweis auf die Timeline | Den Verweis weggelassen → der Fakt gilt ab dem Schreiben statt ab dem Ereignis. → Dem Nachfolger nicht gefolgt → nach dem Verschieben verweist der Fakt auf die inaktive Zeile | | **F7 — typisieren** | Ein Fakt *„ist ein“* gibt der Entität ihren Typ, ~~im Typsystem, das die Bauart festlegt~~ → aus der festen Liste ~~von `entitaeten.typ`~~ → als Typ-Fakt in der Faktentabelle, ein zwingender Wert aus der Liste der sechs, dem Paar gehörend (21.10.2026, `_e` A Nr. 41–43); ~~die freie Klasse wird über das Embedding dem nächsten Typ zugeordnet, unter einer Mindestähnlichkeit bleibt `sonstiges`~~ → die Klassifikation des Fakten-Agenten wählt den Typ aus der festen Liste mit, `sonstiges` eingeschlossen (21.10.2026, `_e` A Nr. 34; eine Mindestähnlichkeit trug am Embedding nicht, gemessen) (entschieden am 17.10.2026, `_k` §5, Punkt 3; `_e` A, Nr. 14) | *„Kassel ist eine Stadt“* → Typ gesetzt; ein zweiter, widersprechender *„ist ein“*-Fakt löst ab wie jeder andere (F5) und ändert den Typ | Zählung: Entitäten mit einem Typ außer `sonstiges` vorher und nachher | Typ nicht übernommen → die Entität bleibt `sonstiges` | ### Die angenommene Bauart (17.10.2026) **Angenommen vom Meister am 17.10.2026** (`_e` A, Nr. 13–21; C). Hier steht, was gebaut werden soll. ~~**Gebaut ist davon nur der gemeinsame Leseweg der Termine** (C1, Scheibe 6 der Lage); alles andere ist entschieden und nicht gebaut.~~ → **Überholt, 22.10.2026:** Was davon gebaut ist, steht je Bauteil unten und in der *Reihenfolge*; zuletzt das Angebot der Sachlage mit den Fakten (C2, Teil H) und der Erinnerungsanker (C5), beide committet (Code-Trees `d810399`, `0d5f633`, `04f823e`), Teil H und der Kanal am Modell gemessen, nichts davon im Betrieb. Gebaut und committet sind C1, S1 bis S7, F1, F2 als passiver Dienst, F5 und C4 mit F6; nicht gebaut sind F3, von F4 die Grenze der Salienz und F7 (am Code geprüft am 22.10.2026). Die Befunde am Bestand sind am Code gelesen (HEAD `7b65297`), nicht im Betrieb gemessen. Die Namen von Modulen und Funktionen sind vorgesehen, nicht verbindlich: Namen, Typen und Nähte legt der Bau fest. Die Beispiele sind synthetisch. **F2 — der Fakten-Agent** (`_e` A, Nr. 6 und 21): **→ überholt im Weg, nicht im Schreiben (20.10.2026, `_e` A Nr. 24–28):** Der Agent ist passiv, ein Dienst ohne Empfang; sein Auftrag kommt in jedem Turn aus der Sachlage über den Dispatcher, nach der Antwort; kein Aushang, keine Negativfälle, kein Platz am Brett; ~~Ausgänge *geschrieben*, *kein Fakt*, *Fehler*~~ → gebaut sind neun Ausgänge je Auftrag (`leer`, `ausgefallen`, `fehler`, `verworfen`, `nur_andere_sprecher`, `modell_ausfall`, `antwort_defekt`, `kein_tripel`, `klassifiziert`) und je Tripel einer von sechs (`angelegt`, `abgeloest`, `identisch`, `mehrdeutig`, `fehler`, `verworfen:`; am Code geprüft am 22.10.2026, `agents/fakten/dispatch.py`, `OUTCOMES`, `TRIPLE_OUTCOMES`). Das Plugin wird mit F1 gelöscht → gelöscht, committet am 21.10.2026. Was unten über Empfang, Planner und Plugin steht, gilt für den Weg nicht mehr; Schreibweg, Kanon und Verifikation gelten. - **Ein Paket `agents/fakten/` nach dem Muster von `agents/timeline/`:** Anmeldung mit Aushang, Negativfällen und Objekt-Merkmal, dazu Dispatch, Klassifikation, Suche, Ausführung, Wiederaufnahme und Bestätigung. - **Ein Kanon der Beziehungen** im Agenten: je Beziehung einwertig oder mehrwertig (`_e` A, Nr. 17). ~~Den Startbestand gibt die Zuordnung der Beziehungen im alten Plugin, in der heute das einwertige `WOHNT_IN` neben den mehrwertigen `HAT_HAUSTIER` und `HAT_SCHWESTER` steht. Dort steht auch die Typliste für F7.~~ → Der Kanon steht seit dem 20.10.2026 in `agents/fakten/beziehungen.py` (`KANON`): 23 Beziehungen, klein geschrieben (`wohnt_in`), 9 davon einwertig; zu jeder Beziehung mit einer Entität als Objekt der Typ einer neuen Objekt-Entität (`ort`, `person`, `tier`), ohne *„ist ein“*. Das alte Plugin ist gelöscht; ~~eine Typliste für F7 steht im Code nicht (am Code geprüft am 22.10.2026)~~ → **Seit dem 25.10.2026 steht die Liste der sechs im Code** (`ENTITY_TYPES`, `agents/fakten/beziehungen.py`), dazu je Beziehung `subjekt_typen`, die Typen, die ihr Subjekt haben darf (`person` für jede; `heisst` jeder Typ außer `sonstiges`; `wohnt_in` und `geboren_in` dazu `tier`; `_e` A Nr. 46). Sie dient der Prüfung des Subjekts, noch nicht dem Typ-Fakt (F7). - **Der Schreibweg:** Empfang → Planner → Dispatch des Agenten. Klassifizieren: Subjekt, Beziehung nach dem Kanon, Wert oder Objekt. Suchen: die Entitäten über den gemeinsamen Dienst zur Auflösung (`memory/services/entity_resolution.py::EntityResolutionService`); bei einer Mehrdeutigkeit ein Klärfall (F3). Ausführen in **einer** Transaktion: Ist der Wert *identisch*, wird nichts geschrieben; bei einer einwertigen Beziehung wird der alte Fakt invalidiert und der neue angelegt; bei einer mehrwertigen wird der neue angelegt; bei *„ist ein“* wird dazu der Typ der Entität gesetzt (F7). Danach verifizieren; der Ausgang kommt aus dem Ergebnis der Verifikation (`agents/write_outcome.py::verified_outcome`), und die Herkunft ist Pflicht. - **Gemeinsame Klassen:** die Anmeldung (`agents/nmcp.py`), das Objekt-Merkmal (`agents/object_feature.py`), das Repository und der Dienst zur Auflösung. - **Das Repository** (`memory/repositories/fakten_repository.py`) wird umgebaut: das Paar in jeder Abfrage (`FAKTEN-PAIR-IGNORED`), Lesen ohne `last_touched` zu schreiben (`FAKTEN-LESEN-SCHREIBT-LAST-TOUCHED`), Ablösen mit einem übergebenen Cursor, also in der Transaktion des Aufrufers (`FAKTEN-ABLOESEN-OHNE-TRANSAKTION`), und der Lauf des Verfalls (S3). - ~~**Vom Plugin `plugins/fakten_manager/` bleibt nur die Empfangsfläche:** sein Ziel, die Absicht `fakten_management` des Routers und der Aushang, wie bei Timeline und Notizen; über diese Fläche findet der Planner den Dienst.~~ → **Seit dem 20.10.2026 hat das Plugin keinen Platz am Brett:** kein Text, keine Absicht; der Agent steht nicht am Empfang und bekommt seine Aufträge vom Dispatcher; das Plugin wird mit F1 gelöscht (`novaberg-memory-fakten_e.md` A Nr. 25–28). Es entfallen die Anreicherung samt ihrer Abschaltung im Enricher, die Ausführung, `fakten_verarbeiten`, `fakten_abfragen` und `fakten_historie`. Mit dem Bau erledigen sich damit `FAKTENPLUGIN-OHNE-KAPPUNG` (die Mappe ist gekappt) und `FAKTEN-UNAUFGELOESTES-OBJEKT-WIRD-WERT`. ~~Das Plugin wird zurückgebaut und nicht gelöscht, weil es für einen Agenten mit eigenem Aushang ohne Plugin noch kein Vorbild gibt.~~ → Es wird gelöscht (`_e` A Nr. 28; der Grund ist mit der Zustellart `queue` entfallen) — gebaut am 21.10.2026, ~~nicht committet~~ → committet mit `bbf6c27`. **F5 — ablösen** läuft im Schreibweg des Agenten (oben). Dass je Paar, Subjekt und einwertiger Beziehung höchstens ein Wert aktiv ist, erzwingt der Teilindex aus S4. **F1 — die Mappe** (`_e` A, Nr. 12 und 21): - **Eine Lesefunktion über dem Repository**, vorgesehen als ~~`memory/fakten_mappe.py::mappe`~~ → gebaut als `memory/fakten_mappe.py::load_mappe`, mit einstellbarer Tiefe (Ausgangswert der zweite Grad) und einer Kappung in Zeichen. Ihr Ergebnis sagt, ob gekürzt wurde, und unterscheidet *leer* von *Ausfall*. → **Ort entschieden am 20.10.2026** (`_e` A Nr. 31): Das Durchlaufen beider Richtungen bis zum zweiten Grad ist eine neue Funktion von `FaktenRepository` (vorgesehen `find_umgebung`); Ordnung, Kappung und Form liegen in `memory/fakten_mappe.py`. Mit F1 wird das Plugin `plugins/fakten_manager/` gelöscht (A Nr. 28). - **Ihre Leser:** der Erinnerungsanker (unten), das Angebot der Sachlage (~~`graph/nodes/sachlage_resolver.py::memory_offer`~~ → `graph/nodes/sachlage_resolver.py::fact_hits`, gerufen in `graph/nodes/sachlage.py::_derive`; Scheibe 13, Teil H) — beide gebaut am 22.10.2026, committet (Code-Trees `d810399`, `0d5f633`, `04f823e`) —, ~~die Suche des Fakten-Agenten~~ (→ kein Leser, 20.10.2026, `_e` A Nr. 30) und die Schnittstelle `api/gedaechtnis.py::fakten_abrufen` (→ `GET /fakten/{user_id}/{entitaet_id}` liefert die Mappe, `GET /fakten/{user_id}` nur die Entitäten, A Nr. 32). `graph/nodes/gespraechsvektor.py::_entity_kontext_laden` entfällt, es hat keinen Aufrufer — mit dem Kommentarblock darüber, der noch `FaktenAgent` nennt (Fundliste 20.10.2026). → Entfernt, samt Kommentarblock, committet am 21.10.2026; das Fehlen hält ein Zeuge (`tests/test_gv_resonanz_kontext.py`; am Code geprüft am 22.10.2026). - ~~**Offen:** Die Wiedervorlage (`agents/wiedervorlage/agent.py`, `find_wiedervorlage_faellig`), einer der sechs alten Leser aus `_k` §3.1, ist in der Bauart nicht genannt.~~ → **Entschieden am 20.10.2026** (`_e` A Nr. 29): Die Wiedervorlage ist kein Leser der Mappe und bleibt bei `find_wiedervorlage_faellig`. **Der Erinnerungsanker** (C5; `_e` A, Nr. 16) — ein Knoten zwischen `sachlage_node` und `router`, vorgesehen als `graph/nodes/erinnerungsanker.py` → **gebaut am 22.10.2026, committet**, in zwei Bauten auf Teil H: Kanal und Suche (Code-Tree `0d5f633`), der Knoten (Code-Tree `04f823e`); der Kanal am Modell gemessen am 22.10.2026 — eine erfragte Person steht genau dann darin, wenn sie akut ist (43 von 92 Läufen), eine nur erwähnte nie (16 von 16; [`novaberg-thinking-lage_m.md`](novaberg-thinking-lage_m.md) Scheibe 13) —, der Knoten nicht; im Betrieb nicht gemessen: - `sachlage_node` legt die Entitäten der akuten, gebundenen Objekte in einen deklarierten Kanal (`objekt_entitaeten`), die in diesem Turn gebundenen wie die schon früher gebundenen. ~~Heute landet die Bindung nur in der Datenbank, nicht im Zustand.~~ → **Gebaut:** `sachlage_assess` schreibt den Kanal auf allen drei Wegen — frisch, Ausfall übernommen, Impuls —, nach `remember_objects` und dem Schreibauftrag, über `memory/sachlage_properties.py::bound_entities` mit den Schlüsseln der akuten Objekte (`graph/nodes/sachlage.py::object_entities`): je Entität ein Element `{name, entitaet_id}`, einmal, in der Ordnung der Objekte; `[]` ohne Bindung, `None` laut bei einem Lesefehler. Ein nicht akutes Objekt steht nicht darin; eine Bindung, die `remember_objects` in diesem Turn setzt, schon. - Der Knoten ruft die Mappe je Entität, sucht über die Entitäten in `lzg_knoten` (vorgesehen: `memory/lzg_knoten.py::knoten_zu_entitaeten`) und ergänzt die Resonanz, entdoppelt nach dem Knoten. Die Mappe legt er als Einträge der Quelle `fakten` in die Gedächtniseinträge und rendert den Gedächtniskontext mit demselben Formatter neu. → **Gebaut:** `knoten_zu_entitaeten` liest die aktiven Knoten des Paares, deren `entitaet_ids` eine der Entitäten trägt, die stärksten zuerst (`gewicht_decay DESC, id DESC`), in der Form von `spreading_lesen` (`schale` 1, ein Pfadschritt mit dem Grund `entitaet`, `geteilte_entitaet_ids` als Menge); ein Datenbankfehler ergibt `None`, nie `[]`. Der Knoten liest höchstens `ANKER_MAX_ENTITAETEN` = 3 Mappen; eine unbekannte Entität fällt auch aus der Suche (`unbekannt`), jeder andere Ausfall der Mappe ist laut (`ausfall`), und gesucht wird trotzdem. Die Suche läuft einmal mit allen übrigen Entitäten und der Grenze `ANKER_MAX_ERINNERUNGEN` = 3 plus der Zahl der Erinnerungen der Resonanz, damit die stärksten, die schon darin stehen, die Plätze nicht nehmen; neu sind höchstens 3, entdoppelt nach `knoten_id`, hinten an `lzg_resonanz["erinnerungen"]` angehängt, `rang` fortgezählt — gerendert ordnet der Formatter alle Erinnerungen nach Gewicht. Je Entität mit Fakten ein Eintrag der Quelle `fakten`, gerendert als Gruppe *[Fakten zu ]* vor `kzg`/`lzg` (`graph/format/memory_context.py`), für beide Leser. Je Turn genau ein Eintrag `berechnung` mit `node = 'erinnerungsanker'`, auch beim Übersprung mit Grund. - So steht alles im Prompt desselben Turns, und die Leser hinter dem Router sehen eine Wahrheit je Turn. ~~**Ohne Fakten bleibt der Prompt zeichengleich mit heute.**~~ → Der Anker sucht immer, auch ohne Fakten, gekappt wie die übrigen Quellen und entdoppelt gegen die Resonanz (21.10.2026, `_e` A Nr. 36); ohne gebundene Entität mit Erinnerungen bleibt der Prompt zeichengleich. → So gebaut: Ohne gebundene Entität oder ohne etwas Neues gehen `memory_entries`, `memory_context`, `memory_context_verfasser` und `lzg_resonanz` unverändert zurück. **Das Angebot der Sachlage** (C2; `_e` A, Nr. 13; Scheibe 13, Teil H der Lage): ~~`memory_offer` nimmt die Quelle `fakten` über dieselbe Mappe. Es arbeitet auf der vorigen Blase;~~ → **Überholt, 22.10.2026, gebaut ist:** Die Quelle `fakten` kommt nicht über `memory_offer`, sondern über `fact_hits`, gerufen in `_derive` zu den akuten Objekten mit offener Eigenschaft des neuen Artefakts; die Bindung liest es aber aus der Datenbank, und die schreibt `remember_objects` erst danach; ein Objekt, das in diesem Turn zuerst genannt wird, hat im Angebot desselben Turns deshalb noch keine Mappe, sondern erst im nächsten — im selben Turn trägt sie der Erinnerungsanker in den Prompt. Eigenschaft und Fakt bleiben getrennt, und drei Regeln halten dasselbe nicht doppelt: (a) Es gibt nur die Richtung Eigenschaft → Zettel → Fakten-Agent. (b) Deckt die Mappe eine Eigenschaft, trägt die Eigenschaft als Quelle den Fakt (`quelle` mit der Art `fakten` und der Kennung des Fakts). (c) Bei einem gebundenen Objekt geht im Angebot die Mappe vor der Eigenschaft, und ~~eine Eigenschaft mit der Quelle `fakten` wird nicht angeboten~~ → eine Eigenschaft mit der Quelle `fakten` wird nur dann nicht angeboten, wenn genau ihr Fakt im Angebot steht (22.10.2026, `_e` A Nr. 44); eine Eigenschaft ohne Verweis auf einen Fakt war nie betroffen. → **Gebaut am 22.10.2026, committet** (Code-Tree `d810399`, Teil H): Je gebundenem, akutem Objekt mit offener Eigenschaft die Mappe seiner Entität, je Fakt ein Eintrag mit der Herkunft `fakten#`, jeder Fakt einmal, gekappt auf `SACHLAGE_FAKTEN_ANGEBOT_MAX` = 8 (`fact_hits`, `SOURCE_FACTS`). Die Reihenfolge im Angebot: Fakten, gespeicherte Eigenschaften, Kalender, Pool und Aufzeichnungen. `EntityNotFoundError` zählt als `unbekannt`, jeder andere Ausfall der Mappe als `ausfall`, laut; der Turn läuft weiter. Die Bindungen liest `memory/sachlage_properties.py::bound_entities` (ein Datenbankfehler ergibt `None`, nie `{}`). Regel (c) steht in der Auswahl von `active_properties` (`hidden_for`: das Objekt ist gebunden; `hidden_origins`: die Herkunft `quelle->>'herkunft'` steht unter den angebotenen Fakten), sodass eine verborgene Zeile keinen Platz unter dem `LIMIT` belegt; `_derive` liest dafür zuerst die Fakten. Eine Eigenschaft aus einem Fakt an einem ungebundenen Objekt bleibt (Umsetzungsentscheidung, `_e` A Nr. 44). **Der Kalender im Angebot** hat seither eine eigene Grenze, `SACHLAGE_BESTAND_KALENDER_MAX` = 5 Zeilen in der Ordnung des Lesewegs; `SACHLAGE_BESTAND_MAX_EINTRAEGE` = 8 gilt nur noch für Pool und Aufzeichnungen, und ein voller Monat verdrängt weder Fakten noch Pool ([`novaberg-thinking-lage_b.md`](novaberg-thinking-lage_b.md) Scheibe 6). Zeugen in `tests/test_sachlage_fakten_angebot.py`; die Zeugen über `_derive` sehen die Abfrage nur über ein Doppel (Backlog `SACHLAGE-ZEUGEN-DOPPEL-STATT-ABFRAGE`). **Am Modell gemessen am 22.10.2026** (Code-Tree `04f823e`; die gelesenen Felder `objekte[].name`, `akut`, `offen` und das Urteil an 23 neuen Äußerungen in fünf Gruppen × 4 Läufe, Mappe und Bindung synthetisch): Der Auflöser wählt `fakten#…` in 18 von 18 Fällen, in denen ein passender Fakt angeboten war, und greift nie fehl (kein Anspruch in den 23 Fällen mit Fakten ohne passenden); der Name trifft das gebundene Objekt 90 von 92 Mal; eine nur erwähnte Person ist nie akut (16 von 16); **die erfragte Person ist aber nur in 43 von 92 Läufen akut** (mit Beziehungsform 4 von 20, mit Kosename 5 von 20) — das Angebot erreicht den Auflöser seltener als angenommen. Die Angebots-Sektion ist mit Fakten im Mittel 409 statt 218 Zeichen lang, ohne angebotene Fakten zeichengleich. Die Tabelle `fakten` ist im Betrieb am 22.10.2026 leer; im Betrieb nicht gemessen ([`novaberg-thinking-lage_m.md`](novaberg-thinking-lage_m.md) Scheibe 13). Aus der Messung zwei Bugs: `SACHLAGE-FAKT-DECKT-MIT-UMSCHREIBUNG` (niedrig) — eine Deckung aus einem Fakt legt den Satz des Auflösers ab, nicht den Wert des Fakts — und `SACHLAGE-PLATZHALTER-ALS-WERT` (mittel). **F3 — Entitäten klären**, nach der Bauart der Klärfälle, angenommen am selben Tag ([`novaberg-klaerung_e.md`](novaberg-klaerung_e.md) A, *Bauart*): Bleibt ein Objekt der Klasse `person` ungebunden, ruft `remember_objects` den Dienst zur Auflösung nur mit dem Namensabgleich, ohne Rückfall auf Embeddings, denn ähnliche Namen ergäben falsche Klärfälle. Bei zwei oder mehr Treffern hängt die Sachlage einen Klärfall der Art `bestimmung` mit den Kandidaten an das Objekt, im selben Turn. Die Antwort bindet das Objekt über `bind_entity` mit einer eigenen Herkunft der Bindung. Ohne Auftrag entscheidet die Haltung, ob Nova fragt; mit Auftrag ist der Agent der Erzeuger, etwa der Fakten-Agent, in derselben Form. Vorbedingung ist der erste Schritt der Klärfälle (Backlog `KLA-KLAERFALL-AM-OBJEKT`). → Seit dem 21.10.2026 gilt dasselbe für den Magnet-Pfad (`_e` A Nr. 35); zwei Akten derselben Person werden auf Rückfrage zusammengelegt (Backlog `ENTITAETEN-ZUSAMMENLEGEN`). **F4 — lernen ohne Auftrag** → **geht im passiven Agenten auf** (20.10.2026, `_e` A Nr. 25, 26): jeder Turn ist ein Auftrag, vorerst ohne Grenze der Salienz. ~~läuft über den Empfang, mit Teil R von Scheibe 13.~~ Es setzt M1, den Fakten-Agenten (F2) und die Quelle `fakten` im Angebot voraus. **Offen bleibt die Grenze der Salienz:** M1 fand, dass die Salienz nah nicht von fremd trennt (`SALIENZ-TRAEGT-NAEHE-NICHT`). **F6 — Zeit über die Timeline** (C4; `_e` A, Nr. 15, 18, 19, 20 und 22): - **Ein neuer Typ `ereignis`** für ein Ereignis, das einer anderen Person geschieht. Er bindet die Zeit des Menschen nicht, löst keine Erinnerung aus und wird nicht gegen andere Einträge geprüft. Die Person steht in `timeline.entitaet_ids`, die heute niemand schreibt. Die Typen der Timeline stehen heute an drei Stellen und sollen eine Quelle bekommen; wie, legt der Bau fest (Backlog `TIMELINE-TYPEN-AN-DREI-STELLEN`). → **Gebaut am 21.10.2026**, ~~nicht committet~~ → committet mit `091a99d` (Tree `fed521d`): Die Typen haben eine Quelle, `memory/timeline_types.py`, und `ereignis` steht darin mit seinen Merkmalen — dazu keine Wiedervorlage, kein Duplikat-Partner, kein Termin des Menschen; ein unbekannter Typ ist laut. ~~Geschrieben wird der Typ noch von keinem Weg, und `entitaet_ids` schreibt weiter niemand~~ → Seit dem 22.10.2026 schreibt ihn der Ereignis-Weg (nächster Punkt), mit der Person in `entitaet_ids`, wenn ihr Name genau eine Entität trifft ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §8, §5.5). - **Über der Grenze der Salienz ohne Auftrag:** ~~Erkennt die Sachlage ein Ereignis und eine dauerhafte Aussage, fragt der Planner im selben Turn zuerst den Timeline-Agenten, dann den Fakten-Agenten. Die Kennung der neuen Zeile geht über das vorhandene Clipboard `timeline_id`.~~ **Überholt, 22.10.2026 — gebaut ist ein anderer Weg** (Code-Tree `04f386f`; [`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §5.5): Über der Grenze stellt die Sachlage neben den Fakten-Auftrag einen passiven Auftrag `timeline`/`ereignis` (`graph/nodes/sachlage.py::build_event_order`), und der Dispatcher führt ihn nach der Antwort vor dem Fakten-Auftrag aus (`_run_passive_orders`) — ohne Planner. Ob der Satz ein Ereignis trägt, entscheidet nicht die Sachlage, sondern das Modell im Dienst `agents/timeline/ereignis.py` (`classify_ereignis`). Die Kennung der neuen Zeile geht nicht über ein Clipboard, sondern als Abbildung `{kandidat: timeline_id}` in `daten["ereignisse"]` des Fakten-Auftrags. Die Zeile schreibt der Timeline-Agent; der Fakten-Agent schreibt in die Timeline nichts. → Gebaut: Die Zeile schreibt der Dienst im Paket des Timeline-Agenten, nicht dessen Subgraph. Eine solche Kette gibt es heute nicht: Der Planner beendet die Reihe nach dem ersten Ausgang, der keine Ablehnung ist. → Für das Ereignis wird sie nicht gebraucht. **Unter der Grenze** fragt Nova je nach Willen und Pflichtbewusstsein. → **Grenze und Umfang, entschieden am 21.10.2026** (`_e` A Nr. 37): ohne Auftrag nur ein Ereignis mit dauerhafter Folge oder Gewicht — Umzug, Hochzeit, Operation, Geburt —, keine Besorgung und kein Ausflug; die Grenze ist `KZG_SALIENZ_HIGH`; vorerst ist der Prompt das Tor, denn die Salienz trennt nah nicht von fremd (`SALIENZ-TRAEGT-NAEHE-NICHT`), gemessen vor dem Commit an einer Rückhaltereihe → **gemessen am 21.10.2026:** das Tor 0 von 9 Fehlalarmen, 9 von 11 Treffern; die Frage unter der Grenze ist nicht gebaut. Für die eigenen Termine des Menschen bleibt es beim Auftrag ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §3a). - **Mit bekanntem Monat und offenem Tag** steht der Eintrag sofort mit der Genauigkeit *Monat* da (S6); nach der Klärung wird er verschoben. → Gebaut am 22.10.2026: `precision = 'month'` am Ersten des Monats, ohne DDL; ~~die Klärung nicht (Schritte 5–6, im Bau)~~ → am selben Tag auch die Klärung (Code-Tree `864c3b9`, die Schritte 5–6): Nennt ein späteres Ereignis derselben Person im Paar einen Tag in diesem Monat, wird die Monatszeile mit `TimelineRepository.verschieben` auf ihn verschoben, statt eine zweite anzulegen; ein Eintrag mit `month` gilt bis zum Monatsende als kommend ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §5.5). ~~Ein Monat ohne Jahr fällt bisher ins laufende Jahr, auch wenn er vorbei ist (`EREIGNIS-KOMMENDES-WIRD-VERGANGEN`).~~ → **Die Zeit eines Ereignisses** liest der Dienst aus dem Zeitausdruck: einen Kalendermonat über `named_period` (`month`), sonst einen Tag über `zeit_parsen_vektor` und `read_time`; **das Jahr eines Ausdrucks ohne Jahr, der nicht von heute aus zählt** (synthetisch *im Mai*, *am 3. März*, *am 12.2.*, *am 3. März um 10 Uhr*), kommt seit dem 22.10.2026 aus der **Zeitlage** des Satzes (Code-Tree `452f786`): Das Modell nennt sie im Feld `zeitlage` der Klassifikation — angekündigt steht das Ereignis am nächsten solchen Datum ab dem laufenden Monat bzw. ab heute, berichtet am letzten bis dahin; ohne Zeitlage gilt *angekündigt*, laut und mit der Herkunft `vorgabe`. Ein Ausdruck mit Jahr oder relativ zu heute bleibt, wie er gelesen wird. Gemessen am Modell vor dem Commit: angekündigt in der Vergangenheit 0 von 16 (vorher 5 von 8), die Zeitlage 22 von 22 richtig; `EREIGNIS-KOMMENDES-WIRD-VERGANGEN` ist geschlossen ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §5.5). - **Der Fakt** wird sofort geschrieben und verweist auf den Eintrag (`fakten.timeline_id`, S2). Er trägt keinen Zeitwert; sein Beginn wird über den Eintrag gelesen. Die Mappe zeigt den abgelösten Wert mit *bis*, den neuen mit *ab*. → Gebaut am 22.10.2026: Ein Kandidat mit eingetragenem Ereignis trägt in der Klassifikation die Marke `EREIGNIS EINGETRAGEN` und ergibt das Tripel des Ergebnisses; der Fakt trägt `timeline_id`. Scheiterte der Eintrag, entsteht kein Fakt (`ereignis_fehlt`). ~~Die Mappe mit *bis* und *ab* nicht.~~ → Die Mappe gebaut am 22.10.2026 (Code-Tree `864c3b9`): `memory/fakten_mappe.py` folgt `fakten.timeline_id` über `aktive_zeile` zur heutigen Zeile und zeigt *ab , *, den abgelösten Wert mit *bis * — nur für eine Zeile des eigenen Paares, sonst ohne beides und laut. - **Verschieben** heißt in der Timeline invalidieren und neu anlegen. Damit ein Verweis das überlebt, trägt die alte Zeile ihren Nachfolger (`timeline.nachfolger_id`, S5), und der Leser folgt der Kette bis zur aktiven Zeile. Dieselbe Spalte ist die Bauart für `TIMELINE-VERWEIS-VERALTET-BEIM-VERSCHIEBEN`; geschlossen ist der Defekt erst, wenn jeder der drei heutigen Verweise ihr folgt. → **Gebaut am 21.10.2026**, ~~nicht committet~~ → committet mit `091a99d`: S5, das Verschieben als ein Schritt in einer Transaktion (`TimelineRepository.verschieben` — die neue Zeile mit Paar, Typ, Merkmalen, `entitaet_ids` und Dauer der alten, dann die alte mit `nachfolger_id` abgelegt) und der Weg über die Kette (`aktive_zeile`, höchstens zehn Schritte, ein Zyklus laut). Kein Verweis folgt ihr bisher; der Defekt bleibt offen ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §5.2). → Seit dem 22.10.2026 folgt ihr der Leser von `fakten.timeline_id`, die Mappe; der Verweis selbst bleibt auf der ersten Zeile. Die drei Verweise des Defekts folgen ihr weiter nicht. - **Im Block `[TERMINE]`** steht ein Ereignis einer anderen Person gekennzeichnet, mit der Person. → ~~Nicht gebaut (Schritte 5–6, im Bau); bis dahin liest der Leseweg ein `ereignis` ungekennzeichnet wie einen Termin.~~ → **Gebaut am 22.10.2026** (Code-Tree `864c3b9`): nach den Terminen unter eigener Kopfzeile, je Zeile Kennzeichnung, Person, Titel, Monat oder Datum; nie als Termin des Menschen, auch nicht im Angebot der Sachlage ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §4a). - **Das Ereignis gehört dem Paar** wie seine Fakten (21.10.2026, `_e` A Nr. 38). Die Timeline bekommt dafür `character_id` (S7), und ihre Leser lesen je Paar; das behebt `TIMELINE-PAIR-MISSING` und kommt vor dem Typ `ereignis`. → **S7 gebaut und getestet am 21.10.2026**, ~~nicht committet; die DDL ist am Betrieb nicht angewandt~~ → committet mit `2cfe1b0`, die DDL am 21.10.2026 angewandt und gemessen (*Die Schemaänderungen*, *Reihenfolge* Schritt 10). **F7 — typisieren** (C3; `_e` A, Nr. 14): `entitaeten.typ` kommt aus einer festen Liste im Agenten (Person, Ort, Organisation, Tier, Objekt). → **Überholt am 21.10.2026, soweit der Typ an der Entität steht** (`_e` A Nr. 41–43; Nr. 43 löst Nr. 41 und 42 darin ab): Der Typ ist ein Fakt — ein zwingender Wert aus der Liste der sechs (Person, Ort, Organisation, Tier, Objekt, `sonstiges`), geschrieben in die Faktentabelle, nicht in `entitaeten` und nicht in eine Tabelle neben ihr. Er gehört dem Paar wie jeder Fakt. *Zwingend* heißt: Sobald ein Typ bekannt wird — durch *„ist ein“* (die Klassifikation wählt die Schublade) oder durch eine Beziehung des Kanons mit Objekt-Typ (*hat Haustier* → Tier) —, stammt sein Wert aus der Liste; ohne Typ-Fakt gilt eine Entität als `sonstiges`, vorab wird nichts geschrieben. Weitere Klassen (*Hund*, *domestiziert*) sind Fakten wie andere. Was in diesem Absatz weiter über `entitaeten.typ` steht, ist der Stand vor Nr. 43 und der heutige Code. → Die Liste ist Absicht und nicht gebaut (am Code geprüft am 22.10.2026): `entitaeten.typ` ist freier Text (`VARCHAR(50)`) mit der Vorgabe `sonstiges`, ohne Prüfbedingung (`db/init.sql`), und im Agenten steht keine Typliste. *„ist ein“* bleibt ein Fakt (`IST_EIN`); ~~seine freie Klasse wird über das vorhandene Embedding-Modell dem nächsten Typ der Liste zugeordnet, unter einer Mindestähnlichkeit wird der Typ `sonstiges`. Den Wert der Mindestähnlichkeit legt die Bauart nicht fest.~~ → Den Typ wählt die Klassifikation des Fakten-Agenten aus der festen Liste mit, `sonstiges` eingeschlossen (21.10.2026, `_e` A Nr. 34; eine Mindestähnlichkeit trug am Embedding nicht, gemessen); im Bau ein Feld der Antwort der Klassifikation, gegen die Liste geprüft und vor dem Commit je Feld am Modell gemessen. Den Typ schreibt nur der Agent, in derselben Transaktion wie den Fakt. Beziehungen bleiben exakt, Schwester ist nicht Bruder. Die Klasse eines Objekts der Sachlage bleibt die Sicht des Gesprächs. → **F7 ist nicht gebaut** (am Code geprüft am 22.10.2026). Seit dem 20.10.2026 setzt der Fakten-Agent einen Typ nur beim Anlegen einer neuen Entität, und nicht aus der Klassifikation: Ein neues Objekt bekommt den Typ seiner Beziehung aus dem Kanon (`ort`, `person`, `tier`; `agents/fakten/beziehungen.py`, `_ENTITAETS_OBJEKTE`), ein neues Subjekt `sonstiges` (`agents/fakten/suche.py`, `typen`). ~~Das geprüfte Tripel trägt kein Typfeld (`agents/fakten/klassifikation.py::vet_triple`)~~ → **Seit dem 25.10.2026 trägt es das Feld `typ`, den Typ des Subjekts aus der Liste der sechs**, gebaut im Code-Tree `47256bf` (~~nicht committet~~ → committet als `a4997ac`) und vor dem Commit am Modell gemessen: 0 fehlt, 0 außerhalb der Liste, 28 von 30 getroffen (`_e` A Nr. 46). `vet_triple` prüft ihn gegen `subjekt_typen` der Beziehung und verwirft laut (`typ_form`, `subjekt_typ`); `sonstiges` geht durch. Das Feld ist gelesen und geprüft, **aber nicht geschrieben**: Es gibt keinen Typ-Fakt, und `entitaeten.typ` ist unverändert — das bleibt F7. *„Ist ein“* steht nicht im Kanon. **Der Verfall** (S3): eine materialisierte Größe wie bei `lzg_knoten`, gepflegt von einem täglichen Lauf als Schritt im vorhandenen Verfallslauf der Synapsen (`agents/synapsen_decay/`). Beide Bauarten des Laufs sind nach der Verfallskonvention zulässig ([`novaberg-convention-verfall.md`](novaberg-convention-verfall.md)); ein träger Verfall beim Lesen scheidet hier aus, denn er schriebe beim Lesen, und genau das wird abgebaut. → **Gebaut am 18.10.2026** (*Reihenfolge* Schritt 3; am Code geprüft am 22.10.2026): `FaktenRepository.run_fakten_decay` als Schritt 11 des Tageslaufs in `agents/synapsen_decay/agent.py` schreibt `staerke_decay = exp(−0,0015 · Tage seit last_touched)`; die Mappe lässt eine Kante unter 0,1 ruhen (`FAKTEN_MAPPE_MIN_STAERKE`). #### Die Schemaänderungen **Im Grundsatz freigegeben am 17.10.2026, ~~nicht gebaut~~ → S1 bis S4 gebaut am 18.10.2026** (Tree `00c7b4c`, Schritt 3 der *Reihenfolge* unten); ~~S5 und S6 nicht gebaut~~ → **S5 gebaut am 21.10.2026** (Tree `fed521d`, ~~nicht committet; die DDL am Betrieb steht aus~~ → committet mit `091a99d`, die DDL am 21.10.2026 angewandt und gemessen), ~~S6 nicht gebaut~~ → S6 gebaut am 22.10.2026 ohne DDL. **S7**, entschieden am 21.10.2026, **gebaut am selben Tag** (Tree `2ec01b2`, ~~nicht committet; die DDL am Betrieb steht aus~~ → committet mit `2cfe1b0`, die DDL am 21.10.2026 angewandt und gemessen). Jede DDL wird vor ihrem Bau einzeln angekündigt und wirkt erst nach dem Neustart des Dienstes (`_e` A, Nr. 20). | Nr. | Änderung | Für | |---|---|---| | S1 | `fakten.herkunft` mit den Werten `mensch`, `nova`, `modell`, `recherche`. Die Herkunft `altbestand` entfällt, weil `fakten` keine Zeile trägt | F2, F4 (die Zählung je Herkunft) | | S2 | `fakten.timeline_id INTEGER`, im Kernschema ohne Fremdschlüssel; der Fremdschlüssel mit `ON DELETE SET NULL` steht im Schema der Timeline (`agents/timeline/init.sql`), wie bei `sachlage_eigenschaft` | F6 | | S3 | ~~`fakten.staerke_decay DOUBLE PRECISION NOT NULL DEFAULT 1.0`~~ → `fakten.staerke_decay DOUBLE PRECISION NOT NULL`, ohne Vorgabewert — eine neue Kante bekommt 1,0 von ihrem Schreiber (`NEW_EDGE_STRENGTH`; gebaut am 18.10.2026, am Code geprüft am 22.10.2026 in `db/init.sql`) — und `decay_am` | der Verfall der Kante (`FAKTEN-BINDUNG-OHNE-VERFALL`) | | S4 | `fakten.einwertig BOOLEAN` und der Teilindex `(user_id, character_id, subjekt_id, attribut) WHERE aktiv AND einwertig` | F5 | | S5 | `timeline.nachfolger_id INTEGER` — **gebaut am 21.10.2026**, ~~nicht committet~~ → committet mit `091a99d`: der Fremdschlüssel `timeline_nachfolger_id_fkey` mit `ON DELETE SET NULL`, der Teilindex `idx_timeline_nachfolger` über gesetzte Nachfolger, der Bestand `NULL`; ~~die DDL am Betrieb steht aus~~ → die DDL am 21.10.2026 angewandt und gemessen (Fremdschlüssel und Teilindex stehen, keine Zeile mit Nachfolger) | F6; `TIMELINE-VERWEIS-VERALTET-BEIM-VERSCHIEBEN` | | S6 | die Genauigkeit *Monat* in `timeline.precision` — ~~ob das eine DDL braucht und wie der Wert heißt, ist offen~~ (`_e` E, B8) → **gebaut am 22.10.2026 ohne DDL** (Code-Tree `04f386f`): der Wert `month`, der Erste des Monats; die Spalte ist Text ohne Prüfung der Werte | F6 | | S7 | `timeline.character_id`, der Bestand auf die Figur `nova` gesetzt, die Indexe je Paar (entschieden am 21.10.2026, `_e` A Nr. 38; nicht im Grundsatz vom 17.10.) — **gebaut am 21.10.2026**, ~~nicht committet~~ → committet mit `2cfe1b0`: Pflicht ohne Vorgabewert, der Bestand einmal in einem `DO $$`-Block, `idx_timeline_paar_time` und `idx_timeline_paar_type`, die Indexe über `user_id` allein entfernt; ~~die DDL am Betrieb steht aus~~ → die DDL am 21.10.2026 angewandt und gemessen (alle 181 Zeilen `nova`, die Indexe je Paar stehen, die alten sind fort) | F6; `TIMELINE-PAIR-MISSING` | #### Verworfene Varianten - **Eigenschaft und Fakt in `fakten` zusammenlegen** — dann schriebe die Sachlage Fakten (gegen `_e` A, Nr. 6), und ungebundene Objekte hätten keinen Ort. **In `sachlage_eigenschaft` zusammenlegen** — dort gibt es keine Entität und keinen zweiten Grad. - **Die freie Klasse als Typ**, und **die Klasse der Sachlage als Typ** — sie kennt weder Tier noch Organisation. - **Ein Ereignis nur auf Auftrag** — dann gälte der Fakt ab dem Schreiben, genau die Gegenprobe von F6. **Der Fakten-Agent schreibt die Zeile der Timeline selbst** — ein zweiter Schreiber der Timeline. - **Ein Ereignis erst nach der Klärung eintragen** — bis dahin stünde es nur als Eigenschaft in der Sachlage, und ohne Klärung würde nie ein Fakt daraus. - **Der Erinnerungsanker im Enricher** — dort gibt es die Mappe noch nicht. **Den Reducer verschieben** — das änderte das Angebot der Sachlage. **Im Knoten des Gesprächsvektors** — dann sähen Haltung und Prägung die Treffer nicht. - **Für die Termine der Sachlage einen eigenen Kalenderweg behalten** — dann gäbe es zwei Abgrenzungen von *vergangen* (C1, gebaut). ### Die zwei Messpunkte vor dem Bau **M1 — die Salienz von Aussagen über nahe Menschen.** Die Grenze aus F4 wird erst gesetzt, wenn gemessen ist, ob Aussagen über Menschen, die dem Menschen nahestehen (Familie, enge Bindung), heute eine hohe Salienz bekommen. Gemessen wird an der bestehenden Salienz im Pipeline-Log (`salienz`), ohne neuen Bau. Gezählt werden die Werte je Gruppe, ohne Inhalte zu lesen. Die Nulllinie bilden Aussagen über fremde Menschen und über Sachen. Das Ergebnis ist ein Abstand zwischen den Gruppen, kein einzelner Wert. Trennt die Salienz die Gruppen nicht, ist das ein Befund über die Salienz und keiner über die Grenze. **Gemessen am 17.10.2026.** Die Salienz trennt Aussagen über Personen deutlich von Aussagen über Sachen (am echten Paar Median 0,70 gegen 0,30, AUC 0,78), nahe Menschen aber nicht von fremden (an synthetischen Sätzen Δ Median 0,00, AUC 0,47), denn der Prompt gibt jeder Information über eine Person mindestens 0,70. Die n sind klein: Am echten Bestand trägt eine einzige Äußerung ein Wort für einen nahen Menschen, synthetisch stehen 5 gegen 6 verschiedene, sachlich formulierte Sätze. Es ist damit ein Befund über die Salienz und keiner über die Grenze; er steht als Backlog `SALIENZ-TRAEGT-NAEHE-NICHT` ([`novaberg-backlog-gedaechtnis.md`](novaberg-backlog-gedaechtnis.md)) und ist Vorbedingung für F4. **M2 — die Tiefe der Mappe.** Reicht der zweite Grad? Gemessen an Fragen zu Entitäten mit Fakten im ersten, zweiten und dritten Grad: Welcher Grad war für die richtige Antwort nötig, und wie viele Zeichen trägt die Mappe je Grad? Der zweite Grad ist der Ausgangswert und wird nur mit diesem Ergebnis geändert. → **Gemessen am 21.10.2026** an der gebauten Mappe, einem gesäten Graphen (5 / 6 / 2 Fakten im ersten, zweiten, dritten Grad) und dem Modell des Betriebs (`labor/2026-10-20_m2_mappe_tiefe_ergebnis.md`): Tiefe 1 beantwortet die drei Fragen des ersten Grades (113 Zeichen); Tiefe 2 dazu beide des zweiten (250 Zeichen), mit einer erfundenen Antwort statt *unbekannt* bei einer Frage über drei Kanten; Tiefe 3 bringt eine von zwei Antworten des dritten Grades, wirr begründet (301 Zeichen). Die Kappung von 1200 Zeichen greift dort nie. **Kein Grund, den Ausgangswert zu ändern** — ~~zur Entscheidung vorgelegt~~ → **entschieden am 21.10.2026: die Tiefe bleibt 2** (`_e` A Nr. 40); eine Stichprobe, keine Rate. ~~M2 vor dem Bau, ohne Bau~~ → **M2 nach F1** (berichtigt am 17.10.2026). Gemessen wird, welcher Grad nötig war, und das geht nur mit der Lesefunktion aus F1 mit einstellbarer Tiefe und mit gesäten Fakten: ~~Die Tabelle `fakten` hat heute keinen Erzeuger (`FaktenManager` hat kein `plan`, der Planner fällt auf das leere aus `plugins/base.py` zurück).~~ → Seit dem 21.10.2026 ist der passive Fakten-Agent der Erzeuger: `FaktenRepository.schreiben`, gerufen über `agents/fakten/dispatch.py::process_fact_orders` aus dem Dispatcher; `FaktenManager` gibt es nicht mehr (am Code geprüft am 22.10.2026). ### Reihenfolge ~~**M1 und M2 zuerst**: Sie brauchen keinen Bau, und ohne sie stehen die Grenze und die Tiefe auf geratenen Zahlen.~~ → **M1 zuerst**, ohne Bau, gemessen am 17.10.2026 (oben). **M2 nach F1**, weil er die Mappe mit einstellbarer Tiefe und gesäte Fakten braucht (berichtigt am 17.10.2026). Ohne die beiden stehen die Grenze und die Tiefe auf geratenen Zahlen. Dann **F2**, weil nur der Agent schreiben darf. Mit ihm **F5**, das Ablösen gehört in seinen Schreibweg. Dann **F1**, die Lesefunktion. Danach **F3**, das an den Klärfall am Objekt der Sachlage anschließt (Backlog `KLA-KLAERFALL-AM-OBJEKT`). **F4** folgt nach M1 und Scheibe 13 der Lage, weil das Lernen über den Empfang läuft. ~~**F6** folgt, sobald die Timeline das Ereignis einer dritten Person kennt (`_k` §5, Punkt 4). **F7** steht zuletzt, nach der Frage nach dem Typsystem.~~ → **Nach der angenommenen Bauart (17.10.2026) in elf Schritten**, jeder für sich ein Bau: 1. **M1** — gemessen am 17.10.2026 (unten). 2. **C1**, der gemeinsame Leseweg der Termine — gebaut am 17.10.2026 (Scheibe 6 der Lage). 3. **Das Schema S1 bis S4 und das Repository:** das Paar in jeder Abfrage, Lesen ohne Schreiben, Ablösen in einer Transaktion, der Lauf des Verfalls. — **gebaut am 18.10.2026** (Tree `00c7b4c`): `herkunft`, `einwertig` und `staerke_decay` als Pflicht ohne Vorgabewert, `chk_fakten_herkunft`, der eindeutige Teilindex über Paar, Subjekt und Beziehung jedes aktiven einwertigen Fakts, `timeline_id` mit `ON DELETE SET NULL`, `staerke_decay` und `decay_am`; `FaktenRepository.abloesen` auf dem Cursor des Aufrufers, `run_fakten_decay` als Schritt des Tageslaufs mit eigenem Audit. 47 Zeugen gegen die Testdatenbank der Suite; der Verfall gemessen an Kanten von 0, 30 und 365 Tagen. Die Rate ist der Startwert des Knotenverfalls und nicht gemessen; wer `last_touched` bei einer Bestätigung setzt, entscheidet Schritt 4 (→ *identisch* setzt ihn, gebaut in Schritt 4), ob eine schwache Kante ruht, Schritt 5. 4. **F2 mit F5:** der Agent mit Kanon, ~~Aushang~~ und Verifikation; ~~das Plugin auf die Empfangsfläche zurückgebaut~~ → das Plugin gelöscht (committet am 21.10.2026 mit `bbf6c27`), der Agent passiv, ohne Aushang (`7bde8d7`; am Code geprüft am 22.10.2026). Nach 3. — **Der Schreibweg gebaut am 20.10.2026** (Trees `e21dab9`, `a452b8c`): `FaktenRepository.schreiben` legt in einer Transaktion an, löst einwertig ab oder findet denselben Wert (*identisch*, frischt `last_touched` auf) und verifiziert in derselben Transaktion; `EntityResolutionService.resolve_by_name` löst nur über den Namen auf, ohne Rückfall, und wirft bei einem Fehler; das Paket `agents/fakten/` klassifiziert mit dem Modell nach einem Kanon von 23 Beziehungen (9 einwertig, alles Unentschiedene mehrwertig), prüft die Antwort gegen die Bitte (Name in der Bitte, Richtung, Grundform) ~~und antwortet auf den vier Ausgängen; zwei gleichnamige Entitäten ergeben eine Rückfrage ohne Schreiben~~ → und meldet seit dem passiven Weg (21.10.2026) neun Ausgänge je Auftrag und sechs je Tripel; zwei gleichnamige Entitäten ergeben `mehrdeutig`: nichts wird geschrieben, eine Rückfrage gibt es nicht, die Frage gehört an das Objekt der Lage (F3, nicht gebaut; am Code geprüft am 22.10.2026, `agents/fakten/suche.py`, `agents/fakten/dispatch.py`). **F5** ist damit gebaut und gemessen. **Erreichbar ist der Agent noch nicht:** Der Empfang über den Router (Aushang mit `management_target = "fakten"`, das Plugin als Empfangsfläche) ist gebaut, gemessen und zurückgehalten — mit ihm bekamen drei Notiz-Bitten mit Zeitangabe keinen Auftrag mehr, denn der Router nennt genau ein Ziel. Seit dem 20.10.2026 ist der Agent passiv (`_e` A Nr. 24); ~~der Weg wird neu ausgearbeitet (`_e` B)~~ → der Weg ist am 20.10.2026 entschieden (`_e` A Nr. 25–28) und committet am 21.10.2026: Die Sachlage stellt den Auftrag aus, der Dispatcher führt ihn nach der Antwort aus, ohne Router und Planner (am Code geprüft am 22.10.2026, `graph/nodes/sachlage.py::build_fact_order`, `agents/fakten/dispatch.py`). 5. **F1:** die Mappe, die Leser umgestellt, `_entity_kontext_laden` entfernt; danach **M2** im Labor. Nach 3. — **Gebaut, committet am 21.10.2026** (am Code geprüft am 22.10.2026): `memory/fakten_mappe.py::load_mappe` über `FaktenRepository.find_umgebung`; `GET /fakten/{user_id}` liefert nur die Entitäten, `GET /fakten/{user_id}/{entitaet_id}` die Mappe; `_entity_kontext_laden` entfernt, das Plugin `plugins/fakten_manager/` gelöscht. **M2** gemessen am 21.10.2026 (*Die zwei Messpunkte*, oben). 6. **Scheibe 13, Teil H:** die Quelle `fakten` im Angebot der Sachlage, mit den Regeln (b) und (c) aus C2. Nach 2 und 5. — **Gebaut am 22.10.2026, committet** (Code-Tree `d810399`): Regel (c) nach `_e` A Nr. 44, dazu der Kalender im Angebot mit eigener Grenze und `bound_entities`; Server-Suite `Ran 5132 tests` · `OK (expected failures=2)`, Gegenproben wie vorhergesagt; am Modell gemessen am 22.10.2026 — der passende Fakt 18 von 18, kein Fehlgriff, die erfragte Person aber nur in 43 von 92 Läufen akut (*Das Angebot der Sachlage*); im Betrieb nicht gemessen. 7. **C5:** der Erinnerungsanker mit seinem Kanal und der Suche über die Entitäten. Nach 5. — **Gebaut am 22.10.2026, committet**, in zwei Bauten auf Teil H: Kanal und Suche (Code-Tree `0d5f633`), der Knoten (Code-Tree `04f823e`); Server-Suite `Ran 5174 tests` · `OK (expected failures=2)`, Gegenproben wie vorhergesagt; der Kanal vor dem Commit am Modell gemessen — er folgt genau aus Name und `akut`, eine nur erwähnte Person steht nie darin (16 von 16; *Der Erinnerungsanker*) —, der Knoten im Betrieb nicht gemessen. 8. **F3:** der Klärfall der Entitäten in `remember_objects`. Nach dem ersten Schritt der Klärfälle (`KLA-KLAERFALL-AM-OBJEKT`). 9. **F4 mit Scheibe 13, Teil R:** lernen ohne Auftrag. Nach 1, 4 und 6; die Grenze erst, wenn die Salienz nah von fremd trennt (`SALIENZ-TRAEGT-NAEHE-NICHT`). 10. **C4 mit F6:** ~~der Typ `ereignis`, S5 und S6,~~ → zuerst S7, die Timeline je Paar (21.10.2026) — **gebaut am 21.10.2026** (Tree `2ec01b2`, ~~nicht committet~~ → committet mit `2cfe1b0`): das Schema mit `character_id` ohne Vorgabewert und den Indexen je Paar, jede Methode von `TimelineRepository` nach dem Menschen im Paar und ohne Figur laut, jeder Leser und Schreiber mit der Figur, die Wiedervorlage mit `nova`; Server-Suite `Ran 4993 tests` · `OK (expected failures=2)`, neun Gegenproben wie vorhergesagt; ~~die DDL am Betrieb steht aus~~ → die DDL am 21.10.2026 angewandt und gemessen ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §9); dann ~~der Typ `ereignis`, S5 und S6,~~ → die Grundlage — S5, die Typquelle mit dem Typ `ereignis`, das Verschieben in einer Transaktion —, **gebaut am 21.10.2026** (Tree `fed521d`, ~~nicht committet~~ → committet mit `091a99d`): Server-Suite `Ran 5027 tests` · `OK (expected failures=2)`, sechs Gegenproben wie vorhergesagt; ~~die DDL am Betrieb steht aus~~ → die DDL am 21.10.2026 angewandt und gemessen ([`novaberg-agent-timeline.md`](novaberg-agent-timeline.md) §9); danach der Weg im Turn — S6, `entitaet_ids` schreiben, `fakten.timeline_id`, der Weg *Timeline vor Fakt* im selben Turn → **gebaut am 22.10.2026** (Code-Tree `04f386f`, die Schritte 3–4 von F6): Server-Suite `Ran 5060 tests` · `OK (expected failures=2)`; am Modell das Tor 0/9 Fehlalarme, der Zeitpunkt des Eintrags 4/9 (`EREIGNIS-KOMMENDES-WIRD-VERGANGEN`); ~~offen die Schritte 5–6 — die Kennzeichnung in `[TERMINE]`, die Leser des Monats, die Mappe, die Klärung des Tages~~ → **die Schritte 5–6 gebaut am 22.10.2026** (Code-Tree `864c3b9`): die Kennzeichnung in `[TERMINE]`, die Leser des Monats, die Mappe mit *ab*/*bis*, die Klärung des Tages; Server-Suite `Ran 5077 tests` · `OK (expected failures=2)`; im Betrieb nicht gemessen; danach das Jahr aus der Zeitlage, **gebaut am 22.10.2026** (Code-Tree `452f786`): Server-Suite `Ran 5104 tests` · `OK (expected failures=2)`, am Modell angekündigt in der Vergangenheit 0 von 16, `EREIGNIS-KOMMENDES-WIRD-VERGANGEN` geschlossen; offen `EREIGNIS-KANDIDAT-OHNE-SPRECHER` (5 von 28 erwarteten Ereignissen erreichen den Aufruf nicht) und die Messung im Betrieb. Nach 4. 11. **F7:** *„ist ein“* → ~~`entitaeten.typ`~~ → ein Typ-Fakt aus der Liste der sechs in der Faktentabelle (21.10.2026, `_e` A Nr. 43). Nach 4. Das weicht vom Plan darüber so ab: Das Repository ist vom Agenten getrennt, damit beide je in einen Bau passen. F1 hängt nicht an F2, sondern am Repository. **F6** wartet nicht mehr auf die Timeline, denn der Typ `ereignis` wird in Schritt 10 mitgebaut. **F7** steht nicht mehr zuletzt, denn die Frage nach dem Typsystem ist entschieden.