Skip to content

fix(quality): das Architektur-Gate sagt wieder die Wahrheit, und die sechste Feldlage-Kopie fällt weg (22.3, 22.4) - #125

Merged
cubetribe merged 1 commit into
mainfrom
chore/s22-luegende-pruefer
Aug 29, 2026
Merged

fix(quality): das Architektur-Gate sagt wieder die Wahrheit, und die sechste Feldlage-Kopie fällt weg (22.3, 22.4)#125
cubetribe merged 1 commit into
mainfrom
chore/s22-luegende-pruefer

Conversation

@cubetribe

Copy link
Copy Markdown
Collaborator

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 main rot

run_gate_check.py führte Nova.AI.Data auf Rang 2, direkt neben Nova.AI — einsortiert nach dem Namen, nicht nach der Abhängigkeitsrichtung.

Nova.AI referenziert Nova.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ändertes origin/main:

main, unverändert: ['Nova.AI: forbidden upward/same-layer edge to Nova.AI.Data']

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-authorize steht 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.Data referenziert nichts außer Nova.Core und 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:

G0-ARCHITECTURE: PASS: asmdef architecture boundaries hold
G0-NEGATIVE-CONTROL: PASS: negative control red as required
                     (Nova.Simulation must not reference Nova.AI);
                     baseline violations in current tree: 0

Die 0 in 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.Maps und Nova.Presentation.Shaders stehen in der Schichtenkarte, haben aber seit der Zusammenlegung der Präsentationsschicht keine .asmdef mehr. Die beiden gleichnamigen .csproj im 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 .asmdef lässt das Gate jetzt rot werden. Die Gegenrichtung (eine .asmdef ohne Rang) war längst abgedeckt; andersherum hatte nie jemand geschaut.

Rot-Nachweis — ein Wächter, den niemand rot gesehen hat, ist eine Behauptung:

sauberer Bestand:   keine Verstöße
Phantom eingefügt:  Nova.Erfunden.Phantom: ranked in ASSEMBLY_RANKS but no
                    .asmdef defines it — drop the entry or add the assembly
Gegenprobe mit den
zwei alten Einträgen: beide werden gefangen

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

BootstrapSceneGenerator backte eine eigene Fünferliste von Feldkoordinaten in MapDefinitionSO, mit dem Kommentar „the five fields MatchBootstrap registers". Seit Paket 21.7 registriert MatchBootstrap fünfzehn. Der Kommentar log, die Liste war veraltet, und beides ist durch zwei Kartenänderungen hindurch niemandem aufgefallen — weil MapDefinitionSO außerhalb von Editor/ 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: MatchBootstrap bekommt 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 von Editor/ 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ün
  • G0-ARCHITECTURE und G0-NEGATIVE-CONTROL: beide pass, Baseline-Verstöße 0 (vorher 1)
  • Rot-Nachweis des neuen Wächters, siehe oben
  • Nicht belegt: Unity stand nicht zur Verfügung. Die Änderung an Assets/_Project/Editor/BootstrapSceneGenerator.cs ist gelesen, nicht kompiliert. using Nova.Gameplay.Match; steht bereits in der Datei und Nova.Editor referenziert Nova.Gameplay ausweislich 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ünf

Herkunft

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.

…sechste Feldlage-Kopie faellt weg (22.3, 22.4)
@cubetribe
cubetribe merged commit 2560768 into main Aug 29, 2026
6 checks passed
@cubetribe
cubetribe deleted the chore/s22-luegende-pruefer branch August 29, 2026 10:53
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant