9.9 KiB
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 ueberNestFactory.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: trueset in frontmatter
Approval: pending