Files
tessera-ctl/.planning/phases/18-desktop-client-fertigstellen/18-VALIDATION.md
T

9.9 KiB

phase, slug, status, nyquist_compliant, wave_0_complete, created
phase slug status nyquist_compliant wave_0_complete created
18 desktop-client-fertigstellen draft false false 2026-09-16

Phase 18 — Validation Strategy

Per-phase validation contract for feedback sampling during execution.


Test Infrastructure

Property Value
Framework Vitest 3.2.6 (apps/api, environment: node), Vitest 4.1.9 (apps/web, environment: jsdom), Cargo/Clippy 1.96 (apps/desktop/src-tauri), POSIX sh -n fuer CI-Skripte
Config file apps/api/vitest.config.ts, apps/web/vitest.config.ts, apps/desktop/src-tauri/Cargo.toml
Quick run command pnpm --filter @tessera/api exec vitest run src/desktop · pnpm --filter @tessera/web exec vitest run src/lib/desktop.test.ts src/components/desktop src/components/settings/desktop-app-settings.test.tsx · cd apps/desktop/src-tauri && cargo check
Full suite command pnpm --filter @tessera/api exec vitest run && pnpm --filter @tessera/web exec vitest run && pnpm --filter @tessera/api type-check && pnpm --filter @tessera/web type-check
Estimated runtime ~18 seconds (Quick), ~90 seconds (Full; Web-Suite 52 Dateien / 354 Tests am 2026-09-16 plus die neuen)

biome check ist kein Tor (bekannter Fehler in der Wurzel-biome.json, nicht anfassen).


Sampling Rate

  • After every task commit: Run the quick command of the touched workspace (siehe Verification Map)
  • After every plan wave: Run pnpm --filter @tessera/api exec vitest run && pnpm --filter @tessera/web exec vitest run
  • Before /gsd-verify-work: Full suite must be green; zusaetzlich ein gruener Pipeline-Lauf mit beiden Paketen (18-05, Phasen-Tor per D-16)
  • Max feedback latency: 18 seconds (Quick); der lokale AppImage-Bau (18-01 T1/T2, 18-04 T2) und der Docker-Neubau (18-01 T1) sind bewusste Ausnahmen von mehreren Minuten

Per-Task Verification Map

