Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ die Versionierung folgt (in der aktuellen Doku-Phase) dem Dokumentationsstand de
sie belegt keine Verbesserung.

### Geändert
- **Beta-Pakete nur aus sauberem Baum: harte Sperre in `build-mac.sh` und
`build-linux.sh`.** Unsauberer Arbeitsbaum bricht vor dem Unity-Aufruf ab
(`--allow-dirty` als Ausweg, `-dirty` im Stempel bleibt, `build-mac.sh --fast`
ausgenommen). `--skip-build` prüft dasselbe und vergleicht gegen die neue
Sidecar-Datei `Builds/<Plattform>/.build-commit`. HEAD ≠ `origin/main` ist nur
eine Warnung, offline bricht nichts ab. Neu: `--check-only`. README 2.0.0 →
2.1.0 mit Bauort-Hinweis. Entwurf D-124 (#132)
- **Die lebende Dokumentation heißt jetzt Hashkrieg (#14, Stufe 3).** 54 Dateien,
84 Stellen — die Marke in der Prosa unter `docs/**` und in den Wurzeldateien.
Zwei Regeln haben den Umfang bestimmt. Erstens **E-3: nur die Marke.** Die
Expand Down
78 changes: 78 additions & 0 deletions docs/production/DecisionLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3662,6 +3662,84 @@ berührt.
Ansturm-Gegner ab. Wer ohne Menü startet (AutoStart, Harness), spielt diesen,
nicht r8.

### D-124 | Entwurf | Beta-Pakete nur aus sauberem Baum (harte Sperre in den Packaging-Skripten)

**Status:** Entwurf aus dem Issue-Lauf vom 2026-10-17 (#132); verbindlich mit dem
Merge des PR. Die Endnummer vergibt der Integrator.

**Kontext:** Issue #132 beschreibt eine Falle: eine untrackte Datei unter
`Assets/` (`InputGateDiagnostic.cs`) kompiliert in jeden Build aus der
Arbeitskopie, nicht aber aus einem frischen Klon. Teil 1 (die Datei) ist
überholt — sie liegt in keiner Arbeitskopie mehr und war nie getrackt. Teil 2
(Betas nur aus sauberem Stand) stand bisher nur in
`tools/packaging/README.md`; `build-mac.sh` und `build-linux.sh` hängten bei
unsauberem Baum lediglich `-dirty` an und warnten. `--skip-build` schrieb
außerdem das Etikett des aktuellen Commits auf einen beliebig alten Build. Der
Editor-Hook `BuildCommitStamp` stempelt `-dirty` für den ganzen Baum
(`git status --porcelain`), also auch für harmlose untrackte Dateien.

**Alternativen:**

1. **Status quo** (Doku plus `-dirty`-Stempel). Kostenlos, aber die Regel wird
nicht erzwungen: ein `-dirty`-Paket kann rausgehen, und ein Tester meldet
dann ein Verhalten, das kein anderer Rechner reproduziert.
2. **Harte Sperre in den Skripten** vor dem Unity-Aufruf, `--allow-dirty` als
bewusster Ausweg, Sidecar-Datei für `--skip-build`. Klein, wirkt dort, wo
Pakete entstehen, und lässt den Editor-Code unberührt. Preis: Pakete aus
der Arbeitskopie mit Art-Änderungen gehen nur noch mit `--allow-dirty`.
3. **Eigenes Klon-Skript**, das `origin/main` in ein Scratch-Verzeichnis klont
und dort baut. Strengste Garantie, aber Unity-Kaltimport bei jedem Lauf und
ein zweiter Pfad neben den bestehenden Skripten; ohne Art-Paket im Klon
zeigt der Beta Graybox.
4. **Abbruch im Editor-Build-Hook** (`BuildCommitStamp`). Würde auch
Editor-Builds sperren und braucht Unity-Code, der in keiner CI läuft.

**Entscheidung:** Alternative 2.

- Beide Skripte prüfen **vor** jedem Unity-Aufruf `git status --porcelain` über
den ganzen Baum (deckungsgleich mit `BuildCommitStamp`) und brechen bei
nicht leerer Ausgabe ab. `--allow-dirty` erlaubt den Lauf, der Stempel behält
`-dirty`. `build-mac.sh --fast` (lokale Iteration, kein DMG) ist ausgenommen
und stempelt ebenfalls `-dirty`.
- Nach einem erfolgreichen Unity-Build steht `Builds/<Plattform>/.build-commit`
(voller HEAD, Zustand `clean`/`dirty`). `--skip-build` läuft durch dieselbe
Prüfung und bricht ab, wenn die Datei fehlt oder nicht zu HEAD und Zustand
passt. Die Datei kommt nicht ins Linux-`tar.gz`.
- HEAD ≠ `origin/main` (nach `git fetch origin main`) ist **nur eine Warnung**.
Ein fehlgeschlagener Fetch (offline) bricht nichts ab. Ob ein Release-DMG
zwingend `main` sein muss, ist damit bewusst nicht entschieden.
- Neue Option `--check-only` beider Skripte: nur Prüfungen, Ausstieg vor Unity.
- Bauort: frischer Worktree von `origin/main` samt `skip-worktree` auf
`AssetMappingRegistry.asset`, weil `ArtAssetAutoSync` sie beim Import
verändert. README 2.0.0 → 2.1.0.
- Teil 1 von #132: die Datei wird nicht eingecheckt; der Inhaber bestätigt
außerhalb des Repos, dass auf keinem Rechner eine Kopie liegt.

**Begründung:** Die Sperre sitzt dort, wo Pakete entstehen, und kostet keinen
Editor-Code. Dass sie vor Unity greift, spart den teuren Lauf, und der Sidecar
schließt die Lücke, durch die ein alter Build ein neues Etikett bekam. Dass die
Prüfung den ganzen Baum erfasst und nicht nur build-relevante Pfade, ist
absichtlich: es ist dieselbe Definition wie im Stempel, und eine Pfadliste
würde genau die Falle wieder öffnen, die das Issue beschreibt (untrackte
Dateien unter `Assets/`).

**Konsequenzen:**

- Ein Beta-Paket aus der Arbeitskopie mit Art-Änderungen bricht ab. Der Weg ist
ein frischer Worktree von `origin/main`; für lokale Pakete gibt es
`--allow-dirty`.
- Auch harmlose untrackte Dateien (Screenshots, `.playwright-mcp/`) sperren
ein Vollpaket. Das ist der Preis der deckungsgleichen Definition.
- Die Prüfung sieht den Stand vor dem Unity-Lauf. Verändert Unity den Baum
beim Import (Registry), stempelt der Editor-Hook `-dirty`, obwohl das Skript
„clean“ gesehen hat — daher `skip-worktree` im Bauort-Worktree.
- Nicht Teil der Entscheidung: die gitignorierte Kopie `tools/build/build-mac.sh`
(der Inhaber löscht sie lokal) und eine Pfadbegrenzung auf build-relevante
Dateien.
- Die Skripte laufen in keiner CI. Geprüft ist die Vorstufe (Sauberkeit,
Sidecar, Fetch) in einem Wegwerf-Repo; die Unity-Erzeugung und das
Schreiben des Sidecars nach einem echten Build sind nicht gelaufen.

## Offene Punkte

- Alle Sprint-4-Review-Befunde (105, davon 9 kritisch): 7 entscheidungsbedürftige kritische Befunde sind durch D-043–D-052 entschieden.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
issue: 132
paket: P-132
branch: chore/132-enforce-clean-beta-builds
agent: builder (sonnet)
datum: 2026-10-17
status: DONE
---
# Beta-Pakete nur aus sauberem Baum (#132)

## Aufgabe
Die Regel „verschickt wird nur, was aus einem sauberen Commit fällt“ stand nur in der README. `build-mac.sh` und `build-linux.sh` hängten bei unsauberem Baum nur `-dirty` an, und `--skip-build` stempelte einen alten Build mit dem aktuellen Commit. Umgesetzt: harte Sperre vor dem Unity-Aufruf, `--allow-dirty`, Sidecar-Datei für `--skip-build`, Warnung bei HEAD ≠ origin/main. Teil 1 von #132 (InputGateDiagnostic.cs) ist überholt, nichts zu tun.

## Was geändert wurde — Files Changed
- tools/packaging/build-mac.sh — neuer Schritt „Quellstand“ vor Unity: Abbruch bei `git status --porcelain` ≠ leer, `--allow-dirty`, `--check-only`, Sidecar-Prüfung bei `--skip-build`, Sidecar schreiben nach Unity-Build, origin/main-Warnung; `--fast` ausgenommen (behält `-dirty`)
- tools/packaging/build-linux.sh — dasselbe (ohne `--fast`, das Linux nicht kennt); Sidecar wird aus dem `tar.gz` ausgeschlossen
- tools/packaging/README.md — 2.0.0 → 2.1.0: Optionstabelle, Abschnitt „Nur aus sauberem Baum“ statt der alten Absatzregel, Bauort (frischer Worktree von origin/main, skip-worktree auf `Assets/_Project/Data/Registries/AssetMappingRegistry.asset` wegen ArtAssetAutoSync), Verlaufszeile
- docs/production/DecisionLog.md — Entwurf D-124 vor „## Offene Punkte“ (Kopfversion/Verlauf nicht angefasst)
- CHANGELOG.md — eine Zeile unter [Unreleased] / Geändert (#132)

## Tests und Prüfungen
- `bash -n` auf beide Skripte: ok.
- `dotnet test tools/Nova.SimRunner.Tests/Nova.SimRunner.Tests.csproj -c Release`: 778/778 grün (Baseline unverändert, keine C#-Änderung).
- `python3 .github/scripts/check_docs.py`: OK, 203 Markdown-Dateien, 5 Quality-JSONs.
- `python3 .github/scripts/check_baseline_guard.py --self-test`: bestanden.
- Shell-Gegenprobe (läuft in keiner CI) in einem Wegwerf-Repo mit Bare-Origin unter dem Scratchpad (Skripte hineinkopiert, `--check-only` bzw. Fake-Linux-Player):
- sauberer Baum: beide Skripte Exit 0, „HEAD = origin/main“
- untrackte Datei: beide Exit 1 mit Pfadliste, vor Unity
- `--allow-dirty`: Exit 0, Stempel `b4a7bca-dirty`; mac `--fast` unsauber ebenso
- Linux `--skip-build`: ohne Sidecar Exit 1; Sidecar mit falschem HEAD Exit 1; Zustand dirty vs. clean Exit 1; passender Sidecar Exit 0
- Linux `--skip-build` vollständig durchgelaufen (Fake-Player): Archiv enthält keine `.build-commit`, Stempel im Archiv stimmt; Wegwerf-Repo bleibt sauber (Builds/ ignoriert)
- mac `--skip-build` ohne Sidecar: Exit 1
- Fetch auf nicht existierende URL bzw. ohne `origin`: kein Abbruch, Hinweis/Warnung; HEAD ≠ origin/main: nur Warnung, Exit 0
- NICHT gelaufen: echter Unity-Build, Schreiben des Sidecars nach einem echten Build (Zweig nach dem Unity-Aufruf), Signieren/Notarisieren/DMG, mac `--skip-build` mit passendem Sidecar bis zum Ende (braucht Unity unter /Applications), echtes Verhalten von ArtAssetAutoSync nach Import. Unity-Tests: keine angelegt.

## Entscheidung
D-124 (Entwurf): Alternative 2, harte Sperre in den Skripten; verworfen: Status quo, Klon-Skript, Abbruch im Editor-Hook. HEAD ≠ origin/main bleibt Warnung. Siehe docs/production/DecisionLog.md.

## Nebenbefunde
- Die gitignorierte Kopie tools/build/build-mac.sh im Hauptarbeitsbaum bleibt ohne Sperre (nicht angefasst; Inhaber löscht sie lokal).
- Der Editor-Hook BuildCommitStamp stempelt `-dirty`, wenn Unity die AssetMappingRegistry beim Import verändert, obwohl das Skript „clean“ sah. Abhilfe steht in der README (skip-worktree), nicht im Code.
- Auch harmlose untrackte Dateien (z. B. `.playwright-mcp/` im Hauptbaum) sperren künftig ein Vollpaket.
- Die Triage nannte Art-Branch-Dateien (ArtViewScale.cs usw.) als untrackt-kompilierend: gleiche Falle wie #132, nicht Teil dieses Pakets.
- P-14 (Welle 4) benennt Build-Namen in denselben Skripten/README um und läuft danach; mögliche Merge-Konflikte in den Header-Zeilen.

## Offene Fragen an den Inhaber
- Soll `build-mac.sh --fast` wirklich von der Sperre ausgenommen sein (so umgesetzt) oder auch `--allow-dirty` brauchen?
- Muss ein Release-DMG zwingend HEAD = origin/main sein (dann Warnung zu Abbruch machen)?
- Teil 1 von #132: Bestätigung, dass auf keinem Rechner eine Kopie von InputGateDiagnostic.cs liegt; Kommentar zu #132 nur mit Freigabe.

## Vorschlag für Commit-Titel und PR-Beschreibung
Commit: `build(packaging): refuse beta packages from a dirty tree (#132)`

PR-Beschreibung:
- Was: build-mac.sh/build-linux.sh brechen vor Unity bei unsauberem Baum ab; `--allow-dirty` (Stempel `-dirty`), `--check-only`; `--skip-build` vergleicht gegen `Builds/<Plattform>/.build-commit`; HEAD ≠ origin/main nur Warnung, offline robust; README 2.1.0 mit Bauort.
- Warum: Die Regel stand nur in der Doku; ein Build aus der Arbeitskopie ist nicht reproduzierbar (#132). Entwurf D-124.
- Bereiche: tools/packaging, README, DecisionLog, CHANGELOG. Keine C#-, keine Simulationsänderung.
- Changelog: Geändert, „Beta-Pakete nur aus sauberem Baum …“ (#132).
- Unity-Spuren: nicht gelaufen (kein Unity-Build, kein Unity-Test). Shell-Gegenprobe im Wegwerf-Repo gelaufen, siehe oben.
- Spielabnahme: nicht gespielt; Restrisiko: Sidecar-Schreiben nach echtem Unity-Build und der macOS-Pfad ab Unity sind unverifiziert.
Loading
Loading