Initial project version
Aegis CI / audit (push) Failing after 1m7s
Aegis CI / selfplay (push) Skipped
Aegis CI / perf (push) Failing after 3s
Aegis CI / report (push) Failing after 2s

This commit is contained in:
2026-08-29 01:45:19 +02:00
commit ea2a2f2cbf
21 changed files with 2830 additions and 0 deletions
+188
View File
@@ -0,0 +1,188 @@
# 04 Resultate & Report (Ausgabe-Dateien)
> Schema-Referenz für alle Artefakte der Test-Suite und Aufbau des generierten `report.html`.
> Diese Dateien werden **zur Laufzeit erzeugt** und **nicht versioniert** (→ `.gitignore`).
---
## 1. Übersicht der Artefakte
| Datei | Erzeugt von | Zweck |
|---|---|---|
| `audit-result.json` | `tests/audit.mjs` | Raw-Reports der 3 Audits + Assertions + Page-Errors + Summary |
| `selfplay-results.json` | `tests/selfplay.mjs` | Episoden-Log + Win-Rate + Aggregates |
| `perf-result.json` | `tests/perf-test.mjs` | FPS, Heap, Setup-Metadaten |
| `report.html` | `tests/report.mjs` | Zusammengefasster, menschlich lesbarer CI-Report |
| `audit-final.png` | `tests/audit.mjs` | Finaler Screenshot des Headless-Browsers |
> `report.mjs` liest die drei `*-result.json` und rendert daraus ein einzelnes `report.html`.
> Fehlt eine JSON-Datei, zeigt `report.html` für die entsprechende Sektion „no data".
---
## 2. `audit-result.json`
```json
{
"timestamp": "2026-08-28T19:20:00.000Z",
"self": {
"connectivity": [
{ "level": 0, "name": "…", "reachable": true }
],
"attacks": [
{ "id": "sniper", "projectiles": 12, "hits": 10 }
],
"skills": [
{ "id": "…", "rank": 4 }
],
"placement": { "wall": true, "path": true },
"autoWave": true,
"endlessTransition": true
},
"extension": {
"mortarSplashTargets": 2,
"teslaAoE": { "targets": 5, "frozen": true },
"rewardDedup": true,
"blockerAltPath": true,
"blockerClosedPath": true
},
"redesign": {
"sniperPriority": true,
"quantumBeam": { "aligned": 3, "offLineUnharmed": true },
"nanoSpawner": { "limit": true, "damage": true, "cleanup": true }
},
"pageErrors": [],
"assertions": [
{ "name": "self.connectivity.allReachable", "pass": true },
{ "name": "self.attacks.noZeroProjectiles", "pass": true },
{ "name": "self.skills.allRank4", "pass": true }
],
"summary": {
"total": 12,
"pass": 12,
"fail": 0
}
}
```
> **Exit-Code-Kopplung:** `audit.mjs` beendet sich mit `1`, sobald `summary.fail > 0`
> oder `pageErrors` nicht leer ist. Ein harter Crash im Browser führt zu `2`.
---
## 3. `selfplay-results.json`
```json
{
"timestamp": "2026-08-28T19:30:00.000Z",
"episodes": [
{
"placed": 40,
"towerCount": 40,
"maxKills": 120,
"waveReached": 8,
"totalUpgrades": 64,
"finalState": "victory",
"finalKills": 120,
"finalLeaked": 0,
"finalLives": 20
}
],
"summary": {
"total": 10,
"wins": 8,
"losses": 2,
"winRate": 80.0,
"avgKills": 118,
"avgWaves": 7.4
}
}
```
**Felder:**
| Feld | Bedeutung |
|---|---|
| `placed` | Anzahl tatsächlich platzierter Türme in der Episode |
| `towerCount` | Endgültige Turm-Anzahl (inkl. Spawner) |
| `maxKills` | Höchststand an Kills während der Simulation |
| `waveReached` | Letzt erreichte Wave |
| `totalUpgrades` | Anzahl gekaufter Skill-Upgrades |
| `finalState` | `victory` \| `defeat` |
| `winRate` | `wins / total × 100` |
---
## 4. `perf-result.json`
```json
{
"timestamp": "2026-08-28T19:45:00.000Z",
"durationMs": 15000,
"fps": 58,
"targetFps": 55,
"pass": true,
"heap": { "usedMB": 48.3, "totalMB": 96.0 },
"setup": {
"levelIdx": 10,
"levelName": "…",
"placed": 50,
"enemies": 40,
"state": "playing"
}
}
```
| Feld | Bedeutung |
|---|---|
| `fps` | Gemittelte Frames pro Sekunde während `durationMs` |
| `targetFps` | Zielwert (Default `55`) `pass` = `fps >= targetFps` |
| `heap.usedMB` | `performance.memory.usedJSHeapSize` / 1048576 |
| `heap.totalMB` | `performance.memory.totalJSHeapSize` / 1048576 |
> Heap-Messung benötigt Chromium (`performance.memory`). In nicht-Chromium-Browsern ist
> `heap` ggf. `null` → `report.mjs` blendet dann die Heap-Spalte aus.
---
## 5. `report.html`
`report.mjs` rendert eine statische, single-file HTML-Seite:
```
┌──────────────────────────────────────────────────────────────────┐
│ Aegis Labyrinth Test & Audit Report │
│ Timestamp: 2026-08-28 19:45 │
├──────────────────────────────────────────────────────────────────┤
│ ✔ AUDIT pass 12/12 self ✔ extension ✔ redesign ✔ │
│ ✔ SELF-PLAY winRate 80% (8/10) avgKills 118 │
│ ✔ PERFORMANCE 58 fps (target 55) heap 48.3 / 96.0 MB │
├──────────────────────────────────────────────────────────────────┤
│ Assertion-Details (expandierbare Liste) │
│ Page-Errors (leer) │
└──────────────────────────────────────────────────────────────────┘
```
**Verhalten:**
- Jede Sektion hat einen Ampel-Status: grün (pass) / gelb (teilweise) / rot (fail).
- Fehlende Quelldatei → Sektion wird als „no data" (grau) gerendert, statt zu crashen.
- Kein externes JS/CSS → `report.html` ist vollständig offline-viewbar.
---
## 6. .gitignore (Empfehlung)
```gitignore
# Test-Artefakte (werden zur Laufzeit erzeugt)
audit-result.json
selfplay-results.json
perf-result.json
report.html
audit-final.png
# Externe Game-Source (manuell in die Root legen)
Aegis-Labyrinth.html
# Node
node_modules/