# BEFUND — Runde ECHTHARDWARE-3 (OrientOS / Osum)

**Stand:** 09.09.2026 · **Baum:** `/root/osum-merge9` · **Zweig:** `merge9`
**Basis:** `29db8fb` (nach MERGE-10) · **Ende:** `3f763c5` · **Justins Abbild:** `39f4cc2`
**Belege:** `/srv/store/belege/orientos-eh3/2026-09-09/`
**Nichts nach GitHub gepusht.**

---

## 0. LESEHINWEIS — WAS HIER BELASTBAR IST

Drei Sorten Aussage, streng getrennt, wie in den Vorrunden:

- **GEMESSEN** — aus einem Tool-Ergebnis (serielle Zeile, MD5, Bildpunkt, Zeilennummer).
- **GELESEN** — aus dem Quelltext mit Datei:Zeile. Belegt, aber nicht am laufenden System gegengeprüft.
- **NICHT GEPRÜFT** — steht ausdrücklich dabei.

**Eine Selbstkorrektur vorweg, und sie dreht den ganzen Auftrag um.**
Der ursprüngliche Auftrag nannte als größten Blocker „die Tastatur liefert
nichts" (`TAST D 2 BER 0 ARM 1 CC 0 RK 00000000 N 0`). Justins zweites Foto
von 22:10 zeigt `BER 44 ARM 45 CC 1 RK 00080000 N 29`, das dritte von 22:12
`BER 111 ARM 112 CC 1 N 6`. **Der USB-Teil ist nicht schuld.** Ich habe den
Schwerpunkt entsprechend verschoben, und die Ursache lag tatsächlich weiter
oben — in zwei Ereignisschleifen in Ring 3. Der erste Befund war nicht
falsch, er war nur der Zustand *vor* der Aufzählung.

---

## 1. DIE TASTATUR — URSACHE GEFUNDEN, ZWEI STELLEN

### 1.1 Die Messwerte, die den USB-Teil entlasten (GEMESSEN, Justins Tafel)

| Zeile | 22:01 | 22:10 | 22:12 | Bedeutung |
|---|---|---|---|---|
| 18 TAST | `BER 0 ARM 1 CC 0` | `BER 44 ARM 45 CC 1` | `BER 111 ARM 112 CC 1` | fertige Transfers / eingereihte Blöcke / letzter Code |
| 18 TAST | `RK 00000000 N 0` | `RK 00080000 N 29` | `RK 00090000 N 6` | letzter nicht-leerer Bericht / deren Zahl |
| 11 USB | `KBD 2 TAS 0` | `KBD 2 TAS 20` | `KBD 2 TAS 54` | Tastaturen / **Tastenereignisse** |
| 20 ENDP | `KBD EP1 F0 H0` | `EP1 F0 H0` | `EP1 F0 H0` | Endpunkt LÄUFT, 0 Fehler, 0 Wiederbelebungen |

`ARM - BER = 1` ist der Block, der gerade offen liegt — der Normalfall.
`CC 1` heißt „gut". `TAS 54` heißt: der Zerleger (`hidin.fi`) hat aus den
Berichten **54 Tastenereignisse gemacht und an `kbd.on_code` übergeben**.
Bis dort ist der Weg also vollständig in Ordnung.

**Antwort auf „was bedeutet H0"** (GELESEN, `kernel/usb.fi:1895`): `H` zählt,
wie oft ein angehaltener Endpunkt **wiederbelebt** werden musste
(`Reset Endpoint` + `CLEAR_FEATURE(ENDPOINT_HALT)` + `Set TR Dequeue Pointer`).
`F0 H0` heißt: kein einziger Übertragungsfehler, also war nie eine
Wiederbelebung nötig. **`H0` ist bei laufendem Empfang richtig; `H > 0` wäre
das Warnzeichen.** Die Frage war berechtigt — die Zahl sieht aus wie „kein
Handler", ist aber „keine Reparatur nötig".

**SET_PROTOCOL / SET_IDLE** (GELESEN, `kernel/usb.fi:1711-1714`): beide werden
gesendet, Boot-Protokoll (`0x21, 0x0B, 0`) und `SET_IDLE 0`
(`0x21, 0x0A, 0`). Kein NAK/STALL sichtbar, sonst stünde `F > 0`.

