# Verifikation: isam-transaktionen-und-dateinummern

Nachprüfung am 05.09.2026, aktueller uncommitteter Arbeitsbaum auf `19804e0`.
Geprüft: Proposal, Design, Tasks, Delta-Specs, betroffene Hauptspec-Verträge,
Implementierung, Regressionstests und ursprüngliche Fehlerreproduktionen.

**Schlussabnahme: V01–V05 behoben und nachgeprüft. Keine offenen Befunde.
Die Hauptspecs sind synchronisiert; alle 11 Tasks sind abgeschlossen.**

| Dimension | Ergebnis |
|---|---|
| Vollständigkeit | 11/11 Tasks abgeschlossen |
| Korrektheit | 4 Anforderungen, 20 Szenarien zugeordnet; Neuanlage über Symlink zusätzlich abgesichert |
| Kohärenz | D1–D3 eingehalten; Dokumentation und Delta-Specs um die Korrekturen ergänzt |
| Befunde | 0 offen; V01–V05 behoben |

## V05 — Neuanlage über einen Symlink: behoben

**Vorher:** Bei `alias.db → target.db` mit noch fehlender Zieldatei gelang
das erste OPEN; das zweite OPEN derselben Datei meldete Fehler 88. Die erste
Anlage speicherte den Alias als Cache-Schlüssel, die nächste Auflösung ergab
den Zielpfad.

**Korrektur:** `db_oeffnen` bestimmt nach erfolgreicher Dateianlage die
endgültige kanonische Identität, speichert den Datenbankhandle darunter und
gibt diesen Pfad an OPEN beziehungsweise DELETETABLE zurück. Bindungen,
Transaktionen und Undo verwenden damit von Anfang an den Zielpfad.

**Nachweise:**

- `symlink_neuanlage_behaelt_die_dateiidentitaet` in
  [isam/tests.rs](../../../../crates/tb-runtime/src/isam/tests.rs): relative und
  absolute Symlinkziele, erneutes OPEN über Alias und Ziel, gemeinsamer
  Transaktionsbestand, DELETETABLE über Alias, Sicherungspunkt-Rücknahme,
  ROLLBACK ALL und persistierter Ausgangsbestand nach erneutem Öffnen.
- Ursprüngliche CLI-Reproduktion in einem frischen temporären Verzeichnis,
  mit fünf Sekunden Frist: beide zusätzlichen Bindungen sehen einen Satz;
  nach ROLLBACK ALL liefert LOF den Wert 0. Prozessstatus 0, keine Fehler 88/52.
- Vollständige Workspace-Suite: **391 bestanden, 0 fehlgeschlagen,
  1 bewusst ignoriert**. Davon 135 Runtime-Tests und 16 aktive CLI-Korpus-/Harness-Tests.

## V01 — Datenbankidentität: behoben

**Vorher:** Nach CLOSE und CHDIR konnte OPEN mit demselben relativen Namen
in die alte Datei schreiben. OPEN über `./db` erkannte eine bereits laufende
Transaktion derselben Datei nicht und meldete Fehler 88.

