OpenSpec-Review dokumentieren und ISAM-Vertragsabweichungen beheben

This commit is contained in:
2026-09-05 17:55:09 +02:00
parent 19804e0e2d
commit 57d6386a5a
61 changed files with 3087 additions and 86 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-09-05

View File

@@ -0,0 +1,32 @@
## Context
Die LISTINDEX-Prüfung konvertiert -1 vor dem oberen Grenzvergleich nach usize. Änderungen an INTERVAL/ENABLED löschen timer_last, dessen nächster Default 0 ist. Timerereignisse werden bereits über die bestehende Queue zugestellt. Siehe proposal.md und die Delta-Specs.
## Goals / Non-Goals
**Goals:** Gültige Übergänge an den bestehenden Property-/Listenmethoden korrigieren und Timerzustand an die Hostzeit koppeln.
**Non-Goals:** Keine neue Control-Bibliothek, keine Änderung der festgelegten Optik, keine zweite Ereignisschleife.
## Decisions
### D1 — Auswahl ist ein eigener gültiger Zustand
-1 vor dem oberen Grenzvergleich behandeln. Einfügungen vor dem ausgewählten Eintrag verschieben dessen Index; Entfernen des gewählten Eintrags hebt die Auswahl auf, Entfernen davor verschiebt sie zurück. ListBox.Text liefert ohne Auswahl leer, eine editierbare ComboBox behält ihren separaten Eingabetext.
### D2 — Aktivierungszeit statt Nullzeit
Beim Übergang auf einen aktiven Timer den aktuellen Hostzeitpunkt als Ausgangsfrist speichern. Ändernde Property-Zugriffe erhalten diesen Zeitpunkt über den bereits vorhandenen VM/Host-Pfad; kein Systemuhrzugriff und kein globaler Zeitcache. Interval=0/Enabled=0 entfernt anstehende Zustellungen dieses Timers. Explizites Umschalten des Intervalls beginnt eine neue Frist.
### D3 — Laufende Timer behalten Nachholregel
Ein kontinuierlich aktiver 100-ms-Timer bekommt bei 250 ms zwei Ereignisse; das gilt nur für Zeit innerhalb seiner aktiven Phase. Reihenfolge gleichzeitig fälliger Timer bleibt dokumentiert nach Namen und bei gleichem Arraynamen nach Index.
## Risks / Trade-offs
- Änderung an Auswahl kann ComboBox-Eingabetext löschen → Stilarten und editierbaren Text getrennt testen.
- Intervalländerung im eigenen Handler kann alte Queueeinträge übriglassen → Reset/Deaktivierung mit bereits wartenden Ereignissen prüfen.
## Migration Plan
Nach ereigniszustellung-und-hostgrenzen. Ändert nur die Requirements zu Listen und Timer, nicht Fokus/Menü desselben Capability-Pfads. Bestehende Spec-/Codeverträge erst nach erfolgreicher Umsetzung synchronisieren und archivieren. Bis dahin bleiben alle Tasks offen. Änderungen als zusammenhängenden Commit je Change integrieren; bei Fehlschlag auf den vorherigen Code zurückgehen und neue Datenformatversionen nicht mit alten Lesern öffnen.

View File

@@ -0,0 +1,24 @@
## Why
Listen und Timer erfüllen einfache gültige Zustandsübergänge nicht: ListIndex=-1 liefert Fehler 5; ein spät aktivierter Timer holt Zeit seit Programmstart nach. F12/F13 betreffen das Zustandsmodell unabhängig von dessen späterem Ereignisdispatch. Siehe [Review vom 05.09.2026](../../../docs/reviews/2026-09-05-openspec-code-review.md).
## What Changes
- Explizites Aufheben einer Listenauswahl unterstützen und List/Text/Count bei Einfügen/Entfernen konsistent halten.
- Timerfristen ab Aktivierung bzw. neu gesetztem Intervall starten und deaktivierte Zeiten nicht nachholen.
## Capabilities
### New Capabilities
Keine neuen Capability-Pfade.
### Modified Capabilities
- `forms-steuerelemente`: Listen-Auswahl und Zeitbezug des Timer-Steuerelements durch präzise Zustandsübergänge ergänzen.
## Impact
crates/tb-ui/src/forms.rs, Forms-Unit-/VM-Tests, Formular-Korpus und docs/forms-referenz.md. Baut auf der geordneten Ereigniszustellung auf.
Nach ereigniszustellung-und-hostgrenzen. Ändert nur die Requirements zu Listen und Timer, nicht Fokus/Menü desselben Capability-Pfads.

View File