### 1.2 Wo die Tasten wirklich starben (GELESEN + behoben)

**`kernel/user/taskbar.fi:4566` und `kernel/user/desktop.fi:325`.**

Beide Programme holen ihre Ereignisse **selbst** mit `WM_EVENT` ab — und
prüften dann nur auf `EV_DOWN` und `EV_CLOSE` (die Leiste) bzw. nur auf
`EV_CLOSE` (der Schreibtisch). Das Abholen **entfernt das Ereignis aus dem
Ring des Servers**. Jede Taste, die an eines dieser beiden Fenster ging, war
damit gelesen und weggeworfen — ohne eine Zeile auf der Leitung.

Nur `kernel/user/wlib.fi:6664` (`wlib.step`) behandelt `EV_KEY`. Programme,
die über `wlib` laufen, bekommen ihre Tasten; Leiste und Schreibtisch nicht.

**Fix:** neue Funktion `wlib.feed_key` (`wlib.fi`, vor `on_key`), und beide
Schleifen reichen die Taste hinein. `on_key` sucht das Ziel wie sonst auch:
offener Dialog zuerst, dann offenes Menü, sonst das Fenster.
Der Tastencode steht in Bit 32..47 des Datenworts (`wm.ev_push` packt
`(a << 32) | (b << 16) | c`) — im Schreibtisch stand zuerst `dd & 0xFFFF`,
das war falsch und ist korrigiert.

### 1.3 Der Ereignisring verlor Tasten (GELESEN + behoben)

Tafel Zeile 4: `RING 3663 VERL 151 KOAL 57699`.

- **`KOAL` ist kein Verlust.** Es zählt Mausbewegungen, die in ein noch nicht
  abgeholtes `E_MOVE` desselben Fensters zusammengefasst wurden
  (`wm.fi` `ev_push`). Eine Maus meldet bis zu 1000-mal je Sekunde, die Leiste
  holt alle 25 ms ab — Zusammenfassen ist Absicht, die Anwendung will ohnehin
  nur die letzte Stelle. **57699 ist damit kein Fehler.**
- **`VERL 151` war echter Verlust.** Bei vollem Ring (32 Plätze je Fenster,
  `wm.fi:165`) flog bisher immer das **älteste** Ereignis heraus. In einem
  vollen Ring liegen fast nur Bewegungen — aber eben nur fast. Stand vorn ein
  Tastendruck, war er weg, und der Mensch sieht einen verschluckten Buchstaben.

**Fix:** bei Überlauf wird jetzt gezielt die **älteste Bewegung** geopfert und
der Rest nachgerückt; nur wenn wirklich keine Bewegung im Ring steht (32 Tasten
ohne eine einzige Abholrunde — ein Programm, das steht), fällt das älteste
Ereignis. Eine Bewegung darf man verlieren, die nächste sagt dasselbe und mehr.
Eine Taste nicht: sie kommt nie wieder.

### 1.4 Was NICHT geprüft ist

Das **Poll-Intervall des Endpunkts in Millisekunden** habe ich nicht
ausgelesen — die Tafel zeigt es nicht, und auf Justins Blech konnte ich nicht
messen. `ARM`/`BER` belegen, dass gepollt wird und Antworten kommen; die
konkrete Zahl aus dem Endpunkt-Deskriptor (`bInterval`) steht noch nicht auf
der Tafel. **Das ist offen und wird nicht als erledigt ausgegeben.**

Ebenso **nicht geprüft**: ob es ein Unifying-Empfänger ist, der ohne HID++
nur die Maus durchreicht. Die Zahlen sprechen dagegen (`TAS 54` heißt, dass
Tastenberichte ankommen und zerlegt werden), aber ich habe kein HID++
gesprochen.

