diff --git a/docs/mla-next/BASELINE.md b/docs/mla-next/BASELINE.md index 6abec8b..86b46ee 100644 --- a/docs/mla-next/BASELINE.md +++ b/docs/mla-next/BASELINE.md @@ -317,3 +317,351 @@ Die Messwerte sind die Vergleichsbasis für Gate 1 (Registry #60) und die Flutter-vs-GTK-Messbasis (löst den offenen Punkt 5 aus §6 teilweise ein — die `la_probe`-Messwerte existieren nun; der Flutter/GTK-Vergleich selbst bleibt offen). + +## §8 Flutter-Release vs. GTK-Shell (Issue #95, 2026-09-30) + +Messprotokoll der #95-Baselinemessung nach Issue-#95-Abnahme: Flutter-Release-Build +gegen die GTK-Shell (statisches Demo-Dashboard) auf demselben Zielrechner, je +Backend Wayland und X11. Ergänzt §1 und die `la_probe`-Referenz aus §7; die +Flutter-vs-GTK-Entscheidung selbst ist 0.4.x-Aufgabe — dieser Abschnitt liefert +nur die Vergleichsbasis (Rohwerte, Mediane, Grenzen), keine Empfehlung. + +### Rahmen + +| Messfenster | Wert | +| --- | --- | +| Task 1 — Flutter-Zellen | 2026-09-30, 07:41–07:58 MESZ (Release-Build 07:36:01+02:00; Probe-Läufe 07:41:28–07:50:16; serielle Zellen 07:51:54–07:57:59+02:00) | +| Task 2 — GTK-Zellen | 2026-09-30, 08:34–08:45 MESZ (08:34:41–08:44:54+02:00; Probe-Läufe 08:34:41–08:36:08, serielle Zellen 08:37:50–08:44:54) | + +Rechner (frisch erhoben 2026-09-30T09:13:15+02:00, ausschließlich unprivilegiert; +Identifikation über CPU/RAM/Kernel wie bei den #94-Fixtures — kein Hostname, +keine Nutzernamen): + +| Messung | Wert | +| --- | --- | +| CPU (`grep -m1 'model name' /proc/cpuinfo`) | 13th Gen Intel(R) Core(TM) i7-13620H | +| RAM (`grep MemTotal /proc/meminfo`) | 16 066 996 kB | +| Kernel (`uname -r`) | 7.0.0-34-generic | +| `getconf CLK_TCK` | 100 | +| Sitzung | `XDG_SESSION_TYPE=wayland`, `WAYLAND_DISPLAY=wayland-0`, `DISPLAY=:1` (XWayland) | +| Referenz | Zorin-Matrix §1 (2026-09-29): Zorin OS 18.1, `zorin:GNOME` | + +Versionen (aus den Task-Reports übernommen, nicht neu gemessen): Flutter +3.47.5 (stable) und Dart SDK 3.13.4 (Task 1, vor dem Build 07:36:01); GTK 4 14 5 / +Adw 1 5 0 via GI-Introspection (Kommando wörtlich aus §1) und Python 3.12.3 +(Task 2; Python frisch bestätigt). Hinweis: der Task-2-Report §1 führt MemTotal +abweichend mit 9 071 472 640 Bytes; die obige Rechner-Box folgt der frischen +Erhebung (16 066 996 kB) — die Messwerte sind davon unberührt. + +### Messdesign + +Vier Zellen {Flutter-Release, GTK-Shell} × {Wayland, X11}; je Zelle 5 Startup- +und 5 Steady-Läufe, strikt sequenziell. + +| Zelle | Artefakt | Startkommando | Startzustand | +| --- | --- | --- | --- | +| `flutter-wayland` | `build/linux/x64/release/bundle/linux-assistant` | Binär direkt (nativer Wayland-Client) | Dashboard mit aktivem 3-s-Stat-Poll — echte Systemdaten (df/ps/uptime/free/loadavg) | +| `flutter-x11` | dito | `GDK_BACKEND=x11 ` | dito (über XWayland `:1`) | +| `gtk-wayland` | `prototype/gtk/mla_app.py` (3 924 Bytes) | `python3 prototype/gtk/mla_app.py` (cwd Repo-Root) | statisches Demo-Dashboard, kein Refresh-Timer — `grep -nE 'timeout_add\|GLib\.timeout\|Thread\|subprocess' prototype/gtk/mla_app.py` → keine Treffer | +| `gtk-x11` | dito | `GDK_BACKEND=x11 python3 prototype/gtk/mla_app.py` | dito | + +Gemessen wird stets der App-Prozess selbst — direkter Launch ohne Shell-Wrapper, +`$!` ist die App-PID. Zwischen den Läufen: SIGTERM ans eigene Kind (max. 10 s +warten, sonst SIGKILL nur ans eigene Kind), auf Exit warten, 2 s Cooldown. + +Wesentliche Messkommandos (1:1 aus den Helferskripten; Abbruchwachen für +60-s-Timeout und vorzeitigen Process-Exit ausgelassen): + +Startup Wayland — erster Wayland-Protokollverkehr (Proxy-Ereignis, vor First-Frame): + +```text +: > "$WL_LOG" +s=$(date +%s%N) +WAYLAND_DEBUG=1 "$BIN" 2>>"$WL_LOG" & # GTK: WAYLAND_DEBUG=1 python3 "$APP" 2>>"$WL_LOG" & +APP_PID=$! +while [ ! -s "$WL_LOG" ]; do sleep 0.005; done +e=$(date +%s%N); echo $(( (e-s)/1000000 )) ms +``` + +`WAYLAND_DEBUG=1` lässt libwayland-client jeden Protokollverkehr auf stderr +drucken; erste Zeile ≈ Verbindungs-/Registry-Phase. Die Perturbation (fprintf +je Nachricht) ist dokumentiert; die Variable ist nur in den 5 Startup-Läufen +je App gesetzt, nie in den Steady-Läufen. Erstes Proxy-Ereignis war die +Registry-Abfrage `wl_display@1.get_registry(new id wl_registry@2)` — echte +erste Protokollzeile, keine Python-Warning. Beleglage je Backend: Bei GTK ist +das je Lauf mit der ersten Protokollzeile belegt; bei Flutter nur über die +Log-Umfänge beim ersten Poll-Treffer (konsistent, aber nicht zeilenbelegt): +Flutter 3 536–3 817 Bytes, GTK konstant 8 255 Bytes (Probe 5 092 — +Auflösungs-/Timing-Varianz des ersten Poll-Treffers, kein Protokollunterschied). + +Startup X11 — Fenster mit passendem Namen im X-Baum: + +```text +s=$(date +%s%N) +GDK_BACKEND=x11 "$BIN" >/dev/null 2>&1 & # GTK: GDK_BACKEND=x11 python3 "$APP" >/dev/null 2>&1 & +APP_PID=$! +while ! xdotool search --name "linux.assistant" >/dev/null 2>&1; do sleep 0.01; done # GTK: --name "Prototyp" +e=$(date +%s%N); echo $(( (e-s)/1000000 )) ms +``` + +Harte Vorbedingung je Lauf (Selbst-Match der prüfenden Shell über +Klammerausdrücke ausgeschlossen; Fremdinstanzen werden nie beendet — bei +Verstoß 3× 30 s warten, dann Abbruch mit Exit 2): + +```text +pgrep -af '[l]inux-assistan[t]|[l]inux_assistan[t]|[m]la_app[.]py' # muss leer sein +xdotool search --name '[Ll]inux.[Aa]ssistant' # nur X11, muss leer sein — GTK-Zellen: 'Prototyp' +``` + +Steady — 10 s Settle, 20 Samples @ 1 Hz, CPU-Fenster 20 s (ohne `WAYLAND_DEBUG`): + +```text +"$BIN" >/dev/null 2>&1 & APP_PID=$! # GTK analog +sleep 10 # Settle +cpu0="$(awk '{print $14+$15}' "/proc/$APP_PID/stat")" +for i in $(seq 1 20); do + grep -E 'VmRSS|VmHWM' "/proc/$APP_PID/status" >> "$sample_file" + grep '^Pss:' "/proc/$APP_PID/smaps_rollup" >> "$sample_file" + sleep 1 +done +cpu1="$(awk '{print $14+$15}' "/proc/$APP_PID/stat")" +kill "$APP_PID"; wait "$APP_PID" 2>/dev/null || true; sleep 2 # SIGTERM, Exit, Cooldown +``` + +- **CPU:** `cpu_percent_eines_Kerns = (cpu1 − cpu0) / (CLK_TCK × 20) × 100` mit + `CLK_TCK=100` (utime+stime in Ticks; comm beider Apps ohne Leerzeichen — + Feldposition sicher). +- **RAM:** je Lauf Median der 20 Samples (`VmRSS`, `Pss`); `VmHWM` = letzter Sample. +- **Median-Regel:** `sort -n`; bei gerader Anzahl Mittel der beiden mittleren + Werte (betroffen: PSS flutter-x11 Lauf 1: 90 883,5 kB). +- **Umgebung je Zelle protokolliert:** `date -Is`, Sitzungsvariablen, + `cat /proc/loadavg` vor/nach der Zelle (Werte in den Zell-Unterschriften unten). + +Vollständige Helferskripte (`/tmp/mla95-measure.sh`, `/tmp/mla95-measure-gtk.sh`) +sind 1:1 in den Session-Scratch-Reports (`.superpowers/sdd/task-1-report.md`, +`task-2-report.md`) abgedruckt; die 20er-Roh-Sample-Serien +(`/tmp/mla95-steady-*.txt`, `/tmp/mla95-gtk-steady-*.txt`) und die Zellenlogs +lagen ausschließlich unter `/tmp` — Reports (gitignored) und `/tmp` sind +beides ephemeral. Dieser Abschnitt führt alle Startup-Einzelwerte +und die je-Lauf-Steady-Mediane selbst. + +### Errata und Prädikate (drei Plan-Pins korrigiert, von Reviewern A/B verifiziert) + +| # | Plan-Pin | Realität / gemessene Umsetzung | +| --- | --- | --- | +| 1 | Artefakt `…/bundle/linux_assistant` | Real **`linux-assistant`** (Bindestrich); comm ebenfalls; pgrep-/ERE-Muster entsprechend | +| 2 | X11-Poll `xdotool search --name "Linux Assistant"` | `WindowManager.instance.setTitle("Linux Assistant")` (`lib/main.dart:27`) greift unter X11 nicht — `WM_NAME`/`_NET_WM_NAME` des Dev-Builds sind `linux-assistant`/`linux_assistant`; gemessen wird das ERE `linux.assistant`, die Vorbedingung prüft breiter `[Ll]inux.[Aa]ssistant`; der erste Probe-Lauf lief in den 60-s-Timeout (BLOCKED, außerhalb der Serie) | +| 3 | `grep VmPss /proc//smaps_rollup` | Key ist **`Pss:`** (ohne `Vm`-Präfix) — gemessen `grep '^Pss:'` (Anker vermeidet `Pss_Dirty`/`Pss_Anon`/…) | + +Prädikate je Zelle: Flutter-X11-Startup-Poll = ERE `linux.assistant`; GTK-X11-Startup-Poll += `Prototyp` (Fenstertitel „Master Linux Assistant · Prototyp" — traf in allen 6 +X11-Läufen sofort; Erratum 2 betrifft GTK nicht); PSS-Schlüssel durchgängig `^Pss:`. + +### Zelle flutter-wayland + +Umgebung `XDG_SESSION_TYPE=wayland`, `DISPLAY=:1`, `WAYLAND_DISPLAY=wayland-0`. +Zelle 07:51:54+02:00 (loadavg 4.89 4.35 3.43) bis 07:54:48+02:00 (4.99 4.63 3.70). + +Startup (5-ms-Poll auf `/tmp/mla95-wl.log`): + +| Lauf | startup_ms | app_pid | wl_log_bytes | +| --- | --- | --- | --- | +| 1 | 30 | 256729 | 3536 | +| 2 | 34 | 256839 | 3769 | +| 3 | 29 | 257037 | 3817 | +| 4 | 23 | 257231 | 3817 | +| 5 | 25 | 257281 | 3769 | + +Zellen-Median Startup: **29 ms** (sortiert: 23, 25, 29, 30, 34). + +Steady: + +| Lauf | RSS-Median (kB) | PSS-Median (kB) | VmHWM (kB) | cpu0 | cpu1 | cpu_percent | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | 161524 | 89740 | 164956 | 996 | 3020 | 101.20 | +| 2 | 161216 | 89720 | 164688 | 998 | 3019 | 101.05 | +| 3 | 161472 | 89775 | 164980 | 996 | 3018 | 101.10 | +| 4 | 161216 | 89676 | 164440 | 997 | 3021 | 101.20 | +| 5 | 161580 | 89749 | 164904 | 998 | 3022 | 101.20 | + +Zellen-Mediane: RSS **161 472 kB** · PSS **89 740 kB** · HWM **164 904 kB** · +CPU **101.20 %** eines Kerns. + +### Zelle flutter-x11 + +Identische Sitzung; App via `GDK_BACKEND=x11` über XWayland `:1`. +Zelle 07:55:05+02:00 (loadavg 4.65 4.57 3.70) bis 07:57:59+02:00 (5.43 5.37 4.18). + +Startup (10-ms-Poll, Prädikat ERE `linux.assistant` — Erratum 2): + +| Lauf | startup_ms | app_pid | +| --- | --- | --- | +| 1 | 37 | 265298 | +| 2 | 39 | 265403 | +| 3 | 72 | 265515 | +| 4 | 37 | 265745 | +| 5 | 41 | 265792 | + +Zellen-Median Startup: **39 ms** (sortiert: 37, 37, 39, 41, 72). Ausreißer Lauf 3 +(72 ms) fiel mit ansteigender Systemlast zusammen (1-min-loadavg erreichte 8.04 +am Ende des steady-Laufs 2); der Rohwert bleibt in der Serie, der Median ist +nicht betroffen. + +Steady: + +| Lauf | RSS-Median (kB) | PSS-Median (kB) | VmHWM (kB) | cpu0 | cpu1 | cpu_percent | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | 162968 | 90883.5 | 166592 | 996 | 3014 | 100.90 | +| 2 | 163232 | 91302 | 166140 | 991 | 3012 | 101.05 | +| 3 | 163100 | 91393 | 166420 | 997 | 3021 | 101.20 | +| 4 | 163148 | 91340 | 166720 | 996 | 3016 | 101.00 | +| 5 | 163240 | 91415 | 166420 | 997 | 3014 | 100.85 | + +Zellen-Mediane: RSS **163 148 kB** · PSS **91 340 kB** · HWM **166 420 kB** · +CPU **101.00 %** eines Kerns. + +### Zelle gtk-wayland + +Identische Sitzung. Zelle 08:37:50+02:00 (loadavg 1.87 2.13 2.66) bis +08:41:12+02:00 (2.70 2.38 2.64). + +Startup (5-ms-Poll auf `/tmp/mla95-gtk-wl.log`): + +| Lauf | startup_ms | app_pid | wl_log_bytes | +| --- | --- | --- | --- | +| 1 | 76 | 310184 | 8255 | +| 2 | 70 | 310246 | 8255 | +| 3 | 57 | 310326 | 8255 | +| 4 | 63 | 310357 | 8255 | +| 5 | 63 | 310407 | 8255 | + +Zellen-Median Startup: **63 ms** (sortiert: 57, 63, 63, 70, 76). + +Steady: + +| Lauf | RSS-Median (kB) | PSS-Median (kB) | VmHWM (kB) | cpu0 | cpu1 | cpu_percent | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | 187520 | 101347 | 187520 | 36 | 36 | 0.00 | +| 2 | 187972 | 101093 | 187972 | 38 | 38 | 0.00 | +| 3 | 187836 | 101166 | 187836 | 37 | 37 | 0.00 | +| 4 | 188096 | 101161 | 188096 | 36 | 36 | 0.00 | +| 5 | 188076 | 101327 | 188076 | 38 | 38 | 0.00 | + +Zellen-Mediane: RSS **187 972 kB** · PSS **101 166 kB** · HWM **187 972 kB** · +CPU **0.00 %** eines Kerns. + +### Zelle gtk-x11 + +Identische Sitzung. Zelle 08:41:26+02:00 (loadavg 2.63 2.38 2.64) bis +08:44:54+02:00 (2.01 2.13 2.48). + +Startup (10-ms-Poll, Prädikat `Prototyp`): + +| Lauf | startup_ms | app_pid | +| --- | --- | --- | +| 1 | 316 | 314505 | +| 2 | 277 | 314589 | +| 3 | 285 | 314702 | +| 4 | 284 | 314790 | +| 5 | 298 | 314902 | + +Zellen-Median Startup: **285 ms** (sortiert: 277, 284, 285, 298, 316). + +Steady: + +| Lauf | RSS-Median (kB) | PSS-Median (kB) | VmHWM (kB) | cpu0 | cpu1 | cpu_percent | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | 187884 | 101749 | 187884 | 37 | 37 | 0.00 | +| 2 | 187772 | 101428 | 187772 | 37 | 37 | 0.00 | +| 3 | 188060 | 101562 | 188060 | 35 | 35 | 0.00 | +| 4 | 188216 | 101800 | 188216 | 37 | 37 | 0.00 | +| 5 | 187996 | 101683 | 187996 | 37 | 37 | 0.00 | + +Zellen-Mediane: RSS **187 996 kB** · PSS **101 683 kB** · HWM **187 996 kB** · +CPU **0.00 %** eines Kerns. + +### Zellen-Mediane über alle vier Zellen + +| Zelle | Startup-Median | RSS (kB) | PSS (kB) | HWM (kB) | CPU (% eines Kerns) | +| --- | --- | --- | --- | --- | --- | +| flutter-wayland | 29 ms¹ | 161 472 | 89 740 | 164 904 | 101.20 | +| flutter-x11 | 39 ms² | 163 148 | 91 340 | 166 420 | 101.00 | +| gtk-wayland | 63 ms¹ | 187 972 | 101 166 | 187 972 | 0.00 | +| gtk-x11 | 285 ms² | 187 996 | 101 683 | 187 996 | 0.00 | + +¹ erster Wayland-Protokollverkehr (Proxy-Ereignis, vor First-Frame). +² Fenster mit passendem Namen im X-Baum (xdotool ohne `--onlyvisible`, nicht + strikt „gemappt sichtbar"). + +### Befunde + +Nüchterne Befunde, keine Empfehlung — die Flutter-vs-GTK-Entscheidung ist +0.4.x-Aufgabe; #95 liefert die Vergleichsbasis für #105. + +**(a) CPU-Dauerrendern Flutter:** Alle 10 Flutter-Steady-Läufe zeigen ~101 % +eines Kerns (100.85–101.20 %): der Release-Build rendert im Ruhezustand +kontinuierlich (Impeller; App-Log „Using the Impeller rendering backend +(OpenGLESSDF)"). Die CPU-Formel trägt eine konstante ~+1 %-Verzerrung +(Sample-Zeit + `sleep 1` verlängern das reale Fenster auf ~20,2 s, der Nenner +bleibt fix 20 s) — sie betrifft nur Flutter. Die GTK-Shell verbraucht im +Fixture-Startzustand 0 CPU-Ticks: cpu0 == cpu1 in allen 10 Steady-Läufen +(statisches Demo-Dashboard ohne Timer, grep-Beleg oben). + +**(b) Startup backendintern vergleichen:** direkt vergleichbar ist X11↔X11 — +identisches Ereignis „Fenster mit passendem Namen im X-Baum": Flutter 39 ms +vs. GTK 285 ms. Wayland↔Wayland nur mit Proxy-Vorbehalt (29 vs. 63 ms — +„erster Protokollverkehr" ≠ First-Frame). Backendübergreifend wird nicht +gerankt. + +**(c) X11-Aufschlag** (backendintern): GTK +222 ms (63 → 285), Flutter ++10 ms (29 → 39). + +**(d) RSS/PSS** (Wayland-Mediane): Flutter 161 472 kB RSS / 89 740 kB PSS; +GTK 187 972 kB / 101 166 kB. PSS ist umgebungsvariabel und sharer-abhängig; +die GTK-RSS enthält die geteilten Python+GI+GTK-Runtime-Seiten (GTK-PSS liegt +~87 MB unter GTK-RSS). In den GTK-Zellen ist RSS praktisch backendunabhängig +(Δ 24 kB ≈ 0,01 %), PSS nahezu (Δ 517 kB ≈ 0,51 %). + +**(e) Lastasymmetrie** (korrigierte Richtung, Task-2-Report §7): Task 1 lief +unter 1-min-loadavg 4.6–8.0 (Zellgrenzen 4.65–5.43; 15-min 3.4–4.2), Task 2 +unter 1.62–2.92 (15-min 2.5–2.7) — gleich gelagert (keine künstliche Last, +stets nur eine App-Instanz aktiv), aber nicht lastgleich. Hohe Last verlängert +Startup-Zeiten, nie umgekehrt: der gemessene Flutter-Startup-Vorteil ist damit +eine **konservative Untergrenze**; die GTK-Aufstellung war schonend (GTK unter +den milderen Bedingungen gemessen). Geltungsbereich: Last wirkt vor allem auf +Startup-Zeiten und CPU-Konkurrenz, praktisch nicht auf RSS/PSS; die +Prozess-CPU ist per `/proc//stat` gemessen (Verzerrungsrichtung ebenfalls +eher Untergrenze). Ob die GTK-Zellen bei Last ~5–8 (Task-1-Bedingung) gleich +ruhig reagieren wie bei ~2, ist aus diesen Daten allein nicht belegbar. + +**(f) Größen** (nur Angabe, kein Ranking): Flutter-Bundle +`build/linux/x64/release/bundle` 26 885 925 Bytes; Flutter-Binary +`linux-assistant` 23 664 Bytes; `mla_app.py` 3 924 Bytes. Unterschiedliche +Natur (das Python-Skript braucht Python+GI-Runtime); `la_probe` (§7: +6 547 240 Bytes, 3 ms Median-Startzeit) bleibt separater Referenzpunkt. + +### «Nicht verglichen» + +1. **GTK-Fixture-Last:** kein Datenadapter/Refresh-Timer in `mla_app.py` + (grep-Beleg) — hängt am #92-Rest; die GTK-Zellen messen den + Fixture-**Startzustand**. +2. **Flutter-Last-Zustände** (z. B. Systemmonitor-1-s-Sampler): nur per + UI-Interaktion erreichbar, unter Wayland nicht fernsteuerbar; bewusst keine + xdotool-Koordinatenklicks in die Baseline (Validitätsrisiko). + User-Entscheidung 2026-09-30 «Reduziert messen». +3. **Wayland-Startzeit = erster Protokollverkehr ≠ First-Frame** (X11 misst + Fenster-Erscheinen) → Startzeiten backend-übergreifend nicht direkt + vergleichbar. +4. **Datenquellen nicht identisch:** Flutter pollt echte Systemdaten + (df/ps/uptime/free/loadavg, 3 s), GTK zeigt statische Demo-Fixtures. +5. **Kein Binärgrößen-Ranking:** Flutter-Bundle vs. Python-Skript haben + unterschiedliche Natur (Skript braucht Python+GI-Runtime) — nur Angabe; + `la_probe` (§7: 6 547 240 Bytes, 3 ms) bleibt separater Referenzpunkt. +6. **Kein Debug-Build, keine Langlauf-/Memory-Growth-Aussage** (Langlauf ist + 0.1.x-Aufgabe). +7. Das X11-Poll-Ereignis ist „Fenster mit passendem Namen existiert im + X-Baum" (xdotool ohne `--onlyvisible`), nicht strikt „gemappt sichtbar" + (Erratum 2). +8. Die Probe-Läufe (je Task 4–5, Zeiten in den Task-Reports) waren + Skript-Validierung außerhalb der 5+5-Serien und fließen in keine Mediane + ein. diff --git a/docs/mla-next/ISSUES.md b/docs/mla-next/ISSUES.md index 06b2d1f..523761d 100644 --- a/docs/mla-next/ISSUES.md +++ b/docs/mla-next/ISSUES.md @@ -213,16 +213,16 @@ _Quelle: `docs/mla-next/AGENT_PLAN.md` (0.0.3), `docs/mla-next/IPC_CONTRACT.md`. CPU-, RAM- und Startzeit-Baseline des Flutter-Release-Builds gegen die GTK-Shell auf demselben Zorin-Rechner. Vorhanden: `la_probe` (Binär 6 547 240 Bytes, Median-Startzeit 3 ms, `BASELINE.md` §7) und die Zorin-Matrix (§1). Neu: Leerlauf und Fixture-Last für beide Varianten. ## Abnahme -- [ ] Messprotokoll in `docs/mla-next/BASELINE.md`: Kommando, Rechner, Sitzungstyp, Datum, Rohwerte -- [ ] Wiederholungen mit Median wie beim `la_probe`-Spike (5 Läufe je Variante) -- [ ] Wayland und X11 getrennt ausgewiesen -- [ ] Das Ergebnis nennt ausdrücklich, was nicht verglichen wurde +- [x] Messprotokoll in `docs/mla-next/BASELINE.md`: Kommando, Rechner, Sitzungstyp, Datum, Rohwerte — 2026-09-30: §8 (Messkommandos 1:1, Rechner-Box frisch erhoben 09:13 MESZ, Wayland-Sitzung mit XWayland `:1`, Messfenster beider Tasks, alle Rohwerte je Zelle) +- [x] Wiederholungen mit Median wie beim `la_probe`-Spike (5 Läufe je Variante) — 2026-09-30: je Zelle 5 Startup- + 5 Steady-Läufe (4 Zellen), Median-Regel wie §7; Zellen-Mediane-Tabelle in §8 +- [x] Wayland und X11 getrennt ausgewiesen — 2026-09-30: vier Zellen getrennt (Flutter/GTK × Wayland/X11); backendintern verglichen, backendübergreifend nicht gerankt (§8 Befunde b/c) +- [x] Das Ergebnis nennt ausdrücklich, was nicht verglichen wurde — 2026-09-30: „Nicht verglichen“-Box in §8 (8 Punkte: 6 Plan-Punkte wortgleich, X11-Poll-Ereignis „im X-Baum, nicht strikt gemappt sichtbar“, Probe-Läufe außerhalb der Serien) ## Handoff (Pflicht je Aufgabe, aus `docs/mla-next/VERIFY.md`) -- [ ] Basis-SHA, Pfade, Scope und Failing-Test/Fixture stehen vor der Umsetzung fest -- [ ] Reviewer 1 (Funktion/UX/Races) und Reviewer 2 (Privilegien/Secrets/argv/IPC) haben geprüft -- [ ] Wirklich ausgeführte Gates mit Ausgabe; rote oder übersprungene Gates benannt; Rückfallplan genannt -- [ ] Kein Merge, Release oder Policy-Update ohne gesonderte Freigabe +- [x] Basis-SHA, Pfade, Scope und Failing-Test/Fixture stehen vor der Umsetzung fest — 2026-09-30: SDD-Plan `docs/superpowers/plans/2026-09-30-mla-95-baseline-flutter-vs-gtk.md` (Basis `31277a2`, Branch `feature/mla-95-baseline`, Commit `5757c0d`); Messaufgabe — kein Failing-Test, Belege sind Rohwerte 1:1 und Gates +- [x] Reviewer 1 (Funktion/UX/Races) und Reviewer 2 (Privilegien/Secrets/argv/IPC) haben geprüft — 2026-09-30: je Task zwei Reviewer (A Korrektheit/B Vollständigkeit): Task 1 A APPROVED/B SPEC_OK; Task 2 A APPROVED/B NEEDS_FIXES (Lastasymmetrie-Richtung §7) → Fix → Re-Review SPEC_OK — Details in VERIFY „Handoff #95“ +- [x] Wirklich ausgeführte Gates mit Ausgabe; rote oder übersprungene Gates benannt; Rückfallplan genannt — 2026-09-30: alle Gates Exit 0 (flutter +200, la_core +60, Python 53/OK, check-versions ok; Gatetabelle in VERIFY „Handoff #95“); rot: keine; übersprungen: build-deb.sh und CI (beim späteren PR) sowie die manuellen Gate-0-Checks (BASELINE §3, bleiben separat offen); Rückfallplan `git revert` der #95-Commits (nur Doku) +- [x] Kein Merge, Release oder Policy-Update ohne gesonderte Freigabe — eingehalten: nur Commits auf `feature/mla-95-baseline`, kein Push; GitHub-#95 bleibt bis zum Merge/Freigabe offen ## Abhängigkeiten Blockiert durch: #94, #92 diff --git a/docs/mla-next/VERIFY.md b/docs/mla-next/VERIFY.md index a2439e6..7c11007 100644 --- a/docs/mla-next/VERIFY.md +++ b/docs/mla-next/VERIFY.md @@ -1,6 +1,6 @@ # MLA-Next: Verifikation und Handoff -Aktualisierung 2026-09-30: Die GTK-Scaffold-Laufzeit ist auf Zorin verifiziert (Wayland- und X11-Start — Gate 0, BASELINE §2; manuelle Checks offen), la_core-Spike und Registry sind getestet inkl. Performance-Messwerten (Gate 1, BASELINE §7). **#93 ist gemerged** (PR #89 → `6c5c625`, PR #107 → `e4c1346`; Merge-Freigabe 2026-09-30) und **#94 (Fixtures + Fehler-/Stale-Modelle) auf `feature/mla-94-fixtures` umgesetzt** (Handoff-Abschnitt unten, alle Gates grün, wartet auf Final-Review/Freigabe). Weiterhin nicht ausgeführt: IPC-/Gate-2-Tests, Flutter-vs-GTK-Vergleichsmessung (#95), manuelle Gate-0-Checks (BASELINE §3). Der Scaffold-Commit ist **kein** Release-Gate. +Aktualisierung 2026-09-30: Die GTK-Scaffold-Laufzeit ist auf Zorin verifiziert (Wayland- und X11-Start — Gate 0, BASELINE §2; manuelle Checks offen), la_core-Spike und Registry sind getestet inkl. Performance-Messwerten (Gate 1, BASELINE §7). **#93 ist gemerged** (PR #89 → `6c5c625`, PR #107 → `e4c1346`; Merge-Freigabe 2026-09-30) und **#94 (Fixtures + Fehler-/Stale-Modelle) auf `feature/mla-94-fixtures` umgesetzt** (Handoff-Abschnitt unten, alle Gates grün, wartet auf Final-Review/Freigabe). Die #95-Baselinemessung Flutter-Release vs. GTK-Shell liegt vor (BASELINE §8, Handoff #95 unten). Weiterhin nicht ausgeführt: IPC-/Gate-2-Tests, manuelle Gate-0-Checks (BASELINE §3). Der Scaffold-Commit ist **kein** Release-Gate. ## Gate 0: Scaffold @@ -384,6 +384,44 @@ unabhängig reproduziert). **Rückfallplan.** `git revert` der Task-Commits genügt: Task 2 isoliert (nur la_core-Neudatei + Barrel-Zeile), Task 1+3 gemeinsam (gemeinsame Fixture-Dateien), Task 4 reine Doku. Kein Migrationsschritt, kein Datenpfad. +## Handoff #95 — Baseline-Messung Flutter-Release vs. GTK-Shell + +**Status:** Messung vollständig (4 Zellen {Flutter-Release, GTK-Shell} × {Wayland, X11}, je 5 Startup- + 5 Steady-Läufe) und als Messprotokoll in `docs/mla-next/BASELINE.md` §8 dokumentiert. Umgesetzt auf `feature/mla-95-baseline` (Basis-SHA `31277a2`; Plan-Commit `5757c0d`, Erratum-Commit `9de72b0`, Task-3-Doku-Commit `f4a0dc0`, Review-Fix-Commit `f295c6a`). Messaufgabe: kein Code, keine Tests, kein Packaging angefasst; die vollständigen Messhelferskripte sind 1:1 in den Session-Scratch-Reports (`.superpowers/sdd/task-{1,2}-report.md`) abgedruckt; die 20er-Roh-Serien und Zellenlogs lagen ausschließlich unter `/tmp` (Reports gitignored, beides ephemeral) — §8 führt alle Startup-Einzelwerte und die je-Lauf-Steady-Mediane selbst. + +**Messfenster/Rechner.** Task 1 (Flutter-Zellen) 2026-09-30 07:41–07:58 MESZ (Release-Build 07:36:01, Probe-Läufe 07:41:28–07:50:16, serielle Zellen 07:51:54–07:57:59); Task 2 (GTK-Zellen) 08:34–08:45 MESZ (08:34:41–08:44:54). Rechner-Box frisch erhoben (BASELINE §8: i7-13620H, 16 066 996 kB RAM, Kernel 7.0.0-34-generic, Wayland-Sitzung, XWayland `:1`; keine Hostnamen — Leak-Disziplin wie bei den #94-Fixtures). Anomalie dokumentiert: der Task-2-Report §1 führt MemTotal abweichend (9 071 472 640 Bytes); die frische Erhebung (`/proc/meminfo`, `free -b`) ergibt 16 066 996 kB — §8 folgt der frischen Erhebung, die Messwerte sind davon unberührt. + +**Failing-Test/Fixture.** Keiner — Messaufgabe (Plan-Constraint 6); Belege sind die Rohwerte 1:1 (BASELINE §8) und die Gates unten. + +**Reviewer.** Je Task A (Korrektheit) + B (Vollständigkeit/Spec): +- Task 1: A APPROVED (alle 20 RESULT-Zeilen gegen die Zellenlogs nachgerechnet, Kontrolllauf ~99,9 % eines Kerns bestätigt das Dauerrendern) / B SPEC_OK (Rohwerte gegen die `/tmp`-Serien belegt, die 3 Plan-Errata verifiziert). +- Task 2: A APPROVED (Helfer diff-identisch zur Task-1-Technik, alle 10 Steady-Mediane nachgerechnet, CPU = 0 Ticks durch eigenen Kontrolllauf reproduziert) / B NEEDS_FIXES (Lastasymmetrie-Begründung §7 textlich invertiert) → Fix-Subagent (Richtung korrigiert: Flutter-Startup-Vorteil = konservative Untergrenze, GTK-Aufstellung schonend, RSS/PSS praktisch lastunabhängig — §8 Befund (e)) → Re-Review SPEC_OK. +- Task 3 (Doku): A NEEDS_FIXES (Befund (d) «Δ < 0,2 %» für PSS falsch — real RSS 0,01 %, PSS 0,51 %; Zahl 1:1 aus dem Scratch-Report übernommen ohne Nachrechnen) / B SPEC_OK (alle 4 Abnahmekriterien + Handoff-Pflicht erfüllt, alle 20 Zellen-Mediane und 9 Gates frisch reproduziert) → Fix-Subagent `f295c6a` (Delta korrigiert; Scratch-/Beleglage präzisiert; ISSUES-Spiegel um Gate-0-Ergänzung deckungsgleich) → Re-Review A APPROVED (Deltas nachgerechnet, keine Kollateralschäden, keine Leaks). +- Final-Whole-Branch-Review (`31277a2..ef702ae`, 2026-09-30): A READY_FOR_PR (alle 20 Mediane scriptgestützt nachgerechnet, Widerspruchsfreiheit quer über alle vier Dokumente, keine Critical/Important-Befunde; alle 9 Gates an `ef702ae` erneut Exit 0 mit identischen Ausgaben) / B READY_FOR_PR (Scope ausschließlich docs, Trinitäts-Diff leer, Messkommandos durchgängig unprivilegiert, Leak-Scan sauber, Grenzen-Ehrlichkeit vollständig; extern verifiziert: #95 OPEN, Branch nicht remote). Minors nur fürs Ledger. + +**Kernresultate (Mediane; Details/Rohwerte in §8).** Startup X11↔X11 (identisches Ereignis „Fenster im X-Baum“): Flutter 39 ms vs. GTK 285 ms; Wayland↔Wayland nur mit Proxy-Vorbehalt (29 vs. 63 ms, „erster Protokollverkehr“ ≠ First-Frame). CPU: Flutter ~101 % eines Kerns in allen 10 Steady-Läufen (Impeller-Dauerrendern; ~+1 %-Formelverzerrung betrifft nur Flutter), GTK 0 Ticks in 10/10 Läufen (kein Timer, grep-Beleg). RSS/PSS (Wayland-Mediane): Flutter 161 472/89 740 kB, GTK 187 972/101 166 kB. X11-Aufschlag backendintern: GTK +222 ms (63→285), Flutter +10 ms (29→39). Größen nur Angabe (Bundle 26 885 925 B, Binary 23 664 B, `mla_app.py` 3 924 B — kein Ranking). „Nicht verglichen“: 8 Punkte in §8 (6 Plan-Punkte wortgleich + X11-Poll-Ereignis „im X-Baum, nicht strikt gemappt sichtbar“ + Probe-Läufe außerhalb der Serien). + +**Gates — tatsächlich ausgeführt (2026-09-30 nach Task 3 auf `f4a0dc0`; die Fix-Runde `f295c6a` ist rein textlich in denselben drei Docs-Dateien), alle Exit 0.** + +| Gate | Ausgabe | +|---|---| +| Root `dart format --output=none --set-exit-if-changed lib test` | `Formatted 122 files (0 changed) in 0.23 seconds.` | +| `flutter analyze` | `No issues found! (ran in 2.2s)` | +| `flutter test` (voller Lauf) | `00:04 +200: All tests passed!` | +| la_core `dart pub get` | `Got dependencies!` | +| la_core `dart format --output=none --set-exit-if-changed lib test` | `Formatted 23 files (0 changed) in 0.04 seconds.` | +| la_core `dart analyze` | `No issues found!` | +| la_core `dart test` | `00:00 +60: All tests passed!` | +| `python3 -m unittest discover -s tests -t .` (additional/python) | `Ran 53 tests in 0.046s` / `OK` | +| `bash tool/check-versions.sh` | `version 0.8.0 is consistent` | + +**Rote/übersprungene Gates.** Keine roten (Messaufgabe). Übersprungen: `build-deb.sh` (kein Paketbezug; CI baut beim späteren PR), CI für den Branch (läuft mit dem späteren PR), manuelle Gate-0-Checks (BASELINE §3 — von #95 unberührt, bleiben separat offen). + +**Manuelle Zorin-Prüfung.** Für #95 nicht erforderlich — die GUI-Messungen liefen automatisiert auf dem Zorin-Zielrechner (Sitzung siehe §8-Rahmen); manuelle Gate-0-Checks bleiben separat offen. + +**Rückfallplan.** `git revert` der #95-Commits (`5757c0d`, `9de72b0`, `f4a0dc0`, `f295c6a`) genügt: reine Doku (Plan-Datei, BASELINE §8, dieser Abschnitt, ISSUES-Spiegel), kein Code, kein Datenpfad, keine Unit, kein Packaging. + +**Grenzen (bewusst offen).** Die #92-Abnahme bleibt formal offen (GTK-Datenadapter-Rest) und ist im §8-„Nicht verglichen“ benannt, nicht weggebügelt; die Flutter-vs-GTK-Entscheidung ist 0.4.x-Aufgabe (#105 nimmt diese Basis auf). + ## Agenten-Handoff Je Aufgabe: Basis-SHA, Pfade, Scope, Failing-Test/Fixture, Umsetzung, Ergebnis von Reviewer 1 (Funktion/UX) und Reviewer 2 (Sicherheit), **wirklich ausgeführte** Gates mit Ausgaben, rote/übersprungene Gates, manuelle Zorin-Prüfung, Rückfallplan. Kein Merge/Release/Policy-Update ohne gesonderte Freigabe. diff --git a/docs/superpowers/plans/2026-09-30-mla-95-baseline-flutter-vs-gtk.md b/docs/superpowers/plans/2026-09-30-mla-95-baseline-flutter-vs-gtk.md new file mode 100644 index 0000000..7725858 --- /dev/null +++ b/docs/superpowers/plans/2026-09-30-mla-95-baseline-flutter-vs-gtk.md @@ -0,0 +1,88 @@ +# SDD-Plan: #95 — Baseline-Messung Flutter-Release vs. GTK (reduzierter Schnitt) + +- **Datum:** 2026-09-30 · **Issue:** #95 ([Next 0.0.3], milestone `MLA-Next 0.0.3 – Fixtures & Baseline`) +- **Branch:** `feature/mla-95-baseline` · **Basis-SHA:** `31277a2` (main, nach Merge PR #108) +- **Freigabe:** Plan am 2026-09-30 via ExitPlanMode genehmigt (vorher User-Freigabe für Merge PR #108 + Close #94 erteilt und ausgeführt). Scope-Entscheidung des User 2026-09-30: **«Reduziert messen»** — 4 Startzustands-Zellen statt voller Last-Matrix. +- **Quellen:** `docs/mla-next/ISSUES.md` #95-Sektion, `docs/mla-next/AGENT_PLAN.md` (0.0.3), `docs/mla-next/BASELINE.md` §1/§6 Punkt 5/§7 + +## Global Constraints (für jeden Task verbindlich) + +1. **Ausschließlich unprivilegierte Kommandos.** Die polkit-Trinität (`_privilegedEntryPoints`, Policy `exec.path`, `chmod +x` in build-deb.sh) bleibt unberührt. Kein `sudo`, kein pkexec. +2. **Keine App-/Test-Codeänderungen** — #95 ist eine Mess-/Dokumentationsaufgabe. Geändert werden dürfen nur `docs/mla-next/BASELINE.md`, `docs/mla-next/VERIFY.md`, `docs/mla-next/ISSUES.md` und diese Plan-Datei (Errata). Mess-Helfer (Skripte, Rohwerte) liegen unter `/tmp` bzw. `.superpowers/sdd/` und werden **nicht** committet. +3. **Gates frisch ausführen und belegen** (nur Task 3/4 ändern Repo-Dateien; Task 1/2 belegen Build- und Messläufe): + - Flutter-Root: `dart format --output=none --set-exit-if-changed lib test && flutter analyze && flutter test` + - la_core: `cd packages/la_core && dart pub get && dart format --output=none --set-exit-if-changed lib test && dart analyze && dart test` (`pub get` vor `dart format` — sonst falsche Language-Version) + - Python: `cd additional/python && python3 -m unittest discover -s tests -t .` → `OK` + - `bash tool/check-versions.sh` +4. Conventional-Commits mit `(#95)`-Suffix, deutschsprachige Bodies wie im Repo üblich. `git status` vor jedem Commit prüfen (`.superpowers/`, `build/`, `/tmp` nie committen). +5. **Kein Push, kein Merge, kein Release** ohne gesonderte Freigabe. gh immer `-R Toqsick/master-linux-assistant`. +6. **Kein TDD-RED möglich** (kein Code) — Handoff-Box «Failing-Test/Fixture»: *keiner; Messaufgabe, Beleg sind die Rohwerte 1:1 und die Gates*. + +## Design-Entscheidungen (vom Controller gesetzt, nicht zur Diskussion im Implementer) + +### Messzellen (4) und Szenario-Definitionen + +| Zelle | Artefakt | Start-Kommando | Startzustand | +|---|---|---|---| +| Flutter × Wayland | `build/linux/x64/release/bundle/linux-assistant` | Binär direkt | Dashboard mit aktivem 3-s-Stat-Poll (`hub_shell.dart`: initialSection-Default, `setSectionActive(usesStats)` in initState) — **echte Systemdaten** | +| Flutter × X11 | dito | `GDK_BACKEND=x11 ` | dito (über XWayland `:1`) | +| GTK × Wayland | `prototype/gtk/mla_app.py` | `python3 prototype/gtk/mla_app.py` | statisches Demo-Dashboard (kein Refresh-Timer; grep-Beleg: kein `timeout_add`/`GLib.timeout`/`Thread` in mla_app.py) | +| GTK × X11 | dito | `GDK_BACKEND=x11 python3 prototype/gtk/mla_app.py` | dito | + +- **5 Läufe je Zelle, Median + Rohwerte.** Pro Lauf: Startzeit messen, 10 s Settle, dann 20-s-Fenster mit 1-Hz-Samples (RAM) und CPU-Delta (Fensteranfang/-ende). Zwischen Läufen: SIGTERM an den App-Prozess, auf Exit warten, 2 s Cooldown, Restprozess-Check (`pgrep`). +- **Gemessen wird der App-Prozess selbst** (`linux-assistant` bzw. `python3`), nie ein Wrapper. `$!` nach direktem Launch ist die App-PID (Gate-0-Lektion: keine Shell-Wrapper dazwischen). +- **Harte Vorbedingung je Lauf:** kein App-Restprozess (`pgrep -af linux_assistant`, `pgrep -af mla_app.py` leer — Self-Match der prüfenden Shell ausschließen) und unter X11 kein Fenster mit dem Suchnamen (`xdotool search --name` leer). Die installierte v0.8.0-App hat denselben Titel «Linux Assistant» und Single-Instance-Verhalten — läuft sie, würde ein zweiter Launch nur fokussieren und sofort exiten. Messung nur ab Ruhezustand. + +### Messgrößen (exakte Kommandos) + +- **Startzeit X11 — Fenster sichtbar:** + ```bash + s=$(date +%s%N); & app_pid=$! + while ! xdotool search --name "linux.assistant" >/dev/null 2>&1; do sleep 0.01; done + e=$(date +%s%N); echo $(( (e-s)/1000000 )) ms # GTK-Zelle: Suchname "Prototyp" + ``` +- **Startzeit Wayland — erster Wayland-Protokollverkehr (Proxy, Vor-First-Frame):** + ```bash + : > /tmp/mla95-wl.log + s=$(date +%s%N); WAYLAND_DEBUG=1 2>>/tmp/mla95-wl.log & app_pid=$! + while [ ! -s /tmp/mla95-wl.log ]; do sleep 0.005; done + e=$(date +%s%N); echo $(( (e-s)/1000000 )) ms + ``` + `WAYLAND_DEBUG=1` lässt libwayland-client jeden Protokollverkehr auf stderr drucken; erste Zeile ≈ Verbindungs-/Registry-Phase. Perturbation (ein fprintf) dokumentieren; **nur für die Startzeit-Läufe setzen, nicht für RAM/CPU-Läufe.** +- **RAM:** je Sample `grep -E 'VmRSS|VmHWM' /proc/$app_pid/status` und `grep '^Pss:' /proc/$app_pid/smaps_rollup`; Median der 20 Samples je Lauf. +- **CPU:** `awk '{print $14+$15}' /proc/$app_pid/stat` bei Fensterbeginn und -ende (utime+stime in Ticks; comm ohne Leerzeichen bei beiden Apps — `linux_assistan`/`python3` — Feldposition sicher); Differenz × 10 ms / 20 s → % eines Kerns. +- **Umgebung je Zelle protokollieren:** `XDG_SESSION_TYPE`, `DISPLAY`, `WAYLAND_DISPLAY`, `date -Is`, `cat /proc/loadavg` vor/nach der Zelle (Ruhe-Bedingung). +- **Bundle-Größe (nur Angabe, kein Ranking):** `du -sb build/linux/x64/release/bundle` und `stat -c '%s' build/linux/x64/release/bundle/linux_assistant`. + +### «Nicht verglichen»-Box (Kriterium 4 — geplanter Wortlaut für BASELINE §8) + +1. **GTK-Fixture-Last:** kein Datenadapter/Refresh-Timer in `mla_app.py` (grep-Beleg) — hängt am #92-Rest; die GTK-Zellen messen den Fixture-**Startzustand**. +2. **Flutter-Last-Zustände** (z. B. Systemmonitor-1-s-Sampler): nur per UI-Interaktion erreichbar, unter Wayland nicht fernsteuerbar; bewusst keine xdotool-Koordinatenklicks in die Baseline (Validitätsrisiko). User-Entscheidung 2026-09-30 «Reduziert messen». +3. **Wayland-Startzeit = erster Protokollverkehr ≠ First-Frame** (X11 misst Fenster-Erscheinen) → Startzeiten backend-übergreifend nicht direkt vergleichbar. +4. **Datenquellen nicht identisch:** Flutter pollt echte Systemdaten (df/ps/uptime/free/loadavg, 3 s), GTK zeigt statische Demo-Fixtures. +5. **Kein Binärgrößen-Ranking:** Flutter-Bundle vs. Python-Skript haben unterschiedliche Natur (Skript braucht Python+GI-Runtime) — nur Angabe; `la_probe` (§7: 6 547 240 Bytes, 3 ms) bleibt separater Referenzpunkt. +6. **Kein Debug-Build, keine Langlauf-/Memory-Growth-Aussage** (Langlauf ist 0.1.x-Aufgabe). + +### Task-sequenz + +- **Task 0 — Controller-Prep** (direkt, kein Implementer): Branch, diese Plan-Datei, Ledger-Sektion. Commit `docs(mla): SDD-Plan #95 Baseline-Messung (#95)`. +- **Task 1 — Flutter-Release-Build + Flutter-Zellen:** `flutter pub get && flutter build linux --release`; Zellen Flutter×Wayland und Flutter×X11 nach Protokoll messen (je 5 Läufe: Startzeit, RAM-Median, CPU-%, Umgebung); Rohwerte 1:1 nach `.superpowers/sdd/task-1-report.md`. Kein Commit (nur /tmp + .superpowers). +- **Task 2 — GTK-Zellen:** Wayland + X11 messen, gleiches Protokoll; Rohwerte nach `.superpowers/sdd/task-2-report.md`. Kein Commit. +- **Task 3 — Dokumentation:** `BASELINE.md` §8 «Flutter-Release vs. GTK-Shell» (Kommando, Rechner, Sitzungstyp, Datum, Rohwerte, Median-Tabelle, «Nicht verglichen»-Box wortgleich zu oben); `VERIFY.md` Gate-1-Zeile + Handoff-Abschnitt #95; `ISSUES.md` #95-Spiegel-Abnahme abhaken (soweit erfüllt). Commit. +- **Task 4 — Abschluss:** Final-Whole-Branch-Review (Reviewer A: Protokolltreue/Rohwert-Plausibilität; Reviewer B: Beweisqualität/Grenzen-Ehrlichkeit — beide als Parallel-Dispatch), alle Gates frisch, dann finishing-a-development-branch → PR-Frage an den User. + +### Boundary / bewusst draußen + +- Manuelle Gate-0-Checks (BASELINE §3) bleiben Bastis eigene, unberührt. +- #92-Abnahme bleibt offen (formale Blockade von #95); im #95-Handoff benannt, nicht «weggebügelt». +- Die Flutter-vs-GTK-**Entscheidung** selbst ist 0.4.x-Aufgabe; #95 liefert nur die Vergleichsbasis für #105. + +## Erratum (2026-09-30, nach Task 1 + Two-Reviewer-Gate) + +Drei Pin-Fehler in diesem Plan, von Implementer gefunden und von Reviewern A/B verifiziert (Belege: `.superpowers/sdd/task-1-report.md` §3): + +1. **Binärname:** Das Release-Bundle enthält `linux-assistant` (Bindestrich), nicht `linux_assistant`. Messungen/Comm-Muster entsprechend (z. B. `pgrep -f 'linux.assistant'`). +2. **X11-Fenstertitel:** `WindowManager.instance.setTitle("Linux Assistant")` (`lib/main.dart:27`) greift unter X11 nicht — `WM_NAME`/`_NET_WM_NAME` des Dev-Builds sind `linux-assistant`/`linux_assistant`. Poll-Prädikat ist das ERE `linux.assistant`; die Vorbedingung nutzt breiter `[Ll]inux.[Aa]ssistant` (deckt auch den Titel der installierten v0.8.0-App ab). Präzisierung für §8: Das Poll-Ereignis ist «Fenster mit passendem Namen existiert im X-Baum» (xdotool ohne `--onlyvisible`), nicht strikt «gemappt sichtbar». +3. **PSS-Key:** `smaps_rollup` führt den Key `Pss:` (kein `VmPss`) — `grep '^Pss:'`. + +Zusätzlich für Task 3 vorgemerkt (aus den Reviews): Rechner-Identifikation (Hostname, CPU-Modell, RAM) frisch erheben; Randbedingungen textieren (Dauer-CPU ~101 % eines Kerns durch Impeller-Dauerrendern, ~+1 %-Fenster-Verzerrung der CPU-Formel, Systemlast 4.6–8.0 während der Messung, 72-ms-X11-Startup-Ausreißer in der Serie belassen, PSS ist umgebungsvariabel/sharer-abhängig).