Files
DogFatherGitandClaude Opus 5 39ca642a52 Acht Pruefungen standen Nacht fuer Nacht als rot da -- sie waren gruen
Der naechtliche Lauf meldete heute frueh "37 Pruefungen sind rot".
Acht davon waren gar nicht rot: fehlerfrei durchgelaufen, Exitcode 0,
keine einzige FEHL-Zeile. Der Laeufer zaehlte bei ihnen aber NULL
Einzelpruefungen, und "null Pruefungen ist ein Fehler" -- eine Regel,
die richtig ist und hier das Falsche traf.

DER GRUND WAR EIN GROSSBUCHSTABE. Der Zaehler suchte `(ok|FEHL)`;
pruef-kachelfarben, -livepunkt, -tippziele, -turn-wege, -leerzustand,
-nachfrage, -tagesruf und -anruf-klingelt schreiben `  OK `.

Zwei Schaeden auf einmal:
  1. Ihre Punkte fehlten in der Gesamtzahl -- allein in fuenf der acht
     sind das 114 Stueck. Ausgerechnet die Zahl, die vor stillen
     Aussetzern schuetzen soll, war selbst eine Luecke.
  2. Acht dauerhaft rote Eintraege in einer Notiz, die morgens gelesen
     wird. Eine Warnung, die immer kommt, ist keine mehr.

Der Zaehler liest jetzt beide Schreibweisen. Die Dateien werden NICHT
vereinheitlicht: Acht umzuschreiben waeren acht Gelegenheiten, etwas
kaputtzumachen -- und die neunte, die morgen jemand anlegt, schreibt
ohnehin wieder, was sie will.

DAZU EINE PRUEFUNG, DIE DAS FESTHAELT (server/pruef-pruefzaehler.mjs).
Ein Kommentar haette den naechsten Fall nicht verhindert. Sie holt
sich den Ausdruck AUS alles-pruefen.mjs (zwei Fassungen desselben
Musters laufen auseinander), startet vier der schnellsten Pruefungen
wirklich -- je zwei in beiden Schreibweisen -- und hat drei
Gegenproben: Sie darf nicht wahllos zaehlen, sie muss zwei als zwei
zaehlen, und sie muss null als null sehen koennen, sonst waere "null
ist ein Fehler" blind.

UND DIE NOTIZ SAGT JETZT, WAS SIE MEINT. Statt "(keine Fehlerzeile
gefunden)" steht bei diesen Faellen: "Kein Befund -- es wurde keine
einzige Pruefung GEZAEHLT", mit der Erklaerung dazu. Fuer alles andere
ohne Fehlerzeile gibt es den dritten Ausgang ("Konnte nicht sagen,
woran es lag") samt den letzten Ausgabezeilen.

NEBENBEFUND, GEFUNDEN VON pruef-rueckmeldung: Die Tuer ins andere Haus
trug Ton 40 -- dieselbe Nummer wie "Entwicklung". Auf DogFathers Wand
standen zwei Kacheln in derselben Farbe, und er ist der Einzige, der
beide sieht; deshalb ist es nie jemandem aufgefallen.

  Die naheliegende Antwort waere eine 46. Farbe gewesen. Gerechnet kam
  ein Abstand von 0,0862 heraus -- unter der Hausgrenze von 0,09. Der
  Farbraum ist bei 45 Toenen voll, und eine zweite benannte Ausnahme
  am selben Tag waere der Anfang vom Ende der Regel.

  Richtig ist die andere Antwort: Die Tuer ist gar keine
  Bereichskachel. Sie fuehrt hinaus und gehoert keinem Bereich an --
  also bekommt sie keine Bereichsfarbe, sondern faellt auf --akzent
  zurueck. Damit unterscheidet sie sich von allen 45 anderen.

  Gefunden hat das die Pruefung erst, nachdem sie SAGEN konnte, welche
  Nummer doppelt ist. Vorher stand dort nur "kein Farbton doppelt (34
  Kacheln vom Server)" -- damit sucht man in vier Listen ueber zwei
  Dateien.

  Dazu: start.js schreibt kein data-ton="undefined" mehr (String()
  macht aus einem fehlenden Wert sonst ein Wort, und jede Pruefung,
  die Toene zaehlt, liest dann Text statt Zahl).

WAS MICH VOR DER FALSCHEN REPARATUR BEWAHRT HAT: Meine erste Vermutung
war, die FEHL-Zeilen staenden zu weit hinten im Ausgabefenster. Die
Gegenprobe dazu wurde rot -- null Dateien. Genau dafuer ist sie da.

GEMESSEN:
- pruef-pruefzaehler (neu): 7 Pruefungen, 0 Fehler.
- pruef-rueckmeldung: 30 geprueft, 0 Fehler (war rot).
- pruef-kachelfarben 26/0, pruef-haus-trennung 100/0,
  pruef-crew-adresse 153/0.
- tools/.nachtlauf-* ist jetzt ignoriert: Laufzeitzustand, der sich
  jede Nacht aendert. Das Ergebnis steht in der Vault-Notiz.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-25 06:46:49 +02:00

108 lines
4.9 KiB
JavaScript

