Updater 3.4 – Lifecycle Hardening (#28)

Production-ready updater lifecycle hardening with final-head checks, Windows PowerShell 5.1 compatibility, reproducible package generation, provenance validation, payload rollback protection and documented acceptance.
This commit was merged in pull request #28.
This commit is contained in:
Masterluke77
2026-07-10 19:54:36 +02:00
committed by GitHub
parent 40071f718e
commit 637275effc
23 changed files with 1358 additions and 413 deletions
@@ -0,0 +1,82 @@
# Abnahmebericht Vendoo Production Updater 3.4
**Status:** in technischer Abnahme
**Branch:** `feature/updater-3.4-lifecycle`
**Pull Request:** `#28`
**Zielversion:** Vendoo `1.43.0`
**Updater-Version:** `3.4.0`
## Verbindliche Ausgangslage
- `main` basiert auf dem gültigen Release aus PR #26.
- PR #27 ist geschlossen, nicht gemergt und kein zulässiger Quellstand.
- Der alte Worker 3.3 ist aus dem aktiven Release-Payload entfernt.
- Persistente Produktionsdaten unter `/app/data` sind nicht Bestandteil des Payloads.
- PR #28 bleibt bis zum vollständigen Linux-/Windows-Nachweis ein Draft.
## Ist-/Lückenanalyse Updater 3.3
| Bereich | Reale 3.3-Lücke | Umsetzung 3.4 | Nachweis |
|---|---|---|---|
| Check-Registrierung | `gh pr checks --watch` konnte bei noch nicht registrierten Checks sofort mit `no checks reported` abbrechen | eigener Check-Classifier mit 90 Sekunden Grace Period | Regressionstest und GitHub-CI ausstehend |
| Manifest-Sync | Head-SHA konnte sich nach Start der Checkphase ändern | aktuelle `headRefOid` wird in jeder Runde gelesen; Wechsel startet Grace Period und Auswertung neu | Regressionstest und Integrationstest ausstehend |
| Wiederholung nach Merge | 3.3 suchte nur offene PRs und konnte nach einem Merge erneut Sourcearbeit beginnen | gemergter passender PR führt direkt in Deployment/Verifikation | Regressionstest vorhanden, CI ausstehend |
| `main` bereits Zielversion | 3.3 erzeugte weiterhin Arbeitskopie und Releasebranch | Sourcephase wird vollständig übersprungen | Regressionstest vorhanden, CI ausstehend |
| Produktion bereits Zielversion | kein sofortiger erfolgreicher Zielzustand | sofortiger Erfolg ohne Branch, PR oder Deployment | Regressionstest vorhanden, reale Produktionsprobe ausstehend |
| veralteter Payload | Overlay plus Force-Push konnte neuere `main`-Änderungen zurücksetzen | Provenienz v2, Base-Ancestor-Prüfung und Pfadkonflikt-Guard vor dem Overlay | realer temporärer Git-Regressionstest vorhanden, CI ausstehend |
| Branch/PR-Idempotenz | Branch wurde stets neu erzeugt und unbedingt mit `--force` gepusht | deterministischer Branch, PR-Reconciliation und `--force-with-lease` | statischer Vertrag vorhanden, Windows-Lauf ausstehend |
| Check-Lifecycle | keine konkrete Workflow-Run-Auswertung am finalen Head | Rollup plus Actions-Runs nach `head_sha`, neuester Run entscheidet | Regressionstests vorhanden, GitHub-Lauf ausstehend |
| Merge-Sicherheit | kein atomarer Nachweis, dass der gemergte Head geprüft wurde | `--match-head-commit` mit unmittelbar zuvor bestätigtem finalen SHA | statischer Vertrag vorhanden, Integration ausstehend |
## Zustandsautomat
Der verbindliche Automat ist in `docs/PRODUCTION_UPDATER_3_4.md` dokumentiert. Die terminalen Zustände sind:
- `COMPLETED`: GitHub- und Produktionsziel nachgewiesen,
- `FAILED`: terminaler Pflichtcheck, Payloadkonflikt, Timeout oder technischer Fehler,
- `CANCELLED`: expliziter Benutzerabbruch mit erhaltenem Sitzungsstand.
Ein fehlender oder noch laufender Check ist kein terminaler Fehler.
## Regressionstest-Matrix
| Szenario | Erwartung | Automatisierter Test | Linux | Windows |
|---|---|---:|---:|---:|
| verspätet registrierte Checks | innerhalb Grace Period weiter warten | vorhanden | ausstehend | ausstehend |
| `queued` / `pending` / `in_progress` | nicht fehlschlagen | vorhanden | ausstehend | ausstehend |
| Manifest-Sync erzeugt neuen Head | alten Head verwerfen, neuen Head vollständig prüfen | Worker-/Lifecycle-Vertrag vorhanden | ausstehend | ausstehend |
| bereits gemergter PR | keinen zweiten PR erzeugen | vorhanden | ausstehend | ausstehend |
| bereits deployte Zielversion | sofort erfolgreich ohne Änderungen | vorhanden | ausstehend | ausstehend |
| doppelter Start | vorhandenen Zustand übernehmen | Entscheidungs- und Sessionvertrag vorhanden | ausstehend | ausstehend |
| parallele Workflow-Runs | zeitlich neuesten Run bewerten | vorhanden | ausstehend | ausstehend |
| veralteter Payload gegen neueren `main` | vor Overlay blockieren | realer temporärer Git-Test vorhanden | ausstehend | ausstehend |
| blockierter Rückschritt | Konfliktpfade ausgeben, keine Sourceänderung | vorhanden | ausstehend | ausstehend |
| älterer Erfolg, neuerer Fehler | neuer Fehler ist terminal | vorhanden | ausstehend | ausstehend |
| älterer Fehler, neuer Lauf | neuer Lauf bleibt pending | vorhanden | ausstehend | ausstehend |
| älterer Abbruch, neuer Erfolg | neuer Erfolg gilt | vorhanden | ausstehend | ausstehend |
## Releasevertrag
Vor einer Freigabe müssen nachweislich erfolgreich sein:
1. Syntax- und Sicherheitsgates unter Linux,
2. vollständiges `npm run verify:all` unter Windows,
3. PowerShell-Parserprüfung von UI, Host und Worker34,
4. Manifest-Reproduzierbarkeit,
5. Release-Staging mit `vendoo-release-package-v2`,
6. SHA-256-Prüfung aller Paketdateien,
7. Nachweis, dass der alte Worker 3.3 nicht ausgeliefert wird,
8. keine Änderung an Datenbank- oder `/app/data`-Inhalten,
9. Review des finalen PR-Head-SHA.
## Noch offene Abnahmepunkte
- GitHub-CI für den finalen PR-Head muss vollständig grün sein.
- Der Windows-Vertrag muss den echten PowerShell-Parser und alle bestehenden Tests erfolgreich durchlaufen.
- Das auslieferbare Paket darf erst danach erzeugt und als Workflow-Artefakt übernommen werden.
- Die öffentliche Produktionsantwort konnte in dieser Arbeitsumgebung noch nicht unabhängig verifiziert werden; sie ist daher kein bereits erbrachter Nachweis.
## Freigabeentscheidung
**Noch nicht freigegeben.**
Es existiert noch kein als produktionsreif deklarierter Download. Der Bericht wird erst nach finaler CI-, Paket- und Produktionsabnahme auf „bestanden“ gesetzt.
+189
View File
@@ -0,0 +1,189 @@
# Vendoo Production Updater 3.4
## Zweck
Updater 3.4 ersetzt den linearen, branchorientierten Ablauf von Updater 3.3 durch einen idempotenten Release-Lifecycle. Der Updater arbeitet auf einen nachprüfbaren Zielzustand hin und erzeugt keine weiteren Quelländerungen, sobald `main` oder die Produktion die Zielversion bereits erreicht haben.
Der Vertrag schützt insbesondere:
- den aktuellen Stand von `main` vor veralteten Payloads,
- den Pull Request vor Merge eines nicht mehr geprüften Head-SHA,
- vorhandene Releases vor doppelten Branches und Pull Requests,
- persistente Produktionsdaten unter `/app/data`,
- Datenbanken, Uploads, Benutzer, Artikel, Einstellungen, API-Schlüssel, FLUX-Modelle und Backups.
## Quellwahrheit
Der Updater wertet den Zustand in dieser Reihenfolge aus:
1. aktueller GitHub-Branch `main`,
2. aktueller Pull-Request-Head und konkrete GitHub-Workflow-Runs,
3. öffentliche Produktionsantwort `/readyz`,
4. lokaler Sitzungsstand nur als Wiederaufnahmekontext.
Ein lokaler Sitzungsstand darf niemals einen neueren GitHub- oder Produktionszustand überschreiben.
## Zustandsautomat
```text
PACKAGE_VALIDATED
-> TOOLS_READY
-> GITHUB_READY
-> TARGET_OBSERVED
TARGET_OBSERVED
-> COMPLETED
wenn main == target und production == target
-> DEPLOY_REQUIRED
wenn main == target und production != target
-> PR_RESUME
wenn ein passender offener PR existiert
-> DEPLOY_REQUIRED
wenn ein passender PR bereits gemergt ist
-> SOURCE_REQUIRED
nur wenn main noch nicht target ist und kein passender PR existiert
SOURCE_REQUIRED
-> PAYLOAD_GUARD
-> LOCAL_CONTRACT
-> TARGET_REOBSERVED
-> PR_RECONCILED
PR_RESUME | PR_RECONCILED
-> CHECKS_TRACKING
CHECKS_TRACKING
-> CHECKS_TRACKING
wenn sich der PR-Head-SHA ändert; Grace Period beginnt erneut
-> CHECKS_TRACKING
wenn Checks noch nicht registriert, queued, pending oder in_progress sind
-> MERGE_READY
wenn alle Pflichtchecks und Pflichtworkflows am stabilen finalen Head erfolgreich sind
-> FAILED
bei terminalem Pflichtfehler, Abbruch oder Gesamtzeitüberschreitung
MERGE_READY
-> MERGED
nur per --match-head-commit für den geprüften Head-SHA
-> DEPLOY_REQUIRED
-> PRODUCTION_VERIFIED
-> COMPLETED
```
## Idempotenzregeln
### Bereits aktuelle Produktion
Wenn `main` und `/readyz` bereits die Zielversion melden, endet der Updater sofort erfolgreich. Es werden weder Arbeitskopie noch Branch, Pull Request, Commit oder Deployment erzeugt.
### `main` bereits auf Zielversion
Wenn `main` bereits die Zielversion enthält, wird die Sourcephase vollständig übersprungen. Der Updater prüft nur noch, ob die Produktion nachziehen muss.
### Bereits gemergter Pull Request
Ein bereits gemergter passender Pull Request wird als abgeschlossene Sourcephase behandelt. Der Updater erzeugt keinen zweiten Pull Request und setzt beim Deployment beziehungsweise bei der Produktionsprüfung fort.
### Bereits offener Pull Request
Ein vorhandener offener Pull Request des deterministischen Releasebranches wird übernommen. Sein aktueller `headRefOid` ist die alleinige Prüfreferenz.
### Doppelter oder paralleler Start
Die Desktopoberfläche verhindert parallele lokale Prozesse per Mutex. Zusätzlich gleicht jeder Lauf GitHub und Produktion erneut ab. Ein konkurrierender Lauf, der zwischen lokaler Prüfung und Push einen Pull Request erzeugt oder `main` aktualisiert, wird bei der zweiten Zielbeobachtung erkannt und übernommen.
## Paket-Provenienz
Auslieferbare Pakete verwenden das Schema `vendoo-release-package-v2` und enthalten:
- `targetVersion`,
- `updaterVersion`,
- `sourceCommit`,
- `baseCommit`,
- `createdAt`,
- `payloadHash`,
- die vollständige SHA-256-Dateiliste,
- explizite Löschungen.
`payloadHash` wird aus den stabilen Manifestfeldern berechnet. Jede Änderung an Herkunft, Zieldateien oder Löschungen verändert die Paketidentität.
Vor dem Overlay wird geprüft:
1. `baseCommit` und aktueller `main` müssen lokal auflösbar sein.
2. `baseCommit` muss Vorfahr des aktuellen `main` sein.
3. Alle Pfade, die Payload und `main` seit `baseCommit` beide verändert haben, werden verglichen.
4. Weicht der gewünschte Payloadstand vom aktuellen `main` ab, wird der Lauf vor jeder Quelländerung blockiert.
5. Nicht kollidierende Fortschritte in `main` dürfen bestehen bleiben.
Damit kann ein altes Paket neuere Änderungen aus `main` weder still noch per Force-Push zurücksetzen.
## GitHub-Check-Lifecycle
Updater 3.4 verwendet nicht mehr `gh pr checks --watch` als Blackbox.
Für jeden aktuellen PR-Head werden ausgewertet:
- `statusCheckRollup` des Pull Requests,
- Workflow-Runs aus `actions/runs?head_sha=<finaler-head>&per_page=100`,
- die Pflichtchecks `Syntax, Sicherheit und Release-Gates`, `Windows vollständiger Releasevertrag` und `Updater-3.4-Paket nach Abnahme`,
- die Pflichtworkflows `Vendoo CI` und `Vendoo Release Manifest Sync`.
Regeln:
- `no checks reported` ist während der 90-sekündigen Registrierungs-Grace-Period kein Fehler.
- `queued`, `pending`, `in_progress`, `waiting` und `requested` sind laufende Zustände.
- Bei mehreren Runs desselben Workflows entscheidet der zeitlich neueste Run; ein alter Erfolg darf einen neueren Fehler nicht verdecken.
- Ändert der Manifest-Sync den Head-SHA, werden Grace Period und Checkauswertung für den neuen Head vollständig neu gestartet.
- Vor dem Merge wird der Head-SHA erneut gelesen.
- Der Merge verwendet `--match-head-commit`; ein weiterer Headwechsel verhindert den Merge atomar.
### Final-Head-Registrierung nach Manifest-Sync
Ein Push mit dem GitHub-Workflow-Token startet für den dadurch erzeugten Commit nicht automatisch einen weiteren Push-Workflow. Deshalb bestätigt der Manifest-Sync nach seinem Commit zuerst den tatsächlichen Remote-Head und dispatcht anschließend explizit:
1. `Vendoo CI` für den neuen Head,
2. `Vendoo Release Manifest Sync` für denselben Head.
Der zweite Manifest-Sync-Lauf findet ein unverändertes Manifest, erzeugt keinen weiteren Commit und dient als konkreter erfolgreicher Workflow-Nachweis am finalen SHA. Die Concurrency des Sync-Workflows darf den auslösenden Lauf nicht abbrechen.
### Paket erst nach Plattformabnahme
Das auslieferbare ZIP entsteht im Job `Updater-3.4-Paket nach Abnahme`. Dieser Job besitzt eine harte `needs`-Abhängigkeit auf Linux- und Windows-Abnahme. Er läuft daher erst, wenn beide Verträge erfolgreich abgeschlossen wurden. Danach werden Root-Manifest, Paketmanifest v2, Zielversion, Updater-Version und ZIP-SHA-256 erneut geprüft. Nur dieses Artefakt ist ein auslieferbarer Kandidat.
## Sitzungsvertrag
Sitzungen verwenden `vendoo-updater-session-v2`. Die Identität besteht aus:
- Repository,
- Zielversion,
- Payload-Hash,
- deterministischem Releasebranch.
Gespeichert werden unter anderem Pull-Request-Nummer und URL, finaler geprüfter Head-SHA, Merge-Commit, Produktionsversion, Releasezustand und Abschlusszeitpunkt. Der Sitzungsstand dient ausschließlich der Wiederaufnahme; jeder Lauf validiert die externen Zustände erneut.
## Branch- und Push-Sicherheit
- Releasebranch: `release/<zielversion>-production-update-v4`
- kein unbedingtes `git push --force`
- vorhandene Branches werden nur mit `--force-with-lease=<erwarteter-remote-sha>` aktualisiert
- Merge ausschließlich für den nachgewiesenen finalen Head-SHA
- kein Quell-PR, wenn `main` bereits auf Zielversion ist
## Produktionsvertrag
Das Deployment verändert keine persistenten Nutzdaten. `/app/data` bleibt außerhalb des Release-Payloads. Der Updater akzeptiert Erfolg erst, wenn `/readyz` sowohl `ok: true` als auch exakt die Zielversion meldet.
Die Option `-SkipProductionDeploy` ist ausschließlich für Source-/CI-Abnahmen vorgesehen. Sie darf nicht als Nachweis eines vollständigen Produktionsupdates ausgegeben werden.
## Fehlerdiagnose
Bei Fehler oder Timeout werden protokolliert:
- aktuelle Phase,
- aktueller PR und Head-SHA,
- Pflichtcheck- und Workflow-Matrix,
- Prozessausgabe und Exit-Code,
- Payload-Konfliktpfade,
- konkrete Wiederanlaufempfehlung.
Ein erneuter Start beginnt nicht blind von vorn, sondern beobachtet Zielzustand, Pull Requests, Merge und Produktion erneut und setzt beim tatsächlich offenen Zustand fort.