Technischer Bericht · Stand 10. November 2026 · von Emilio Salimo
01Gedächtnis pro Werkzeug, kein gemeinsamer Stand
Fast jedes KI-Werkzeug hat inzwischen ein eigenes Gedächtnis, meist „Memory“ genannt. Dasselbe Beispiel in drei Momenten und zwei Fassungen: einmal merkt sich jedes Werkzeug etwas für sich, einmal lesen alle aus einem Archiv.
Gedächtnis pro Werkzeug
Werkzeug A · Montag
verkürzt
Eigenes Gedächtnis
Werkzeug B · Donnerstag
für sich allein
Eigenes Gedächtnis
Werkzeug A · vier Wochen später
ohne Quelle
Eigenes Gedächtnis
Gemeinsames Archiv
Werkzeug A · Montag
im Wortlaut
Werkzeug B · Donnerstag
gleicher Stand
Werkzeug A · vier Wochen später
mit Quelle
Archiv · Artikel „Aufträge“Kapazität frühestens ab März 2027, nach dem Auftrag von Halvorsen. [Mo · Zeile 1]

02Vier Eigenschaften des Systems
Ein Schreiber, ein Protokoll, Wissen als Ableitung
04Single Writer, Append-only-ProtokollJede Aussage lässt sich nachprüfen
05Beleg, Rechte, feste RegelnWas darauf entsteht, für einen Menschen und für eine Firma
12Was auf diesem Kern aufbaut03Quelle, Aussage, Artikel
Was gesagt wurde, bleibt im Wortlaut als Quelle. Das Gesprochene wird vollständig abgelegt, nicht nur eine Zusammenfassung. Eine Zusammenfassung verliert genau das, was man später prüfen will.
Aus den Quellen entsteht je Thema ein Artikel. Ein Sprachmodell zieht aus neuen Gesprächen Aussagen heraus, jede mit Datum und Verweis auf die Stelle. Danach wird jeder betroffene Artikel neu gefasst.
Das nächste Gespräch setzt beim aktuellen Stand an. Jedes neue Gespräch kennt den Index, ein Inhaltsverzeichnis mit einer Zeile je Thema, und liest den passenden Artikel nach. Von Hand übergibt niemand etwas.
04Single Writer, Append-only-Protokoll
Das Gedächtnis folgt dem Single-Writer-Prinzip. Im laufenden Betrieb verändert genau ein Prozess, der Schreiber, das Archiv. Alle anderen Rollen sind Absender: Sie legen Meldungen in eine eigene Ablage und haben keinen Schreibzugriff. Der Schreiber gehört zum Kern, einem deterministischen Programm ohne Sprachmodell. Im Gedächtnis arbeitet ein Sprachmodell nur in der Rolle des Autors, und auch der Autor ist ein Absender.
Annahme nach festen Regeln. Der Schreiber prüft jede Meldung gegen feste Regeln. Die Prüfung ist deterministisch: Dieselbe Meldung führt immer zum selben Ergebnis. Auch eine abgewiesene Meldung wird protokolliert.
Append-only-Protokoll. Jede angenommene und jede abgewiesene Meldung erzeugt genau einen Eintrag mit fortlaufender Nummer. Einträge werden nur angehängt. Aus einem Schnappschuss des Archivs und dem Protokoll danach lässt sich ein früherer Stand wiederherstellen. Neuere Einträge tragen die geschriebene Fassung selbst und werden so zurückgeholt, ältere werden nachgerechnet und gegen ihre Prüfsumme geprüft.
Quellen und abgeleitete Artikel. Das Archiv trennt Quellen von Artikeln. Quellen wachsen nur durch Anhängen: Ein abgelegtes Stück eines Gesprächs wird nicht überschrieben. Artikel sind aus ihnen abgeleitet und werden immer wieder neu gefasst. Ein Fehler des Sprachmodells betrifft deshalb höchstens eine Fassung eines Artikels, nie eine Quelle.
Daraus folgt eine Invariante: Jede Änderung am Wissen ist eine Meldung, und der Schreiber trägt sie zuerst ins Protokoll und danach ins Archiv ein. Ein Absturz hinterlässt so kein halb geschriebenes Wissen: Beim Start bringt der Kern jede unterbrochene Meldung zu Ende, wenn ihre Protokollzeile steht, und verwirft sie sonst.
Ein Gespräch wird gemeldet
- Das Gespräch endet. Der Abgleich nimmt es im Wortlaut mit.
- Er legt es als Meldung in die Ablage dieses Absenders.
- Der Schreiber prüft die Meldung nach festen Regeln.
- Erst schreibt er eine Zeile ins Protokoll.
- Dann legt er das Gespräch als Quelle ins Archiv.
Der Autor fasst einen Artikel
- Das Archiv gibt neue Gespräche nur über den Lesezugang heraus.
- Der Autor liest die Gespräche, die er verarbeiten soll.
- Er meldet Aussagen und eine neue Fassung. Selbst schreiben kann er nicht.
- Der Schreiber prüft diese Meldung nach denselben Regeln.
- Wieder zuerst eine Zeile ins Protokoll.
- Dann steht der Artikel neu gefasst im Archiv.
Das nächste Gespräch liest mit
- Der Lesezugang gibt Artikel nur an den heraus, der sie lesen darf.
- Index und Artikel kommen als Kopie auf den Client.
- Das nächste Gespräch beginnt mit dem Index und kennt, was im ersten gesagt wurde.
Ein Sensor meldet
- Ein Sensor sieht in Postfach oder Kalender nach.
- Was neu ist, meldet er in seine eigene Ablage.
- Der Schreiber prüft die Meldung wie jede andere.
- Erst eine Zeile ins Protokoll.
- Dann ins Archiv.
Jeder Rahmen der Zeichnung ist eine eigene Grenze. Im Gedächtnis arbeitet das Sprachmodell ausschließlich im Autor. Das Gespräch und die Aussagen des Autors durchlaufen denselben Schreiber. Die Neufassung des Artikels nimmt später denselben Weg.
05Beleg, Rechte, feste Regeln
Jede Aussage hat einen Beleg. Der Kern nimmt eine Aussage nur mit Beleg an und prüft, dass die belegte Stelle existiert. Der Beleg macht eine Aussage überprüfbar. Ob sie zutrifft, belegt er nicht.
Jede Rolle hat nur die Rechte, die ihre Aufgabe verlangt. Die Rechte hängen am Unix-Nutzer und stehen in einer festen Tabelle, das Betriebssystem setzt die Grenze durch. Sie hängt nicht von einer Anweisung an das Sprachmodell ab. Ein fehlerhafter oder übernommener Dienst sieht so nur seinen Teil.
Das Sprachmodell schlägt vor, der Kern führt aus. Im Gedächtnis und beim Sortieren eingehender Nachrichten hat das Sprachmodell keine Werkzeuge und liefert ausschließlich Text in einem festen Format. Eine präparierte Mail oder ein Modellfehler kann deshalb keine Aktion direkt auslösen. Ausgeführt wird nur durch ein festes Programm nach Regeln, die ein Mensch gesetzt hat.
Das Sprachmodell sieht nur, was es verarbeiten soll. Texte, die das Modell lesen soll, werden an den Ort übertragen, an dem es läuft: zu einem Anbieter oder auf eigene Hardware. Dieser Ort bestimmt, wer die Texte einsehen kann. Besonders sensible Inhalte liegen nicht im Archiv, sondern in einem getrennten Speicher: verschlüsselt, der Schlüssel außerhalb des Servers, geöffnet nur bei Bedarf und nur im Arbeitsspeicher.
Vergessen ist eine eigene Funktion mit definierter Reichweite. Entfernen blendet aus und ist umkehrbar. Vergessen ist endgültig, darf nur der Mensch und verlangt eine eigene Bestätigung. Die Quelle wird entfernt. Im Protokoll wird ihr Inhalt geschwärzt, Nummer und Zeitpunkt bleiben erhalten. Die nächste Neufassung des Artikels lässt weg, was aus der Quelle abgeleitet war.
06Entwurfsentscheidungen mit Risiko und Grenze
Weitere Entscheidungen, die die Architektur prägen. Jede nennt das Risiko, die Maßnahme, die verworfene Alternative und die Grenze.
Wissen
Lesen statt Suchen
- Risiko
- Ein Suchtreffer ist noch keine Nutzung: Das Wissen liegt bereit, wird aber nicht geöffnet.
- Maßnahme
- Ein Index mit einer Zeile je Thema lädt in jedes Gespräch, das Gespräch liest den ganzen Artikel.
- Verworfen
Vektor-Datenbank mit Suche: Treffer werden gefunden, aber nicht gelesen.- Grenze
- Trifft die Indexzeile nicht, wird der Artikel nicht gelesen.
Teilen statt verdichten
- Risiko
- Wächst ein Artikel über seine Grenze, gehen beim Kürzen Aussagen still verloren.
- Maßnahme
- Ab einer festen Größe wandern die Aussagen wörtlich in Unterartikel. Das Modell nennt nur Nummern, das Programm kopiert die Aussagen. Jede Nummer lässt sich nur einmal vergeben, die Summe bleibt so gleich.
- Verworfen
Verdichten durch das Modell- Grenze
- Welche Aussage wohin gehört, entscheidet das Modell.
Widersprüche datieren
- Risiko
- Das Sprachmodell entscheidet still, was gilt.
- Maßnahme
- Die ältere Aussage bleibt mit Datum als früherer Stand stehen.
- Verworfen
Entscheiden durch das Sprachmodell- Grenze
- Das ist eine Regel für den Autor, der Kern erzwingt sie nicht. Ob die neuere Aussage stimmt, prüft das System nicht.
Nichts fällt still weg
- Risiko
- Aussagen gehen auf dem Weg verloren, und niemand merkt es.
- Maßnahme
- Der Autor schreibt jede verworfene Zeile mit Grund in sein Log. Die Zahl der gesendeten Zeilen ist immer die Summe aus behaltenen und verworfenen.
- Verworfen
Stilles Kappen an festen Grenzen- Grenze
- Das Log macht einen Verlust sichtbar, es verhindert ihn nicht.
Schreiben und Daten
Der Eingang ist die Warteschlange
- Risiko
- Eine eigene Warteschlange ist ein weiteres System, das ausfallen oder Meldungen verlieren kann.
- Maßnahme
- Meldungen sind Dateien in der Ablage des Absenders, atomar abgelegt und der Reihe nach abgeholt.
- Verworfen
Eigene Warteschlange vor dem Eingang- Grenze
- Ausgelegt ist das auf einen Schreiber, nicht auf Massenbetrieb.
Daten getrennt von der Oberfläche
- Risiko
- Die Oberfläche wird zur Quelle der Wahrheit, jeder Umbau trifft die Daten.
- Maßnahme
- Die Oberfläche liest und meldet wie jedes Modul, ins Archiv schreibt sie nicht.
- Verworfen
Daten in der App oder im Code-Repository- Grenze
- Die Oberfläche hängt vollständig am Kern.
Wissen als Kopie beim Nutzer
- Risiko
- Ein Serverausfall stoppt die Gespräche.
- Maßnahme
- Index und Artikel liegen als Kopie auf dem Client, also dem eigenen Rechner, ein Abgleich hält sie aktuell.
- Verworfen
Live-Leitung zum Server- Grenze
- Neues Wissen kommt verzögert an: Der Abgleich läuft regelmäßig, die Artikel werden erst danach neu gefasst.
Sicherheit
Absender vom Betriebssystem festgestellt
- Risiko
- Eine Meldung gibt sich als jemand anderes aus.
- Maßnahme
- Absender ist die Ablage, in die nur dieser Nutzer schreiben kann. Beim Lesen stellt das Betriebssystem den Nutzer fest.
- Verworfen
Schlüssel je Modul: Ein Schlüssel lässt sich abschreiben, eine Nutzerkennung kann ein Prozess nicht fälschen.- Grenze
- Module mit demselben Nutzer teilen ihre Rechte.
Betrieb
Betrieb mit engen Rechten
- Risiko
- Ein fehlerhafter Betriebsdienst trifft das ganze System.
- Maßnahme
- Das Betriebsmodul im Kern darf nur Dienste neu starten und Läufe wiederholen. Den Rückfall auf die vorige Programmfassung übernimmt ein getrenntes kleines Skript, das nur den Zustand abfragt, neu startet oder zurückgeht. Alles andere wird dem Menschen vorgelegt.
- Verworfen
Ein Betriebsdienst mit vollen Rechten für alles- Grenze
- Das Skript für den Rückfall läuft mit vollen Rechten. Was Rechte oder Sicherheit berührt, wartet auf einen Menschen.