**NumLock/LED:** die Kette existiert (`usb.fi:2938 ff.`, `set_leds` aus
`kbd.locks`), und sie läuft über `kbd.fi` als einzige Wahrheit. Dass der
angezeigte Zustand bei Justin nicht stimmte, passt zu 1.2: der Zustand wurde
nie aktualisiert, weil die Tasten nicht ankamen. **Ob es nach diesem Fix
stimmt, ist auf echter Hardware nicht nachgemessen.**

---

## 2. DIE UHR — ZWEI FEHLER, EINER DAVON GEMESSEN BEHOBEN

Justins Tafel: `19 UHR RTC 22:10:18 KRN 00:10:17 TZ 120 D 09.09`,
Leiste: `00:10:17 10.09.26`.

**Fehler 1 (behoben, GEMESSEN).** `kernel/user/taskbar.fi` `clock_build`
addierte den Versatz aus `/etc/time.conf` **ein zweites Mal**.
`SYS_SYSINFO I_HOUR` liefert seit Runde ECHTHARDWARE-1 bereits Ortszeit
(`uio.fi` `zeit_feld` → `time.now_local` = TIME_BOOT + Zyklen + tz).
Das Stick-Abbild schreibt die Datei nicht, die Abnahmeskripte
(`tools/design/aufnahme.sh:162`) schon — deshalb ging die Uhr in den
Abnahmebildern zwei Stunden vor.

**Fix:** neues Feld `I_TZMIN` (18) in `kernel/uio.fi` + `kernel/user/ulib.fi`.
Die Leiste addiert `offset` nur noch, wenn der Kern selbst keinen Versatz
kennt — dann ist die Datei die einzige Auskunft, die es gibt.

**GEMESSEN, Gegenprobe in QEMU** (`-kernel`/`-initrd`, `tz=120`):

```
taskbar: text clock ... t=22:43:59 09.09.26     Hostzeit 20:44:00 UTC = 22:44 CEST
```

Uhrzeit **und** Datum stimmen, auch der Tagesübertrag.

**Fehler 2 (NICHT reproduziert).** Dass die Leiste die **Laufzeit** zeigte
(`00:10:17` = 10 min 17 s nach dem Start), heißt `TIME_BOOT == 0`, also hat
`time.init` (`kernel/time.fi:235`) die RTC nicht übernommen — obwohl dieselbe
RTC auf der Tafel mit `22:10:18` richtig steht (die Tafel liest sie über
`time.rtc_field` **frisch**, die Leiste über `TIME_BOOT`).
**In QEMU tritt das nicht auf**, dort ist `TIME_BOOT` korrekt. Die
Plausibilitätsprüfung in `time.init` (`y >= 1970 && y < 2200 && mo 1..12 && d 1..31 && h < 24 && mi < 60 && s < 60`)
lehnt auf Justins Brett offenbar den ersten Lesevorgang ab — vermutlich, weil
sie **einmal** liest, während der CMOS-Baustein gerade überträgt.
`rtc_field` wartet zwar auf Bit 7 von Status A, aber nur mit gedeckelter
Schleife. **Das ist eine begründete Vermutung und keine Messung** — ohne
Zugriff auf sein Blech kann ich es nicht belegen. Es bleibt offen (siehe §7).

---

## 3. DAS FRAMEWORK — SECHS EBENEN STATT DREI

Justins Kernkritik: „mach bitte das Framework für die ganzen Sachen viel
besser, wo du auch die einzelnen Situationen verwenden kannst."

**Ursache (GELESEN, `kernel/wm.fi:218-220`):** es gab genau drei Ebenen —
`L_DESK`, `L_NORMAL`, `L_TOP`. Wer über die Taskleiste musste, lag **mit ihr
auf einer Ebene**; dann entschied die Reihenfolge des Anlegens, wer oben ist.
Daraus folgen drei von Justins Befunden **auf einmal**:

| Befund | Warum |
|---|---|
| Tooltip verschwindet hinter der Leiste | Blase lag auf `L_NORMAL`, Leiste auf `L_TOP` — die Leiste lag zu Recht darüber |
| Rechtsklick öffnet ein echtes Fenster mit Minimieren/Maximieren/X | `menu_open` legte es auf `L_NORMAL`; `taskbar.fi` legte es **von Hand** auf `L_TOP` nach, mit `tip_win_id` auf ein Menü-Fenster — ein Griff in die falsche Tabelle |
| Startmenü überlappt die Leiste, kein Rahmen | lag auf `L_TOP`, also derselben Ebene wie die Leiste |

