## Context

`Vm::run` und `run_visible_forms` laufen synchron bis zu einem RunEvent; Host-Warten und mehrere Eingabe-/Dialog-Builtins blockieren. VM-Werte verwenden Rc und sind nicht Send. Der CLI-Runner baut bei RUN eine frische VM. `ScreenWidget` prüft bisher auch seine Zeichenfläche gegen 80×25. BASIC-SHELL startet aktuell direkt ein Kind mit geerbter Standard-I/O. Diese Pfade müssen gemeinsam integriert werden; nur F5 an `run` zu hängen würde die IDE blockieren.

## Goals / Non-Goals

**Goals:** Eine weiter bedienbare IDE, fortsetzbare Runtime-Zustände und gemeinsamer Reset; unveränderte CLI-Semantik ohne aktivierte IDE-Steuerung.

**Non-Goals:** Zweite VM, native Prozesse als BASIC-Ausführung, unsafe Send, generische Task-Runtime, VM-Worker pro Fenster oder Live-Patching.

## Decisions

1. **Kooperatives Treiben im selben Prozess und Thread:** VM-Ausführung erhält eine begrenzte Poll-/Slice-Schnittstelle, die an sicheren Anweisungsgrenzen Yield melden kann. Yield ist kein Step und kein Breakpoint. Die UI verarbeitet danach Ereignisse und rendert. Bestehendes `run` treibt denselben Mechanismus für die CLI bis zum bisherigen RunEvent weiter. Ein fester Anweisungszähler reicht für das Slice-Budget; es wird keine Zeitabfrage pro Opcode und kein neuer Clock-Zugriff im bisherigen trapfreien Fastpath eingeführt.
2. **Blockierende Runtime-Pfade gehören ausdrücklich zur Umsetzung:** INPUT/LINE INPUT, INPUT$, SLEEP, Modal-Forms/MSGBOX/INPUTBOX und die sichtbare Forms-Schleife erhalten bei IDE-Betrieb fortsetzbare Wartezustände. Bereits gelesene Zeichen, Prompt, Stackargumente, Deadline und Return-Ziel bleiben gespeichert. Erneutes Polling führt weder den Builtin-Aufruf noch seine Nebenwirkungen von vorne aus. Bei CLI-Betrieb wird der Zustand intern weitergetrieben. Nur den Host mit einem Timeout zu versehen oder einen beliebigen Fehler als „Pause“ zu verwenden genügt nicht. Das verhindert eine zusätzliche Worker-/Debug-Synchronisation mit nicht-Send-Werten.
3. Die Sitzung unterscheidet Bearbeitung, Übersetzen, Laufend, Wartend, Angehalten und Beendet/Fehler. Ein Lauf trägt Kompilatrevision und separates Laufziel. Ctrl+Break und der IDE-Unterbrechen-Befehl wirken auch bei Editorfokus; Ctrl+C kopiert dort, unterbricht aber bei Output-Fokus. Pause aus einer ausstehenden Eingabe zeigt deren Quellstelle; Continue führt die gespeicherte Operation weiter. Während eines laufenden Programms haben Modifikation/Neustart klare Übergänge, keine zweite parallele Sitzung.
4. Gemeinsame Reset-/Laufzielhelfer werden aus `run_chain`/`run_target` gezogen. RUN verwirft die alte VM und Runtime, nicht die bearbeiteten IDE-Dokumente. Bei gleichem Ziel wird dessen aktueller zulässiger Dokumentstand gemäß gewählter Neustartentscheidung übersetzt; fremde RUN-Ziele benutzen denselben Loader und eigene Laufquellen. Breakpoints können nach Neustart neu gebunden werden; Frames und Watchwerte werden nie übernommen.
5. Die optionale Startdatei aus 01 ordnet beim Compile das ausgewählte Modul zuerst und die anderen stabil danach. Explizites FRM wird `startup_form`, explizites BAS setzt kein automatisches Startformular. Ohne Metadaten bleibt das jetzige Verhalten (Modulreihenfolge, erstes Formular) erhalten. Diese Regel liegt im gemeinsamen Projektcompiler, damit CLI, IDE und geschriebenes TBC übereinstimmen; der vorhandene TBC-Container kann die Startformular-ID bereits speichern.
6. `TextScreen` bleibt die einzige Programmausgabe. Die physische Mindestgrößenprüfung gehört in den Terminalrahmen; eine Output-Ansicht rendert Ausschnitt/Scrollposition. Nur tatsächliches Resize ändert Runtime-Geometrie über den vorhandenen Hostpfad. F4 verändert ausschließlich die Ansicht. IDE-Thema und BASIC-Farben werden nicht vermischt.
7. Shell ist eine kontrollierte Terminalübergabe: Ausführung pausiert, Guard gibt Raw/Alternate-Screen/Mouse ab, Kind läuft mit normaler Standard-I/O, danach werden Terminal und Fokus wiederhergestellt. Ein kleiner Host-Einstieg ermöglicht dieselbe Übergabe für BASIC-SHELL; die CLI behält ihren Exit-Code-Vertrag. Während interaktiver Shell gehört das Terminal dem Kind, das ist kein weiterlaufender IDE-Dialog. Benutzerabbruch muss Kindbeendigung und Terminalrückgabe durchlaufen; es werden keine Prozesse losgelöst hinterlassen.
8. File→Print ist eine dokumentierte Plattformanpassung: Dialog für Quelltext/Selektion, Ziel UTF-8-Textdatei, Standard LPT1.TXT passend zum bisherigen Druckerpfad. Kein Hardwaredruckertreiber. Datei- und Überschreibschutz verwenden 01.

## Risks / Trade-offs

- Eine übersehene blockierende Operation friert weiter ein → alle Host-Warteaufrufe und deren Builtin-Aufrufer inventarisieren, repräsentative Eingabe-, Schlaf- und Modalpfade über echten App-Eventweg testen.
- Fortsetzbare Operationen verlieren Stack oder wiederholen I/O → dedizierte Suspend/Resume-Tests mit teilweise gelesener Eingabe, Timer und Fehlerhandler; CLI-Vergleich derselben Ereignisfolge.
- Kooperative Grenzen unterbrechen kein beliebiges blockierendes Betriebssystem-Datei-I/O → Eingabe-/Timer-/Forms-Warten wird resumierbar; reale synchrone Dateioperationen behalten ihre bisherige Semantik. Keine Zusage harter Echtzeitunterbrechung fremder Systemaufrufe.
- VM-Umbau verändert Ereignis- oder Fehlersemantik → komplette vorhandene VM-/Runtime-/Forms-Regressionen plus GUI-freier CLI-Vergleich. Scheduling-Yield und Debug-Step strikt trennen.

## Migration Plan

Poll-Pfad neben den bisherigen Run-Einstieg setzen, dann dessen interne Schleife darüber führen. Jeder wartende Builtin wird zusammen mit seinem Fortsetzungstest umgestellt. CLI-Ausgabe/Exit-Codes bleiben die Vergleichsreferenz. Es wird kein neues Bytecode-Dateiformat benötigt; Laufzustände sind ausschließlich im Speicher.