07Go, Dateien, Unix-Rechte
- Sprache
- Go, ein einzelnes Programm
- Ein Programm lässt sich als Ganzes prüfen, ausrollen und zurücknehmen.
- Abhängigkeiten
- Fünf direkte: IMAP, Mailformat, Kompression, YAML, Systemaufrufe
- Jede Abhängigkeit ist Code, dem man vertrauen muss. Alles Übrige deckt die Standardbibliothek ab.
- Betriebssystem
- Ubuntu LTS, Dienste unter systemd
- Neustarts und Abhängigkeiten regelt das System.
- Rechte
- Unix-Nutzer und eine feste Rechtetabelle
- Die Grenzen setzt das Betriebssystem, nicht das Programm.
- Speicher
- Markdown-Dateien, Protokoll als JSONL, keine Datenbank
- Die Daten bleiben ohne das System lesbar.
- Schreiben
- Ablagen je Absender,
renameund inotify - Das Dateisystem ist Eingang und Warteschlange zugleich.
- Lesen
- Unix-Socket mit
SO_PEERCRED - Der Absender lässt sich nicht vortäuschen.
- Abgleich
- Dasselbe Go-Programm als Hintergrundlauf auf dem Client, regelmäßig über SSH, in beide Richtungen
- Gespräche gehen hoch, Index und Artikel kommen als Kopie zurück.
- Modell
- Externes Sprachmodell ohne Werkzeuge
- Das Modell ist die einzige Stelle im Gedächtnis, die nicht festes Programm ist.
- Server
- Ein einzelner kleiner Server
- Die Rechenarbeit liegt beim Modell. Der Kern hält das Archiv im Arbeitsspeicher.
08Schreibpfad einer Meldung
Absender
-
1 Ablegen
Der Absender schreibt die Meldung unter einem Zwischennamen in seine Ablage und benennt sie per
renameum. Der Kern sieht so nie eine halbe Datei.
Kern
-
2 Abholen
Der Kern merkt das über inotify, dazu gleicht er regelmäßig ab. Er zieht die Datei per
renamein einen privaten Ordner. -
3 Prüfen
Ein einziger Schreiber nimmt die Meldungen nacheinander und prüft Schema und Absender.
-
4 Festlegen
Alles Zufällige oder Zeitabhängige legt der Kern selbst fest, etwa IDs. Daraus berechnet er die neuen Dateifassungen im Speicher.
-
5 Protokollieren
Die neuen Fassungen gehen atomar in einen Zwischenordner, dann folgt die Protokollzeile mit ihren sha256 und
fsync. Ab hier ist die Meldung angenommen. - angenommen
6 Anwenden
Die Fassungen wandern per
renameaus dem Zwischenordner an ihren Platz, danach sichertfsyncdas Verzeichnis.
09Fünf Stellen aus dem Kern
Fünf Stellen aus dem Kern in Go, wörtlich übernommen. Ausgelassene Zeilen sind mit „…“ markiert. Das Protokoll heißt im Code journal.
Jede Meldungsart ist eine Funktion
Die Funktion bekommt die Meldung und einen Kontext und gibt neue Dateifassungen zurück. Selbst schreibt sie nichts. Zeit und neue IDs kommen aus dem Kontext, nicht von der Uhr oder vom Zufall. Darum liefert dieselbe Meldung beim Nachspielen dieselben Dateien: Das Protokoll hält die IDs fest, beim Nachspielen werden sie der Reihe nach wieder ausgegeben. Neuere Zeilen tragen die Fassung selbst, ältere werden so nachgerechnet und gegen ihre Prüfsumme geprüft.
// ApplyContext is what a kind sees while it applies: the current files and the values the core fixed
// for this report, so replaying the report gives the same files.
type ApplyContext interface {
// …
File(id string) (archive.File, bool)
Time() time.Time
NewID() string
// …
}
// …
type Applier func(Report, ApplyContext) ([]Change, error)
// …
// fixedIDs hands out the recorded IDs in order; running out means the replay diverged.
func fixedIDs(ids []string) func() string {
i := 0
return func() string {
if i >= len(ids) {
return ""
}
i++
return ids[i-1]
}
}
Nach dem Absturz
Die Protokollzeile ist der Punkt, an dem eine Meldung gilt. Beim Start geht der Kern alle abgelegten Fassungen durch: Ohne Zeile wurde die Meldung nie angenommen und die Fassung fällt weg. Mit Zeile werden die Dateien auf den Stand der Zeile gebracht, mit demselben Code wie im Normalbetrieb. Tests brechen den Ablauf gezielt vor und nach der Zeile ab.
func (s *SingleWriter) recoverInFlight() error {
entries, err := os.ReadDir(inFlightDir(s.k.Root))
if err != nil {
return err
}
for _, e := range entries {
seq, err := strconv.ParseUint(e.Name(), 10, 64)
if err != nil || !e.IsDir() {
// …
}
if seq >= s.jrnl.NextSeq() {
if err := os.RemoveAll(inFlightSeq(s.k.Root, seq)); err != nil {
return err
}
if err := archive.SyncDir(inFlightDir(s.k.Root)); err != nil {
return err
}
continue
}
var line *journal.Line
err = s.jrnl.Each(seq-1, func(z journal.Line) error {
line = &z
return journal.ErrStop
})
if err != nil {
return err
}
if line == nil || line.Seq != seq || line.Redacted || line.Result != string(Accepted) {
// …
}
if err := s.complete(*line); err != nil {
return err
}
}
return nil
}
Jede Datei in der Ablage ist verdächtig
Die Ablage gehört dem Absender, der Kern traut ihrem Inhalt deshalb nicht. Er öffnet die Datei zuerst und prüft dann den geöffneten Deskriptor, damit sie zwischen Prüfen und Lesen nicht ausgetauscht werden kann. Symlinks, Hardlinks, fremde Eigentümer und übergroße Dateien werden endgültig abgewiesen.
f, err := os.OpenFile(holdPath, os.O_RDONLY|syscall.O_NOFOLLOW|syscall.O_NONBLOCK, 0)
if err != nil {
if errors.Is(err, syscall.ELOOP) {
return nil, "Symlink (O_NOFOLLOW)", true
}
// …
}
defer f.Close()
fi, err := f.Stat()
// …
st, ok := fi.Sys().(*syscall.Stat_t)
switch {
case !fi.Mode().IsRegular():
// …
case !ok || uint64(st.Nlink) != 1:
// …
case c.fileUID(st) != boxUID:
// …
case fi.Size() > MaxSize:
// …
}
Das Modell nennt Nummern, keinen Text
Beim Teilen eines Artikels nennt das Modell nur Nummern. Das Programm geht sie durch und kopiert die Aussagen selbst. Eine Nummer lässt sich nur einmal vergeben. Was keine Nummer bekam, bleibt im Artikel. Eine Aussage kann beim Teilen deshalb weder umformuliert werden noch verschwinden.
for _, i := range slices.Sorted(slices.Values(indexes)) {
// …
if assigned[a][i] {
// …
}
assigned[a][i] = true
has = append(has, statements[a][i])
latest = max(latest, statements[a][i].Date)
}
// …
for i, s := range statements[a] {
if !assigned[a][i] {
kept = append(kept, s)
}
}
Der Absender kommt vom Betriebssystem
Wer lesen will, weist sich nicht aus. Der Kern fragt das Betriebssystem, welcher Nutzer am anderen Ende des Sockets sitzt, und schlägt dessen Rechte in einer festen Tabelle nach. Wer dort nicht steht, bekommt nichts.
// peerUID reads the UID of the connected process via SO_PEERCRED.
func peerUID(c net.Conn) (uint32, error) {
// …
var cred *unix.Ucred
var serr error
if err := raw.Control(func(fd uintptr) {
cred, serr = unix.GetsockoptUcred(int(fd), unix.SOL_SOCKET, unix.SO_PEERCRED)
}); err != nil {
return 0, err
}
// …
return cred.Uid, nil
}
// …
name, err := s.Name(p.uid)
prefixes, ok := s.rights[name]
if err != nil || !ok {
// …
return
}