**Die neue Ordnung ist ab jetzt eine Zusage** (`kernel/wm.fi`):

```
L_DESK    0  Schreibtisch
L_NORMAL  1  gewöhnliche Fenster und Dialoge
L_TOP     2  die Taskleiste
L_MENUE   3  Startmenü / Überlagerung      -- über der Leiste
L_POPUP   4  Klapp- und Kontextmenüs
L_TIP     5  Blasen, über ALLEM
```

Die Zahlen 0..2 bleiben, was sie waren — jedes Programm, das `L_TOP` sagt,
meint weiter die Leiste. Neu ist nur, dass darüber noch etwas **sein kann**.

Dazu, je Oberflächenart:

- **Blase** (`wlib.tip_win_open`): legt sich selbst auf `L_TIP` und
  **nimmt keinen Klick** — `wm.hit` überspringt `L_TIP` (eine Blase liegt über
  allem, damit man sie *sieht*; wer dorthin klickt, meint das darunter).
- **Menü** (`wlib.menu_open`): legt sich selbst auf `L_POPUP` und setzt
  `WS_KEYS` — damit funktionieren Hoch/Runter/Eingabe/Flucht, die
  `wlib.on_key` für `NK_MENU` längst führt. Der Schmuck war schon aus
  (`WS_DECO 0`), es fehlte die **Ebene**.
- **Startmenü** (`launcher.fi`): `L_MENUE` statt `L_TOP`.
- **`taskbar.fi`**: die Handnachhilfe für das Kontextmenü ist **entfallen** —
  sie muss nichts mehr richten und durfte es auch nie.

`WS_LAYER` nimmt jetzt 0..5 (`sysgui.fi`, `wm.set_layer`); die Prüfung
`a2 != L_NORMAL → nur Wurzel` bleibt unverändert, sonst könnte jedes Programm
jede Oberfläche nachbauen.

**NICHT GEBAUT:** eine eigene Fensterart `Dialog` mit „modal, Rahmen, kein
Minimieren" auf Kernebene. `wlib` kennt `NK_DLG` und behandelt ihn modal für
die Tastatur (`on_key`), aber der Kern unterscheidet Dialog und normales
Fenster nicht. Das ist ehrlich offen (siehe §7).

---

## 4. WAS SONST BEHOBEN IST