**Korrektur:** [datenbank_pfad](../../../../crates/tb-runtime/src/isam.rs#L1560)
löst vorhandene Dateien kanonisch auf. Bei neuen Dateien wird ihr vorhandener
Elternpfad kanonisiert. OPEN und DELETETABLE verwenden diesen Schlüssel
durchgängig für Datenbanken, Transaktionen, Bindungen und Rücknahme.

**Nachweise:**

- [isamidentitaet.bas](../../../../tests/compat/isamidentitaet.bas): Nach Wechsel
  von a nach b ist die zweite Datenbank leer; der Alias `./db` sieht innerhalb
  einer Transaktion den gleichen Bestand. DELETETABLE über `../a/db` und
  Rücknahme funktionieren ebenfalls.
- [pfadaliase_teilen_transaktion_und_ruecknahme](../../../../crates/tb-runtime/src/isam/tests.rs#L696):
  absolute Pfade mit `..` und auf Unix auch ein Symlink teilen denselben Writer.
- Separate CLI-Prozesse lesen anschließend genau einen Satz mit Nr=1 aus
  `a/db` und einen Satz mit Nr=2 aus `b/db`. Beide Dateien existieren.

## V02 — Prozessfristen: behoben

**Vorher:** Nur der besondere CLI-Unterprozess war geschützt; die direkten
ISAM-Aufrufe im Korpustest und in Runtime-Tests konnten weiterhin hängen.

**Korrektur:** [Prozessfrist](../../../../tests/support/prozessfrist.rs) überwacht
jeden Runtime-Datenbanktest über dessen TempDb sowie jeden Aufruf von
[run_corpus_file](../../../../crates/tb-cli/tests/compat.rs#L359), einschließlich
beider Korpusdurchläufe und des bewusst ignorierten Golden-Generators.
Nach 30 Sekunden beendet ein unabhängiger Watchdog den gesamten betroffenen
Testprozess mit Status 124. Beim regulären Abschluss wird die Frist aufgehoben.
Der spezielle CLI-Unterprozess behält seine eigene Fünf-Sekunden-Frist.

**Nachweis:** `frist_beendet_blockierten_testprozess` startet einen Kind-Test,
der absichtlich unbegrenzt blockiert. Dessen Watchdog beendet ihn mit Status 124
und benannter Fehlermeldung; der Elternprozess prüft beides und besitzt zusätzlich
eine unabhängige Fünf-Sekunden-Kill-Frist. Dieser Test besteht sowohl im Runtime-
als auch im CLI-Testbinary. Keine Änderung am Produktcode zur Simulation nötig.

## V03 — Bindungen nach DELETETABLE: behoben

**Vorher:** Ein alter Handle konnte nach DELETETABLE unbemerkt eine interne
Satztabelle ohne Layoutmetadaten wieder anlegen.

**Korrektur:** [tabelle_loeschen](../../../../crates/tb-runtime/src/isam.rs#L988)
löst nach erfolgreicher Löschung alle Bindungen genau dieser Tabelle und
Datenbank. Eine Rücknahme stellt den Bestand wieder her, öffnet aber keine
zuvor geschlossenen Bindungen. Ein neues OPEN bindet den restaurierten Bestand.

**Nachweise:**

- [deletetable_loest_alle_betroffenen_bindungen](../../../../crates/tb-runtime/src/isam/tests.rs#L725):
  Beide alten Handles melden Fehler 52, eine andere Tabelle bleibt gebunden.
  Rücknahme und Wiederöffnung stellen Sätze und eindeutigen Index wieder her.
  Erneute Löschung und Neuanlage ergeben eine leere Tabelle ohne alten Index.
- Die ursprüngliche CLI-Reproduktion meldet jetzt Fehler 52 beim INSERT über
  die alte Nummer und LOF=0 nach Neuanlage. RETRIEVE auf der leeren Tabelle
  meldet erwartungsgemäß Fehler 85; es gibt keinen Geistersatz.

## V04 — DELETE bei ausgeschöpftem Puffer: behoben

**Vorher:** DELETE speicherte Undo und entfernte den Satz trotz Puffergröße 0.

**Korrektur:** [satz_loeschen](../../../../crates/tb-runtime/src/isam.rs#L1123)
prüft die alten Satzbytes gegen den noch verfügbaren Puffer, bevor Satz oder
Indizes verändert beziehungsweise Undo hinzugefügt werden.

**Nachweise:**

- [delete_pufferfehler_erhaelt_saetze_indizes_und_cursor](../../../../crates/tb-runtime/src/isam/tests.rs#L760):
  Fehler 89 außerhalb und innerhalb einer Transaktion lässt Bestand, aktiven
  Index, Cursor und Undo unverändert. Bei exakt passender Größe gelingt ein
  DELETE; der nächste scheitert ohne Änderung. Rücknahme restauriert beide
  Sätze und gibt den Puffer wieder frei.
- Ursprüngliche CLI-Reproduktion: `free=0`, `ERR=89`, `LOF=1`, `restored=1`.

## Szenarionachweise

| Delta-Szenario | Nachweis |
|---|---|
| Sequenzielles Schreiben und Lesen | `tests/compat/dateien.bas` |
| Doppeltes Öffnen derselben Nummer | `isamdateinummern.bas`: Fehler 55 in beiden Richtungen |
| Freie Dateinummer | `isamdateinummern.bas`: gemischte Modi und wiederbelegte Lücken |
| ISAM belegt eine Dateinummer | `isamdateinummern.bas`: FREEFILE=2 |
| Gleicher relativer Name nach Verzeichniswechsel | `isamidentitaet.bas` und separate Persistenzprüfung |
| Neuanlage über einen noch nicht auflösbaren Symlink | `symlink_neuanlage_behaelt_die_dateiidentitaet` und CLI-Reproduktion |
| Pfadalias in einer Transaktion | `isamidentitaet.bas`, Runtime-Pfadaliastest |
| Bindungen nach Tabellenlöschung und Rücknahme | Runtime-DELETETABLE-Bindungstest |
| Tabelle wird beim ersten Öffnen angelegt | `isamtabellen.bas` |
| Abweichendes Satzlayout | `isamtabellen.bas`: Fehler 88 |
| CLOSE lässt eine laufende Transaktion stehen | `close_beendet_keine_transaktion`, `isamopen.bas` |
| Entfernte Tabelle | `isamtabellen.bas`, `isamopen.bas`: Fehler 82 |
| Weitere Tabelle während einer Transaktion | `isamopen.bas` und CLI-Test mit Prozessfrist |
| Rücknahme stellt den Bestand wieder her | CLI-Probe der Erstprüfung: INSERT/DELETE und bare ROLLBACK ergeben LOF=1 und LOC=0; Rücknahmepfad unverändert |
| Rücknahme auf einen Sicherungspunkt | `isamtrans.bas`, `isamstruktur.bas`, Runtime-Strukturtests |
| ROLLBACK ALL beendet die Transaktion | `isamtrans.bas`; CLI-Probe der Erstprüfung mit zwei Savepoints und anschließendem Fehler 5 |
| Indexanlage nach Sicherungspunkt | `isamstruktur.bas`: Fehler 83; Runtime-Strukturtests |
| Geschlossene Tabelle rücknehmen | `isamstruktur.bas`, Runtime-Tests für CLOSE und Struktur-Rücknahme |
| Pufferfehler wird benannt | `isampuffer.bas`, `struktur_undo_prueft_puffer_vor_dem_loeschen` |
| DELETE bei ausgeschöpftem Puffer | Neuer Runtime-DELETE-Puffertest und ursprüngliche CLI-Reproduktion |

## Prüfungen einschließlich erneuter Verifikation

- `cargo test -p tb-runtime --quiet`: 135 bestanden.
- `cargo test -p tb-cli --test compat --quiet`: 16 bestanden, Golden-Generator ignoriert.
- Erneut `cargo test --workspace --quiet`: **391 bestanden, 0 fehlgeschlagen,
  1 bewusst ignoriert**; einschließlich beider Watchdog-Selbsttests.
- Formatprüfung aller geänderten Rust-Dateien und des neuen Testhelfers bestanden.
- `git diff --check` und Whitespace-Prüfung der neuen Dateien bestanden.
- `openspec validate isam-transaktionen-und-dateinummern --strict`: bestanden.
- Ursprüngliche Reproduktionen und positive Zusatzproben erneut ausgeführt:
  Index-Neuanlage mit geändertem Aufbau und Rücknahme, RESET/COMMIT,
  Rücknahme über zwei Datenbankdateien, Programmende ohne COMMIT sowie
  Persistenz über neue CLI-Prozesse. Alle externen Proben mit fünf Sekunden Frist.

Keine GUI-, Windows-/Linux-Abnahme, Speichererschöpfung oder simulierten
redb-I/O-Ausfälle ausgeführt. Keine neue Abhängigkeit, kein neues Datenbankformat.
Die vier geänderten Anforderungen wurden in die Hauptspecs datei-eio und
isam-datenbank synchronisiert; alle 15 Hauptspecs bestehen die strikte Validierung.
