Quick 260917-kgc (Plan/Recherche/Bericht/Verifikation) und Schnellfix a6d1a64
in der Quick-Task-Tabelle; Nachweise in allen sechs Berichten nachgetragen
(Playwright lokal, CI-Laeufe 382-384, Windows-Test-VM: In-App-Update
7479cb4 -> a6d1a64). Ueberholte .continue-here-Dateien entfernt,
Desktop-Client-Todo geschlossen.
Dieser Push aendert nichts unter apps/desktop -- er ist zugleich der
Beweisfall 2 des CI-Desktop-Skips (Pakete aus dem Zwischenspeicher).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016g2npLxzH5gZpg8s2S6vKh
spawn_version_check setzt den Tray-Eintrag und den abgelegten PendingUpdate-Stand zu Beginn jeder Pruefung zurueck (Server-Wechsel darf keinen alten Hinweis stehen lassen)
In der laufenden App (oder einem AppHandle-Mock) zweimal hintereinander die Server-Adresse wechseln, waehrend ein Update-Fund im State liegt, und pruefen, dass der Eintrag sofort auf den Standardtext springt und PendingUpdate leer ist, bevor die neue Pruefung antwortet
Menuetext == UPDATE_ITEM_DEFAULT, Eintrag gesperrt, PendingUpdate == None unmittelbar nach dem Wechsel
Die 33 Unit-Tests decken ausschliesslich die reinen Helfer (is_update_newer, beta_commit, update_endpoint, release_labels, update_labels, parse_server_url, server_host, tray_labels, setup_page_url, with_desktop_marker) ab; spawn_version_check haengt an AppHandle/TrayItems/PendingUpdate-State und wird von keinem Test aufgerufen — Reset-Verhalten ist nur am Laufzeit-Client oder mit einem Tauri-Mock zu beobachten
truth
test
expected
why_human
Tray-Klick 'update' nimmt den abgelegten Stand per take() (verhindert Doppelklick-Downloads), laedt mit Fortschritt im Menuetext, installiert (Windows NSIS passiv / Linux AppImage) und startet neu; bei Fehler springt Menuetext/Stand zurueck und der Browser-Rueckfall oeffnet
Am echten (oder in der Windows-VM installierten) Client: Update-Fund abwarten, Tray-Eintrag zweimal schnell hintereinander anklicken, danach den vollen Ablauf bis zum Neustart beobachten; anschliessend denselben Ablauf mit einem absichtlich fehlerhaften Download (z. B. Netz trennen) wiederholen
Zweiter Klick loest keinen zweiten Download aus (Eintrag bleibt gesperrt); bei Erfolg Fortschritt 'Laedt ... N %' -> 'Wird installiert...' -> Neustart auf neuem Stand; bei Fehler Menuetext/Stand zurueck, Eintrag wieder aktiv, Benachrichtigung 'Update fehlgeschlagen: ...' und Einstellungsseite im Browser
spawn_update_install und der Menue-Zweig 'update' (take()-Semantik, download_and_install, app.restart()) werden von keinem Unit-Test ausgeloest — das ist explizit als offener Orchestrator-Nachweis (Windows-VM) im PLAN/SUMMARY vermerkt und braucht ein vom CI signiertes Paket
test
expected
why_human
(a) CI-Bau auf main: beide tauri-build-Schritte mit den Secrets TAURI_SIGNING_PRIVATE_KEY/_PASSWORD durchlaufen lassen
'Pakete einsammeln' loggt 'signiert' fuer linux und windows; Manifest im Abbild traegt updateVersion (X.Y.Z-beta.g<sha7>) und je Plattform signature; Job publish gruen; alter Stempel-Cache (ohne die Felder) wird verworfen (Neubau)
Nur im Gitea-Runner beweisbar (Secrets, echte tauri-CLI, Cross-Bau-Toolchain) — lokal simuliert per Mini-Fixture-Proben (siehe unten), aber nicht der echte Bau
200 mit version, absoluter url (.../api-proxy/desktop/download/windows), signature, pub_date, notes; target=linux analog; base=https://alpha.tessera.ctl.de/x -> 400; vor dem Pull des neuen Abbilds noch 404 (Route existiert nicht)
Braucht den laufenden Server mit dem neuen Abbild — nicht lokal simulierbar
test
expected
why_human
(c) Windows-VM (8233): bereits installierter Client 1.2.0 aktualisiert sich per Tray-Klick, sobald ein neuer signierter Beta-Bau auf dem Server liegt
Benachrichtigung 'Neuer Beta-Stand <sha7> verfuegbar', Eintrag 'Auf Beta-Stand <sha7> aktualisieren'; Klick -> Fortschritt im Menuetext -> passives NSIS-Fenster -> Tessera startet neu, Tray zeigt neuen Stand, Server-Adresse bleibt erhalten; SmartScreen-Verhalten notieren
Reale Installation/Neustart/Betriebssystem-Verhalten (SmartScreen) ist nur am Bildschirm zu pruefen; Client 1.2.0 hat das Plugin noch nicht, der erste Wechsel muss einmal ueber den Browser laufen (Einmaliger Wechsel, wie im Anwenderhandbuch dokumentiert)
test
expected
why_human
(d) Cross-Bau von ring/rustls (x86_64-pc-windows-msvc, cargo-xwin) in der CI-Pipeline
Bau gruen; Fallback bei rotem Bau: tauri-plugin-updater mit default-features = false, features = ["native-tls", "system-proxy"]
Nur im Runner mit der echten xwin/Clang-Toolchain beweisbar
Quick Task 260917-kgc: Desktop-Client — Update in der App Verifizierung
Ziel: Der Desktop-Client aktualisiert sich selbst per Tray-Klick (tauri-plugin-updater 2, minisign-Signaturpruefung, Endpunkt zur Laufzeit aus der gespeicherten Server-Adresse); API GET /desktop/update liefert das Format im Updater-Vertrag; Manifest/CI signieren und stempeln entsprechend; Doku + CHANGELOG.
Verifiziert: 2026-09-17
Status: human_needed
Hinweis: Kein einziger truth ist FEHLGESCHLAGEN. Die zwei offenen Punkte sind Laufzeitverhalten (Zustandswechsel/Installation), die von keinem der bestehenden Unit-Tests ausgeloest werden koennen und laut PLAN/SUMMARY selbst als "Nachweis durch Orchestrator" gefuehrt werden (Windows-VM, echtes CI-Paket). Das ist keine Luecke in der Umsetzung, sondern der erwartete Zustand fuer diesen Task-Typ.
spawn_version_check: check() mit eigenem Comparator, 15 s Pruefung, 600 s Download-Timeout vor Ablage, InsecureTransportProtocol -> gesperrter Text, Reset zu Beginn
⚠️ PRESENT_BEHAVIOR_UNVERIFIED
Code exakt wie gefordert (Z. 263-338), Timeout-Trennung im Code bestaetigt; kein Test ruft die Funktion auf (State-Reset ist ein Laufzeit-Zustandswechsel)
Code exakt wie gefordert (Z. 352-411, 591-601); kein Test loest den Menue-Zweig/spawn_update_install aus — explizit als offener Windows-VM-Nachweis im PLAN gefuehrt
6
API GET /desktop/update: base-Origin-Validierung 400, 204-Faelle, dynamisches Format, /latest und download unveraendert
✓ VERIFIED
23/23 vitest-Tests selbst ausgefuehrt, Route-Order-Gate bestanden, Code gelesen (safeOrigin, getUpdate, UPDATE_VERSION_RE, RFC3339_RE) — deckt sich exakt mit dem Vertrag
7
desktop-collect.sh schreibt signature+updateVersion mit Pflichtregel; desktop-stamp.sh check verlangt beides
✓ VERIFIED
Alle Mini-Fixture-Proben aus dem PLAN selbst nachgestellt (Beta/Live/Dev-Kanal, fehlende .sig auf main/Tag/mit Schluessel -> Abbruch, dev -> Warnung, zweizeilige .sig -> Abbruch, stamp reuse=true/false-Faelle) — alle bestanden
8
CI: Secrets nur an den zwei tauri-build-Schritten, kein Job-env, kein --no-sign, sonst strukturgleich
✓ VERIFIED
js-yaml-Tiefenvergleich gegen git show 5a444ec:.gitea/workflows/ci.yml selbst ausgefuehrt — CI-OK; Negativ-Grep --no-sign leer; .gitignore traegt *.key; git ls-files '*.key' leer
Hinweis zu Wahrheit 3 (kein coincidental reliance)
Die is_update_newer-Regel wird von acht dedizierten Tests direkt und unmittelbar geprueft (kein Fixture-Only-Fall, keine unbekannte Vorbedingung) — als sauber VERIFIED eingestuft, keine Advisory-Markierung noetig.
Artefakt-Pruefung
Artefakt
Erwartet
Status
Details
apps/desktop/src-tauri/src/lib.rs
Updater-Kette, Helfer, Tests
✓ VERIFIED
Alle geforderten Symbole vorhanden (is_update_newer, beta_commit, update_endpoint, release_labels, spawn_update_install, open_download_page, PendingUpdate, download_and_install, version_comparator); DesktopLatest entfernt, /desktop/latest nicht mehr referenziert
Eigenstaendig im Scratchpad nachgestellt (siehe PLAN Task 3 <verify>)
Alle 15 Teilpruefungen gruen
✓ PASS
Doku-Grep-Gates (14 Pruefungen)
siehe PLAN Task 4 <verify>
Alle gruen
✓ PASS
changelog.test.ts
pnpm --filter @tessera/web exec vitest run src/lib/changelog.test.ts
10/10 gruen
✓ PASS
Secret-Leck-Pruefung
grep auf private-key-Werte im Diff
Nichts gefunden
✓ PASS
.key-Dateien im Repo
git ls-files '*.key'
leer
✓ PASS
Requirements Coverage
Requirement
Quelle
Beschreibung
Status
QUICK-260917-KGC
260917-kgc-PLAN.md
Desktop-Client Update in der App (siehe Task-Ziel)
✓ SATISFIED (bis auf die zwei Laufzeit-Nachweise, siehe oben)
Anti-Pattern-Scan
Keine TBD/FIXME/XXX-Debt-Marker (der einzige Treffer auf "XXXX" ist ein Doc-Kommentar-Beispiel 1.2.0-beta.gXXXX, kein Debt-Marker); keine TODO/HACK/PLACEHOLDER; keine "not implemented"-Stellen ausser zwei bereits bestehenden, legitimen NotFoundException-Meldungen ("Desktop packages are not available on this server"). Keine unerwarteten Dateien ausserhalb files_modified veraendert (3 generierte gen/schemas/*.json-Dateien sind dokumentierte Abweichung, Praezedenz aus Phase 18-04).
Erforderliche menschliche Verifizierung
Siehe human_verification im Frontmatter — die vier vom Orchestrator selbst als offen gefuehrten Nachweise (a) CI-Bau mit echten Secrets, (b) Endpunkt-curl gegen alpha, (c) Windows-VM Update-Durchlauf, (d) Cross-Bau ring/rustls. Diese sind keine Luecken, sondern der erwartete naechste Schritt nach diesem Quick Task (siehe SUMMARY.md "Nachweis durch Orchestrator (offen)").
Zusammenfassung
Alle zehn must_haves.truths sind im Code vorhanden, exakt wie im PLAN spezifiziert verdrahtet, und alle automatisierten Gates (Rust fmt/clippy/test, API-Tests/Type-Checks, Skript-Proben, CI-Deep-Compare, Doku-Grep-Gates, Changelog-Test) wurden von mir selbst ausgefuehrt und bestanden — keine SUMMARY-Behauptung wurde ungeprueft uebernommen. Zwei Wahrheiten (State-Reset bei Server-Wechsel, Tray-Klick-Installationsfluss inkl. take()-Semantik) haengen an Tauri-Laufzeitzustand, den keiner der 33 Unit-Tests ausloest; das deckt sich mit den vier vom Orchestrator selbst als offen gefuehrten Nachweisen und ist fuer einen Quick Task dieser Art normal, nicht ein Zeichen unvollstaendiger Umsetzung.
Verifiziert: 2026-09-17Verifizierer: Claude (gsd-verifier)