@@ -0,0 +1,51 @@
## MODIFIED Requirements
### Requirement: Steuerelemente mit Listeninhalt
ListBox und ComboBox SHALL `ADDITEM` und `REMOVEITEM` unterstützen und
`List`, `ListCount`, `ListIndex` und `Text` konsistent führen; bei
`Sorted = -1` SHALL die Einfügereihenfolge der Sortierung folgen.
`ListIndex = -1` SHALL „keine Auswahl" bedeuten. Die ComboBox SHALL die
drei Stilarten (Dropdown, Simple, Dropdown List) darstellen.
Eine Zuweisung von ListIndex = -1 SHALL in leerer wie gefüllter Liste zulässig sein. Einfügen vor der Auswahl SHALL ihren Index verschieben, Entfernen der Auswahl SHALL sie aufheben. Eine ListBox ohne Auswahl SHALL Text als leeren String liefern; editierbare ComboBox-Stile SHALL ihren unabhängigen Eingabetext erhalten.
#### Scenario: Element hinzufügen
- **WHEN** `List1.ADDITEM "b"` und `List1.ADDITEM "a"` bei `Sorted = -1` ausgeführt werden
- **THEN** liefert `List1.List(0)` den Wert `a` und `List1.ListCount` den Wert 2
#### Scenario: Keine Auswahl
- **WHEN** eine ListBox ohne Auswahl gelesen wird
- **THEN** liefert `ListIndex` den Wert 1
#### Scenario: Auswahl ausdrücklich aufheben
- **WHEN** nach ADDITEM die Eigenschaft ListIndex auf -1 gesetzt wird
- **THEN** tritt kein Fehler auf und ListIndex ist -1
#### Scenario: Eintrag vor Auswahl einfügen
- **WHEN** vor einem ausgewählten Eintrag ein Element eingefügt wird
- **THEN** bleibt derselbe Eintrag ausgewählt und sein Index steigt um 1
### Requirement: Timer-Steuerelement
Ein Timer SHALL bei `Enabled = -1` und `Interval > 0` sein
`Timer`-Ereignis im eingestellten Abstand auslösen, gestützt auf die
Zeitquelle der Ereignissteuerung. `Interval = 0` SHALL ihn abschalten.
Sind mehrere Timer gleichzeitig fällig, SHALL die Reihenfolge festgelegt
und dokumentiert sein.
Die erste Frist SHALL ab dem Einschalten beziehungsweise neu gesetzten Intervall zählen. Zeit vor der Aktivierung MUST NOT nachgeholt werden. Deaktivierung oder Interval = 0 SHALL noch anstehende Timerereignisse verwerfen.
#### Scenario: Timer feuert im Abstand
- **WHEN** ein Timer mit `Interval = 100` läuft und die Zeit um 250 ms vorrückt
- **THEN** ist sein Ereignis zweimal gelaufen
#### Scenario: Interval 0 schaltet ab
- **WHEN** `Timer1.Interval = 0` gesetzt wird
- **THEN** läuft kein weiteres Ereignis
#### Scenario: Späte Aktivierung
- **WHEN** bei Hostzeit 1000 ms ein zuvor inaktiver Timer mit Interval 100 eingeschaltet wird
- **THEN** läuft bis 1099 ms kein Timerereignis und bei 1100 ms genau eines
#### Scenario: Abschalten verwirft anstehende Ereignisse
- **WHEN** Timerereignisse anstehen und vor ihrer Zustellung Interval auf 0 gesetzt wird
- **THEN** werden sie nicht mehr zugestellt

View File

@@ -0,0 +1,13 @@
## 1. Listen
- [ ] 1.1 ListIndex=-1 korrekt zulassen und Text/List/Count bei ADDITEM/REMOVEITEM konsistent halten; verifizieren mit leeren/sortierten Listen, Einfügen vor Auswahl, Entfernen der Auswahl und allen ComboBox-Stilen.
## 2. Timer
- [ ] 2.1 Aktivierungs-/Änderungszeit über den Host erfassen und deaktivierte Queueeinträge entfernen; verifizieren mit Aktivierung bei 1000 ms, erster Fälligkeit bei 1100 ms, Änderung im Handler und Interval=0.
- [ ] 2.2 Fortlaufende Timer und gleichzeitige Fälligkeit erhalten; verifizieren mit exakt zwei Ereignissen bei 250 ms sowie mehreren Timer-/Arraynamen und Wiederholbarkeit.
## 3. Abnahme
- [ ] 3.1 Formular-Korpus um Listenauswahl und späte Timeraktivierung ergänzen und Referenz dokumentieren; verifizieren mit cargo test -p tb-ui, cargo test -p tb-vm und cargo test -p tb-cli --test compat.
- [ ] 3.2 Delta-Specs und Diffs prüfen; verifizieren mit openspec validate forms-zustand-und-bedienung --strict und git diff --check.