Updater 3.4 – Lifecycle Hardening #28

Merged
Masterluke77 merged 96 commits from feature/updater-3.4-lifecycle into main 2026-07-10 17:54:37 +00:00
Showing only changes of commit e661bc902f - Show all commits
+176
View File
@@ -0,0 +1,176 @@
# 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` sowie `Windows vollständiger Releasevertrag`,
- 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.
## 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.