# Persistenz

> Wie ein LMSP-Dienst seinen Zustand speichert, mit einer eingebetteten SQLite-Datenbank, den Tabellen, den Transaktionsregeln für Aufgaben und Ereignisse, der Aufbewahrung und der Wiederherstellung beim Start.

Source: https://madeforagent.com/de/lmsp/1.0/persistence/
Language: de
Specification: LMSP 1.0 (draft)
Updated: 2026-11-08

## 11.1 Speicherung {#storage}

Ein Dienst **SOLLTE** seinen Zustand in einer eingebetteten [SQLite](https://www.sqlite.org/)-Datenbank halten. Ein vorgeschlagener Satz von Tabellen:

| Tabelle | Inhalt |
| --- | --- |
| `service_config` | Dienstidentität und Konfiguration. |
| `clients` | Gekoppelte Clients, Token-Hashes und Scopes. |
| `models` | Modellmetadaten und Inhalts-Digests. |
| `responses` | Gespeicherte Antworten. |
| `tasks` | Asynchrone Aufgaben. |
| `task_events` | Das Ereignisprotokoll jeder Aufgabe, mit Sequenznummern. |
| `idempotency_keys` | Idempotenzschlüssel, Anfrage-Digests und Ergebnisse. |

Modelldateien **MÜSSEN** außerhalb der Datenbank bleiben. Die Datenbank enthält nur Metadaten und Inhalts-Digests.

Tabellennamen und Aufbau sind eine Implementierungsentscheidung. Was Clients beobachten können und was interoperabel sein muss, ist das Verhalten in den nächsten beiden Abschnitten.

## 11.2 Regeln {#rules}

Welchen Speicher ein Dienst auch verwendet, er:

- **MUSS** eine Aufgabe persistieren, bevor er `202 Accepted` zurückgibt.
- **MUSS** Ereignis-Sequenznummern und Aufgabenstatus in derselben Transaktion aktualisieren.
- **MUSS** den Abbruchübergang atomar machen, um die Race Condition einer Aufgabe zu vermeiden, die abgebrochen und dann abgeschlossen wird.
- **SOLLTE** beendete Aufgaben und Ereignisse für eine konfigurierbare Aufbewahrungsdauer vorhalten.
- **DARF NICHT** unfertige Aufgaben bei der Protokollbereinigung löschen.
- **MUSS** beim Start die übrig gebliebenen Aufgaben `queued`, `loading`, `running` und `cancelling` durchsehen und die Neustartrichtlinie jeder einzelnen anwenden ([Abschnitt 7.5](https://madeforagent.com/de/lmsp/1.0/tasks.md#restart)).

## 11.3 Wiederherstellung beim Start {#recovery}

Die Tabelle zeigt den Zustand, in den eine übrig gebliebene Aufgabe gemäß ihrer `on_restart`-Richtlinie überführt wird:

| Beim Start gefundener Zustand | `fail` | `retry` | `resume` |
| --- | --- | --- | --- |
| `queued` | `failed` | `queued` | `queued` |
| `loading` | `failed` | `queued` | `queued` |
| `running` | `failed` | `queued` | `running`, Fortsetzung vom Snapshot |
| `cancelling` | `cancelled` | `cancelled` | `cancelled` |

Eine Aufgabe, die nach `failed` überführt wird, erhält den Fehlercode `server_restarted` und ein `response.failed`-Ereignis. Eine Aufgabe, die nach `cancelled` überführt wird, erhält ein `response.cancelled`-Ereignis. Der neue Zustand und sein Ereignis werden in einer Transaktion geschrieben ([Abschnitt 11.2](https://madeforagent.com/de/lmsp/1.0/persistence.md#rules)).