10Sicherung an drei Orten, monatlich zurückgespielt
Das Protokoll sichert gegen Abstürze, die Sicherungen sichern gegen den Verlust des ganzen Servers. Das Archiv liegt an drei Orten: auf dem Server, auf einem externen Speicher und auf einem eigenen Rechner.
- 1
Täglich verschlüsselt nach außen
Risiko:Der Server geht ganz verloren.
Maßnahme:Das Archiv wird täglich mit AES-256 verschlüsselt und über einen eigenen Zugang auf einen externen Speicher übertragen.
Grenze:Was seit dem letzten Lauf kam, fehlt zunächst. Gespräche sendet der Abgleich erneut, weil er beim Kern nachfragt, wo dieser steht.
- 2
Versionen statt nur der letzten
Risiko:Ein Fehler fällt erst nach Wochen auf, und die Sicherung trägt ihn schon.
Maßnahme:Es bleiben Versionen über Tage, Wochen und Monate.
Grenze:Irgendwann läuft auch die älteste Version aus.
- 3
Kopie auf einem eigenen Rechner
Risiko:Server und Speicher werden geleert oder übernommen.
Maßnahme:Der Rechner zieht die Sicherungen täglich nur lesend und prüft jede per sha256. Der Server hat keinen Zugriff auf den Rechner. Verschwinden auf dem Server auffällig viele Sicherungen, wird auf dem Rechner nichts gelöscht und der Mensch bekommt einen Hinweis.
Grenze:Die Kopie ist so aktuell wie der letzte Lauf des Rechners. Die Prüfsumme kommt vom Server: Sie deckt Fehler bei Übertragung und Ablage auf, keine Manipulation dort.
- 4
Schlüssel außerhalb des Servers
Risiko:Mit dem Server geht auch der Schlüssel verloren.
Maßnahme:Der Schlüssel liegt an einem getrennten Ort. Der Server holt ihn für jeden Lauf und hält ihn nur im Arbeitsspeicher.
Grenze:Ohne Schlüssel ist jede Sicherung wertlos.
- 5
Monatliche Probe
Risiko:Eine Sicherung gilt als gut, wurde aber nie zurückgespielt.
Maßnahme:Die neueste Sicherung wird im Arbeitsspeicher entschlüsselt. Aus Schnappschuss und Protokoll entsteht der Stand neu, und seine Prüfsumme muss mit den gesicherten Dateien übereinstimmen. Jeder Lauf hält sein Ergebnis fest, nur ein Fehlschlag meldet sich beim Menschen.
Grenze:Geprüft wird das Archiv, nicht jeder andere Teil des Systems.
11Messwerte aus dem laufenden Betrieb
Das System läuft im täglichen Einsatz. Sein Wissen reicht bis Juni 2026 zurück.
Stand: 10. November 2026.
- Protokollzeilen
- > 15.800
- Themen im Index
- 145
- zusammen mit den Unterartikeln 233 Artikel
- Aussagen mit Beleg
- ≈ 9.700
- Ältere Gespräche nachträglich eingelesen
- 650
- technisch ohne Fehler, seitdem laufend neue
- Dateien in der monatlichen Probe wiederhergestellt
- 6.628
- Ergebnis ok
- Tests im Kern
- 1.281
- mehr Testcode als Programmcode
- Läufe des Abgleichs
- > 1.350
- letzter Lauf ohne Fehler
Eine echte Protokollzeile
Eine geschwärzte Zeile aus dem Protokoll, Feld für Feld. Der Inhalt ist weg, Nummer und Zeit bleiben, damit das Protokoll lückenlos bleibt. Zeit, Kennung und Zeile sind gekürzt.
6916 Nummer"2026-…" Zeittrue geschwärzt"a6f9…" Kennung der Meldung12Was auf diesem Kern aufbaut
- Läuft heute
Über denselben Kern sortieren Sprachmodelle verschiedene Eingangskanäle. Die Tagesvorbereitung läuft noch daneben.
- Zielbild
Im fertigen System wird auf ihren Vorschlag auch erledigt, was innerhalb fester Grenzen liegt.
- Ausblick
Dieselbe Architektur kann mehrere Menschen tragen: Entscheidungen werden zu Quellen, Rechte hängen an der Rolle.