# Verifikation: projektmodule-und-kompilat Geprüft am 05.09.2026: Arbeitsbaum auf Basis von `58b1f62`, alle sieben Delta-Requirements mit 21 Szenarien, Tasks, D1–D4, Implementierung und Abnahmenachweis. **Sechs offene Befunde; der Change ist nicht abnahmebereit.** Die vorherige Aussage vollständiger Umsetzung wird durch diese Verifikation korrigiert. Der Produktcode wurde bei diesem Review nicht verändert. | Dimension | Ergebnis | | --- | --- | | Vollständigkeit | 7/7 Tasks sind angehakt und alle sieben Requirements haben Implementierungspfade. Die Befunde widerlegen jedoch die vollständige Erfüllung insbesondere von 1.1, 1.2 und 2.2; Checkboxen allein sind kein Abnahmenachweis. | | Korrektheit | 437 bestehende Workspace-Tests bestanden; zusätzliche unabhängige Review-Proben: 1 bestanden, 6 fehlgeschlagen. Vier Kernfunktionslücken (CRITICAL), zwei weitere Vertragsabweichungen (WARNING). | | Kohärenz | D4 und die FRM-Grundpfade von D3 sind umgesetzt. Quellorte und Modulkontexte gehen in weiteren Absenkungs-/Importpfaden verloren; der gemeinsame Objektraum berücksichtigt `$FORM` nicht vollständig. | ## CRITICAL — vor Archivierung beheben ### V1 — Quellorte und Breakpoints fehlen an Zweig- und Schleifengrenzen **Priorität: hoch.** Delta „Zeilentabelle für Fehlerortung“ und „Unterbrechbare step()-Ausführung“, D1, Tasks 1.1/2.2. Die Fehlerortung funktioniert bei einfachen Anweisungen, nicht jedoch bei weiteren ausführbaren Teilen zusammengesetzter Anweisungen: | Probe | Erwartet | Beobachtet | | --- | --- | --- | | `IF 0 THEN` / `PRINT 1` / `ELSEIF 1/0 THEN` | Fehler 11 in Zeile 3 | Zeile 1 | | `SELECT CASE 1` / `CASE 1/0` | Fehler 11 in Zeile 2 | Zeile 1 | | `FOR i%=32767 TO 32767` / `PRINT 1` / `NEXT` | Überlauf beim NEXT in Zeile 3 | Zeile 2 | | `DO` / `PRINT 1` / `LOOP UNTIL 1/0` | Fehler 11 in Zeile 3 | Zeile 2 | | ELSEIF-Bedingung aus `cond.bi:1` | Include-Datei `cond.bi` | `main.bas:1:1` | | Breakpoint auf ELSEIF in Zeile 3 | Halt vor Bedingung | Programm endet ohne Halt | **Ursache:** [ELSEIF-Absenkung](../../../../crates/tb-frontend/src/sema.rs#L1937) und [CASE-Absenkung](../../../../crates/tb-frontend/src/sema.rs#L2914) verwenden den Quellort des äußeren Statements. NEXT-/LOOP-Positionen werden nicht vollständig durch AST/HIR bis zur auszuführenden Grenze getragen. Der [FOR-Codegenerator](../../../../crates/tb-vm/src/codegen.rs#L737) dokumentiert selbst die bisherige Verschiebung einer genauen NEXT-Zuordnung auf Phase 5; das widerspricht der hier übernommenen vollständigen Quellortanforderung. **Korrektur:** Physische Positionen aller ausführbaren Zweig-/Schleifenteile bereits beim Parsen erhalten und passende Source-/Stmt-Grenzen ausgeben. Nicht nur Fehlermeldungen umbenennen: Breakpoints, Einzelschritt und RESUME müssen dieselbe richtige Zuordnung verwenden. Numerische ERL-Labels separat lassen. Probe `v1_zweige_und_schleifen_behalten_eigene_quellorte`. ### V2 — Deklarationsimport verändert Typkontext und Abhängigkeitsreihenfolge **Priorität: hoch.** Projektpipeline und vollständige Prozedursignaturen, D2, Tasks 1.2/2.1. Drei zulässige Mehrmodulkonstellationen werden abgewiesen: - MAIN ruft `Doppelt(3)` auf; LIB enthält `DEFINT A-Z` und `FUNCTION Doppelt(x)`. Erwartete Ausgabe 6, tatsächlich `Parameter type mismatch: MAIN!DOPPELT`. - MAIN enthält `CONST A=3` und verwendet B; LIB enthält `CONST A=3` und `CONST B=A+1`. Erwartet B=4, tatsächlich `LIB.bas:2:1: Invalid constant`. - Beide Module enthalten denselben TYPE Inner. LIB definiert anschließend TYPE Outer mit einem Feld `i AS Inner`; MAIN verwendet Outer. Erwartet korrektes Layout und Feldausgabe 3, tatsächlich `Type not defined` an der gültigen Outer-Definition sowie Folgefehler für Feldzugriffe. **Ursache:** [import_declarations](../../../../crates/tb-vm/src/project.rs#L103) kopiert rohe Signatur-ASTs ohne den DEFtype-Kontext des definierenden Moduls. Fremde CONST-/TYPE-Knoten werden [vor sämtliche lokalen Deklarationen gehängt](../../../../crates/tb-vm/src/project.rs#L158). Dadurch fehlen ihnen zu diesem Zeitpunkt lokal vorhandene Abhängigkeiten. Die Fehlerposition in LIB ist hier irreführend: Die dortige Originalreihenfolge ist gültig. **Korrektur:** Exportierte Signaturen und Konstanten im Ursprungskontext auflösen; abhängige Typdefinitionen mit erhaltenen Identitäten und gültiger Abhängigkeitsreihenfolge verbinden. Lokale Definitionen und echte Duplikate nicht wieder durch Text-Deduplizierung verstecken. Probe `v2_importierte_deklarationen_behalten_kontext_und_abhaengigkeiten`. ### V3 — `$FORM`-Module teilen versehentlich dasselbe Formularobjekt **Priorität: hoch.** Delta „Objektzugriffe in Grammatik und Semantik“ einschließlich `$FORM`, getrennte Formulare, D2/D3, Task 1.2. A.bas und B.bas enthalten jeweils `'$FORM`. A setzt `Caption="a"`, ruft eine SUB aus B auf, die dort `Caption="b"` setzt, und liest anschließend die eigene Caption. **Erwartet: a. Beobachtet: b.** Das verknüpfte Objektverzeichnis enthält nur SCREEN und A. Auch `B.Caption` aus A wird als unbekanntes Objekt abgewiesen. Der Fehler besteht nach TBC-Rundlauf fort. **Ursache:** [lower_with_forms](../../../../crates/tb-frontend/src/sema.rs#L404) erweitert pro Modul eine lokale Katalogkopie um das jeweilige `$FORM`-Objekt. Der Linker übernimmt [nur die Objekte des ersten Moduls](../../../../crates/tb-vm/src/project.rs#L188) und versetzt die Objektoperanden weiterer Module nicht. Deren Form-ID zeigt anschließend auf A. **Korrektur:** Sämtliche FRM- und `$FORM`-Formulare vor der modulweisen Semantik in einen gemeinsamen Katalog mit stabilen IDs aufnehmen oder die Objekt-/Ereignisreferenzen beim Linken vollständig versetzen. Zugriffe, Form_Load-Bindungen und gegenseitige Formreferenzen für beide Quellarten prüfen. Probe `v3_form_metabefehle_erzeugen_getrennte_formularobjekte`. ### V4 — COMMON verliert Variablenidentität und initialisiert Arrays mehrfach **Priorität: hoch.** Designrisiko SHARED/COMMON, D2, Task 1.2 und Erhalt der bestehenden COMMON-Sprachsemantik. - Bereits ein Modul mit `COMMON SHARED c%, c$` wird mit `COMMON type mismatch: C` abgewiesen. Die beiden durch Typ-Suffixe verschiedenen Variablen dürfen nebeneinander existieren. - MAIN und LIB deklarieren dasselbe `COMMON SHARED a%(2)`. MAIN soll `a%(1)=7` setzen und LIB den gemeinsamen Wert 7 ausgeben. Stattdessen entsteht vor dem Nutzcode `LIB.bas:1:1: Runtime error 10: Duplicate definition`. **Ursache:** Die [COMMON-Zuordnung](../../../../crates/tb-vm/src/project.rs#L270) verwendet nur Block und untypisierten Basisnamen. Arrays haben zusätzlich nur `TypeInit::Empty` als Slotvorbelegung; Elementtyp und Form gehen in der Vergleichsprüfung verloren. Der Slot wird zwar zusammengeführt, aber [beide DIM-Initialisierungen](../../../../crates/tb-vm/src/project.rs#L381) werden ausgeführt. **Korrektur:** Vollständige Variablenidentität und Arrayvertrag beim Binden berücksichtigen. Kompatible gemeinsame Arrays einmal initialisieren; inkompatible Deklarationen vor der Ausführung am ursprünglichen Quellort ablehnen. Probe `v4_common_behaelt_typidentitaet_und_initialisiert_arrays_einmal`. ## WARNING — weitere Vertragsabweichungen ### V5 — LOAD/UNLOAD umgehen die explizite Containerauflösung **Priorität: mittel.** Formularnamensraum und expliziter Containerzugriff, D2, Task 1.2. Bei zwei Formularen mit jeweils Text1 als Control-Array werden `LOAD Form2!Text1(3)` und `UNLOAD Form2!Text1(3)` mit `Unknown object 'FORM2!TEXT1'` abgewiesen. Property-Zugriffe und die Übergabe desselben qualifizierten Controls an einen CONTROL-Parameter funktionieren. **Ursache:** Der [LOAD-/UNLOAD-Pfad](../../../../crates/tb-frontend/src/sema.rs#L3370) übergibt den gesamten Bang-Pfad an `find_object`; die bereits vorhandene containerbezogene Auflösung wird hier nicht verwendet. **Korrektur:** LOAD/UNLOAD über dieselbe Objekt-/Containerauflösung wie Property- und Referenzzugriffe führen; gleichnamige Arrays beider Formulare und dynamische Instanzen gemeinsam prüfen. Probe `v5_load_und_unload_loesen_den_expliziten_container_auf`. ### V6 — Linkerdiagnosen verlieren Datei, Zeile und Spalte **Priorität: mittel.** Delta „Diagnostik mit Vorbild-Meldungen“, D1, Task 1.1. MAIN deklariert `SUB F(x%)`, LIB implementiert `SUB F(x$)`. Die Ablehnung ist richtig, die Meldung jedoch `0:0: Parameter type mismatch: MAIN!F` ohne Datei. Das ist eine quellbezogene Diagnose, kein Fehler ohne zuordenbare Quelle. **Ursache:** [diagnostic](../../../../crates/tb-vm/src/project.rs#L17) erzeugt `file=None` und `SourcePos::default()`. [Linkfehler](../../../../crates/tb-vm/src/project.rs#L66) werden erst nach `locate_diagnostics` in dieses Format umgewandelt. Dasselbe Problem betrifft COMMON-Konflikte und weitere symbolbezogene Linkfehler. **Korrektur:** Ursprung der betroffenen Deklaration bzw. Aufrufstelle mit in die Linker-Symbolinformationen übernehmen und strukturierte Diagnosen mit tatsächlicher SourcePos zurückgeben. Keine pauschale Ersatzposition 1:1 eintragen. Probe `v6_linkerdiagnose_nennt_den_urspruenglichen_dateiort`. ## Szenarioabdeckung und positive Nachweise Alle 21 vorhandenen Delta-Szenarien wurden abgeglichen. Die einfachen Originalbeispiele besitzen Implementierungs- und Testnachweise; die oben reproduzierten Randpfade widersprechen den umfassenderen Requirements. | Requirement / Szenarien | Ergebnis | | --- | --- | | Monomorpher Opcode-Satz: gemischter Ausdruck, aufgelöste Namen | Vorhandene Codegen-/HIR-Tests bestanden. Alle 152 Opcodes samt Operandentypen und Encodingbreiten stimmen mit der Dokumentation überein. | | TBC: Roundtrip, unbekannte Version, Formularwerte | CLI-/VM-Projekttests bestanden: bytegleicher Rundlauf, hello/world aus Designarrays 0/2 nach Entfernen sämtlicher BAS-/FRM-/MAK-/BI-Quellen, Ablehnung alter/höherer Versionen. V2/V3 begrenzen dennoch das vollständige Projektmodell. | | Quellorte: Fehlerzeile, Bibliotheksfehler | `lib.bas:2` und verschachtelte Include-Fehler bestehen. Unabhängig zusätzlich Fehler in physischer Zeile 42 geprüft. V1 zeigt fehlende Zweig-/Schleifenorte. | | Benannte Objekte: Lesen/Schreiben, keine Standardeigenschaft, Wertebereich, getrennte Controls | Bestehende Semantik-/VM-/Modelltests und neuer Zwei-FRM-Test bestanden; Check1.Value=3 bleibt Fehler 5. V3 betrifft weitere Formularquellen, V5 die weiteren qualifizierten Zugriffspfade. | | Diagnosen: Position, Include-Diagnose | Lexer-/Parser-/Semantikpfad trägt Originalpositionen. V6 betrifft die anschließende Linkerphase. | | Objektgrammatik/-semantik: unbekanntes Objekt/Eigenschaft, Typkonflikt, TYPEOF, gleiche Controls | Bestehende Tests bestanden. V3/V5 verletzen den allgemeinen Modul-/Containervertrag trotz grüner Property-Beispiele. | | Unterbrechung: Breakpoint, Inspektion, gleiche Zeile in zwei Modulen | Unabhängige Probe: MAIN passiert Zeile 10, LIB hält in Zeile 10; qualifizierte Array-/UDT-Inspektion liefert 7/8; Einzelschritt meldet Spalte 5; ERR/ERL bleiben 6/200. V1 lässt Breakpoints an ELSEIF aus. | Erneut ausgeführt: - `cargo test --workspace`: **437 bestanden, 0 fehlgeschlagen, 1 ignoriert**. Golden-Generator nicht ausgeführt, keine Sollausgaben geändert. - [Review-Proben](review-probes.rs): **1 bestanden, 6 fehlgeschlagen**. Jede fehlgeschlagene Probe entspricht einem der sechs Befunde; mehrere verwandte Reproduktionen werden innerhalb einer Probe gesammelt. - Zusätzlich zeitlich begrenzte CLI-Proben für die Befunde; temporäre Quellverzeichnisse anschließend entfernt. - `cargo bench -p tb-vm --bench compile`: 508 Zeilen **0,54 ms**, 49.760 Zeilen in 20 verbundenen Modulen **67 ms**; beide Budgets erfüllt. - Dokumentation: **152/152 Opcodes**, Operanden-/Gesamtbreiten und **9/9 Containerabschnitte** gegen den aktuellen Code abgeglichen. - `cargo fmt --all -- --check`, `openspec validate projektmodule-und-kompilat --strict` und `git diff --check`: bestanden. - Clippy nicht nochmals ausgeführt: keine Produktcodeänderung seit dem erfolgreichen Clippy-Lauf der Implementierungsabnahme. Kein neuer interaktiver Originalsystemvergleich und keine Windows-/Linux-Testmatrix. ## Review-Proben reproduzieren Im Repository-Wurzelverzeichnis ausführen. Der temporäre Treiber hält die noch roten Vertragsproben außerhalb der normalen Workspace-Suite; ihre Erwartungen beschreiben das Sollverhalten. Exit-Code ist bis zur Behebung 101. ```sh python3 - <<'PY' from pathlib import Path import json, subprocess, tempfile, os root = Path.cwd() with tempfile.TemporaryDirectory(prefix='tb-project-review-') as folder: p = Path(folder) manifest = '[package]\nname="tb-project-review"\nversion="0.0.0"\nedition="2021"\n[workspace]\n' manifest += '[[test]]\nname="probes"\npath=' + json.dumps(str(root / 'openspec/changes/archive/2026-09-05-projektmodule-und-kompilat/review-probes.rs')) + '\n[dependencies]\n' for name in ['tb-ui', 'tb-vm', 'tb-runtime', 'tb-frontend']: manifest += name + ' = {path=' + json.dumps(str(root / 'crates' / name)) + '}\n' (p / 'Cargo.toml').write_text(manifest) result = subprocess.run(['cargo', 'test', '--manifest-path', str(p / 'Cargo.toml'), '--offline', '--test', 'probes', '--', '--nocapture'], env={**os.environ, 'CARGO_TARGET_DIR': str(root / 'target/review-projektmodule')}, timeout=120) raise SystemExit(result.returncode) PY ``` **Abnahmeentscheidung:** V1–V4 vor Archivierung beheben; V5/V6 ebenfalls in die vollständige Umsetzung aufnehmen. Keine zusätzlichen Stilvorschläge.