Task ID Plan Wave Requirement Threat Ref Secure Behavior Test Type Automated Command File Exists Status
18-01-01 01 1 DESK-03, DESK-05 T-18-01 / T-18-02 Plattform-Whitelist vor Dateisystemzugriff; Dateiname nur aus Manifest; Namensmuster-Pruefung HTTP-Durchstich (NestFactory) + Unit pnpm --filter @tessera/api exec vitest run src/desktop ❌ W0 (apps/api/src/desktop/desktop.service.spec.ts) ⬜ pending
18-01-01 01 1 DESK-03 T-18-06 Manifest-Hash stimmt mit Datei ueberein Skript-Probe sh .gitea/scripts/desktop-collect.sh --require linux + sha256-Vergleich ✅ (Skript entsteht in der Task) ⬜ pending
18-01-01 01 1 DESK-03 T-18-01 Abbild liefert nur Manifest-Dateien, attachment-Header Integration (lokaler Docker-Stack) curl -sf http://localhost:3001/desktop/latest + Header-Check /desktop/download/linux + /api-proxy/desktop/latest ✅ ⬜ pending
18-01-02 01 1 DESK-05 — Nur rein numerische Versionen werden geschrieben (NSIS) Skript-Probe (positiv + negativ) sh .gitea/scripts/desktop-version.sh --print = 1.1.0; DESKTOP_TAG=v1.2.3-beta … --print endet mit Exit 1 ✅ (Skript entsteht in der Task) ⬜ pending
18-02-01 02 2 DESK-01, DESK-04 T-18-06 / T-18-21 publish bricht ohne Manifest ab; kein upload-artifact; Cache-Schluessel exakt am SHA Statisch (Workflow-Greps, sh -n, Probelauf) grep auf fail-on-cache-miss, needs: desktop, desktop-dist-${{ gitea.sha }} (2x), upload-artifact=0; publish-images.sh --print-plan (4 push-Zeilen) ✅ ⬜ pending
18-02-02 02 2 DESK-04 T-18-03 Token nur ueber Header-Datei, nie in einer curl-Zeile Statisch (sh -n, Probelauf, Greps) sh -n publish-release.sh; publish-release.sh --dry-run --tag v1.1.0 nennt assets?name=Tessera-1.1.0.AppImage; grep -c 'curl.*GITEA_TOKEN'=0 ✅ ⬜ pending
18-03-01 03 2 DESK-03 T-18-07 Linkziel nur aus API_URL + relativem url Unit + Komponente pnpm --filter @tessera/web exec vitest run src/lib/desktop.test.ts src/components/desktop ❌ W0 (apps/web/src/lib/desktop.test.ts, apps/web/src/components/desktop/desktop-download-links.test.tsx) ⬜ pending
18-03-02 03 2 DESK-03 T-18-08 Hinweistext statt Knoepfe ohne Manifest; Text escaped Komponente + i18n-Paritaet/Umlaut-Guard + Web-Suite pnpm --filter @tessera/web exec vitest run src/components/settings/desktop-app-settings.test.tsx …; node-Paritaetsskript (i18n OK); pnpm --filter @tessera/web exec vitest run ❌ W0 (apps/web/src/components/settings/desktop-app-settings.test.tsx) ⬜ pending
18-04-01 04 2 DESK-02, DESK-05 T-18-10 / T-18-12 Nur http/https; Opener nur mit gespeicherter server_url; Capability-Scope Compile + Clippy + Kennzeichen-Greps cargo check && cargo clippy (in apps/desktop/src-tauri); Greps auf fn check_server, api-proxy, "Öffnen", opener:allow-open-url ✅ (kein Vitest; Rust-Toolchain vorhanden) ⬜ pending
18-04-02 04 2 DESK-01, DESK-02 T-18-11 Kein Fremdcode in CSP; kein Modul-Import; keine vorbelegte Adresse Statisch + lokaler Bau Greps auf window.__TAURI__.core, invoke('check_server', unpkg.com=0; magick identify Icon-Groessen; AppImage neuer als lib.rs; desktop-collect.sh --require linux ✅ ⬜ pending
18-05-01 05 3 DESK-01, DESK-04 T-18-15 --locked Werkzeuginstallation; Reihenfolge AppImage vor NSIS Statisch Greps auf cargo-xwin (≥3), --target x86_64-pc-windows-msvc --bundles nsis, --require linux,windows; node-Reihenfolgepruefung ✅ ⬜ pending
18-05-02 05 3 DESK-01, DESK-04, DESK-05 T-18-18 Secrets im Log maskiert Manuell (Checkpoint: Orchestrator pusht und liest den Lauf) — (human-action) N/A ⬜ pending
18-05-03 05 3 DESK-01, DESK-04 T-18-17 Jede Runde ein Commit mit Ursache Statisch + Compile sh -n (drei Skripte); cargo check; git rev-list --count --grep='ci(desktop): Runde' HEAD~6..HEAD ≤ 3 ✅ ⬜ pending
18-06-01 06 4 DESK-03, DESK-05 T-18-19 / T-18-20 SmartScreen-Hinweis an Herkunft gekoppelt; keine Firmenadresse Doku-Greps Greps auf ## Desktop-App, (#desktop-app), Trotzdem ausführen, ≥9 ### im Kapitel, 0 Firmenadressen; CHANGELOG-Position (node) ✅ ⬜ pending
18-06-02 06 4 DESK-04 T-18-20 Keine Firmenadresse in neuen Abschnitten Doku-Greps Greps auf ## 10. Desktop-App, DESKTOP_DIST_DIR, /app/desktop-dist, ### Fehlerbilder, cargo-xwin (≥2), ### Desktop-App lokal bauen, Tauri-Grundgerüst=0 ✅ ⬜ pending
18-06-03 06 4 DESK-01..05 — — Gesamtlauf + Bedienprobe grep -c DESK-Eintraege = 5 und Traceability = 5; Full suite + cargo check (ALL-GREEN) ✅ ⬜ pending

Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky


Wave 0 Requirements

  • apps/api/src/desktop/desktop.service.spec.ts — HTTP-Durchstich ueber NestFactory.create(DesktopModule) mit echtem Temp-Verzeichnis: Manifest vorhanden (200), fehlt (404), unbekannte Plattform und Traversal (400, vor jedem Dateisystemzugriff), fehlende Plattform im Manifest (404), Manifest-Name mit Pfadzeichen (404), @Public()-Metadaten — entsteht in 18-01 Task 1 (DESK-03, DESK-05, T-18-01/02)
  • apps/web/src/lib/desktop.test.ts — memoisiertes Laden, still bei Fehler, desktopDownloadUrl, formatFileSize — 18-03 Task 1 (DESK-03)
  • apps/web/src/components/desktop/desktop-download-links.test.tsx — Link erscheint/verschwindet je nach API-Antwort, nur-Linux-Fall — 18-03 Task 1 (DESK-03, D-12)
  • apps/web/src/components/settings/desktop-app-settings.test.tsx — Version/Knoepfe/Groesse, Beta-Zeile, Hinweisfall — 18-03 Task 2 (DESK-03, D-12)
  • Framework install: none — Vitest ist in beiden Apps konfiguriert; Rust/Clippy und ImageMagick sind auf dem Entwicklungsrechner vorhanden (18-RESEARCH.md, Environment Availability; am 2026-09-16 geprueft)

Manual-Only Verifications

Behavior Requirement Why Manual Test Instructions
Windows-NSIS-Cross-Bau erzeugt eine gueltige .exe DESK-01, DESK-04 Kein Windows-Werkzeug lokal (kein makensis, kein cargo-xwin auf dem Entwicklungsrechner); nur in der Pipeline beweisbar (D-16) 18-05 Task 2: Orchestrator pusht, liest den Job desktop, meldet beide Dateizeilen aus "Pakete einsammeln"; Iterationsschleife max. 3 Runden
Installer laeuft auf einem Windows-PC, Erststart zeigt die Anmeldung, Tray/Schliessen/Autostart/Beenden, Einstellungsseite DESK-01, DESK-02, DESK-03 Bedienung eines echten Windows-Systems 18-06 Task 3 <human-check>, Schritte 1-10 (Nutzer)
Update-Hinweis bei neuerer Client-Version DESK-05 Braucht einen Server mit hoeherer Version als der installierte Client — erst nach dem naechsten Freigabe-Tag 18-06 Task 3 <human-check> Punkt (a): nach Tag v1.2.0 zeigt der 1.1.0-Client die Benachrichtigung und den Menueeintrag "Version 1.2.0 herunterladen"
Release-Dateien am Gitea-Release DESK-04 Upload laeuft nur bei Tags; ein Test-Tag wuerde den Live-Kanal ausloesen 18-06 Task 3 <human-check> Punkt (b): nach Tag v1.2.0 traegt der Release Tessera-Setup-1.2.0.exe und Tessera-1.2.0.AppImage; bis dahin: publish-release.sh --dry-run --tag v1.1.0 nennt die Uploads (18-02 Task 2)

Validation Sign-Off

  • All tasks have <automated> verify or Wave 0 dependencies
  • Sampling continuity: no 3 consecutive tasks without automated verify
  • Wave 0 covers all MISSING references
  • No watch-mode flags
  • Feedback latency < 18s
  • nyquist_compliant: true set in frontmatter

Approval: pending