Skip to content

test(waechter): die Ausnahmeliste muss noch etwas tragen, und kein blinder Fleck ohne Nennung - #46

Merged
Bernhard-Reiter merged 1 commit into
mainfrom
waechter/ausnahmeliste-prueft-sich-selbst
Sep 4, 2026
Merged

Bernhard-Reiter merged 1 commit into
mainfrom
waechter/ausnahmeliste-prueft-sich-selbst

Conversation

@Bernhard-Reiter

Copy link
Copy Markdown
Owner

Die Ausnahmeliste war leer geworden, ohne dass es auffiel

Folge aus dem Review von #45. Der Wächter dort ist besser als vorher — meine vier Proben gehen alle durch. Aber die neue Präfix-Regel hat einen Preis, und er trifft ausgerechnet die Ehrlichkeitsprüfung, die #44 eingeführt hat:

cc-status-dot--good   auf BEKANNT_UNBENUTZT
                      → wird durch das Präfix »cc-status-dot« ohnehin freigestellt
                      → der Eintrag schützt nichts mehr
                      → behauptet aber weiter, jemand habe hingesehen

Und drei erfundene tote Klassen unter vorhandenen Präfixen wurden nicht gemeldet: cc-status-dot--kaputt, tafel-gibtsnicht, toolbar-tot.

Die Ursache lag nicht bei der Präfix-Regel

Sie lag beim Lesen. Der Template-Regex fängt das Literal als Ganzes — damit sind die inneren "…" konsumiert, und die "-Alternative kommt gar nicht mehr dran:

className={`cc-status-dot${r.on ? " cc-status-dot--on" : ""}`}

" cc-status-dot--on" ist ein vollständiges Literal in der Quelle und ging trotzdem verloren. Danach brauchte der Wächter die Präfix-Regel, um --on wiederzufinden — und die stellt --good mit frei. Der Fehlalarm-Vermeider war die Folge eines Lesefehlers, nicht der Sache.

Vier Änderungen

1 · Interpolations-Inhalte werden mitgelesen. +3 Tokens, darunter cc-status-dot--on. Damit steht es wörtlich in der Menge und braucht kein Präfix mehr.

2 · Nur Präfixe mit Trennzeichen am Ende (ampel--, it-session-). Ein Baukasten endet auf - oder _. Vorher galten 73 Zeichenketten als Präfix — darunter '\n\n', '/rest/v1/', 'Lehrling-Korpus:\n'. Jetzt 10.

3 · Neue Prüfung »kein blinder Fleck ohne Nennung«. Keine CSS-Klasse darf nur über ein dynamisches Präfix als benutzt gelten. Heute sind es null. Kommt eine dazu, verlangt der Test eine Entscheidung, statt still ein Loch zu lassen. Die Präfix-Regel bleibt ein bewusstes Zugeständnis — bei tafel-${x} weiß niemand statisch, welche Werte x annimmt —, aber was sie freistellt, darf nicht unbemerkt wachsen.

4 · Die Ausnahmeliste prüft sich selbst. Jeder Eintrag muss ohne sich selbst gemeldet werden. Eine Ausnahme, die nichts mehr ausnimmt, ist kein geprüfter Fall, sondern ein vergessener.

Gegenproben mit dem echten Läufer, einzeln

Nicht mit meinem node-Nachbau — ein eigenes Prüfwerkzeug ist kein Beweis, auch nicht meins. Dafür habe ich im Worktree installiert und vitest laufen lassen:

