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
5 changes: 5 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

## Checkliste
- [ ] `dotnet test tools/Nova.SimRunner.Tests` lokal grün
- [ ] **Unity-Spuren:** EditMode N/N, PlayMode M/M — oder „nicht gelaufen“ mit Grund.
Pflichtzeile, wenn der PR `Assets/_Project/Scripts/{Simulation,Core,AI,AI.Data,Data,Gameplay,Presentation}/`,
`Assets/_Project/Editor/`, `Assets/_Project/Scenes/` oder `Assets/Tests/` berührt;
sonst „nicht betroffen“. Kommando: `python3 tools/unity-tests/run_unity_tests.py all`
(siehe [CONTRIBUTING.md](../CONTRIBUTING.md) §3)
- [ ] Zeile unter `[Unreleased]` in [CHANGELOG.md](../CHANGELOG.md)
- [ ] Echte Entscheidung getroffen? → D-ID im [DecisionLog](../docs/production/DecisionLog.md), sonst streichen
- [ ] Bei Simulationsänderung: keine Determinismus-Baseline im selben PR geändert
Expand Down
30 changes: 26 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AGENTS.md – Arbeitsregeln für KI-Agenten & Mitwirkende

**Dokumentversion:** 5.0.0 | **Status:** verbindlich | **Verantwortungsbereich:** Project Owner | **Sprint:** 16 | **Governance-Tier:** 2 ([GOVERNANCE.md](GOVERNANCE.md))
**Dokumentversion:** 5.1.0 | **Status:** verbindlich | **Verantwortungsbereich:** Project Owner | **Sprint:** 16 | **Governance-Tier:** 2 ([GOVERNANCE.md](GOVERNANCE.md))