/* =====================================================================
ZAEHLT DER LAEUFER AUCH WIRKLICH ALLE? (25.09.2026)
=====================================================================
Der naechtliche Lauf meldete am 25.09.2026 „37 Pruefungen sind rot".
Acht davon waren gar nicht rot: Sie liefen fehlerfrei durch,
Exitcode 0, keine einzige FEHL-Zeile -- aber `alles-pruefen.mjs`
zaehlte bei ihnen NULL Einzelpruefungen, und „null Pruefungen ist
ein Fehler" ist eine richtige Regel.
DER GRUND WAR EIN GROSSBUCHSTABE. Der Zaehler suchte `(ok|FEHL)`;
diese acht Dateien schreiben ` OK `. Zwei Schaeden auf einmal:
1. Ihre Punkte fehlten in der Gesamtzahl -- allein in fuenf der
acht waren das 114 Stueck. Ausgerechnet die Zahl, die vor
stillen Aussetzern schuetzen soll, war selbst eine Luecke.
2. Acht dauerhaft rote Eintraege in einer Notiz, die morgens
gelesen wird. Eine Warnung, die immer kommt, ist keine mehr.
WARUM ES DAFUER EINE PRUEFUNG GIBT UND NICHT NUR EINEN KOMMENTAR:
Weil der Kommentar den naechsten Fall nicht verhindert. Morgen legt
jemand eine Pruefdatei an, die ihre Ergebnisse wieder anders
schreibt -- mit drei Leerzeichen, mit einem Haken, auf englisch --
und sie verschwindet genauso lautlos aus der Gesamtzahl. Diese
Datei startet deshalb ein paar der schnellsten Pruefungen WIRKLICH
und vergleicht, was der Ausdruck aus ihrer Ausgabe herausliest.
DER AUSDRUCK WIRD AUS alles-pruefen.mjs GELESEN, nicht hier noch
einmal hingeschrieben. Zwei Fassungen desselben Musters waeren die
Sorte Dopplung, die genau dann auseinanderlaeuft, wenn es darauf
ankommt.
Aufrufen mit: node server/pruef-pruefzaehler.mjs
===================================================================== */
import { readFileSync } from "node:fs";
import { spawn } from "node:child_process";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const WURZEL = join(dirname(fileURLToPath(import.meta.url)), "..");
let fehler = 0;
const ok = (gut, text) => { if (!gut) fehler++; console.log(` ${gut ? "ok " : "FEHL"} ${text}`); };
/* ---- Den Ausdruck holen, den der Laeufer wirklich benutzt --------- */
const laeufer = readFileSync(join(WURZEL, "tools", "alles-pruefen.mjs"), "utf8");
const treffer = laeufer.match(/const einzeln = \(aus\.match\((\/.+?\/gm)\)/);
if (!treffer) {
console.log(" FEHL KONNTE NICHT NACHSEHEN: der Zaehl-Ausdruck steht nicht mehr da,");
console.log(" wo diese Pruefung ihn sucht (tools/alles-pruefen.mjs).");
console.log(" Das ist kein Befund am Programm -- diese Datei muss nachgezogen werden.");
process.exit(1);
}
const quelle = treffer[1];
console.log(`Der Laeufer zaehlt mit: ${quelle}\n`);
const bauen = () => new RegExp(quelle.slice(1, quelle.lastIndexOf("/")), "gm");
/* ---- Die schnellsten Vertreter beider Schreibweisen --------------- */
const PROBEN = [
{ datei: "pruef-tippziele.mjs", schreibweise: "OK" },
{ datei: "pruef-turn-wege.mjs", schreibweise: "OK" },
{ datei: "pruef-leerzustand.mjs", schreibweise: "OK" },
{ datei: "pruef-deutsche-texte.mjs", schreibweise: "ok" },
];
const laufen = (datei) => new Promise((fertig) => {
const kind = spawn(process.execPath, [join(WURZEL, "server", datei)],
{ cwd: WURZEL, stdio: ["ignore", "pipe", "pipe"] });
let aus = "";
kind.stdout.on("data", (d) => { aus += d; });
kind.stderr.on("data", (d) => { aus += d; });
const wecker = setTimeout(() => { try { kind.kill("SIGKILL"); } catch { /* weg */ } }, 120_000);
kind.on("close", (code) => { clearTimeout(wecker); fertig({ aus, code }); });
kind.on("error", () => { clearTimeout(wecker); fertig({ aus, code: -1 }); });
});
console.log("=== Jede Schreibweise wird gezaehlt ===");
for (const p of PROBEN) {
const r = await laufen(p.datei);
const zahl = (r.aus.match(bauen()) || []).length;
ok(zahl > 0,
`${p.datei.padEnd(26)} schreibt "${p.schreibweise}" -> ${zahl} Punkte erkannt`);
}
/* ---- GEGENPROBE: der Ausdruck darf nicht alles zaehlen ------------ */
console.log("\n=== Gegenprobe: er zaehlt nicht wahllos mit ===");
const beispiel = [
"OK ohne Einrueckung ist kein Pruefpunkt",
" OK zu weit eingerueckt",
" OKAY ist kein eigenes Wort",
" Ergebnis: alles gut",
" ok ein echter",
" OK auch ein echter",
" FEHL ein dritter",
].join("\n");
const gezaehlt = (beispiel.match(bauen()) || []).length;
ok(gezaehlt === 3,
`von sieben Zeilen zaehlen genau die drei echten (${gezaehlt})`);
/* Und er muss einen Aussetzer auch WIRKLICH sehen koennen. */
ok(((" ok etwas\n ok noch etwas").match(bauen()) || []).length === 2,
"zwei Punkte werden als zwei gezaehlt");
ok((("kein einziger Punkt hier").match(bauen()) || []).length === 0,
"und eine Ausgabe ohne Punkte als null -- sonst waere 'null ist ein Fehler' blind");
console.log(`\n${fehler === 0 ? "ALLES IN ORDNUNG" : fehler + " Fehler"}`);
process.exit(fehler === 0 ? 0 : 1);