fix(quality): das Architektur-Gate sagt wieder die Wahrheit, und die sechste Feldlage-Kopie fällt weg (22.3, 22.4) - #125
Merged
Conversation
…sechste Feldlage-Kopie faellt weg (22.3, 22.4)
This was referenced Aug 29, 2026
cubetribe
added a commit
that referenced
this pull request
Aug 29, 2026
## Was Sprint 22 ist abgeschlossen — am selben Tag geschnitten und geliefert. Alle vier Pakete liegen auf `main`: | Paket | PR | |---|---| | 22.1 Auswahl benutzbar (#50) | [#123](#123) | | 22.2 Gate-Vertrag (#14 Stufe 1) | [#121](#121) | | 22.3 Sechste Feldlage-Kopie | [#125](#125) | | 22.4 Phantom-Assemblies | [#125](#125) | ## Der Ergebnisabschnitt hält vor allem eines fest Beim Bauen des Wächters für 22.4 kam heraus, dass **G0-B.3 auf unberührtem `main` rot war** — `Nova.AI.Data` stand einen Rang zu hoch, wodurch die reale Kante `Nova.AI → Nova.AI.Data` als verbotene Kante innerhalb derselben Schicht galt. Gemerkt hat es niemand, weil das Gate nicht läuft. Das ist derselbe Befund wie [#110](#110), eine Ebene tiefer. **Drei Fälle davon in zwei Sprints:** der Gate-Vertrag mit dem falschen Repo-Namen, der rote PlayMode-Test, und jetzt die Schichtenkarte. Die Gemeinsamkeit ist nicht der einzelne Fehler, sondern dass ihn jedes Mal nur ein Mensch gefunden hat, der zufällig hinsah. Das steht so im Sprintdokument, weil es die eigentliche Lehre der beiden Sprints ist. ## Ebenfalls drin Die zwei Befunde, die als Issues rausgegangen sind, statt still im Bericht zu versauern: - [#126](#126) — der Erreichbarkeitstest aus 21.7 sieht ein Feld unter einer Wand als erreichbar - [#127](#127) — `MapDefinitionSO` hat keinen Laufzeitkonsumenten Und, unverändert, was offen bleibt: **eine gespielte Runde** auf der neuen Karte, die Unity-Testspuren, und die Entscheidung über Unity in der CI. Reine Dokumentationsänderung.
cubetribe
added a commit
that referenced
this pull request
Aug 31, 2026
…#139) ## Warum Aus der Proberunde des Inhabers vom 31.08.2026 auf Build `97e5459`: > „Mir fehlt ein globales Overlay, in dem man sieht, wie viel Strom man hat, vor allem auch wie viel Lagerplatz man noch hat." Fixes #137 Bisher erfuhr der Spieler seinen Zustand nur an Stellen, die dafür nicht gemacht sind: den Kontostand in der Baukarte, wo er Knöpfe sperrt; Strom und Lagerdecke ausschließlich in der DebugHud, teils erst hinter `F3` — einem Entwicklerwerkzeug. **Die Lagerdecke stand nirgends im Spiel-UI.** Damit waren drei Regeln unsichtbar, die aktiv in die Partie eingreifen: - der **Verfall über der Decke** (D-024) — der Grund, warum in derselben Runde Material vernichtet wurde, ohne dass es jemand sehen konnte ([#136](#136)) - der **Strommangel** — halbiert die Reparaturrate und schaltet den Radar ab (16.6/C4); ohne Anzeige ist eine langsamere Reparatur ein Rätsel - das **Startguthaben über der Decke** ([#131](#131)) ## Was die Leiste zeigt - **Aetherium: Bestand und Decke.** `2.318 / 3.000` liest sich sofort als „darüber"; `2.318` allein sagt nichts. Die Decke kommt immer aus `CapacityFor` — nirgends steht eine Zahl fest, denn sie wächst mit jedem Lager und fällt, wenn eines zerstört wird. - **Strom:** Erzeugung gegen Verbrauch mit erkennbarem Mangelzustand. - **Ein Warnzustand**, wenn die Decke erreicht ist — der Moment, in dem der Spieler handeln muss, und der einzige, in dem eine Zahl allein nicht reicht. ## Wie es gebaut ist Die Formatier- und Zustandslogik liegt in `Gameplay/UI/ResourceBarPresenter` als **reine, Unity-freie Funktionen**, die `Presentation/UI/ResourceBarHud` nur noch zeichnet. Dasselbe Muster, das Paket 21.5 mit `CommandCardPresenter` etabliert hat: was in `OnGUI` hängt, kann niemand testen; was daneben liegt, schon. **19 neue EditMode-Tests** decken den Presenter ab. Die Leiste steht bewusst **nicht** in `IsPointerOverHud`: sie ist eine reine Anzeige und schluckt keine Klicks. Die Entscheidung samt Begründung steht im Docstring, nicht nur hier. Im Szenengenerator wird sie **als letzte** Komponente hinzugefügt — die `AddComponent`-Reihenfolge ist die `OnGUI`-Malreihenfolge, sie zeichnet also über der Debug-Statuszeile statt darunter. ## Nachweis — erstmals in Unity gefahren Das ist der Teil, der bei den letzten Paketen offen bleiben musste: - **Unity EditMode: 648/648 grün, null Kompilierfehler.** 629 vorher plus die 19 neuen. Die HUD-Komponente kompiliert also wirklich, nicht nur „gelesen und für gut befunden". - `dotnet test tools/Nova.SimRunner.Tests`: **739/739 grün, unverändert** — diese Kette kompiliert `Presentation/` gar nicht mit und belegt hier nur, dass nichts in die Simulation durchgeschlagen ist. - Die Bootstrap-Szene ist **neu erzeugt**, sonst erscheint die Leiste in keinem Build. **Nicht belegt und nur am Bildschirm zu klären:** wie die Leiste aussieht und ob sie sich mit anderen Flächen beißt. Bekannte Nachbarschaft, bewusst in Kauf genommen: bei geöffnetem F3-Panel *und* sehr schmalem Fenster *und* zwei gleichzeitigen Warnungen kann sie das Debug-Panel überlappen. F3 ist Entwicklersicht; die Leiste weicht dafür keiner Spiel-Fläche aus. ## Zwei Nebenwirkungen der Szenenerzeugung - **`MAP_Glutrinne.asset` bekommt 10 Zeilen dazu.** Das ist die Wirkung von Paket 22.3: seit [#125](#125) liest der Generator die Feldlage aus `MatchBootstrap` statt sie zu wiederholen — das Asset trägt jetzt die 15 Vorkommen statt der alten 5. Der erste Beleg, dass die Korrektur greift. - **`UniversalRenderPipelineGlobalSettings.asset` wurde bewusst zurückgesetzt.** Unity hat die Datei beim Frischimport neu serialisiert und dabei eine Laufzeitliste geleert. Das hat mit diesem PR nichts zu tun und könnte das Rendering ändern — es gehört nicht heimlich mit hinein. ## Herkunft Erarbeitet von **Kimi K3** als delegiertem Worker (Presenter, HUD, Tests). Verdrahtung im Szenengenerator, Szenenerzeugung und der Unity-Testlauf vom Orchestrator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Der rote Faden
Pakete 22.3 und 22.4 aus Sprint 22 haben denselben Kern: etwas behauptet, geprüft zu haben, und prüft in Wahrheit nichts. Beide waren heute folgenlos — und genau deshalb hat sie niemand bemerkt.
Unterwegs kam ein dritter Fund derselben Familie dazu, der schwerer wiegt als die beiden geplanten.
Der Fund, der nicht geplant war: G0-B.3 ist auf
mainrotrun_gate_check.pyführteNova.AI.Dataauf Rang 2, direkt nebenNova.AI— einsortiert nach dem Namen, nicht nach der Abhängigkeitsrichtung.Nova.AIreferenziertNova.AI.Data. Bei gleichem Rang ist das eine Kante innerhalb derselben Schicht, und die verbietet D-061. Das Kriterium G0-B.3 (check_architecture) meldete damit auf jedem beliebigen Baum eine Verletzung — nachgeprüft gegen unverändertesorigin/main:Aufgefallen ist es nur, weil ich beim Bauen des neuen Wächters die Funktion einmal von Hand gefahren habe. Das Gate selbst läuft nicht (
gate-evidence-authorizesteht auf „skipping") — ein rotes Kriterium, das keine Kette fährt, ist ein Kriterium, das niemanden warnt. Dasselbe Muster wie #110, nur eine Ebene tiefer.Der Rang war falsch, nicht die Kante.
Nova.AI.Datareferenziert nichts außerNova.Coreund wird sonst nur aus Rang 4 gelesen (Nova.Presentation.UI). Rang 1 ist der einzige Rang, der den bestehenden Graphen gültig macht, ohne eine Zeile Code zu bewegen — jede ein- und ausgehende Kante bleibt streng abwärts. Das ist deshalb eine Berichtigung und keine Architekturentscheidung zwischen Alternativen.G0-B.3 ist damit erstmals grün:
Die
0in der letzten Zeile ist der eigentliche Beleg — vorher stand dort 1.22.4 — zwei Ränge für Assemblies, die es nicht gibt
Nova.Presentation.MapsundNova.Presentation.Shadersstehen in der Schichtenkarte, haben aber seit der Zusammenlegung der Präsentationsschicht keine.asmdefmehr. Die beiden gleichnamigen.csprojim Repo-Wurzelverzeichnis sind untrackte Unity-Reste.Ein toter Rang ist nicht harmlos: er genehmigt stillschweigend eine Schicht für den nächsten, der diesen Namen wieder einführt, statt die Entscheidung zu erzwingen.
Beide Einträge sind raus — und, wichtiger, die Klasse ist dicht: ein Eintrag in der Karte ohne zugehörige
.asmdeflässt das Gate jetzt rot werden. Die Gegenrichtung (eine.asmdefohne Rang) war längst abgedeckt; andersherum hatte nie jemand geschaut.Rot-Nachweis — ein Wächter, den niemand rot gesehen hat, ist eine Behauptung:
Was der Wächter bewusst nicht fängt: einen Rang, der falsch statt tot ist. Eine Assembly, die eine Schicht zu tief einsortiert ist, kommt hier durch und fällt erst über die Kantenprüfungen auf, die sie dann nicht mehr auslöst — genau der Fall, den ich oben gefunden habe, und den ein Mensch finden musste. Er feuert außerdem während einer Umbenennung, und das ist beabsichtigt: die Karte ist Teil der Umbenennung, nicht etwas, das ihr hinterherläuft.
22.3 — die sechste Feldlage-Kopie
BootstrapSceneGeneratorbackte eine eigene Fünferliste von Feldkoordinaten inMapDefinitionSO, mit dem Kommentar „the five fields MatchBootstrap registers". Seit Paket 21.7 registriertMatchBootstrapfünfzehn. Der Kommentar log, die Liste war veraltet, und beides ist durch zwei Kartenänderungen hindurch niemandem aufgefallen — weilMapDefinitionSOaußerhalb vonEditor/keinen Laufzeitkonsumenten hat.Die Literale zu aktualisieren wäre die falsche Behebung gewesen. Dann stünde die Lage weiter an sechs Stellen und ginge beim nächsten Kartenwechsel wieder an fünfen kaputt. Stattdessen ist die Kopie beseitigt:
MatchBootstrapbekommt zwei statische Leseflächen (CanonicalFieldCells,CanonicalHqCentreCells), und der Generator liest. Die HQ-Mitten, die dort ebenfalls ein zweites Mal literal standen, gehen denselben Weg — jetzt abgeleitet aus denselben Slot-Layouts, aus denen die Partie spawnt, sodass die D-107-Punktsymmetrie per Konstruktion gilt statt per zweiter handgepflegter Liste.Risiko R-1 aus Sprint 21 zählt damit wieder fünf statt sechs Stellen — und diese fünf sind alle durch Tests gepinnt.
Die offene Frage, die ich nicht entscheide
Wozu gibt es
MapDefinitionSO, wenn es niemand liest? Geschrieben wird es vom Szenengenerator, gelesen außerhalb vonEditor/von niemandem. Entweder es bekommt einen Konsumenten, oder es verschwindet. Ein Drittes gibt es nicht, und die Entscheidung gehört dem Inhaber. Bis dahin lügt es wenigstens nicht mehr.Nachweis
dotnet test tools/Nova.SimRunner.Tests -c Release: 736/736 grünG0-ARCHITECTUREundG0-NEGATIVE-CONTROL: beide pass, Baseline-Verstöße 0 (vorher 1)Assets/_Project/Editor/BootstrapSceneGenerator.csist gelesen, nicht kompiliert.using Nova.Gameplay.Match;steht bereits in der Datei undNova.EditorreferenziertNova.Gameplayausweislich seiner.asmdef, die Sichtbarkeit ist also gegeben — der Compilerlauf steht trotzdem aus. Wer die Bootstrap-Szene das nächste Mal neu generiert, sollte hinsehen: es müssen fünfzehn Feldmarker sein, nicht fünfHerkunft
Diese beiden Pakete waren an einen Kimi-Worker vergeben; der Lauf ist an der Stundenquote des Kontos gescheitert, bevor er begann. Umgesetzt vom Orchestrator direkt.