Saboteur Ergebnis
A .tafel-neuertest ins CSS (lebt nur über tafel-) kein blinder Fleck ohne Nennung rot
B Interpolations-Lesen wieder entfernt cc-status-dot--on wird als tot gemeldet (Fehlalarm sichtbar)
C Trennzeichen-Bedingung aufgehoben (= Zustand von #45) beide neuen Prüfungen rot, wörtlich: »cc-status-dot--good wird inzwischen als benutzt erkannt«

Saboteur C ist der wichtige: er stellt den Stand von #45 wieder her, und der Test benennt den Befund von selbst.

Dazu die vier Proben aus dem #45-Review und die drei erfundenen unter Präfix — alle richtig. 3 Tests in der Datei, 495 im Paket, typecheck sauber.

Was bleibt

cc-status-dot--good ist weiterhin echt tot (SystemStatus.tsx setzt nur --on) und steht weiterhin mit Grund auf der Liste — jetzt wieder wirksam. Fremder Code, nicht angefasst.

…inder Fleck ohne Nennung

Befund an #45, gemessen: die Praefix-Regel stellte cc-status-dot--good frei, das
niemand setzt — der Eintrag in BEKANNT_UNBENUTZT war damit wirkungslos und behauptete
trotzdem, jemand habe hingesehen. Das untergraebt genau die Ehrlichkeit, die die
Liste herstellen soll.

Die Ursache lag tiefer: der Template-Regex faengt das Literal als GANZES, damit sind
die inneren Strings konsumiert und die '-Alternative kommt nicht mehr dran.
'cc-status-dot${on ? " cc-status-dot--on" : ""}' traegt --on als vollstaendiges
Literal, und es ging trotzdem verloren. Danach BRAUCHTE der Waechter die Praefix-
Regel, um --on wiederzufinden — und die stellt --good mit frei. Der Fehlalarm-
Vermeider war die Folge eines Lesefehlers, nicht der Sache.

Vier Aenderungen:
1. Interpolations-Inhalte werden mitgelesen (+3 Tokens, darunter cc-status-dot--on).
2. Nur Praefixe mit Trennzeichen am Ende gelten (ampel--, it-session-). Vorher galten
   73 Zeichenketten als Praefix, darunter '\n\n' und '/rest/v1/'; jetzt 10.
3. Neue Pruefung 'kein blinder Fleck ohne Nennung': keine CSS-Klasse darf NUR ueber
   ein dynamisches Praefix als benutzt gelten. Heute null; kommt eine dazu, verlangt
   der Test eine Entscheidung statt eines stillen Lochs.
4. Die Ausnahmeliste prueft sich selbst: jeder Eintrag muss ohne sich selbst gemeldet
   werden. Eine Ausnahme, die nichts mehr ausnimmt, ist kein gepruefter Fall.

Mit echtem Laeufer gegengeprobt, einzeln (nicht mit meinem node-Nachbau):
  A .tafel-neuertest ins CSS      => 'kein blinder Fleck' rot
  B Interpolations-Lesen entfernt => cc-status-dot--on wird als tot gemeldet
  C Trennzeichen-Bedingung weg    => BEIDE neuen Pruefungen rot, mit der Meldung
    'cc-status-dot--good wird inzwischen als benutzt erkannt' — also genau der
    Zustand von #45.
3 Tests gruen, 495 im Paket, typecheck sauber.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Bernhard-Reiter

Copy link
Copy Markdown
Owner Author

Gemergt — sieben Proben, sieben Treffer

Mit vitest gegen den echten Wächter, jeder Saboteur einzeln und nachweislich gesetzt:

Probe Ergebnis
Teilstring einer lebenden Klasse (.hash-zeil) ✅ gemeldet
erfundene tote Klasse (.karte-fuss-neu) ✅ gemeldet
tot unter vorhandenem Präfix (.cc-status-dot--kaputt) ✅ gemeldet — vorher unsichtbar
tot unter vorhandenem Präfix (.toolbar-tot) ✅ gemeldet — vorher unsichtbar
lebende Klasse (.rolle) ✅ kein Fehlalarm
lebende Klasse in die Ausnahmeliste eingetragen 🔴 »rolle wird inzwischen als benutzt erkannt — der Eintrag ist wirkungslos und gehört entfernt, sonst wird die Liste zum Sammelbecken«
Klasse, die nur über ein Präfix lebt (.tafel-neuertest) 🔴 »Diese Klassen gelten nur deshalb als benutzt, weil irgendwo ein dynamisches Präfix steht — geprüft ist damit keine von ihnen«

388 Tests grün.

Die Wurzel ist wirklich zu

Isoliert nachgemessen an der echten Zeile aus SystemStatus.tsx:

vorher:  Tokens [ 'cc-status-dot' ]                       — --on verloren, Präfix nötig
jetzt:   Tokens [ 'cc-status-dot--on', 'cc-status-dot' ]  — Präfixliste leer

Damit fällt die Präfix-Regel für diesen Fall ganz weg, statt sie enger zu schrauben. Das ist der Unterschied zwischen »den Fehlalarm loswerden« und »den Lesefehler beheben«.

Was ich an diesem PR am meisten mag

Nicht die Fixes, sondern Nummer 3: der Wächter sagt jetzt, was er nicht sieht. Eine Klasse, die nur über ein dynamisches Präfix als benutzt gilt, ist nicht geprüft — sie ist bloß nicht gemeldet. Heute sind es null; kommt eine dazu, verlangt der Test eine Entscheidung, statt sie stillschweigend durchzuwinken.

Und Nummer 4 schließt den Kreis, den ich offen gelassen hatte: meine Ehrlichkeitsregel prüfte, dass jede Ausnahme einen Grund hat und die Klasse noch im CSS steht — aber nicht, dass sie noch etwas ausnimmt. Genau daran ist sie gescheitert: cc-status-dot--good war durch die Präfix-Regel längst freigestellt, und mein Eintrag behauptete weiter, jemand habe hingesehen.

Zu deiner Frage

Ja, schreib den Handgriff auf. Meine Fassung davon: bei jeder Ausnahme, jedem Filter, jeder Heuristik nicht nur prüfen, ob die bekannten Fälle stimmen, sondern auszählen, was sie insgesamt durchlässt. Ich hatte vier grüne Proben und war zufrieden — dass die Präfix-Regel dabei 73 Zeichenketten zu Freibriefen machte, habe ich nie gemessen. Eine Regel, die zu viel erlaubt, ist genauso still wie eine, die nichts prüft.

@Bernhard-Reiter
Bernhard-Reiter merged commit 981a9ea into main Sep 4, 2026
2 checks passed
@Bernhard-Reiter
Bernhard-Reiter deleted the waechter/ausnahmeliste-prueft-sich-selbst branch September 4, 2026 00:52
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.

2 participants