| # | Befund | Ursache (Datei:Zeile) | Fix | Beleg |
|---|---|---|---|---|
| C1 | Start-Knopf stark gepixelt | `taskbar.fi` `marke_malen` — `marke_start` hat **drei** eingebackene Größen (16/24/32) und vervielfacht ganzzahlig (Nearest-Neighbour). Auf 2560×1440 mit uiscale 2: 32er Bild, vierfach → Treppen | zeichnet jetzt `icons.START` aus `assets/osum-icons.ttf` mit `wlibc.icon_at` **in Zielgröße** aus den Konturen; `marke_start` bleibt Rückfall, falls das Font fehlt | **GEMESSEN:** `taskbar: marke vektor px=28` |
| C1b | „SVG-Icons überall" | — | **Kein zweiter Symbolweg nötig, und hier die Begründung:** `assets/osum-icons.ttf` (46 Lucide-Glyphen, Umrisse) liegt im Baum, und `wlibc.icon_at` rastert daraus **in jeder gewünschten Pixelgröße**. Das ist genau das, was SVG hier leisten müsste. Akku, Ton und Netz gehen diesen Weg längst (`taskbar.fi:3185 ff.`); der Startknopf war der letzte, der es nicht tat | GELESEN + `marke vektor px=28` |
| C2 | Leisten-Icons falsche Größe | `taskbar.fi` `gl_w()` war fest `16 × ui_scale` — die **Dicke der Leiste** kommt aber aus dem Formsatz und `/etc/taskbar.conf` | jetzt zwei Drittel der Knopfhöhe, gerundet auf ein Vielfaches der Vervielfachung, begrenzt auf 12..32. Bei der Vorgabe (Knopf 32) kommt **genau die alte 16** heraus — bisherige Bildpunktzusagen bleiben gültig | GELESEN |
| C3 | Helligkeitsregler lässt sich nicht ziehen | **Drei** Ursachen übereinander: (a) `qs.fi` `step()` kannte nur `EV_KEY`/`EV_DOWN`/`EV_CLOSE` — eine Bewegung bei gedrückter Taste kam nie an, der Wert sprang auf die Klickstelle und blieb. (b) Der Schließweg **pollt** den Zeiger (der Server meldet einem Fenster nur, was *innerhalb* geschieht) und sah dabei nur „Taste unten, Zeiger draußen“ — das trifft auch auf die Mitte eines Ziehens zu. (c) Das Panel lag auf `L_NORMAL`, also **unter** der Leiste | (a) `EV_MOVE` + `EV_UP`; (b) die **Flanke** entscheidet: ging die Taste innerhalb herunter, gehört sie dem Regler — ein Merker aus der Ereignisschleife genügt *nicht*, die Abfrage läuft im selben Umlauf früher; (c) `L_MENUE` + `WS_KEYS` | **GEMESSEN:** Griff bei y=591 an drei Stellen — links `x=916..924`, Mitte `x=1082..1090`, rechts `x=1247..1255`; die drei PNG auch als MD5 verschieden |
| C4 | Fenstergröße ändern geht nicht | `wm.fi` `on_mouse`: der Griff war ein Quadrat von `GRIP0 = 12` **nur unten rechts**. Auf 2560×1440 mit uiscale 2 sind das 24×24 — wer danebentrifft, **verschiebt** das Fenster, weil der Klick daneben ein gewöhnlicher Klick ist | der ganze rechte **und** untere Rand ist Griff, `GRIP0` 12 → 8 | GELESEN — **nicht am Bild belegt**, siehe §7 |
| C5 | Tiling ein/aus zerschießt alles | `wm.fi` `set_tile_on`: „Alles, was jetzt schon offen ist, kommt in den Baum" war **wörtlich** gemeint — Schreibtisch (ganzer Schirm), Taskleiste (reservierte Kante), Startmenü, Menüs, Blasen wurden zu Kacheln. Die Leiste bekommt eine halbe Bildschirmfläche und verlässt ihre Kante; ohne Leiste gibt es danach keinen Knopf mehr, um es zurückzunehmen → „fast gar nichts mehr" | neue Regel `kachelbar()` — normale Ebene, keine reservierte Kante, nicht minimiert. Sie steht **in `tile_take`**, also an EINER Stelle: `tile_take` hat vier Rufer, und eine Regel an vier Stellen ist vier Gelegenheiten, sie zu vergessen. Genau so ist die Leiste in den Baum geraten | GELESEN |
| C7 | „App Zeiger" ist deutsch | die **ganze** Diagnosetafel war deutsch beschriftet | 15 Beschriftungen übersetzt: `QUEUE CURSOR PANEL CALIB BEAT STAGE IMAGE PICK STRIP BOARD KEYS CLOCK FOUND NET SAFETY TICK` | GELESEN |
| C10b | Zeile 23 `SICHER` dauerhaft rot | **kein Sicherheitsproblem.** `WA 0` (Stapelwächter, muss 0 — ist 0), `R3W 0` (falsche GS-Basis, muss 0 — ist 0), `R3K 7` (Ring 3 auf 7 Kernen, gut), `KS 55016` von 65536 (84 %, eng aber nicht drüber). Rot war sie **allein** wegen `LG 4 Z19 51`: vier Tafelzeilen abgeschnitten, die längste Zeile 19 mit 51 Zeichen bei 48 Spalten | Zeile 19 gekürzt (`KRN`→`K`, `TZ`→`Z`), spart 4 Zeichen → 47 | GELESEN |

---

## 5. DHCP — DER KLIENT IST NICHT SCHULD (GEMESSEN)

Tafel Zeile 22: `IP 169.254.10.1` — Link-Local, kein Lease. Justins Schluss
„Adresse da, aber kein Weg nach draußen" ist richtig.