Verbindliche Betriebsanleitung für jeden KI-Coding-Agenten (Claude, Kimi, Codex,
Cursor u. a.) und jede Person, die an *Hashkrieg* arbeitet. **Lies diese Datei
Expand Down Expand Up @@ -57,6 +57,9 @@ Zusätzlich, wenn zutreffend:
stattdessen „nicht gespielt“, Grund, automatisierte Ersatznachweise und
Restrisiko nennt. Der PR ist dann mergebar, aber nicht spielerisch abgenommen
und kein Meilenstein-Nachweis.
- Unity-Auslöser berührt (§4)? → beide Unity-Spuren lokal fahren und die Zeile
„Unity-Spuren“ im PR ausfüllen; „nicht gelaufen“ samt Grund ist erlaubt, muss
aber dastehen
- Neues oder entferntes Dokument? → [docs/README.md](docs/README.md)-Index nachziehen
- Inhaber-PR? → Selbst-Merge erst nach grüner Pflicht-CI und dokumentiertem,
unabhängigem Read-only-Review.
Expand All @@ -81,9 +84,27 @@ im PATH liegt:
export DOTNET_ROOT="$PWD/.dotnet"; export PATH="$DOTNET_ROOT:$PATH"
```

Die CI führt bei jedem PR die Simulationstests aus. Unity-EditMode-Tests laufen
mangels CI-Lizenz nur lokal – wer die Präsentationsschicht anfasst, führt sie aus
und schreibt das Ergebnis in den PR.
Die CI führt bei jedem PR die Simulationstests aus. Die Unity-Spuren (EditMode
und PlayMode unter `Assets/Tests/`) laufen in keiner CI, sondern **lokal vor dem
Merge** (D-125). Auslöser ist jede Änderung unter
`Assets/_Project/Scripts/{Simulation,Core,AI,AI.Data,Data,Gameplay,Presentation}/`,
`Assets/_Project/Editor/`, `Assets/_Project/Scenes/` oder `Assets/Tests/` –
auch eine reine Simulationsänderung kann einen PlayMode-Test brechen (#141).
Zuständig ist, wer den PR vorbereitet (Orchestrator bei der Sprint-Integration),
und der Inhaber prüft die Zeile „Unity-Spuren“ beim Merge. Ein Agent in einer
Umgebung ohne Unity meldet „nicht gelaufen“ samt Grund.

```bash
python3 tools/unity-tests/run_unity_tests.py all # EditMode, dann PlayMode
python3 tools/unity-tests/run_unity_tests.py --self-test
```

Das Skript nimmt die Editor-Version aus `ProjectSettings/ProjectVersion.txt`,
bricht bei offenem Editor ab, setzt **nie `-quit`** (Unity beendet sich sonst vor
dem Testlauf, schreibt keine Ergebnisdatei und meldet trotzdem Erfolg), lässt
PlayMode mit Grafik laufen und prüft Ergebnisdatei, Frische, Testanzahl und
Fehlschläge. Es warnt außerdem vor Resten im Arbeitsbaum (`ProjectSettings.asset`,
`InitTestScene*`). Die Zahlen gibt es aus; sie stehen nirgends fest in der Doku.

## 5. Repository-Struktur

Expand Down Expand Up @@ -170,3 +191,4 @@ gh pr create --fill --base main
| 4.0.0 | 2026-08-06 | D-076: auf Governance-Tier 1 zurückgeschnitten. Gate-Kette, Receipt-Verträge und Evidenzpflicht schlafen gelegt; DoD von 13 auf 4 Punkte; Doku-Ritual freiwillig; Sprint-Ritual entfernt; `dotnet test` als kanonischer CI-Check verankert | Orchestrator |
| 4.1.0 | 2026-08-08 | D-091: Governance-Tier 2 für externe Beiträge aktiviert; Maintainer-Review/CLA für fremde PRs und Versionspflicht für Verträge/öffentliche Doku ergänzt | Dennis Westermann / Michael Falk |
| 5.0.0 | 2026-08-10 | D-105: Dennis Westermann als alleinigen Projektinhaber, Maintainer, Tier-Entscheider und Mergeberechtigten festgelegt; Selbst-Merge bei grüner Pflicht-CI und unabhängigem Review sowie ehrliche Spielabnahme-Zurückstellung geregelt | Dennis Westermann |
| 5.1.0 | 2026-10-17 | D-125 (Entwurf): Unity-Spuren als lokale Pflichtspur mit Skript, Auslöserliste, Zuständigkeit und Nachweiszeile im PR; DoD §3 und Testabschnitt §4 ergänzt (#110) | Orchestrator |
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ die Versionierung folgt (in der aktuellen Doku-Phase) dem Dokumentationsstand de
spielerisch abgenommen und kein Meilenstein-Nachweis

### Hinzugefügt
- **Unity-Spuren sind eine lokale Pflichtspur mit Skript, Auslöserliste und
Nachweiszeile im PR (D-125, Entwurf; Refs #110).** EditMode und PlayMode laufen
in keiner CI und haben das schon mehrfach gekostet (#110, #141, #143). Das neue
`tools/unity-tests/run_unity_tests.py` fährt beide Spuren in einem Kommando:
nie mit `-quit`, `-nographics` nur für EditMode, Abbruch bei offenem Editor,
alte Ergebnisdatei vorher gelöscht, danach Prüfung auf Frische, Testanzahl und
Fehlschläge, dazu eine Warnung vor Resten im Arbeitsbaum. Der Auslöser ist
breiter als bisher (auch Simulation, Editor, Szenen und Tests, nicht nur
Präsentation und Gameplay). `AGENTS.md` und `CONTRIBUTING.md` (beide 5.1.0)
und die PR-Vorlage (Pflichtzeile „Unity-Spuren“, „nicht gelaufen“ mit Grund
bleibt erlaubt) ziehen nach. `tests.yml` bleibt unverändert; eine CI-Aufnahme
nur für EditMode ist mit Wiedervorlage-Bedingungen vertagt.
- **Die KI spielt nicht mehr jede Partie gleich (D-114, Stufe A).** Bisher lief
jede lokale Partie identisch: Die KI würfelt bewusst nie, und das Menü
startete immer mit demselben Seed. Jetzt zieht „Neues Spiel“ und „Neue Runde“
Expand Down
24 changes: 20 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Beitragen zu Hashkrieg

**Version:** 5.0.0 | **Status:** verbindlich | **Verantwortungsbereich:** Project Owner | **Sprint:** 16 | **Governance-Tier:** 2 ([GOVERNANCE.md](GOVERNANCE.md))
**Version:** 5.1.0 | **Status:** verbindlich | **Verantwortungsbereich:** Project Owner | **Sprint:** 16 | **Governance-Tier:** 2 ([GOVERNANCE.md](GOVERNANCE.md))

Branch-, PR- und Review-Ablauf für Menschen und KI-Agenten. Detailregeln stehen
in [AGENTS.md](AGENTS.md), Dokumentregeln in
Expand Down Expand Up @@ -57,9 +57,24 @@ Pflicht auf jedem PR:
CLA-Zustimmung und die Freigabe des Projektinhabers auf dem aktuellen Head
vorliegen.

Unity-EditMode-Tests laufen mangels CI-Lizenz nicht automatisch. Wer die
Präsentationsschicht (`Assets/_Project/Scripts/{Presentation,Gameplay}`) anfasst,
führt sie lokal aus und schreibt das Ergebnis in den PR.
**Unity-Spuren – lokal, vor dem Merge (D-125).** Die Unity-Tests (EditMode und
PlayMode unter `Assets/Tests/`) laufen in keiner CI; es gibt dort keine
Unity-Lizenz. Wer einen PR vorbereitet, der
`Assets/_Project/Scripts/{Simulation,Core,AI,AI.Data,Data,Gameplay,Presentation}/`,
`Assets/_Project/Editor/`, `Assets/_Project/Scenes/` oder `Assets/Tests/`
berührt, fährt beide Spuren selbst – auch bei einer reinen Simulationsänderung,
die einen PlayMode-Test brechen kann (#141):

```bash
python3 tools/unity-tests/run_unity_tests.py all
```

Das Skript setzt nie `-quit` (Unity beendet sich damit vor dem Testlauf und
meldet trotzdem Erfolg), bricht bei offenem Editor ab, lässt PlayMode mit Grafik
laufen und prüft Ergebnisdatei, Frische, Testanzahl und Fehlschläge. Das
Ergebnis kommt in die Zeile „Unity-Spuren“ der PR-Vorlage. „Nicht gelaufen“
samt Grund ist erlaubt, muss aber dastehen; der Inhaber sieht es beim Merge.
Wer Unity nicht hat, sagt das, statt es zu überspringen.

## 4. Zugänge und Reviews (Tier 2)

Expand Down Expand Up @@ -156,3 +171,4 @@ sind keine Game-Releases. Es gibt bisher kein veröffentlichtes Release.
| 4.0.0 | 2026-08-08 | D-091: Tier 2 aktiviert; Maintainer-Peer-Review auf aktuellem Head für jeden PR, Fork-only plus CLA für externe Beiträge, Baseline-Wächter und zwei festgelegte Merge-Accounts dokumentiert | Dennis Westermann / Michael Falk |
| 4.0.1 | 2026-08-08 | CLA-Wirkung nicht rückwirkend präzisiert und D-ID-Pflicht auf echte Entscheidungen vereinheitlicht | Dennis Westermann |
| 5.0.0 | 2026-08-10 | D-105: `@cubetribe` als alleinigen Projektinhaber und Mergeberechtigten festgelegt; Inhaber-Selbst-Merge, externe aktuelle Freigabe und ehrliche Spielabnahme-Zurückstellung geregelt | Dennis Westermann |
| 5.1.0 | 2026-10-17 | D-125 (Entwurf): Unity-Spuren als lokale Pflichtspur mit Skript, Auslöserliste und Nachweiszeile im PR (#110) | Orchestrator |
132 changes: 132 additions & 0 deletions docs/production/DecisionLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3662,6 +3662,138 @@ berührt.
Ansturm-Gegner ab. Wer ohne Menü startet (AutoStart, Harness), spielt diesen,
nicht r8.

### D-125 | Entwurf | Unity-Spuren als lokale Pflichtspur (kein CI-Lauf)

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

**Kontext:** `.github/workflows/tests.yml` fährt ausschließlich
`dotnet test tools/Nova.SimRunner.Tests`. Die zwei Unity-Spuren unter
`Assets/Tests/` (EditMode, PlayMode) laufen in keiner CI, weil es dort keine
Unity-Lizenz gibt. Der Zustand war weder verboten noch geregelt, und er hat
mehrfach gekostet:

1. **#110:** `MainMenuTests.NetworkPanel_ValidatesMasksAndCancelsWithoutStartingGameplay`
war auf `main` rot, und niemand hat es bemerkt. Die Erwartung war seit
Sprint 14 (D-092) überholt; sie wurde mit `e3149f9` berichtigt.
2. **#141 (`e4faa75`):** ein Wirtschaftsfix, der nur `Scripts/Simulation/Economy/`
und Tests anfasste, machte `GrayboxDemoProofTests` rot. Die headless-Kette war
mit 754/754 grün, der PR wurde gemergt. Die bisherige Regel in
[CONTRIBUTING.md](../../CONTRIBUTING.md) und [AGENTS.md](../../AGENTS.md)
verlangte den Unity-Lauf nur bei Änderungen an Präsentation und Gameplay und
nannte nur EditMode.
3. **#143 (`85c912b`):** die Reparatur dazu. Aufgefallen war es nur, weil der
Orchestrator vor dem Bauen von Hand `-runTests -testPlatform PlayMode`
gefahren hat. Danach meldete er EditMode 663/663 und PlayMode 15/15.
4. **#144 (`a6858d1`)** änderte `MainMenuController.cs` und zwei `.asmdef` ohne
erwähnten Unity-Lauf.

Treffender als „läuft nirgends“ ist also: **Die Spuren laufen sporadisch, ohne
Pflicht, ohne Auslöser und ohne Zuständigen.** Dazu kommt eine Falle, die nur
in Test-Docstrings und im Graybox-Log stand: `-quit` zusammen mit `-runTests`
beendet Unity vor dem Testlauf, schreibt keine Ergebnisdatei und meldet
trotzdem Erfolg; das hat in Sprint 21 einen grünen Eindruck erzeugt, den es nie
gab. PlayMode braucht außerdem ein Grafikgerät (kein `-nographics`;
Screenshot-Capture und UI Toolkit rendern, vgl.
[GrayboxLog.md](GrayboxLog.md), `GrayboxDemoProofTests`).

Die Empfehlung des Arbeiters aus Sprint 21 (Weg A, GameCI, „EditMode und
PlayMode beide headless“) liegt nur außerhalb des Repos und ist in einem Punkt
**falsch**: PlayMode läuft nicht ohne Grafik. Sie wird hier ausdrücklich
verworfen, nicht stillschweigend übergangen.

**Alternativen:**

1. **A – GameCI `unity-test-runner` in GitHub Actions.** Ein neuer Workflow
fährt Unity `6000.5.4f1` im Docker-Image mit einem Lizenz-Secret.
- *Für:* schützt auch gegen vergessene Läufe; ein roter Check ist sichtbar.
- *Gegen:* ein Lizenz-Secret im Repo-Kontext und ein neuer Workflow sind eine
Sicherheitsfläche mit eigener Prüfung (`@ci-security-guardian`,
`@security`). Fork-PRs bekommen keine Secrets, der Check liefe gerade für
externe Beiträge nicht. Ob Unity Personal in CI zulässig ist und ob ein
Image für `6000.5.4f1` existiert, ist unverifiziert. PlayMode bräuchte
xvfb und Software-Rendering, ob die UI-Toolkit-Tests so laufen, ist
unverifiziert. Ein flackernder Pflichtcheck blockiert den alleinigen
Mergenden. Aufwand L bis XL.
2. **B – selbstgehosteter Runner auf dem Rechner des Inhabers.** Echte GPU, kaum
Kosten. *Gegen:* das Repository ist öffentlich und nimmt Fork-PRs an
(`external-contributor-review`). Der Runner würde fremden Code auf dem
Inhaberrechner ausführen; GitHub rät bei öffentlichen Repositories davon ab.
**Verworfen.**
3. **C – ausdrücklich „nur lokal, vor dem Merge“, mit Skript, Auslöserliste,
Zuständigem und Nachweiszeile im PR.** Keine Secrets, keine
Workflow-Änderung. *Gegen:* nichts erzwingt den Lauf; die Regel trägt nur,
wenn der Zuständige sie fährt. Die Zeile im PR macht ein Auslassen sichtbar,
nicht unmöglich. Aufwand M.
4. **Status quo** (nur der Satz „laufen mangels CI-Lizenz nur lokal“). Er hat
#141 nicht verhindert. **Verworfen.**

**Entscheidung:** **C**, mit vertagter Wiedervorlage von **A nur für
EditMode**.

- `tools/unity-tests/run_unity_tests.py` (`edit | play | all`, `--self-test`) ist
das eine Kommando:
- Editor-Version aus `ProjectSettings/ProjectVersion.txt`;
- Abbruch bei offenem Editor (`Library/EditorInstance.json`, Prozess lebt);
- **nie `-quit`**; `-nographics` nur für EditMode;
- alte Ergebnis-XML wird vorher gelöscht;
- danach Prüfung von Existenz, Frische, Testanzahl größer null und
`failed == 0`. Eine fehlende, leere, veraltete, kaputte oder rote Datei ist
Exit 1, ein Unity-Exitcode ungleich null ebenso;
- `git status` vor und nach dem Lauf wird verglichen und warnt vor Resten
(`ProjectSettings.asset`, `InitTestScene*`); das Skript räumt nichts auf.
- **Auslöser** ist jede Änderung unter
`Assets/_Project/Scripts/{Simulation,Core,AI,AI.Data,Data,Gameplay,Presentation}/`,
`Assets/_Project/Editor/`, `Assets/_Project/Scenes/` und `Assets/Tests/`, nicht
mehr nur Präsentation und Gameplay (Beleg: #141).
- **Zuständig** ist, wer den PR vorbereitet (bei der Sprint-Integration der
Orchestrator); der Inhaber prüft die Zeile beim Merge. Ein Agent in einer
Umgebung ohne Unity (isolierter Worktree, fremde Maschine) fährt die Spur
nicht und meldet „nicht gelaufen“.
- **Nachweis:** Die PR-Vorlage trägt die Pflichtzeile „Unity-Spuren: EditMode
N/N, PlayMode M/M — oder nicht gelaufen mit Grund“. „Nicht gelaufen“ bleibt
erlaubt, muss aber dastehen (analog zur ehrlichen Spielabnahme-Zurückstellung
aus D-105).
- **Keine Testanzahlen** in `AGENTS.md`, `CONTRIBUTING.md` oder der Vorlage;
das Skript gibt sie aus.
- `tests.yml` bleibt unangetastet. Auch der `--self-test` des Skripts läuft
nicht in der CI: ihn dort einzuhängen, hieße `.github/workflows/` ändern. Er
läuft von Hand mit dem Skript und ist ein Kandidat für die Wiedervorlage.
- **Wiedervorlage von A (nur EditMode, `-nographics`)**, sobald eine dieser
Bedingungen eintritt: (a) externe PRs werden wieder erwartet (der letzte
externe Beitragende ist seit 2026-08-21 inaktiv); (b) der Inhaber hat geklärt,
dass Unity Personal in CI zulässig ist, und ein Lizenzweg steht; (c) trotz
Pflichtzeile geht ein weiterer rot gemergter Unity-Test auf `main`. PlayMode
bleibt dauerhaft lokal.

**Begründung:** Das Projekt hat faktisch einen Entwickler und einen
Orchestrator auf dem Inhaberrechner, auf dem Unity liegt. Eine CI für PlayMode
ist ohne Grafikgerät unverifiziert, ein Lizenz-Secret plus Workflow ist eine
Sicherheitsfläche, und ein Runner auf dem Inhaberrechner (B) ist bei einem
öffentlichen Repository mit Fork-PRs zu gefährlich. Was sich heute zuverlässig
beheben lässt, ist der Zwischenzustand: ein Kommando, das nicht lügen kann
(kein `-quit`, Ergebnisdatei erzwungen), ein Auslöser, der #141 erfasst hätte,
ein Name und eine Zeile im PR. Was engine-frei ist, gehört weiterhin in die
`dotnet`-Kette (Vorbild: der Geländespiegel aus #126).

**Konsequenzen:**

- **Die Regel erzwingt nichts.** Wer die Zeile ehrlich mit „nicht gelaufen“
füllt, darf mergen lassen. Der Schutz hängt an der Prüfung des Inhabers beim
Merge. Das ist bewusst: es ist die Ehrlichkeitsregel aus
[AGENTS.md](../../AGENTS.md) Regel 5, angewandt auf Unity.
- **Das Skript läuft nur auf Rechnern mit Unity `6000.5.4f1`.** Worker in
isolierten Worktrees ohne Editor liefern „nicht gelaufen“; der Lauf bleibt
beim Orchestrator oder Inhaber.
- **Ein offener Editor blockiert den Lauf** (gewollt, mit klarer Meldung).
- **Ein Lauf kann den Arbeitsbaum verändern.** Das Skript meldet das, räumt aber
nicht auf; wer committet, prüft `git status`.
- **Beide Dokumente bekommen Version 5.1.0** und eine Verlaufszeile.
- **#110 schließt der Inhaber**, nicht dieser PR.
- **Offen und getrennt zu behandeln:** das SENTIS-Define in
`ProjectSettings.asset` (seit #143 auf `main` verloren) ist ein eigener Befund,
nicht Teil dieser Entscheidung.

## 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
Loading
Loading