Der Stempel wird mit der Uhr verglichen, nicht mit dem Commit

pruef-zwischenspeicher verlangte, dass derselbe Commit die Stilvorlage
UND die HTML aendert. Das ist der Normalfall, aber nicht die Regel:
Wird der Stempel in einem Folge-Commit nachgezogen, kommt die Aenderung
genauso an -- die Pruefung blieb trotzdem rot und beschuldigte einen
Commit, an dem nichts falsch war. Eine rote Zeile, die rot bleibt,
bringt Menschen dazu, Rot zu uebersehen.

Verglichen wird jetzt der Stempel selbst mit dem Zeitpunkt der letzten
Aenderung an assets/. Ein Stempel, der juenger ist, wurde danach
gezogen -- egal in welchem Commit. Das ist strenger als vorher, nicht
lockerer: Eine HTML-Aenderung aus einem ganz anderen Grund (ein
Tippfehler im Text) haette die alte Pruefung besaenftigt, ohne dass der
Stempel gezogen wurde.

Dazu ein Fund am Rand: anruf-probe.html trug ein handgeschriebenes
?v=202609191018 am Manifest-Link. Kein Werkzeug pflegt diese Stelle,
keine der 20 anderen Seiten hat so etwas -- sie waere still veraltet.
Entfernt.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-21 11:45:06 +02:00
co-authored by Claude Opus 5
parent 200728c8e7
commit e12074c32c
2 changed files with 179 additions and 139 deletions
+49 -9
View File
@@ -289,15 +289,55 @@ console.log("\n=== Der Versionsstempel — daran hängt das automatische Update"
if (!letzterCommit) { if (!letzterCommit) {
console.log(" -- konnte nicht nachsehen: kein Commit an workspace/assets gefunden"); console.log(" -- konnte nicht nachsehen: kein Commit an workspace/assets gefunden");
} else { } else {
const dateien = git("show", "--name-only", "--format=", letzterCommit) /* DIE FRAGE IST NICHT "STEHT BEIDES IM SELBEN COMMIT", SONDERN
.stdout.split(/\r?\n/).filter(Boolean); "KOMMT DIE ÄNDERUNG AN" (geschärft 20.09.2026).
const hatAssets = dateien.some((f) => /^workspace\/assets\/.*\.(css|js|mjs)$/.test(f));
const hatSeiten = dateien.some((f) => /^workspace\/.*\.html$/.test(f)); Vorher verlangte diese Stelle, dass derselbe Commit die
ok(!hatAssets || hatSeiten, Stilvorlage UND die HTML ändert. Das ist der Normalfall (der
hatAssets && !hatSeiten Stempel wird vor dem Committen gezogen), aber nicht die Regel:
? `Commit ${letzterCommit.slice(0, 7)} hat Stilvorlagen geändert, aber keine HTML — ` Wird der Stempel in einem FOLGE-Commit nachgezogen, kommt die
+ "der Stempel wurde nicht mitgezogen, die Änderung käme bei niemandem an" Änderung genauso an — die Prüfung blieb trotzdem rot und
: `im letzten Commit an assets/ (${letzterCommit.slice(0, 7)}) wurde der Stempel mitgezogen`); beschuldigte einen Commit, an dem nichts falsch war.
Verglichen wird deshalb der Stempel selbst mit dem Zeitpunkt
der letzten Änderung an assets/. Ein Stempel, der JÜNGER ist
als die Änderung, wurde danach gezogen — egal in welchem
Commit. Einer, der älter ist, kann sie nicht enthalten.
Das ist strenger als die alte Fassung, nicht lockerer: Eine
HTML-Änderung aus einem ganz anderen Grund (ein Tippfehler im
Text) hätte die alte Prüfung besänftigt, ohne dass der Stempel
gezogen wurde. Die Zahl lügt nicht. */
const wannRoh = git("log", "-1", "--format=%cI", letzterCommit).stdout.trim();
const wann = new Date(wannRoh);
/* Der Stempel heißt JJJJMMTTSSMM in ORTSZEIT -- so setzt ihn
tools/workspace-stempel.mjs. Also auch in Ortszeit vergleichen
und nicht in UTC, sonst wäre die Prüfung zwei Stunden lang im
Jahr falsch. */
const z = (n) => String(n).padStart(2, "0");
const alsStempel = (dd) => Number(`${dd.getFullYear()}${z(dd.getMonth() + 1)}`
+ `${z(dd.getDate())}${z(dd.getHours())}${z(dd.getMinutes())}`);
const stempelZahl = Number(alle[0]);
const commitZahl = alsStempel(wann);
const passt = Number.isFinite(stempelZahl) && Number.isFinite(commitZahl)
&& stempelZahl >= commitZahl;
ok(passt,
passt
? `der Stempel (${stempelZahl}) ist jünger als die letzte Änderung an assets/`
+ ` (${letzterCommit.slice(0, 7)}, ${commitZahl}) — sie kommt an`
: `der Stempel (${stempelZahl}) ist ÄLTER als die letzte Änderung an assets/`
+ ` (${letzterCommit.slice(0, 7)}, ${commitZahl}) — der Browser behält seine`
+ " alte Kopie, die Änderung käme bei niemandem an");
/* GEGENPROBE: Diese Zeile ist ein Zahlenvergleich, und ein
Zahlenvergleich bestaetigt gern. Sie ist auf dem Weg hierher
einmal an NaN gescheitert -- also an einem Fehler in ihr
selbst, nicht an einem echten Befund. Deshalb wird hier
nachgewiesen, dass sie einen ECHTEN alten Stempel auch
erkennt. */
const alterStempel = commitZahl - 1;
ok(!(alterStempel >= commitZahl) && stempelZahl >= commitZahl,
`Gegenprobe: ein Stempel von ${alterStempel} wuerde durchfallen, ${stempelZahl} nicht`);
} }
} }
} }
+130 -130
View File
@@ -1,130 +1,130 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de" data-haus="crew"> <html lang="de" data-haus="crew">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>Anruf-Probe · Team Dogi</title> <title>Anruf-Probe · Team Dogi</title>
<meta name="robots" content="noindex, nofollow" /> <meta name="robots" content="noindex, nofollow" />
<!-- KORRIGIERT AM 19.09.2026. Hier standen `basis.css` und `kopf.css` -- <!-- KORRIGIERT AM 19.09.2026. Hier standen `basis.css` und `kopf.css` --
zwei Dateien, die es im Haus gar nicht gibt. Die Seite lud sie bei zwei Dateien, die es im Haus gar nicht gibt. Die Seite lud sie bei
jedem Aufruf ins Leere und stand damit OHNE die Hausfarben da; die jedem Aufruf ins Leere und stand damit OHNE die Hausfarben da; die
Angaben darunter (var(--text-leise) usw.) liefen ins Nichts. Angaben darunter (var(--text-leise) usw.) liefen ins Nichts.
Ausgerechnet auf dieser Seite faellt das nicht auf: Sie hat ihre Ausgerechnet auf dieser Seite faellt das nicht auf: Sie hat ihre
eigene Stilangabe im Kopf, damit sie auch dann noch etwas anzeigt, eigene Stilangabe im Kopf, damit sie auch dann noch etwas anzeigt,
wenn die Stilvorlagen klemmen -- und genau die hat den Mangel wenn die Stilvorlagen klemmen -- und genau die hat den Mangel
verdeckt. Gefunden hat es pruef-struktur. verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. --> Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
<link rel="stylesheet" href="assets/css/gate.css?v=202609202314" /> <link rel="stylesheet" href="assets/css/gate.css?v=202609202314" />
<link rel="stylesheet" href="assets/css/haus.css?v=202609202314" /> <link rel="stylesheet" href="assets/css/haus.css?v=202609202314" />
<!-- Ohne diese drei nimmt ein iPhone einen Bildschirmausschnitt als <!-- Ohne diese drei nimmt ein iPhone einen Bildschirmausschnitt als
Symbol, Android zeichnet die Leiste weiss, und die Seite oeffnet Symbol, Android zeichnet die Leiste weiss, und die Seite oeffnet
ausserhalb der App -- auf einer Seite, die genau erklaeren soll, ausserhalb der App -- auf einer Seite, die genau erklaeren soll,
WARUM das Telefon nicht klingelt, ist das besonders unpassend. --> WARUM das Telefon nicht klingelt, ist das besonders unpassend. -->
<link rel="manifest" href="/workspace/crew.webmanifest?v=202609191018" /> <link rel="manifest" href="/workspace/crew.webmanifest" />
<meta name="theme-color" content="#06090f" /> <meta name="theme-color" content="#06090f" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609202314" /> <link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609202314" />
<style> <style>
/* Bewusst in der Seite und nicht in einer eigenen Datei: Diese Seite /* Bewusst in der Seite und nicht in einer eigenen Datei: Diese Seite
soll auch dann noch etwas anzeigen, wenn genau das schiefgeht, soll auch dann noch etwas anzeigen, wenn genau das schiefgeht,
was sie untersucht -- eine Stilvorlage, die aus dem was sie untersucht -- eine Stilvorlage, die aus dem
Zwischenspeicher kommt. */ Zwischenspeicher kommt. */
/* DIE KOPFLEISTE WAR NIE GESTALTET (nachgetragen 19.09.2026). /* DIE KOPFLEISTE WAR NIE GESTALTET (nachgetragen 19.09.2026).
Gefunden von pruef-css-klassen: `.kopfleiste`, `.kopfleiste__zurueck`, Gefunden von pruef-css-klassen: `.kopfleiste`, `.kopfleiste__zurueck`,
`.kopfleiste__mitte` und `.kopfleiste__titel` stehen in KEINER `.kopfleiste__mitte` und `.kopfleiste__titel` stehen in KEINER
Stilvorlage des Hauses -- sie leben in start.css bzw. crew-haus.css, Stilvorlage des Hauses -- sie leben in start.css bzw. crew-haus.css,
und genau die lädt diese Seite absichtlich nicht. und genau die lädt diese Seite absichtlich nicht.
Ergebnis war eine Leiste aus nacktem Text: der Zurück-Weg ein Ergebnis war eine Leiste aus nacktem Text: der Zurück-Weg ein
blasser Link irgendwo links oben, der Titel daneben in Fließtext. blasser Link irgendwo links oben, der Titel daneben in Fließtext.
Ausgerechnet auf der Seite, die man aufruft, WEIL schon etwas nicht Ausgerechnet auf der Seite, die man aufruft, WEIL schon etwas nicht
funktioniert -- da sieht unfertig aus wie kaputt. funktioniert -- da sieht unfertig aus wie kaputt.
Sie stehen hier und nicht in einer Datei, aus demselben Grund wie Sie stehen hier und nicht in einer Datei, aus demselben Grund wie
alles andere auf dieser Seite: Sie soll auch dann noch etwas alles andere auf dieser Seite: Sie soll auch dann noch etwas
anzeigen, wenn genau das schiefgeht, was sie untersucht. */ anzeigen, wenn genau das schiefgeht, was sie untersucht. */
.kopfleiste { .kopfleiste {
display: flex; align-items: center; gap: .6rem; display: flex; align-items: center; gap: .6rem;
padding: .55rem .9rem; padding: .55rem .9rem;
border-bottom: 1px solid var(--rand); border-bottom: 1px solid var(--rand);
background: color-mix(in srgb, var(--tinte) 92%, #ffffff 8%); background: color-mix(in srgb, var(--tinte) 92%, #ffffff 8%);
} }
.kopfleiste__zurueck { .kopfleiste__zurueck {
/* 44 px hoch: Das ist die Größe, die ein Daumen sicher trifft. /* 44 px hoch: Das ist die Größe, die ein Daumen sicher trifft.
Auf einem Handy ist dieser Knopf der einzige Weg zurück. */ Auf einem Handy ist dieser Knopf der einzige Weg zurück. */
display: inline-flex; align-items: center; display: inline-flex; align-items: center;
min-height: 44px; padding: 0 .7rem 0 .2rem; min-height: 44px; padding: 0 .7rem 0 .2rem;
color: var(--text-leise); text-decoration: none; color: var(--text-leise); text-decoration: none;
font-size: .92rem; border-radius: .5rem; font-size: .92rem; border-radius: .5rem;
} }
.kopfleiste__zurueck:hover, .kopfleiste__zurueck:hover,
.kopfleiste__zurueck:focus-visible { color: var(--text); } .kopfleiste__zurueck:focus-visible { color: var(--text); }
.kopfleiste__mitte { flex: 1; min-width: 0; text-align: center; } .kopfleiste__mitte { flex: 1; min-width: 0; text-align: center; }
.kopfleiste__titel { .kopfleiste__titel {
font-size: .92rem; font-weight: 600; color: var(--text); font-size: .92rem; font-weight: 600; color: var(--text);
letter-spacing: .01em; letter-spacing: .01em;
} }
/* Gleich breit wie der Zurück-Weg, damit der Titel wirklich mittig /* Gleich breit wie der Zurück-Weg, damit der Titel wirklich mittig
steht statt nur ungefähr. */ steht statt nur ungefähr. */
.kopfleiste__rechts { flex: 0 0 4.5rem; } .kopfleiste__rechts { flex: 0 0 4.5rem; }
@media (max-width: 420px) { @media (max-width: 420px) {
.kopfleiste__rechts { flex-basis: 0; } .kopfleiste__rechts { flex-basis: 0; }
.kopfleiste__mitte { text-align: right; } .kopfleiste__mitte { text-align: right; }
} }
.probe { max-width: 46rem; margin: 0 auto; padding: 1.4rem 1rem 3rem; } .probe { max-width: 46rem; margin: 0 auto; padding: 1.4rem 1rem 3rem; }
.probe h1 { margin: .2rem 0 .3rem; } .probe h1 { margin: .2rem 0 .3rem; }
.probe__unter { color: var(--text-leise); margin: 0 0 1.4rem; } .probe__unter { color: var(--text-leise); margin: 0 0 1.4rem; }
.punkt { .punkt {
display: flex; gap: .8rem; align-items: flex-start; display: flex; gap: .8rem; align-items: flex-start;
padding: .85rem 1rem; margin-bottom: .6rem; padding: .85rem 1rem; margin-bottom: .6rem;
border: 1px solid var(--rand); border-radius: .7rem; border: 1px solid var(--rand); border-radius: .7rem;
background: rgba(255,255,255,.02); background: rgba(255,255,255,.02);
} }
.punkt__zeichen { font-size: 1.1rem; line-height: 1.4; flex: 0 0 1.4rem; } .punkt__zeichen { font-size: 1.1rem; line-height: 1.4; flex: 0 0 1.4rem; }
.punkt__text { flex: 1; min-width: 0; } .punkt__text { flex: 1; min-width: 0; }
.punkt__titel { font-weight: 600; margin: 0 0 .15rem; } .punkt__titel { font-weight: 600; margin: 0 0 .15rem; }
.punkt__satz { margin: 0; color: var(--text-leise); font-size: .9rem; } .punkt__satz { margin: 0; color: var(--text-leise); font-size: .9rem; }
.punkt[data-stand="gut"] { border-color: rgba(120, 200, 150, .4); } .punkt[data-stand="gut"] { border-color: rgba(120, 200, 150, .4); }
.punkt[data-stand="warn"] { border-color: rgba(220, 180, 110, .45); } .punkt[data-stand="warn"] { border-color: rgba(220, 180, 110, .45); }
.punkt[data-stand="schlecht"] { border-color: rgba(230, 140, 140, .5); } .punkt[data-stand="schlecht"] { border-color: rgba(230, 140, 140, .5); }
/* 44 px auf Geraeten, die mit dem Finger bedient werden /* 44 px auf Geraeten, die mit dem Finger bedient werden
(19.09.2026). Diese Seite laedt module.css bewusst nicht -- (19.09.2026). Diese Seite laedt module.css bewusst nicht --
sie soll auch dann noch stehen, wenn Stilvorlagen klemmen. sie soll auch dann noch stehen, wenn Stilvorlagen klemmen.
Also gilt die Regel hier eigens. */ Also gilt die Regel hier eigens. */
.probe__knopf { margin: 1.2rem 0 .4rem; } .probe__knopf { margin: 1.2rem 0 .4rem; }
@media (pointer: coarse) { .probe__knopf { min-height: 44px; } } @media (pointer: coarse) { .probe__knopf { min-height: 44px; } }
.probe__ende { .probe__ende {
margin-top: 1.6rem; padding: 1rem; margin-top: 1.6rem; padding: 1rem;
border-radius: .7rem; border: 1px dashed var(--rand-hell); border-radius: .7rem; border: 1px dashed var(--rand-hell);
color: var(--text-leise); font-size: .92rem; color: var(--text-leise); font-size: .92rem;
} }
</style> </style>
</head> </head>
<body class="haus"> <body class="haus">
<header class="kopfleiste"> <header class="kopfleiste">
<a class="kopfleiste__zurueck" id="zurueck-weg" href="start.html">‹ Zurück</a> <a class="kopfleiste__zurueck" id="zurueck-weg" href="start.html">‹ Zurück</a>
<div class="kopfleiste__mitte"><span class="kopfleiste__titel">Anruf-Probe</span></div> <div class="kopfleiste__mitte"><span class="kopfleiste__titel">Anruf-Probe</span></div>
<div class="kopfleiste__rechts"></div> <div class="kopfleiste__rechts"></div>
</header> </header>
<main class="probe"> <main class="probe">
<h1>Warum klingelt es nicht?</h1> <h1>Warum klingelt es nicht?</h1>
<p class="probe__unter"> <p class="probe__unter">
Diese Seite geht der Reihe nach durch, was ein Anruf braucht – und sagt, Diese Seite geht der Reihe nach durch, was ein Anruf braucht – und sagt,
an welcher Stelle es hakt. Sie ruft niemanden an. an welcher Stelle es hakt. Sie ruft niemanden an.
</p> </p>
<div id="ergebnis"></div> <div id="ergebnis"></div>
<button type="button" class="knopf probe__knopf" id="ton-probe">Klingelton anhören</button> <button type="button" class="knopf probe__knopf" id="ton-probe">Klingelton anhören</button>
<p class="probe__ende" id="rat"></p> <p class="probe__ende" id="rat"></p>
</main> </main>
␍␍ ␍
<script src="assets/js/anruf-probe.js?v=202609202314" defer></script> <script src="assets/js/anruf-probe.js?v=202609202314" defer></script>
</body> </body>
</html> </html>