**GEMESSEN in QEMU mit e1000**, voller Ablauf:

```
dhcp: discover xid=3797828681  mac=82840185286
dhcp: offer ip=10.0.2.15  maske=255.255.255.0  gateway=10.0.2.2  server=10.0.2.2
dhcp: request ip=10.0.2.15
dhcp: ack ip=10.0.2.15  lease=86400  weg=0
dhcp: gesetzt ip=10.0.2.15
dhcp: /etc/network.conf geschrieben, Oktette 103
dhcp: /etc/resolv.conf geschrieben, dns 1
taskbar: text net ... t=10.0.2.15
```

Discover/Offer/Request/Ack, Lease, Router, DNS — und die Leiste zeigt die
Adresse **ehrlich** statt „no network". **Der DHCP-Klient funktioniert.**

**Folgerung für Justins Brett:** seine Karte ist eine Realtek `10ec:8168`
→ `kernel/r8169.fi`. Die Tafel meldet `L 1` (Verbindung da), trotzdem kein
Lease. Der Verdacht liegt damit beim **r8169-Treiber** (Senden/Empfangen von
Rundrufen), nicht beim Klienten. `r8169.fi` lädt bewusst **keine
PHY-Firmware** (Kommentar Z. 120 f.). **Nicht behoben, nicht geprüft** — ohne
die Karte kann ich es nicht messen (siehe §7).

**Eine Falle für künftige Läufe, damit sie niemanden mehr kostet:** ohne
`nip=<addr>/<prefix>` auf der Kommandozeile gibt es **gar keinen Stapel** —
`netsvc.fi:185` meldet dann `nic: no stack`, und `/bin/dhcp` sagt „kein Netz
im Kernel". Das ist die nötige Startadresse und kein Fehler. Mein erster
Messlauf ist genau darüber gestolpert.

---

## 6. ABNAHME — DIE BILDER

Werkzeug `tools/design/aufnahme.sh`, TCG (KVM ist auf diesem Zweig defekt,
begründet in `aufnahme.sh` Z. 44 ff.).

Verzeichnisse unter `/srv/store/belege/orientos-eh3/2026-09-09/`:
`hell-1280`, `dunkel-1280`, `hell-2560`, `dunkel-2560`.

**Der wichtigste Messwert der Abnahme — und der Vergleich mit der Vorrunde.**
Im PROGRAMM-AUDIT vom selben Tag waren die Bilder je Lauf **byte-gleich**
(`709f9da8 … 01-schreibtisch.png` = `02-startmenue.png`), Explorer, Dialog,
Kontrollzentrum und Einstellungen gingen **nie auf**. Jetzt, `hell-1280`:

```
49ad19ca  01-schreibtisch.png
4becea41  02-startmenue.png      <- geht auf
eb527d1d  03-explorer.png        <- geht auf
eb527d1d  04-dialog.png          <- gleich wie Explorer, siehe unten
0f34ff82  05-kontrollzentrum.png <- geht auf
da31c75d  06-einstellungen.png   <- geht auf
```

**Fünf verschiedene Bilder statt einem.** Farbproben je Bild (Stichprobe
alle 13 Spalten × 17 Zeilen): Schreibtisch 33, Startmenü 60,
Kontrollzentrum 69 verschiedene Farben — die Fenster sind wirklich da und
nicht leer.

**Was NICHT gut ist und hier stehen bleibt:** `04-dialog.png` ist
byte-gleich mit `03-explorer.png` — der Dialog geht im Drehbuch nicht auf.
Das ist derselbe Fehlerkopf wie `G-003` („Strg+N öffnet keinen Dialog") und
**in dieser Runde nicht behoben**.

### 6.1 DIE DURCHKLICK-FOLGEN (die Bildserien, die Justin verlangt hat)

`durchklick/` und `durchklick2/`, Drehbücher `tools/design/durchklick3.txt`
und `durchklick3b.txt`. Jeder Schritt ein Bild.

**Startmenü öffnen → tippen → Ergebnis wählen → Enter.** Das ist die Probe
auf die Tastenzustellung, und sie ist die wichtigste Messung der ganzen
Runde. Aus `durchklick/serial.txt`:

```
launcher: suche []    treffer=5   apps=5  dateien=0
launcher: suche [e]   treffer=17  apps=5  dateien=12
launcher: suche [ed]  treffer=5   apps=1  dateien=4
launcher: suche [edi] treffer=3   apps=1  dateien=2
key: e   key: d   key: i   key: [enter]
```

**Die Liste wird mit jedem Tastendruck kürzer.** Vor dieser Runde nahm
`taskbar.fi` jede Taste aus dem Ring und warf sie weg — dann bleibt diese
Zahl auf 5 stehen, egal was man tippt. Die fünf Bilder `10-start-offen` bis
`14-enter-gestartet` sind fünf verschiedene MD5.

**Tooltip vor der Leiste.** Bildvergleich `30-tooltip-ueber-leiste` gegen
`60-vor-tiling` (gleicher Zustand, nur ohne Blase): Unterschiede von
**y=712 bis y=790**. Die Taskleiste beginnt bei **y=764** — die Blase
zeichnet also *durch sie hindurch*. Vorher lag sie dahinter.

**Rechtsklick auf ein Leisten-Icon.** `taskbar: kontext btn=1`,
`40-kontextmenue` ≠ `41-kontextmenue-zu`: das Menü geht auf und schließt bei
einem Klick daneben.

**Tiling ein und wieder aus.** `60-vor-tiling`, `61-tiling-ein` und
`62-tiling-aus` sind byte-gleich — auf einem Schreibtisch ohne gewöhnliche
Fenster ändert der Kachelmodus seit dieser Runde *nichts*, und das ist
richtig so. Die Gegenprobe ist `63-nach-tiling-startmenue`, und die ist
**verschieden**: nach ein und aus geht das Startmenü noch auf. Justins
„danach geht fast gar nichts mehr" ist damit weg.

**Helligkeitsregler ziehen.** `durchklick2/`, gemessen am Bild bei y=591
(dort liegt nur der Griff, nicht die Rinne):

| Bild | Griff bei |
|---|---|
| `72-hell-links` | x = 916..924 |
| `73-hell-mitte` | x = 1082..1090 |
| `71-hell-rechts` | x = 1247..1255 |

Drei Züge, drei Stellen, drei verschiedene MD5. Die Rinne läuft von x=898
bis x=1266 — der Griff steht also wirklich links, mittig und rechts.

### 6.2 DREI FEHLER, DIE IM LÄUFER LAGEN UND NICHT IM SYSTEM

Das gehört hierher, weil es mich drei Läufe gekostet hat und weil der
Unterschied nicht sichtbar war:

1. **`fahre` fährt immer erst nach 0,0.** Absolut positionieren geht über
   QEMUs `mouse_move` nur relativ, also fährt der Läufer erst in die Ecke.
   Beim **Ziehen** wandert die gedrückte Taste mit — das Kontrollzentrum
   sieht einen Druck bei 0,0 und schließt sich völlig zu Recht
   (`qs: closed by outside`). Es sah aus, als täte der Regler nichts.
   `ziehe` bewegt jetzt ab dem Druck nur noch relativ.
2. **Koordinaten geschätzt.** Ich habe die Reglerrinne aus
   `PAD/GAP/TOP2/ZH` nachgerechnet und lag **16 Punkte daneben**; der Griff
   landete außerhalb des Panels. Jetzt meldet das Programm sie selbst:
   `qs: hell spur von=898 bis=1266 ym=583`, und `fahren.py` kennt dafür den
   Rechtecknamen `hellspur` samt Befehl `ziehespur <name> <von%>,<bis%>`.
3. **`zieheauf frect0` fand kein Rechteck**, weil in jenem Lauf gar kein
   Dateimanager lief. Deshalb ist `21-fenster-groesser` byte-gleich mit
   `20-fenster-vorher` — **das ist kein Beleg gegen den Griff, sondern gar
   keiner.** Siehe §7.

---

## 7. WAS OFFEN BLEIBT — EHRLICH

| Punkt | Warum offen |
|---|---|
| **`TIME_BOOT == 0` auf echtem Blech** | In QEMU nicht reproduzierbar; die Uhr ist dort korrekt. Vermutung: `time.init` liest den CMOS während einer Übertragung und verwirft das Ergebnis. **Vermutung, keine Messung.** Der Doppel-Versatz ist behoben und gemessen; dieser Teil braucht Justins Brett. |
| **Poll-Intervall des Tastatur-Endpunkts** | `bInterval` steht nicht auf der Tafel und wurde nicht ausgelesen. `ARM`/`BER` belegen, **dass** gepollt wird, nicht **wie oft**. |
| **NumLock-LED auf echter Hardware** | Die Kette ist vorhanden und die Ursache (Tasten kamen nicht an) behoben — ob die Anzeige jetzt stimmt, ist auf Blech nicht nachgemessen. |
| **DHCP auf r8169** | Klient gemessen in Ordnung; der Treiber ist der Verdächtige. Ohne die Karte nicht messbar. |
| **Dialog als eigene Fensterart im Kern** | `wlib` behandelt `NK_DLG` modal für die Tastatur, der Kern unterscheidet ihn nicht. Nicht gebaut. |
| **`04-dialog.png` = `03-explorer.png`** | Der Dialog geht im Drehbuch nicht auf (`G-003`). Nicht behoben. |
| **Fenstergröße: kein Bildbeleg** | Der Fix ist gelesen und begründet (`GRIP0` 12→8, ganzer rechter und unterer Rand), aber `zieheauf frect0` fand in beiden Durchklick-Läufen kein Rechteck — im ersten lief kein Dateimanager, im zweiten lief der Lauf in seine 600-s-Frist. `21-fenster-groesser` ist deshalb byte-gleich mit `20-fenster-vorher`, und das ist **kein Beleg gegen den Griff, sondern gar keiner**. Das Werkzeug dafür steht jetzt (`zieheauf`), der Lauf fehlt. |
| **`durchklick2` unvollständig** | Der Lauf hat seine 600-s-Frist erreicht, nachdem die drei Regler-Bilder standen (`qemu exit 124`). Die Tiling-Bilder `81`–`83` dieses Drehbuchs fehlen deshalb — die Tiling-Probe steht aber vollständig im ersten Lauf (`durchklick/60`–`63`). |
| **Dunkelmodus: einzelne Programme weiß** | Ich habe alle Programme mit Fenstern gegen `wlibc.theme` geprüft: `freunde`, `lock`, `papierkorb`, `powermon`, `rechner`, `snip`, `viewer` nutzen `wlib` (also das Thema) und haben **keine** fest eingetippten Farben — die gefundenen Hex-Werte sind Masken und Sentinels, keine Farben. `sh.fi` ist ein **Terminal**: seine Farben setzt der Kern (`DK_TERM_FG/BG`), und die Vorgaben sind bereits dunkel. **Damit habe ich die von Justin gesehenen weißen Fenster nicht reproduzieren können** und sage das, statt einen Fix zu behaupten. |
| **Hover/Druck in Taskmanager und Einstellungen** | `wlib` führt `F_HOVER`/`F_PRESSED` bereits und malt beide (`paint_button`, `on_move` Z. 5580 ff.); beide Programme nutzen `wlib`. Ich konnte **keinen** fehlenden Weg finden und habe nichts geändert. Falls es dort trotzdem fehlt, brauche ich von Justin, welcher Knopf konkret. |
| **Einstellungen „sieht leer aus"** | Nicht angefasst — ohne konkreten Punkt wäre jede Änderung geraten. |

---

## 8. COMMITS

```
2954ea2  ECHTHARDWARE-3, Teil 1: Ebenen, Tastenzustellung, Uhr, Griff, Vektor-Startknopf
50df1ad  ECHTHARDWARE-3, Teil 2: der Kachelmodus nimmt nicht mehr die ganze Oberflaeche mit
978dd5b  ECHTHARDWARE-3, Teil 3: Helligkeitsregler laesst sich ziehen, Leistensymbole folgen der Leiste
```

Alle auf `merge9`, **nichts gepusht.**
