Commit Graph
29 Commits
Author SHA1 Message Date
DogFatherGitandClaude Opus 5 4fdf08d003 Anruf-Probe: eine Seite, die sagt, WARUM es nicht klingelt
Filipe: „funktioniert nichts davon was machst du?"

Zu Recht. Ich habe an einem Abend fuenf Dinge repariert, jedes einzeln
nachgewiesen -- und bei ihm klingelte trotzdem nichts. Der Grund ist
jedes Mal derselbe gewesen: Ich kann von hier aus messen, was der
SERVER tut, aber nicht, was in SEINEM Browser ankommt. Und genau dort
lag es.

Gemessen habe ich gerade wieder: Der Server liefert die richtige Datei
aus (32616 Bytes, Klingelton enthalten), sobald sie mit Stempel
angefordert wird. Ohne Stempel kommt eine sieben Stunden alte Fassung
aus dem Zwischenspeicher. WELCHE von beiden sein Browser anfordert,
sehe ich nicht -- und das ist die Frage, an der alles haengt.

/workspace/anruf-probe.html dreht das um. Sie laeuft in SEINEM Browser
und beantwortet der Reihe nach:

  1. Ist die neue Fassung ueberhaupt geladen? Sie holt anruf.js und
     sieht nach, ob Klingelton und Nachklingeln darin stehen. Fehlen
     sie, kommt die Seite aus dem Zwischenspeicher -- und JEDE
     Reparatur ist unsichtbar, egal wie oft man neu laedt.
  2. Darf der Browser Ton abspielen? (Er erlaubt ihn erst nach der
     ersten Beruehrung -- wer ueber eine Benachrichtigung hereinkommt,
     hoert sonst nichts und haelt das Telefon fuer kaputt.)
  3. Sind Benachrichtigungen erlaubt UND ist ein Geraet beim Server
     angemeldet? Das sind zwei verschiedene Dinge, und die Luecke
     dazwischen sieht man sonst nirgends.
  4. Steht die Verbindung, ueber die das Klingeln kommt?

Dazu ein Knopf, der genau den Klingelton abspielt, den ein Anruf
macht. Wer ihn hoert, weiss, dass es an der Seite nicht liegt.

Am Ende steht EIN Satz: das Wichtigste zuerst, mit dem, was zu tun
ist. Keine Liste zum Selbstdeuten.

Sie ruft niemanden an und zeigt nichts ueber andere.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 00:14:01 +02:00
DogFatherGitandClaude Opus 5 c87c396ef5 Anruf: es klingelt jetzt wirklich -- vorher gab es gar keinen Ton
Filipe: „ist das normal dass es nicht mal klingelt wenn man anruft?"

Nein. Und der Grund war so einfach wie peinlich: Es gab ueberhaupt
keinen Ton. Weder beim Anrufer noch beim Angerufenen. Der Anruf zeigte
einen Kasten auf dem Bildschirm, sonst nichts -- wer nicht zufaellig
hinsah, merkte nichts, und wer anrief, wusste nie, ob ueberhaupt etwas
passiert.

Damit erklaert sich auch, warum heute Abend alles „kaputt" wirkte,
obwohl Verbindung, Raum, Anmeldung und Code stimmten: Ein stummes
Telefon ist von einem defekten nicht zu unterscheiden.

ZWEI TOENE, JE NACH SEITE:
  Angerufener  zwei weiche Toene (880/660 Hz), dann Pause -- alle
               2,4 Sekunden, dazu Vibration, wo das Geraet sie kann.
  Anrufer      ein leiseres, langsameres Freizeichen (440 Hz). Ein
               stiller Kasten mit laufender Uhr sagt nur, DASS etwas
               passiert; ein Freizeichen sagt, was.

OHNE TONDATEI. Ein .mp3 waere eine Datei mehr im Netz, eine
Lizenzfrage und ein Ladefehler, der genau dann auffaellt, wenn man ihn
braucht. Zwei Sinustoene aus dem Browser reichen. Sanft ein- und
ausgeblendet, weil ein hart geschalteter Sinus knackt -- und das
Knacken ist das Unangenehme daran.

Der Ton hoert auf, sobald jemand rangeht (`dabei`), sobald die
Verbindung steht und beim Auflegen. Drei Stellen, weil ein
Freizeichen, das waehrend des Gespraechs weiterlaeuft, das ist, was
man an Telefonanlagen hasst.

EHRLICH DAZU: Browser lassen Ton erst zu, wenn jemand auf der Seite
etwas angeklickt hat. Wer die Seite gerade erst geoeffnet hat, hoert
unter Umstaenden nichts -- dann bleibt die Benachrichtigung des
Geraets der Weg. Das ist eine Regel des Browsers, keine Entscheidung
von uns.

Geprueft: pruef-anruf 100 -> 101. Gemessen wird am Oszillator, nicht
am Lautsprecher: Ob wirklich etwas zu hoeren ist, haengt an Geraet und
Lautstaerke -- dass die Seite Toene ERZEUGT, laesst sich messen.
Gegenprobe (Freizeichen ausgebaut): „0 Toene erzeugt", rot.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 23:59:25 +02:00
DogFatherGitandClaude Opus 5 e43fe97550 Anruf: zwei Minuten Zeit -- und ein verpasster Anruf bleibt sichtbar
Filipe: „das mit dem anruf klappt nicht … es geeeeeht einfach nicht."

NACHGEMESSEN WAR SERVERSEITIG ALLES IN ORDNUNG: Der Anruf kam an
(Protokoll), der Raum stimmte (Dogfather + VanVan), sie war angemeldet
(Sitzung bis morgen frueh), sie hat ein Geraet fuer
Benachrichtigungen, und der neue Code lief. Trotzdem ging es nicht --
und zwar aus zwei Gruenden, die beide nichts mit Technik zu tun haben,
sondern mit Zeit und Sichtbarkeit.

1. 45 SEKUNDEN SIND KEIN KLINGELN. Bei einem Telefon hebt man ab.
   Hier muss in dieselben Sekunden: Benachrichtigung zustellen,
   bemerken, Handy entsperren, antippen, App laden, Anmeldung pruefen.
   Das reicht, wenn man das Geraet in der Hand haelt -- und sonst nie.
   Jetzt zwei Minuten: lang genug, um aus der Tasche zu kommen, kurz
   genug, dass niemand vor einem Anruf sitzt, den es nicht mehr gibt.

2. UND DANACH WAR ES, ALS WAERE NIE ETWAS GEWESEN. Ein verpasster
   Anruf verschwand lautlos: keine Zeile, kein Hinweis, nicht einmal,
   DASS jemand angerufen hat. Genau das fuehlt sich an wie „geht
   nicht", auch wenn alles funktioniert hat. Jedes Telefon der Welt
   zeigt einen verpassten Anruf; jetzt steht er als Zeile im Gespraech,
   beim Anrufer, mit Uhrzeit.

Geprueft: pruef-anruf 95 -> 100. Der neue Abschnitt misst den echten
Ablauf (anrufen, niemand geht ran, Zeile erscheint) und dass sie NUR
EINMAL erscheint -- `aufraeumen()` laeuft bei jeder Anfrage mit.

Dafuer ist die Klingeldauer ueber die Umgebung einstellbar: Eine
Pruefung, die zwei Minuten wartet, wird abgeschaltet, und dann waere
der verpasste Anruf wieder ungeprueft. Im Betrieb steht die Variable
nirgends.

Und noch ein eigener Messfehler: Die Pruefung las zuerst
/api/chat/raum/:id -- die Route heisst /api/chat/raeume/:id/nachrichten.
Sie meldete „0 Nachrichten, vorher wie nachher" und sah damit aus wie
ein Befund ueber den Code.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 23:30:52 +02:00
DogFatherGitandClaude Opus 5 4ea7b37333 Anruf: "sie kriegt nur eine Benachrichtigung aber keinen Anruf"
Filipe, gerade gemeldet. Es waren ZWEI Fehler, und beide erklaeren
genau das, was er gesehen hat.

--- 1. Die Benachrichtigung sagte nicht, dass es ein Anruf ist ------

Gemessen kam bei ihr an:

    Nachricht von [object Object]
    (kein Text)

`nachricht.von` ist beim Klingeln ein OBJEKT (`{id, name}`) und keine
Zeichenkette; einen `text` gibt es bei einem Anruf gar nicht. Moeglich
wurde beides, weil die ART des Ereignisses die Benachrichtigung nie
erreichte: `chatEreignis` nimmt sie als vierten Parameter entgegen,
reichte sie aber nur in den Ereignisstrom weiter. Fuer den Push galt
jedes Ereignis als Chatnachricht -- auch das Klingeln.

Jetzt steht dort "Filipe ruft an" / "Tippen zum Rangehen", und beim
Tippen landet man im richtigen Gespraech.

--- 2. Und dort klingelte es dann trotzdem nicht --------------------

Das Klingeln lief ausschliesslich ueber den offenen Ereignisstrom. Wer
zusieht, hoert es. Wer die Seite NICHT offen hat, bekommt die
Benachrichtigung, tippt darauf, die Seite laedt -- und bleibt still.
Das Ereignis war vorbei, bevor sie da war.

Der Anruf funktionierte damit ausgerechnet fuer die nicht, fuer die
die Benachrichtigung ueberhaupt gebaut wurde.

Neu: `GET /workspace/api/anruf/offen` -- beim Laden fragt die Seite
einmal nach, ob in einem ihrer Raeume jemand wartet. Nur was noch
klingelt (45 s), nur Raeume, in denen die Person drin ist, und nicht
beim Anrufer selbst.

--- Gepruefte Wege -------------------------------------------------

pruef-anruf 80 -> 95. Zwei neue Abschnitte, beide mit Gegenprobe:
Route stillgelegt -> 3 rot; der Text ist jetzt einzeln pruefbar
(`pushTextFuer`), weil er vorher tief in einer Funktion entstand, die
nur der Push-Weg aufruft -- von aussen nicht messbar.

Nebenbei gefunden: `istDrinFuerAnruf` braucht die PERSON, nicht ihre
Nummer, und sagt das mit einem eigenen TypeError. Meine erste Fassung
uebergab die Nummer.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 23:01:13 +02:00
DogFatherGitandClaude Opus 5 2b74e40007 Startseite: der Ring zaehlte Aufgaben -- ein Zuschauer hat keine
Nach dem Aufgabenblock und der dritten Zahl war noch ein Rest da, und
zwar der auffaelligste: In der Mitte der Seite stand gross

    100 %
    HEUTE NICHTS OFFEN

Der Ring zaehlt AUFGABEN -- was heute faellig war und was davon fertig
ist. Ein Mitglied hat keine, also stand dort dauerhaft 100 %. Dieselbe
tote Zahl wie "0 betreut" daneben, nur groesser.

Was ein Mitglied an dieser Stelle wissen will, ist etwas anderes:
Laeuft heute noch etwas? Der Ring zaehlt bei ihm jetzt die TERMINE des
Tages und faerbt, was davon vorbei ist. Bei null Terminen sagt er das
in Worten ("Heute steht nichts an") statt eine Null als Prozentzahl
auszugeben -- jede Prozentangabe waere da eine Behauptung ueber
nichts.

Dafuer kann der Server jetzt `mitte` schicken: einen Text fuer die
Ringmitte. Fehlt das Feld, bleibt alles wie bisher -- fuer alle
anderen aendert sich nichts.

UND DER FUSSTEXT ERKLAERTE EINEN KASTEN, DEN ES NICHT GAB. Unten stand
"„Was ist dran" fuehrt keine eigene Liste, sondern zeigt ..." -- der
Kasten selbst erscheint aber nur, wenn er etwas zu zeigen hat, und bei
einem Mitglied nie. Eine Erklaerung fuer etwas, das nicht da ist, ist
schlimmer als keine: Man sucht danach. Sie verschwindet jetzt mit ihm.

Gemessen (Handy): Startseite 1781 -> 1634 px.
pruef-community-sicht 10, pruef-zentrale-ring 14, pruef-vorlagen 24 --
alle ohne Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 22:16:53 +02:00
DogFatherGitandClaude Opus 5 ed8c83af09 Community: zwei Namen fuer zwei Sachen -- und ein praeziserer Satz
DIE LETZTEN BEIDEN SEITEN ANGESEHEN, die einem Mitglied offenstehen.
Sie standen bisher nur in der Messung ("keine toten Wege, keine fremde
Sprache") -- angesehen hatte ich sie nie.

1. ZWEIMAL "REGELN & HILFE". Die Seite mit den fuenf Regeln hiess
   genauso wie das BRETT, auf das sie verweist. Auf dem Brett stand
   damit ein Link "Regeln & Hilfe", der auf eine Seite namens "Regeln
   & Hilfe" fuehrte -- wer ihn drueckte, glaubte im Kreis gelaufen zu
   sein. Und dieser Link steht auf JEDEM Brett des Treffs.

   Es sind zwei verschiedene Dinge: Hier die fuenf Regeln, kurz und
   fest. Dort ein Brett, das daneben haeufige Fragen, Hilfe und die
   Folgen sammelt. Die Seite heisst jetzt "Die Regeln".

2. "GESPEICHERT WIRD ERST, WENN DU ABSCHICKST" -- daneben stand "du
   kannst zwischendurch aufhoeren und spaeter weitermachen". Beides
   zusammen kann nicht stimmen, und nachgemessen stimmt der zweite
   Satz: bewerben.js legt einen Entwurf im Browser ab (localStorage).

   Der alte Satz war also nicht falsch, aber missverstaendlich -- er
   meinte "an uns uebermittelt wird erst beim Abschicken" und klang
   nach "nichts wird gespeichert". Bei einem Formular mit sechzehn
   Feldern ist das der Unterschied zwischen "ich mache spaeter weiter"
   und "ich fange lieber gar nicht erst an". Und es ist eine
   Datenschutzauskunft: Wer an einem fremden Geraet sitzt, sollte
   wissen, dass die Antworten dort liegen bleiben.

Die Bewerbungsseite selbst ist im Uebrigen vorbildlich: jedes Feld mit
"noetig"/"freiwillig" markiert, Hilfetexte, die ehrlich sind ("Ehrlich
ist besser als beeindruckend"), und am Ende steht, wer es liest.

pruef-community-sicht: 7 Pruefungen, 0 Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 22:04:59 +02:00
DogFatherGitandClaude Opus 5 542070e864 Community: der Chat-Knopf fuehrte auf JEDER Seite ins Leere
ERST DIE METHODE, DANN DER FUND. An einem Tag habe ich in der
Community elf Dinge gefunden, die dort nicht hingehoerten -- jedes
einzelne, weil ich zufaellig hingesehen habe. Das ist keine Methode.
Der Workspace ist fuer die Agentur gebaut worden, und die Community
hat ihn geerbt; solche Reste findet man nicht durch Nachdenken,
sondern indem man ALLE Seiten durchgeht, die ein Mitglied erreichen
kann.

server/pruef-community-sicht.mjs tut genau das. Sie leitet aus
rechte.js ab, welche Seiten offenstehen (4) und welche nicht (27) --
von Hand aufgezaehlt waere das eine Liste, die bei der naechsten Seite
niemand nachzieht --, oeffnet jede davon als Mitglied und fragt
zweierlei: Fuehrt ein sichtbarer Weg auf eine verbotene Seite? Steht
dort die Sprache eines Arbeitsplatzes?

BEIM ERSTEN LAUF: 27 sichtbare Wege, davon ZEHN ins Leere -- und alle
zehn derselbe Knopf. Der Chat steht oben rechts in der Kopfleiste, auf
jeder einzelnen Seite, mit Zaehler. `chat.html` steht einem Mitglied
aber nicht offen: Der Klick landet wieder auf der Startseite. Keine
Meldung, kein Grund, nichts passiert -- an der Stelle, die man am
ehesten drueckt.

Der Knopf haengt jetzt an `darf_chat` aus /api/ich, und das kommt aus
derselben Rechtetabelle wie die Schranke dahinter. Die Oberflaeche
vergleicht keine Rollennamen -- das waere eine zweite Wahrheit, die
bei der naechsten Rechteaenderung auseinanderlaeuft. Dieselbe
Ueberlegung steht zwei Zeilen weiter oben schon einmal.

UND DIE PRUEFUNG HAT GLEICH MEINEN EIGENEN FEHLER GEFUNDEN: Die erste
Fassung stand in `aufbauChat`, wo es die Person gar nicht gibt --
ReferenceError auf allen zehn Seiten. Ohne den Skriptfehler-Abschnitt
waere der Knopf verschwunden UND die Seite kaputt gewesen, und das
haette wie ein Erfolg ausgesehen.

Jetzt haengt es dort, wo die Person ankommt (`werZeigen`) -- ein
vorhandener Knopf laesst sich immer entfernen, auf die Reihenfolge des
Ladens zu bauen waere eine Annahme.

GEGENPROBE: DogFather hat seinen Chat-Knopf weiterhin und 24 Wege auf
andere Seiten. Ohne diesen Abschnitt saehe eine abgeschaffte Funktion
genauso aus wie eine, die richtig entscheidet.

7 Pruefungen, 0 Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 21:59:53 +02:00
DogFatherGitandClaude Opus 5 4f5ac04bc9 Startseite: ein Zuschauer hat keine Aufgaben -- und keine toten Knoepfe
ZUM ERSTEN MAL MIT GAST-AUGEN ANGESEHEN. Gemessen wurden bisher immer
nur die sieben Bretter, nie die Seite davor -- dabei ist sie das
Erste, was ein Mitglied sieht.

Sie zeigte:
  "DEINE AUFGABEN" mit sieben Zaehlern (Ueberfaellig, Heute faellig,
  Offen, In Arbeit, Review, Erledigt, Abgebrochen), darunter "Nichts
  offen. Alles abgearbeitet - goenn dir was." und im Kopf "Nichts
  liegt an - guter Tag zum Vorarbeiten."

Das ist die Sprache eines Arbeitsplatzes. Eine Zuschauerin hat hier
keinen: Sie arbeitet nicht vor, ihr wird nichts zugewiesen, und
"Review" sagt ihr nichts.

UND JEDE DER SIEBEN ZAHLEN WAR EIN LINK auf aufgaben.html. Die
Rechtetabelle nennt dort "ALLE" -- was die Rolle der Community
ausdruecklich NICHT einschliesst. Nachgemessen: Ein Klick landet
wieder auf start.html. Sieben tote Knoepfe, und der Kommentar direkt
daneben sagt selbst: "Ein toter Knopf ist keine Antwort."

WORAN DIE ENTSCHEIDUNG HAENGT -- nicht an der Rolle. Rollennamen der
Community gehoeren nicht in eine Datei, die jeder herunterladen kann
(pruef-modi-wortleck wacht darueber, und ROLLENTEXT laesst sie aus
demselben Grund aus). Gefragt wird stattdessen nach etwas, das der
Server ohnehin beantwortet hat: Hat diese Person die Aufgaben-Kachel?
Er schickt nur, was jemand sehen darf. Keine zweite Wahrheit, kein
Rollenname -- und es bleibt richtig, wenn sich die Rechte aendern.

GEGENPROBE IM MESSWERKZEUG: ein zweiter Durchgang als DogFather auf
derselben Seite.
  DogFather : Block DA, 7 Links, "Vorarbeiten" ja
  Community : Block weg, 0 Links, keine Arbeitswoerter
Ohne diesen Durchgang saehe eine abgeschaffte Funktion genauso aus
wie eine, die richtig entscheidet.

Nebenbei: Die Startseite ist fuer die Community von 1436 auf 1231 px
geschrumpft.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 21:30:23 +02:00
DogFatherGitandClaude Opus 5 e128c169b9 Community: das Handy aufgeraeumt, und leere Bretter zeigen keine Filter
BISHER HABE ICH AM RECHNER GEMESSEN. Die Community ist ueberwiegend
mit dem Telefon unterwegs -- also 412 px, alle sieben Bretter.

1. FUENF KARTEN, DREI VERSCHIEDENE ANORDNUNGEN. Am Rechner stehen
   Etikett, Titel und Zustand nebeneinander, und das ist richtig. Auf
   412 px hing es an der LAENGE des Etiketts: Bei "SONSTIGES" passte
   der Titel noch daneben und "Offen" rutschte darunter; bei "FUER DEN
   STREAM" stand das Etikett allein oben und "Offen" ploetzlich RECHTS
   vom Titel. Inhaltlich unterschied sich nichts -- man liest es als
   Unordnung.

   Unter 560 px jetzt feste Reihenfolge: die Marken oben nebeneinander,
   der Titel darunter ueber die volle Breite. Immer gleich.

2. "ERLEDIGT" STAND ZWISCHEN NAME UND ROLLE: "von Filipe · erledigt ·
   DogFather". Der Rollenname gehoert zum Namen davor, und "erledigt"
   ist eine Aussage ueber den Eintrag, nicht ueber die Person --
   dazwischen gelesen wirkt es, als sei jemand erledigt.

3. FILTER FUER NICHTS. Am ersten Tag steht auf jedem Brett ein Satz wie
   "Noch hat niemand Hallo gesagt. Sei der Erste - ein Satz reicht."
   Darueber standen fuenf Filterknoepfe. Das ist die schlechteste
   Stelle fuer Bedienelemente, die ins Leere fuehren: Wer zum ersten
   Mal hier ist, soll den Satz lesen und schreiben.

   Wie bei "Nur offene" ist `!filter` der wichtige Teil: Ist die Liste
   leer, WEIL gefiltert wird, bleibt die Reihe stehen -- sonst kaeme
   man nie wieder zu "Alle" zurueck. Gemessen: leer 0 Filter, mit
   Inhalt 5 bzw. 6.

UND DAS MESSWERKZEUG KANN JETZT LEERE BRETTER ZEIGEN (LEER=ja). Die
Texte dafuer gibt es seit Langem -- gesehen hatte sie noch niemand,
weil jede Messung vorher erst den Startkatalog uebernimmt. Genau
deshalb war der Filter dort nie aufgefallen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 20:24:10 +02:00
DogFatherGitandClaude Opus 5 447a4157a5 Community: die Koepfe sagen jetzt, wofuer das Brett da ist
DIE SIEBEN BRETTER HATTEN KEINE UNTERZEILE. Ein Mitglied sah nur:

    — TERMINE
    Was ansteht
    Hier schreibt das Team.

Die Oberzeile ist eine Kategorie, kein Satz; darunter stand
ausschliesslich, OB man schreiben darf -- auf drei Brettern sogar
wortgleich dasselbe. Was das Brett IST und was man hier tut, stand
nirgends.

Jetzt sagt jeder Satz zwei Dinge: wofuer das Brett da ist und was man
konkret tut. Zum Beispiel: "Was ihr euch wuenscht. Drueck ,Will ich
auch' - danach wird sortiert, was am meisten gewollt ist." Der Hinweis
aufs Schreibrecht haengt sich dahinter, in dieser Reihenfolge: "was
ist das hier" kommt vor "darf ich mitmachen".

--- Zwei Funde aus der Highlights-Galerie ---------------------------

1. DREI KARTEN, DREI HOEHEN. `align-items: start` liess jede Karte
   dort enden, wo ihr Text aufhoerte. Eine Galerie ist ein Raster --
   ungleiche Kanten liest man als Fehler, nicht als Absicht. Jetzt
   gleich hoch (gemessen: aus 3 verschiedenen Hoehen wurde 1).

2. "NUR OFFENE" AUF BRETTERN OHNE ZUSTAENDE. Fuenf der sieben kennen
   gar kein "offen/erledigt" -- ein Clip ist nicht erledigt. Der Knopf
   stand trotzdem ueberall und tat dort nichts. Ein Knopf, der nichts
   tut, kostet das Vertrauen in den naechsten.

   Er erscheint jetzt nur, wenn die Liste ueberhaupt etwas Erledigtes
   enthaelt -- dieselbe Regel wie bei der Kanalzeile. Das `||
   filter === 'offen'` daneben ist kein Beiwerk: Ist der Filter aktiv,
   sieht man gerade keine erledigten mehr, und der Knopf wuerde unter
   der eigenen Hand verschwinden.

   GEGENPROBE IM MESSWERKZEUG: Ein Wunsch wird auf erledigt gesetzt.
   Wunschliste 6 Filter (mit "Nur offene"), Highlights 5 (ohne).
   Ohne diesen Eintrag saehe eine abgeschaffte Funktion genauso aus
   wie eine, die richtig entscheidet.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 20:16:55 +02:00
DogFatherGitandClaude Opus 5 6e062b2439 Community: ein Ton je Art -- gesucht, nicht geraten
Alle Etiketten trugen denselben blauen Ton. Auf "Regeln & Hilfe"
stehen siebzehn Karten untereinander, auf dem Treff acht -- das Auge
hatte nichts, woran es sich festhalten konnte. Man liest dann jede
Ueberschrift, statt zu ueberfliegen.

NACH BEDEUTUNG, NICHT NACH REIHENFOLGE. Lob gruen, "etwas stimmt
nicht" warmrot, Fragen blau, Regeln golden. Deshalb traegt die Art
"frage" auf drei Brettern denselben Ton: Wer das Muster einmal
gelernt hat, soll es wiedererkennen.

WARUM EIN WERKZEUG UND KEINE FARBLISTE. Der erste Versuch war von
Hand: feste Helligkeit, Buntheit nach Gefuehl. Vier Toene lagen
ausserhalb des darstellbaren Bereichs, drei Paare zu nah. Nach dem
Nachbessern waren es fuenf zu nahe Paare -- wer die Buntheit eines
Violetts senkt, schiebt es naeher an alles andere Gedaempfte. Zwei
Zahlen von Hand zu stimmen, waehrend eine dritte Bedingung mitlaeuft,
geht nicht auf. Das ist eine Suche, keine Wahl.

tools/art-farben.mjs sucht deshalb selbst: Der Farbwinkel steht fest
(das ist die Entscheidung), Helligkeit und Buntheit werden gesucht --
unter drei Bedingungen gleichzeitig: in sRGB, Kontrast mindestens
4,5:1 auf dunklem Grund, und mindestens 0,10 OKLab-Abstand zu jeder
Art, die auf DEMSELBEN Brett vorkommt. Ueber Bretter hinweg darf sich
ein Ton wiederholen -- man sieht nie zwei gleichzeitig.

UND ES SUCHT DIE LEISESTE FASSUNG, nicht die kraeftigste. Der erste
Durchlauf maximierte die Buntheit; heraus kamen #35f695 und #f584fd --
Neongruen und Neonviolett. Das widerspricht der Hausregel ("gedeckte
statt reisserisch-grelle Neon-Optik"), und bei siebzehn Karten waere
es eine Leuchtreklame. Jetzt: gerade bunt genug, um sie zu
unterscheiden. Buntheit ist eine Kostenstelle, kein Ziel.

Ergebnis: 23 Toene, 39 Paare geprueft, engstes Paar je Brett 0,100.

DAS WERKZEUG PRUEFT AUCH DAS CSS gegen seine eigene Rechnung. Ohne
das misst es nur sich selbst: Wer einen Ton von Hand aendert, bliebe
unbemerkt -- genau die Art Pruefung, die immer bestaetigt. Gegenprobe:
ein Ton von Hand verstellt -> rot mit Angabe von Soll und Ist.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 20:10:38 +02:00
DogFatherGitandClaude Opus 5 11c4a795e2 Community: Starthilfe beim Schreiben -- und vier Funde aus den Bildern
Filipe: "perfektioniere jede einzelne kategorie der community ... ich
will auch dass du fertige und beispiele machst fuer die community
damit die auch start hilfe haben ueberall."

STARTHILFE: Wer zum ersten Mal schreibt, steht vor einem leeren Feld
-- der haeufigste Grund, warum ein Brett still bleibt, obwohl viele
mitlesen. Im Formular stehen jetzt Beispiele: ein Klick fuellt Art,
Ueberschrift und Text. Auf treff, wunsch, highlight und mitmachen --
nicht auf anschlag, ansteht, regeln, denn dort schreibt die Community
nicht, und ein Angebot fuer eine verschlossene Tuer ist keins.

JEDE VORLAGE HAT LUECKEN. Eine, die man absenden KANN, wird
abgesendet; dann steht dort zehnmal derselbe Satz, und der elfte
Mensch merkt, dass hier niemand wirklich schreibt. Die Pruefung misst
das: keine Vorlage ohne "…".

NICHT ZU VERWECHSELN MIT DEM STARTKATALOG. Der ist fuers Team (fertige
Beitraege zum Uebernehmen), das hier fuer die Mitglieder.

--- Vier Funde, drei davon nur aus dem Bild -------------------------

1. ZWEI KNOPFREIHEN MIT DENSELBEN WOERTERN. Auf "Regeln & Hilfe"
   standen "Regel · Haeufige Frage · Hilfe · Was passiert, wenn"
   zweimal untereinander -- die eine filterte, die andere sprang zur
   Ueberschrift, und beide sahen gleich aus. Wo nach Art gegliedert
   wird, entfaellt jetzt der Filter; die Sprungmarken sind Links
   geworden, mit "Springe zu" davor und der Anzahl dahinter.

2. "MELDEN" UNTER JEDER REGEL. Siebzehn Melden-Knoepfe unter Texten
   des Teams -- man meldet keine Regel. Steht jetzt nur noch an
   Beitraegen von Mitgliedern. Die Gegenprobe im Messwerkzeug legt
   dafuer eigens einen Beitrag eines zweiten Mitglieds an: Ohne ihn
   saehe ein abgeschaffter Meldeweg genauso aus wie ein
   funktionierender.

3. DER HINWEIS LAG AUF DER NAECHSTEN BESCHRIFTUNG. Auf 412 px stand
   "Gehoert allen hier - wer Der Treff sieht ..." quer ueber
   "UEBERSCHRIFT". Der Hinweis haengt absolut unter dem Feld, und
   darunter sind 30 px Luft -- genug fuer EINE Zeile. Unter 560 px
   steht ohnehin nur ein Feld je Zeile; dort gibt es nichts
   auszurichten, und er darf einfach im Fluss stehen.

4. UND MEIN EIGENER FEHLER, der alles unsichtbar machte: `vorlagen`
   gab es hier schon -- als Checkliste fuer Creator, mit demselben
   Behaelter `#vorlagen`. Die spaetere Funktionsdeklaration gewinnt,
   zwei Elemente trugen dieselbe Kennung, und die Starthilfe erschien
   NIE. Keine Fehlermeldung, keine rote Pruefung, nichts in der
   Konsole. Gefunden nur durch einen Blick auf das Bild.
   Deshalb prueft pruef-vorlagen jetzt im Browser mit, dass keine
   Kennung doppelt vorkommt -- derselbe Fehler wie am 17.09. mit
   `.teilen`, und beim naechsten Mal soll ihn nicht der Zufall finden.

Nebenbei messbar: "Regeln & Hilfe" ist von 4569 auf 3623 px
geschrumpft, die Karten sind 54 px niedriger.

Geprueft: pruef-vorlagen (neu, 24), pruef-video unveraendert 67.
Gegenproben: unbekannte Art -> rot; Vorlage ohne Luecke -> rot.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 19:00:43 +02:00
DogFatherGitandClaude Opus 5 d4e05e460a Community: die echte Sicht messbar machen -- und die Sternchen weg
Filipe: "perfektioniere jede einzelne kategorie der community."

ERST MESSEN. tools/community-blick.mjs meldet sich als GAST an und
fotografiert alle sieben Bretter. Das war noetig, weil als DogFather
auf jedem Brett Knoepfe und Felder stehen, die ein Mitglied nie sieht
-- wer so beurteilt, beurteilt eine Seite, die es fuer die Community
nicht gibt.

Der Weg dorthin war laenger als gedacht, und jeder Umweg steht als
Kommentar im Werkzeug:
  - Die Community hat eine EIGENE Anmeldeseite (crew-index.html); auf
    der anderen gibt es die Rolle "gast" gar nicht.
  - Wer sich zum ersten Mal anmeldet, muss sein Alter bestaetigen
    (400 "alter_offen"), sonst kommt er nicht hinein.
  - Ueber die echte Adresse schickt der Server HSTS, woraufhin
    Chromium alle Unterdateien auf https umbiegt -- der Testserver
    spricht nur http. Ergebnis: eine nackte Seite ohne Stil und ohne
    Skripte, auf der kein Knopf etwas tat. Die Kopfzeile ist richtig
    so und bleibt; stattdessen wird jetzt ueber die Kopfzeile
    angemeldet und das Sitzungsplaetzchen in den Browser gelegt.
Ohne diese drei Punkte fotografiert man die Anmeldeseite und haelt
"0 Karten, kein Schreibfeld" fuer einen Befund ueber die Bretter.

ERSTER BEFUND, BEHOBEN: An zehn Stellen stand **Fettschrift** als
Sternchen im Text. Auf "Regeln & Hilfe" hiess es woertlich "Drei
Stufen: **Hinweis** ..., **Pause** ..., **Ausschluss**" -- ausgerechnet
die drei Stufen, um die es geht, sahen aus wie ein Tippfehler.

KEIN innerHTML: Gebaut wird aus einzelnen Knoten. Was nicht zwischen
zwei Sternchenpaaren steht, wird Text und kann nichts anderes werden.
Ein einzelnes Sternchen bleibt ein Sternchen -- "3 * 4" ist keine
Hervorhebung.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 18:33:02 +02:00
DogFatherGitandClaude Opus 5 e933de3248 Anruf: der Lautsprecher -- und warum es kein Freisprech-Knopf ist
Filipe: "die funktion lautsprecher fehlt."

Er ist das Gegenstueck zum Mikrofon: "Mikro aus" heisst, die anderen
hoeren MICH nicht -- "Lautsprecher aus" heisst, ICH hoere sie nicht.
Beides braucht man, aus verschiedenen Gruenden: das Mikro, wenn es bei
einem selbst laut ist; den Lautsprecher, wenn nebenher etwas laeuft
oder jemand ins Zimmer kommt.

WAS BEWUSST NICHT GEBAUT WURDE: der Umschalter zwischen Hoermuschel
und Freisprechen, den ein Telefon hat. Recherchiert statt geraten --
den gibt es im Browser nicht: Auf dem iPhone entscheidet Safari
selbst, wohin der Ton geht, und Android laesst einzelne Toene gar
nicht auf ein anderes Geraet legen (setSinkId ist dort nicht
verfuegbar, weil die Plattform es nicht hergibt). Ein Knopf, der dort
nichts tut, waere schlimmer als keiner -- man drueckt ihn und sucht
den Fehler dann bei sich.

Wo es GEHT (Rechner mit Chrome, Edge, Safari), steht dafuer eine echte
Geraeteauswahl daneben. Sie erscheint nur, wenn es mehr als ein Geraet
gibt UND die Namen bekannt sind; eine Auswahl mit einem Eintrag ist
keine Auswahl, sondern eine Behauptung.

DIE PRUEFUNG, AUF DIE ES ANKOMMT: Kommt jemand dazu oder geht jemand,
werden die Toenelemente NEU GEBAUT -- und neue Elemente wissen nichts
von einem Schalter, der vorher umgelegt wurde. Genau daran scheitern
solche Knoepfe sonst: Sie wirken, bis sich die Runde aendert, und dann
hoert man ploetzlich wieder mit. Gegenprobe (Anwenden nach dem
Neuzeichnen ausgebaut) macht genau diese eine Pruefung rot, waehrend
alle anderen gruen bleiben.

Geprueft: pruef-anruf 73 -> 80, im echten Dreiergespraech im Browser.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 17:08:31 +02:00
DogFatherGitandClaude Opus 5 59c84bd248 Videos: Stufe 7 -- aus einem Wunsch wird ein Video, mit Namen
"Ein Video aus einem Wunsch zeigt den Namen." Wer sich etwas
gewuenscht hat, soll sehen, dass daraus etwas geworden ist -- das ist
der Sinn eines Wunschbretts. Ohne die Verbindung ist die Galerie eine
Sammlung, und der Wunsch von letzter Woche bleibt unbeantwortet im
Raum stehen.

DER KNOPF STEHT AM WUNSCH, nicht im Formular oben. Das ist dieselbe
Entscheidung wie bei den Kettenknoepfen daneben, aus demselben Grund
(dort woertlich): "Wer ein Formular ausfuellt, denkt nicht an den
Wunsch von letzter Woche." Hier denkt er an nichts anderes.

DAS LECK, das es nicht geben darf: Der Titel der Quelle wird auf der
Kachel ANGEZEIGT. Eine Kette in die Content-Planung waere deshalb kein
Schoenheitsfehler, sondern ein Weg, interne Arbeit in die Community zu
tragen. Die Quelle muss ein Community-Brett sein -- dieselbe Regel wie
beim "Daraus"-Knopf.

ZWEI WEGE, EIN ZIEL: "Daraus ein Highlight machen" gibt es laenger.
Wer ihn geht und DANACH das Video einfuegt, bekaeme sonst ein zweites
Highlight aus demselben Wunsch -- zwei Wege zum selben Ziel, die
nichts voneinander wissen. Das Video haengt sich jetzt an den
vorhandenen Eintrag. Der Titel bleibt dabei der des Wunsches: Er
stammt von einem Menschen, der von TikTok ist eine Bildunterschrift
mit Schlagwoertern.

Geprueft: pruef-video 51 -> 67. Gegenprobe (Brett-Pruefung und
Anhaengen ausgebaut) macht 6 rot, darunter "ein Eintrag aus der
Content-Planung kommt NICHT als Quelle durch (201)".

UND DAS BILDSCHIRMFOTO HAT ETWAS GEFUNDEN, das keine Zahl gemeldet
haette: Das Eingabefeld erschien am ENDE der Karte, unter der
Fusszeile -- getrennt von dem Knopf, den man gerade gedrueckt hatte.
Alle Pruefungen waren gruen, das Feld war da und reagierte. Jetzt
haengt es an der Knopfreihe.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 17:00:16 +02:00
DogFatherGitandClaude Opus 5 fb55377e19 Videos: Stufe 5 -- fuehrt der Knopf noch irgendwohin?
Ein Video kann bei TikTok geloescht oder auf privat gestellt werden.
Bei uns blieb der Eintrag stehen -- mit Cover, Text und einem Knopf
auf eine Fehlerseite. Das faellt beim Bauen nicht auf und beim Testen
nicht; es faellt dem auf, der klickt, und das ist die Community.

DREI ANTWORTEN, NICHT ZWEI. Die naheliegende Fassung fragt TikTok und
setzt bei einem Fehlschlag "weg". Die waere an einem einzigen
schlechten Nachmittag von TikTok in der Lage, die halbe Galerie als
geloescht zu markieren -- und wer das hinterher sucht, sucht lange,
denn im Protokoll stuende sauber, dass gefragt wurde. Also:

  Daten kommen an       -> da. Zaehler zurueck, eine frueher gesetzte
                           Markierung faellt weg (privat gestellte
                           Videos kommen wieder).
  "gibt es nicht" (404) -> ein Fehlversuch. Erst der DRITTE an drei
                           verschiedenen Tagen markiert.
  niemand antwortet     -> weiss nicht. Aendert gar nichts, nicht
                           einmal den Zeitstempel: Wer ihn setzte,
                           verschoebe die naechste Nachfrage um sieben
                           Tage, obwohl nichts gemessen wurde.

Drei Geschwindigkeiten beim Nachsehen: unauffaellig woechentlich,
verdaechtig taeglich (sonst dauerte eine Loeschung drei Wochen bis zur
Anzeige), schon markiert wieder woechentlich -- taeglich nachzufragen
waere Hammern fuer eine Auskunft, die wir schon haben. Gefunden hat
das eine rote Pruefung, nicht das Nachdenken davor.

Der Knopf verschwindet nicht, er sagt "Bei TikTok nicht mehr da".
Bewusst kein Rot: Es ist kein Fehler, sondern eine Auskunft -- Titel,
Text und Cover stimmen weiter, die liegen bei uns.

Geprueft: pruef-video 37 -> 51. Gegenprobe (Stoerung als "weg" werten
plus Markieren ab dem ersten Versuch) macht 8 rot, darunter woertlich
"eine Stoerung erhoeht den Zaehler NICHT (0 -> 1)".

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 16:08:15 +02:00
DogFatherGitandClaude Opus 5 775c4b4207 Vermittlungsserver: coturn mit Zugangsdaten, die verfallen
Damit Anrufe auch in Netzen zustande kommen, die keine direkte
Verbindung zulassen (15-25 % der Faelle). coturn ist installiert,
steht aber still, bis die Konfiguration liegt -- ein coturn mit
Werkseinstellung ist ein offenes Relais.

KEIN FESTES PASSWORT. Es laege dauerhaft im Browser jedes
Team-Mitglieds und liesse sich nie entziehen. Der Server rechnet
stattdessen bei jeder Abfrage Zugangsdaten, die nach zwoelf Stunden
verfallen (server/workspace-turn.js, coturns `use-auth-secret`). Das
Geheimnis liegt in einer Datei, nicht in der Datenbank: einstellung-
Setzen() schreibt Werte ins Protokoll, und coturn braucht denselben
Wert ohnehin in /etc.

Die Oberflaeche frischt die Daten vor jedem Anruf auf. Der Chat ist
eine App, die tagelang offen bleibt -- wer nur beim Laden holt,
telefoniert am zweiten Tag ohne Vermittlung, und es faellt nicht auf:
Es scheitern nur die, die sie gebraucht haetten.

DIE WICHTIGSTE ZEILE DER KONFIGURATION ist die Sperrliste. Gemessen:
dreizehn Dienste lauschen auf diesem Server nur oertlich, darunter
Caddys Verwaltung auf 127.0.0.1:2019 -- wer sie erreicht, kann jede
Website umleiten. Ohne Sperrliste waere der Vermittlungsserver die
Tuer dorthin, und die Anfrage saehe fuer Caddy aus wie von localhost.

Geprueft: pruef-anruf.mjs 51 -> 73 Pruefungen. Gegenprobe (Geheimnis
als Passwort ausliefern + fremde Zugangsdaten ueberschreiben) macht
genau 5 rot, darunter "das Geheimnis steht NIRGENDS in der Antwort".

tools/turn-probelauf.sh beweist am echten coturn, was ein fester
Vergleichswert nicht kann: dass coturn unsere Rechnung akzeptiert.
Beide Seiten koennten sonst konsequent falsch rechnen und jede
Pruefung waere gruen. Seine eigene Gegenprobe war zweimal zu Recht
rot -- der erste Aufbau mass wegen `-y` gar nicht das Ziel, das er zu
messen behauptete, sondern coturns eingebauten Loopback-Schutz.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 15:22:14 +02:00
DogFatherGitandClaude Opus 5 5bbf1f2019 Der Anruf funktioniert wirklich -- gefunden im Dreier-Test
GEBAUT WAR NICHT BEWIESEN. Der Anruf ist fuer bis zu vier Leute
geschrieben, geprueft war er zu zweit -- und der Zweier-Test pruefte
nur, dass der Kasten erscheint und die Uhr laeuft. Ob jemals TON
ankommt, hat er nie gefragt.

Der Dreier-Test hat es gefragt. Ergebnis beim ersten Lauf:

  DogFather      0 Stroeme, "Verbunden"
  rechte Hand    0 Stroeme, "Verbunden"
  der Modi       0 Stroeme, "Verbindung ..."

DREI FEHLER, gefunden durch Messen statt Raten:

1. SIGNALE, DIE ZU FRUEH KOMMEN, WURDEN WEGGEWORFEN -- und das haette
   JEDEN Anruf getroffen, auch zu zweit.

   Wer rangeht, meldet "dabei". Der Anrufer bekommt das sofort und
   schickt sein Angebot. Der Angerufene braucht danach aber noch ein
   bis zwei Sekunden fuer das Mikrofon, und in dieser Zeit war `anruf`
   noch null. Das Angebot wurde still verworfen; danach kommt keins
   mehr. Beide Seiten zeigten "Verbindung ...", und es passierte nie
   wieder etwas.

   In der Spur war es unuebersehbar, sobald man hinsah:
     ereignis:signal inhalt=angebot     <- kommt an
     ereignis:signal inhalt=weg
     verbindung angelegt                <- erst JETZT

   Ein Signal ist keine Nachricht, die man wiederholen kann. Wer es
   wegwirft, hat den Anruf verloren -- es wird jetzt aufgehoben und
   abgearbeitet, sobald das Mikrofon steht.

2. DIE WARTESCHLANGE LAG ZUERST AN DER FALSCHEN STELLE. Eingebaut in
   `signalVerarbeiten`, verworfen wurde aber schon eine Ebene hoeher.
   Gefunden erst, als die Diagnose zeigte, dass `signalVerarbeiten` NIE
   aufgerufen wird: keine einzige Konsolenzeile, obwohl beide Zweige
   dort etwas melden. Eine Reparatur an der falschen Stelle sieht aus
   wie eine Reparatur.

3. "VERBUNDEN" STAND DA, BEVOR ETWAS VERBUNDEN WAR. Die Meldung wurde
   gesetzt, wenn jemand RANGEHT -- die Verbindung braucht danach noch
   Sekunden. Den richtigen Zeitpunkt kennt nur die Verbindung selbst
   (`onconnectionstatechange`). Eine Anzeige, die etwas Falsches sagt,
   ist schlimmer als keine.

Dazu zwei Kleinigkeiten, die dabei auffielen: Das Abarbeiten laeuft
jetzt NACHEINANDER (ein Verbindungsweg, der vor der Beschreibung
ankommt, wird abgewiesen -- parallel gewinnt oft der Weg), und die
Warteschlange wird beim Auflegen geleert, damit kein altes Signal in
den naechsten Anruf wandert.

Und die Pruefung selbst hatte einen Fehler: Abschnitt 6 setzt erfundene
STUN-Adressen und liess sie stehen. Der Browser haette im naechsten
Abschnitt gegen deren Zeitlimit gekaempft statt gegen den Code. Sie
werden jetzt wieder geleert -- eine Pruefung, die der naechsten den
Boden verstellt, macht deren Ergebnis unlesbar.

pruef-anruf 40 -> 51. Der neue Abschnitt prueft das, worauf es
ankommt: Bei drei Teilnehmern muss JEDER zwei Stroeme haben. Haette
`verbindungen` eine einzelne Variable statt einer Karte, ginge es zu
zweit gut und der Dritte ueberschriebe stillschweigend den Ersten --
man sieht sich zu dritt und hoert einen.

Gegenprobe (Warteschlange wieder ausgebaut): 4 rot, genau die
Tonpruefungen.

Gruen: anruf, chat, css-klassen, namen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 14:42:44 +02:00
DogFatherGitandClaude Opus 5 93c9788782 Telefonieren im Chat -- und die Farben nach Nachbarschaft verteilt
ZWEI SACHEN IN EINEM COMMIT, weil beide aus derselben Nacht stammen.

=== 1. DIE FARBEN: DER RICHTIGE ABSTAND ===

Filipe: "es gibt noch mehr die aehnlich aussehen von den farben also
leg los alle die sich aehnlich sind von den farben wechseln."

Er hatte recht, und mein Denkfehler laesst sich benennen: Ich hatte den
kleinsten Abstand ueber ALLE 37 Paare maximiert -- und der liegt bei 37
Farben zwangslaeufig bei 0,10. Das ist die Packungsgrenze, kein
Versaeumnis.

NUR SIEHT NIEMAND ALLE 37 NEBENEINANDER. Man sieht NACHBARN. Im Browser
gemessen, an der tatsaechlichen Lage auf dem Schirm -- 125 Paare, die
wirklich nebeneinander stehen, 15 davon unter 0,15:

  Creator-Profile / Zahlen      0,1019   beide rosa-rot
  LIVE-Analyse / Technik        0,1030   beide orange
  Wunschliste / Meldungen       0,1032   beide gelbgruen
  Wer sieht was / Entwicklung   0,1039   beide cyan
  Regeln & Hilfe / Mitmachen    0,1047   beide gruen
  Der Treff / Anschlagbrett     0,1070   beide rosa

Die Farben bleiben, ihre ZUTEILUNG aendert sich:

  Nachbarabstand     0,1047 -> 0,2133   (mehr als verdoppelt)
  Nachbarn unter 0,15     6 -> 0

Die Nachbarschaft steht in server/kachel-nachbarn.json, gemessen im
Browser -- nicht aus der Struktur im Quelltext abgeleitet. Die sagt,
was zusammengehoert, nicht was zusammen zu sehen ist.

=== 2. TELEFONIEREN IM CHAT ===

Filipe: "kann man machen dass die modis, rechte hand und ich auch
telefonieren koennen im chat?" ... "was man selbst in die app
reinsetzten kann, nicht meinen pc belastet und trotzdem vielleicht in
gruppe, mit video oder einzelnd."

DER TON GEHT NICHT UEBER DEN SERVER. Direkt von Browser zu Browser
(WebRTC); der Server reicht nur die Verbindungsdaten weiter, ein paar
Kilobyte je Anruf. Zu zweit kodiert jedes Geraet einen Strom und
dekodiert einen -- die Last eines gewoehnlichen Videoanrufs.

KEIN NEUER DIENST. Der Chat hatte bereits alles: `chatEreignis()` fuer
den Hinweg (SSE), Push fuers Klingeln, Raeume mit mehreren
Teilnehmern. Ein eigener WebSocket daneben waere eine zweite
Verbindung fuer dieselbe Frage -- und die zweite wird beim naechsten
Umbau vergessen.

Gebaut: Ton und Video, einzeln und in Gruppe bis GRUPPE_MAX (4),
Klingeln mit Annehmen/Ablehnen, Mikro und Kamera schaltbar,
Gespraechsdauer, Auflegen. Der Chat bleibt daneben benutzbar -- man
schreibt oft, waehrend man spricht.

EIN FUND, DER OHNE PRUEFLAUF LIVE GEGANGEN WAERE: Der Server sperrt
Mikrofon und Kamera per Permissions-Policy auf ALLEN Seiten. Der erste
Lauf meldete "microphone is not allowed in this document" -- der Anruf
haette bei JEDEM versagt, mit einer Meldung, die auf die falsche
Faehrte fuehrt (man sucht an den Browsereinstellungen). Die Sperre
bleibt ueberall und ist an genau EINER Stelle geoeffnet: der
Chat-Seite, und nur fuer sie selbst (`self`, nicht `*`).

NOCH NICHT GEBAUT -- und ausdruecklich nicht heimlich: coturn. Ohne
Vermittlungsserver klappen Anrufe nur im selben Netz. Die Adressen
stehen in den Einstellungen statt im Quelltext; sie lassen sich
nachtragen, ohne eine Zeile zu aendern. Ein oeffentlicher STUN-Dienst
als Standard kam nicht in Frage: Er saehe bei jedem Anruf die
IP-Adressen beider Teilnehmer, und fuer ein Team, das ueber Moderation
und Vorfaelle spricht, ist das keine Kleinigkeit.

server/pruef-anruf.mjs, 40 Pruefungen. Der wichtigste Abschnitt: Wer
nicht in den Raum gehoert, kommt an KEINE Route. Ein Anruf hinterlaesst
keine Spur -- wer mithoert, faellt nicht auf.

Gegenproben, jede zielgenau:
  Empfaengerpruefung der Signalisierung weg -> 1 rot
  Raumpruefung weg                         -> 5 rot (jede Route offen)
  Kopfzeilen-Ausnahme weg                  -> 4 rot

Gruen: anruf, chat, chat-optik, chat-kanaele, css-klassen, namen,
struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 10:10:04 +02:00
DogFatherGitandClaude Opus 5 438493c7dc Kacheln: 37 Farben neu gerechnet, und in jeder ein eigenes Universum
Filipe, zwei Wuensche: "ich will das jede kachel eine andere farbe hat
... keine die sich irgendwie aehnlich sind ... richtig geil und
speziell" und "der hintergrund ... soll noch mehr viel mehr nach
universum sein. nicht einfach so paar weisse punkte sondern richtig
geil hochwertiger geiler universum ... in den kacheln ueberall".

BEIDES WAR BERECHTIGT, und beides liess sich messen:

  kleinster Farbabstand    0,0529   (Rueckmeldung / Steckbrief)
  Paare unter 0,10         26 von 666
  schlechtester Kontrast   1,64:1   (Ton 35 -- praktisch unlesbar)
  sieben Toene unter 4,5:1
  Universum                auf GENAU EINER Kachel

WIE DAS PASSIEREN KONNTE, obwohl es ein Farbwerkzeug gab: Es kannte 21
Farben. Seit dem 08.09. waren SECHZEHN von Hand dazugekommen (Ton 22
bis 37) -- jede einzeln plausibel, keine gegen die anderen gerechnet.
Das Werkzeug meldete weiter "0,0973, alle Bedingungen erfuellt" und
meinte einen Stand, den es nicht mehr gab. Dieselbe Krankheit wie eine
abgeschriebene Spaltenliste: Die Zahl wird nicht falsch, sie wird
UNZUSTAENDIG. Es liest die Anzahl jetzt aus den Dateien.

NEU GERECHNET, alle 37 auf einmal:
  kleinster Abstand   0,0529 -> 0,1010   (fast doppelt)
  Paare unter 0,10        26 -> 0
  schlechtester Kontrast 1,64 -> 4,50:1
  Buntheit bis 0,300 statt 0,170, Helligkeit 0,58 bis 0,92

Drei Stellschrauben: Buntheitsgrenze hoch (augenschonend heisst dunkles
Schema und kein Flackern, NICHT blass), Raster von 2 Grad auf 1 Grad
und von fuenf auf zwanzig Helligkeitsstufen, und sechzehn Startpunkte
statt einem. Der Kontrast 4,5:1 bleibt hart -- eine Kachelfarbe traegt
Text.

DAS UNIVERSUM STEHT JETZT IM HINTERGRUND JEDER KACHEL, nicht in einem
Element: Beide Pseudo-Elemente sind vergeben (Leuchtschiene, Glanz),
und ein neues Element muesste an jeder Stelle nachgetragen werden, die
Kacheln baut. Eine Ebene, die man vergessen kann, wird vergessen.

Siebzehn Ebenen: drei nahe Sterne mit Hof, vier mittlere (zwei im
Kachelton), fuenf Staubkoerner, eine Milchstrasse als Schraege, drei
Nebel im Kachelton, ein kuehler Gegenpol, eine Vignette. Die Nebel
tragen `var(--ton)` -- 37 Kacheln sind damit 37 verschiedene Nebel.
Keine Bewegung: 28 driftende Felder waeren 28 Dauerlaeufer auf der
Grafikkarte.

Nach dem ersten Bildschirmfoto nachgeschaerft -- die Sterne lagen bei
6 bis 14 Prozent und waren aus der Naehe nicht zu sehen, genau die
"paar weissen punkte". Der Grund steht in der Kachel selbst: Sie ist
halbdurchsichtig, darunter liegt das Buehnenbild. Ein Sternenfeld muss
sich hier gegen ein FOTO durchsetzen, nicht gegen Schwarz.

NEU: server/helfer-png.mjs -- ein PNG-Leser (zlib, 90 Zeilen). Er
beantwortet die Frage, die aus dem CSS nicht mehr zu beantworten war:
Zwischen Textfarbe und Flaeche liegen jetzt sieben Ebenen plus das
durchscheinende Buehnenbild. Gemessen am Bildschirmfoto: schlechtester
Textkontrast 8,02:1 (Grenze 4,5).

NEU: server/pruef-kachel-universum.mjs, 12 Pruefungen.
DREI ANLAEUFE FUER DIE STERNPRUEFUNG, und die ersten zwei waren gruen
und wertlos:
  1. Ebenen im CSS zaehlen -- `0px` ist auch eine Zahl. Alle Sterne
     auf null: blieb gruen.
  2. Helle Punkte im Bildschirmfoto zaehlen -- die Kachel ist
     halbdurchsichtig, das Foto darunter hat selbst Punktstruktur.
     Gemessen: 459 Punkte mit Sternen, 441 ohne. Vier Prozent sind
     kein Nachweis, sondern Rauschen.
  3. Jetzt die GROESSEN aus dem CSS (>= 0,7 px). Schwaecher, aber
     ehrlich -- und die Gegenprobe greift: 12 -> 0.
Dabei fiel ein eigener Messfehler auf: Der Bereich wurde aus der
Textposition geschaetzt und lag OBERHALB der Kachel. Verraten hat es
die Gegenprobe, die zweimal exakt 153 lieferte -- eine Messung, deren
Ergebnis sich nicht aendert, wenn man das Gemessene entfernt, misst
etwas anderes.

Gegenproben, alle zielgenau:
  zwei gleiche Farben   -> 3 rot      Sterne auf 0px  -> 1 rot
  Nebel ohne Kachelton  -> 1 rot (nach dem Schaerfen: vorher blieb es
                            gruen, weil `--ton` auch im Grundverlauf steht)

Gruen: kachel-universum, css-klassen, start-ansicht, namen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 02:55:23 +02:00
DogFatherGitandClaude Opus 5 3d9de349ad Wer sich kuemmert -- an jeder Anfrage und an jedem Kandidaten
Ein Versprechen von frueher, nie gebaut: die Arbeit mit der rechten
Hand teilen. Gemessen: Es gab dafuer NICHTS. Weder an `bewerbungen`
noch an `talent_stufe` stand eine Zustaendigkeit -- beide sehen alles,
niemand ist benannt.

Das ist nicht "geteilt", das ist "jeder dachte, der andere macht es".
Bei einer Anfrage wartet ein Mensch darauf. Bei einem Kandidaten
bleibt er auf seiner Stufe liegen -- die Standzeit an der Karte sagt
zwar, DASS etwas liegt, aber nicht, wer es aufheben sollte.

MAN NIMMT SELBST, MAN BEKOMMT NICHT ZUGETEILT. Ein "DogFather weist
zu" waere eine Rangordnung, und die gehoert hier nicht hin (18.08.2026:
"mich bitte nie wie da hoeher stellen wie andere"). Wer Zeit hat,
uebernimmt; wer keine mehr hat, gibt ab -- mit DEMSELBEN Knopf, wie bei
den Merkmalen und den Probeschritten.

DER FALL, AUF DEN ES ANKOMMT: Eine FREMDE Uebernahme wird mit 409
abgewiesen, nicht stillschweigend ueberschrieben. Sonst nimmt einer dem
anderen die Anfrage aus der Hand, ohne dass es jemand merkt -- und
beide glauben, sie sei erledigt. Wer trotzdem will, laesst erst
abgeben.

DER UNBESETZTE ZUSTAND IST DER AUFFAELLIGE. "Ich kuemmere mich" steht
als Knopf da, "Du kuemmerst dich" als ruhige Zeile, fremdes als
gestrichelter Rahmen ohne Zeigefinger (ein Knopf, der aussieht wie
einer und nichts tut, ist eine Falle). Andersherum waere die Liste ein
Feld aus Namen, in dem die Luecke nicht auffaellt -- und genau die
Luecke ist die Auskunft.

Verglichen wird ueber die NUMMER, nicht ueber den Namen: Zwei Leute
duerfen gleich heissen.

DREI EIGENE FEHLER, alle beim Nachsehen gefunden statt beim Schreiben:

 1. `nurLeitung` HAT AN MEINER ROUTE GEFEHLT. Der Router setzt
    `angemeldet` fuer den ganzen Pfad, `nurLeitung` aber je Route --
    ich hatte nur die Nachbarzeilen ueberflogen. Ohne den Riegel haette
    sich jeder Angemeldete fuer eine fremde Anfrage zustaendig erklaert:
    kein Datenabfluss, aber ein Name an einer Anfrage, der dort nichts
    zu suchen hat -- und sie gilt als betreut, waehrend sich niemand
    kuemmert. Gegenprobe bestaetigt: ohne die Zeile 200 statt 404.
 2. `nummer()` aufgerufen, das es in dieser Datei gar nicht gibt --
    ein Absturz zur Laufzeit, den `node --check` nicht sieht.
 3. Die Pruefung benutzte `json()` und rohe Cookie-Objekte statt der
    Hausmittel `alsJson`/`holen`/`schicken` dieser Datei. Abgeschrieben
    aus der Nachbardatei, in der sie anders heissen.

Und wieder eine Zeile, die ohne Daten gruen war: "um die sich niemand
kuemmert" bestaetigte auch bei LEERER Liste -- `undefined` ist nun
einmal kein Zustaendiger. Die Anzahl gehoert in die Bedingung.

pruef-nachwuchs 244 -> 258, pruef-bewerbung 77 -> 91.
Gegenproben:
  Riegel gegen fremde Uebernahme weg -> 5 rot
  nurLeitung weg                     -> 2 rot (der eigene Fehler)

pruef-nachruesten fuehrt beide neuen Spalten mit.

Gruen: nachwuchs, bewerbung, nachruesten, namen, css-klassen, struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 01:47:11 +02:00
DogFatherGitandClaude Opus 5 1a2dfa07f3 Trichter und Entwicklungskarte kennen einander
An der Stufe "Im Team" steht seit jeher zweimal: "ab hier zaehlt die
Entwicklungskarte, nicht mehr diese". Gemessen: Es gab keinen Weg
dorthin. Wer den Satz las, musste die Seite selbst finden und die
Person dort aus einer Liste heraussuchen.

Das ist heute das DRITTE Mal dasselbe Muster -- ein Text verspricht
einen Weg, den es nicht gibt:
  "uebernehmen oder sauber beenden"  -> der Ausgang fehlte
  Kalender zeigt Brettzettel         -> zurueck fuehrte nichts
  "ab hier die Entwicklungskarte"    -> kein Link

HIN: Von der Talentkarte fuehrt ein Weg auf die Entwicklungskarte
GENAU DIESER Person -- ueber `?zeigen=person-<id>`, den Weg, den das
Haus dafuer schon hat (kopf.js), nicht ueber eine zweite Mechanik. Die
Karte ist beim Ankommen offen; ein Link, der auf einer Liste endet, auf
der man die Person wieder sucht, hat nichts erspart.

Der Sprung passiert ERST, wenn alle Kacheln stehen. Waehrend der
Schleife haengt die gesuchte noch nicht im Dokument und hat keine
Position -- ein Sprung dorthin waere einer an den Seitenanfang,
lautlos, und man haelt den Link fuer kaputt.

ZURUECK: Die Entwicklungskarte sagt jetzt, wie dieser Mensch gekommen
ist -- mit dem Namen der Talentkarte und wer ihn eingearbeitet hat.
Beim ersten Beurteilen ist genau das die Frage ("woher kommt der
eigentlich?"), und wer sie nicht beantwortet bekommt, faengt bei null
an, obwohl vier Wochen Beobachtung vorliegen.

NUR DER WEG, NICHT DIE DATEN. Die Merkmale aus dem Trichter hierher zu
kopieren waere bequem und falsch: zwei Kataloge, zwei Fragen (taugt er?
/ wie entwickelt er sich?). Eine Zahl aus dem einen sieht im anderen
aus wie eine Beurteilung und ist keine.

Moeglich wurde beides erst durch `talent_stufe.person_id` von vorhin --
ohne die Verknuepfung gibt es keine Richtung, in die man zeigen
koennte.

pruef-nachwuchs 236 -> 244. Geprueft wird nicht, ob ein Link DASTEHT,
sondern ob man am Ziel ankommt: Karte offen, richtige Person, Kachel
hervorgehoben, Herkunft da, Rueckweg da. Mit Gegenprobe an einer
zweiten Karte, die NICHT aus dem Trichter kam (sonst hiesse "kam ueber
den Trichter" nur, dass ueberall etwas steht).

Gegenproben:
  Sprung ausgebaut    -> 5 rot
  Herkunft ausgebaut  -> 2 rot, genau die beiden richtigen

Und wieder eine Schriftgroesse unter der Hausgrenze (.7rem = 11,2 px),
gefunden von pruef-css-klassen. Zurueckhaltend wird ueber FARBE
gedaempft, nicht ueber Groesse -- das ist der Unterschied zwischen
"leise" und "zusammengekniffen".

Gruen: nachwuchs, entwicklung, sprung, modi-wortleck, namen,
css-klassen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 01:01:12 +02:00
DogFatherGitandClaude Opus 5 a435e734c9 Aus dem Talent wird ein Mensch mit Aufgaben
Filipe: "wie talente bewertet werden, aufgaben bekommen, analysiert
werden von vanvan und mir, alles moegliche."

GEMESSEN VOR DEM BAU, und der Befund war groesser als erwartet: Der
letzte Schritt des Trichters legt einen Zugang an -- und die
Verknuepfung wurde NIRGENDS gespeichert. `zugangAnlegen()` gab die
Person zurueck, der Code wurde einmal gezeigt, und danach wusste die
Karte nicht mehr, wer aus ihr geworden ist.

Was dadurch nicht ging:
  - von der Karte zur Person springen
  - dem Neuen aus der Karte heraus seine ersten Aufgaben geben
  - in einem halben Jahr nachsehen, aus welchem Kandidaten eigentlich
    welches Teammitglied wurde

DREI SPALTEN WAEREN ZU VIEL GEWESEN, eine reicht: `talent_stufe.person_id`.
Kein Fremdschluessel auf `personen` -- wird ein Zugang geloescht, soll
die Karte stehen bleiben. Sie erzaehlt, wie jemand gekommen ist, und
das bleibt wahr, auch wenn er wieder geht. Ein CASCADE haette genau
diesen Verlauf mitgeloescht.

NUR SETZEN, NIE LOESCHEN (COALESCE): Sonst verloere die Karte ihren
Menschen, sobald jemand sie auf eine fruehere Stufe zuruecksetzt.

WOMIT ER ANFAENGT. Der Katalog mit 101 Aufgaben in 14 Bereichen gab es
laengst -- nur fuehrte der Weg dorthin ueber eine andere Seite, wo man
die Person heraussuchen und Bereich plus Stufe waehlen musste. Vier
Schritte, die niemand macht, waehrend er gerade jemanden aufnimmt;
dasselbe Muster hat heute schon zu einer Karte auf "Im Team" ohne
Menschen darin gefuehrt. Jetzt steht der Kasten an der Karte, ein Klick
legt einen Bereich an.

ES BLEIBT EIN ANGEBOT, KEINE AUTOMATIK -- Filipes Entscheidung bei der
Live-Checkliste gilt hier genauso: "was ungefragt Dinge anlegt, ist
schwer wieder loszuwerden". Und der Kasten ist ZU, wenn schon Aufgaben
da sind; offen wuerde er zum Nachlegen einladen, und das ist selten
gemeint. Daneben steht, wie viele schon offen sind -- ohne diese Zahl
legt man beim zweiten Hinsehen dasselbe noch einmal an.

pruef-nachwuchs 200 -> 236, davon 14 im Browser (Abschnitt 17 mit
eigenem Browser: der aus Abschnitt 15 lief, bevor es den Kandidaten
ueberhaupt gab -- ein Stand von zwei Abschnitten vorher ist keine
Messung, sondern eine Annahme).

VIER EIGENE FEHLER DABEI GEFUNDEN, drei davon durch die Gegenproben:

 1. `d.angelegt?.length` -- die Antwort ist eine ZAHL, kein Feld. Der
    Knopf haette "6 Aufgaben stehen bereit" gemeldet, auch wenn null
    entstanden sind.
 2. Der "Schritt zurueck" ging auf `probe` -- und der verlangt Buddy
    und Datum. Die Route antwortete 400, die Stufe blieb stehen, und
    die Zeile darunter bestaetigte, dass sich nichts geaendert hat:
    eine Pruefung, die immer gruen ist. Aufgefallen erst an der
    Gegenprobe (COALESCE ausgebaut -> blieb gruen). Eine Gegenprobe
    ist keine Kuer, sie prueft die Pruefung.
 3. Feldnamen `buddy`/`datum` statt `buddy_id`/`erste_schicht` --
    Fehler in der Pruefung, nicht im Code.
 4. Die Rollennamen-Zeile war ZU SCHARF und meldete prompt einen
    Treffer: "Die Modis, die mit ihm gearbeitet haben" aus dem
    Probeplan -- ein Satz, der ueber eine Schnittstelle kommt, die nur
    die Leitung erreicht, und genau dorthin gehoert. Geprueft wird
    jetzt, was hier neu ist; ueber die ausgelieferten DATEIEN wacht
    pruef-modi-wortleck (101 Dateien, mit eigener Gegenprobe).

Gegenproben, jede zielgenau:
  Nummer ungeprueft     -> "erfundene Zugangsnummer wird abgewiesen"
  COALESCE weg          -> "Schritt zurueck nimmt ihr den Menschen weg"
  Person nicht geliefert-> 4 rot

pruef-nachruesten fuehrt die neue Spalte mit -- jede neue Spalte gehoert
in diese Liste, sonst prueft die Datei den Weg von gestern.

Gruen: nachwuchs, nachruesten, modi-wortleck, namen, css-klassen,
struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 00:12:14 +02:00
DogFatherGitandClaude Opus 5 5e628e0078 Brett und Kalender kennen einander jetzt in beide Richtungen
Der Kalender zeigt seit heute, was auf den Brettern steht und einen
Termin hat. Die Verbindung war aber EINSEITIG, und beide Halften
fehlten:

  Beim SCHREIBEN konnte niemand wissen, dass ein Tag in der Zukunft den
  Zettel in den Kalender bringt. Das Feld heisst "Datum" und ist mit
  HEUTE vorbelegt -- die Funktion war vorhanden und unauffindbar. Eine
  Funktion, die niemand findet, ist keine.

  Beim LESEN sagte die Karte nichts. Am Fuss stand bloss ein Datum, und
  "24.09.2026" sieht aus wie "17.09.2026" -- obwohl das eine ein Termin
  ist und das andere der Tag, an dem jemand getippt hat.

EINE REGEL, ZWEI VERWENDER -> server/workspace-termin-regel.js.
Der Kalender fragt "welche gehoeren hinein?" (SQL, ganze Tabelle), die
Brettkarte fragt "stehe ICH drin?" (JavaScript, je Zeile). Beide Fassungen
stehen jetzt nebeneinander in EINER Datei, importfrei wie
treff-tabellen.js.

Das ist kein Vorsichtsprinzip, sondern Erfahrung: Zwei Fassungen
derselben Regel sind im Haus dreimal auseinandergelaufen -- die
abgeschriebene Spaltenliste (11.09., drei Spalten samt Inhalt weg), die
zweite Artenliste neben ARTNAME (ein BigMatch liess sich anlegen und
war unsichtbar) und `.teilen` heute frueh.

server/pruef-terminregel.mjs, 35 Pruefungen. Der Kern ist Abschnitt 2:
Er prueft die beiden Fassungen GEGENEINANDER, nicht jede fuer sich --
zwei Pruefungen, die je eine Seite bestaetigen, finden genau diesen
Fehler nicht. Verglichen wird beides: WELCHE Zettel und WELCHER Tag.
Neun Faelle, davon vier, die zu Recht wegbleiben.

Vier Gegenproben, jede in ihre eigene Richtung:
  JS laesst mehr durch -> "die Karte behauptet einen Termin, den der
                           Kalender nicht kennt"
  JS nennt anderen Tag -> "verschiedene Tage: Kalender 22., Karte 17."
  SQL laesst mehr durch-> "steht im Kalender, aber die Karte sagt nichts"
  Marke ausgebaut      -> 0 statt 1

EIN ECHTER FEHLER DABEI BEHOBEN, und er war aelter als diese Arbeit:
Das Formularraster gibt jedem Feld GENAU ZWEI Zeilen (Schild dehnbar,
Eingabe fest 44 px) -- deshalb sitzen die Eingaben auf einer Linie. Ein
Hinweisabsatz erzeugt eine dritte Zeile, und weil das Raster alle
Felder auf gleiche Hoehe dehnt, rutscht ausgerechnet diese Eingabe nach
oben. Gemessen: 328..372 gegen 351..395. 23 px -- genau das, was man
als "verzogen" sieht.

Mit `git stash` getrennt: aufgaben.html war dadurch SCHON VORHER rot
(ein anderes Feld hat dort ebenfalls einen Hinweis), bereich.html hatte
ich neu verursacht. Der Hinweis haengt jetzt absolut unter dem Feld --
beide sind gruen, und zwar an der Wurzel, nicht symptomatisch.
`pointer-events: none`, sonst faengt der Satz Klicks ab, die dem
Element darunter galten.

Am Handy gemessen statt geschaetzt: 0 Ueberschneidungen mit anderen
Feldern. Gegenprobe (row-gap auf 2 px): 1 Ueberschneidung.

Und noch zwei eigene Pruefungsfehler behoben, beide von derselben Sorte:
ein falscher Selektor samt `.catch(() => {})`, der den Fehlgriff
lautlos verschluckte (danach war das Hinweisfeld leer und die Zeile
darunter trotzdem gruen, weil "" nun einmal nicht "ja" ist) -- und die
Marke wurde ueber `textContent` gezaehlt statt ueber ihre Sichtbarkeit.
Aufgefallen ist das am Bildschirmfoto, auf dem ich sie fuer fehlend
hielt; deshalb macht die Pruefung jetzt zusaetzlich einen AUSSCHNITT
der Karte -- auf einem Vollbild von 2000 px ist eine Pille von 28 px
nicht zu beurteilen.

Gruen: terminregel, kalender, formulare, ueberlappung, countdown,
namen, css-klassen, struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 23:53:05 +02:00
DogFatherGitandClaude Opus 5 fabb1f94a8 Kalender: was auf den Brettern steht und einen Termin hat
Filipe, zu einer Clip-Karte: "ich will dass die auch in einer kalender
drin sind, aber ich will dass es richtig geil ist und perfektionier das
bitte."

Gemessen vor dem Bau: /workspace/api/termine lieferte `termine` und
`fristen`. Die Zettel von den achtzehn Brettern kamen nirgends vor --
obwohl `eintraege` seit langem VIER Zeitfelder hat: datum, uhrzeit,
geplant, event_ende.

WELCHE HINEINGEHOEREN, IST DIE GANZE FRAGE -- und sie laesst sich
messen statt raten. `datum` ist ein Pflichtfeld und faellt auf HEUTE
zurueck, wenn niemand eins waehlt. Alle Eintraege hineinzukippen hiesse
also: jeder je getippte Zettel steht an dem Tag, an dem ihn jemand
getippt hat. Nach einem Monat waere der Kalender ein Protokoll und kein
Plan -- und ein Kalender, in dem alles steht, sagt nichts mehr.

GEZEIGT WIRD NUR, WOFUER JEMAND EINE ZEIT BESTIMMT HAT:
  geplant        eine Zusage ("Wird gemacht -- am 24.09.")
  event_ende     ein Zeitraum
  uhrzeit        niemand tippt aus Versehen 20:00
  datum > heute  der Rueckfall ist IMMER heute oder frueher
Erledigtes bleibt draussen. Der vierte Fall ist der wichtigste und der
unauffaelligste: kein neues Feld, keine Umgewoehnung.

RECHTE: dieselbe Funktion wie die Bretter selbst (`sichtbarEintrag`),
nicht eine zweite Meinung. Im Kalender steht nur eine kleine Pille mit
einem Titel -- dass darin ein vertrauliches Vorhaben steckt, faellt
niemandem auf, der nicht danach sucht. Genau so kam am 03.09. eine
Managerin an fremde Aufgabenfristen.

DREI FEHLER AM BILDSCHIRMFOTO GEFUNDEN, nicht an einer Zahl:
  1. Der Brettname stand VOR dem Titel -- aus "Clip am Wochenende"
     wurde "Cli...". Das Etikett verdraengte, was es einordnen sollte.
     Jetzt zweite Zeile: Hoehe ist im Monatsraster der billigere Platz.
  2. Am Handy (45px Zellbreite) wurde daraus ein "Co..." -- Hoehe ohne
     Information. Jetzt eine CONTAINER-Abfrage: entschieden wird nach
     der Breite der ZELLE, nicht des Fensters. Eine Fensterschwelle
     waere wieder die Rechnung von gestern (September, Kopfleiste,
     zweimal).
  3. .64rem = 10,24px -- unter der Hausgrenze 11,5px, gefunden von
     pruef-css-klassen. Gedaempft wird jetzt ueber Farbe und Gewicht,
     nicht ueber Groesse.

EIN ECHTER FEHLER VERHINDERT: In der Listenansicht waeren die Zettel im
Termin-Zweig gelandet -- mit Wecker, "erledigt" und "loeschen". Der
Knopf haette PATCH /api/termine/b12 geschickt: eine Nummer, die es dort
nicht gibt, an eine Schnittstelle, die davon nichts weiss. Still, ohne
Wirkung, ohne Meldung.

DER WEG FUEHRT AUF DEN ZETTEL, nicht nur auf das Brett -- ueber
`?zeigen=` (kopf.js), den Weg, den das Haus dafuer schon hat. Zwischen
zwanzig Eintraegen waere der gesuchte sonst von Hand zu suchen.

pruef-kalender: +25 Pruefungen. Sieben Gegenproben, jede zielgenau:
  Schnitt weg            -> 6 rot   Erledigtes rein      -> 6 rot
  Rechteregel ausgehebelt-> 1 rot   COALESCE weg         -> 1 rot
  Termin-Knoepfe an      -> 2 rot   Container-Regel weg  -> 1 rot
  Sprung-Zweig weg       -> 3 rot

UND SIEBEN FESTE ZAHLEN ABGELEITET. Die alten Pruefungen zaehlten
"alle fünf Einträge", "vier Arten", "vier Filter" -- mit den neuen
Testdaten wurden daraus zehn, und sieben Pruefungen je Bildschirmgroesse
wurden rot, ohne dass am Kalender etwas kaputt war. Mit `git stash`
nachgemessen (ohne meine Aenderung: 0 Fehler), also nicht angepasst,
sondern gerechnet: jede Zahl kommt jetzt aus den Testdaten darueber.

Zwei eigene Pruefungsfehler dabei behoben: ein falscher Umschalter-
Selektor liess `every()` auf einem leeren Feld laufen (gruen ohne
Daten), und die Sichtbarkeit der zweiten Zeile wurde ueber
`textContent` gemessen -- das liefert auch, was `display: none`
ausblendet.

Gruen: kalender, sprung, namen, css-klassen, struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 22:48:38 +02:00
DogFatherGitandClaude Opus 5 e3e015bca4 Kopfleiste: ein Name, der zweimal vergeben war
Filipe zu einem Bildschirmfoto: "was soll das jetzt, wieso sieht das in
gewissen seiten so scheisse aus?!"

Der Teilen-Knopf stand doppelt so hoch wie seine Nachbarn, mit dem
Zeichen UEBER dem Wort statt daneben. Es war kein Gestaltungsfehler,
sondern ein Name: `.teilen` gab es ZWEIMAL --

  gate.css      Knopf der Kopfleiste   inline-flex, waagerecht
  bereich.css   Layout der Teilen-Seite  flex column, 22px, 44rem

Auf den drei Seiten, die beide Dateien laden (bereich, bewerben,
teilen), gewann die spaeter geladene. Der Knopf bekam das Layout einer
ganzen Seite. "Gewisse Seiten" war exakt richtig beobachtet.

DERSELBE NAME KOSTETE AUSSERDEM DEN KNOPF: kopf.js baut ihn nur ein,
wenn `getElementById('teilen')` nichts findet -- ein Schutz gegen
doppelten Einbau. Auf teilen.html steht `<section id="teilen">` aber
schon im HTML. Dort fehlte der Knopf ganz, ohne Spur, ohne Meldung.

REPARIERT ALS REGEL, NICHT ALS EINZELFALL:
  - Was kopf.js in die Leiste haengt, traegt jetzt `kopf-` davor
    (kopf-teilen, kopf-sicht-wahl, kopf-sicht-feld, kopf-fremd-band).
    Eine Seite darf dann heissen wie sie will -- auch "teilen", "chat"
    oder "suchen", und genau diese Woerter braucht als naechstes eine
    Seite.
  - Die Teilen-Seite bekommt eigene Klassennamen (tl-*).

NEU: server/pruef-namen.mjs (12 Pruefungen, ohne Server, <1 s).
Es ist der ZWEITE Namenskonflikt an einem Tag -- der erste war
`.t-schritt` auf der Talente-Seite, gefunden nur durch Zaehlen im
Browser. Beide waren gruen in jeder bestehenden Prueflinie.
Gemessen, um den Schnitt zu finden, der etwas taugt:
  2872 Klasse in zwei geladenen Dateien erwaehnt      -> Rauschen
  1887 davon mit eigener Blockdefinition              -> Rauschen
    12 davon mit widersprechendem `display`
     6 davon ohne `display: none`                     -> geprueft
Mit Gegenprobe, die aus den Dateien ABGELEITET wird (die erste, fest
abgeschriebene Fassung fand nichts, weil die gewaehlte Klasse dort gar
kein `display` setzt -- eine Gegenprobe, die selbst danebenliegt,
beweist nichts).

pruef-kopf-messen: 3 -> 16 Messungen, und drei eigene Fehler behoben,
die alle dieselbe Form hatten -- zu frueh hingesehen:
  1. Sie mass NUR uebersicht.html. Die laedt bereich.css nicht und war
     fuer diesen Fehler blind.
  2. Sie mass nur 320/390/430px. Unter 720px versteckt gate.css das
     Wort "Teilen"; der Knopf bleibt klein, auch falsch angeordnet.
     Filipes Bild war 1366px breit.
  3. Sie wartete 300ms. kopf.js haengt Teile erst nach `/api/ich` ein
     und hat ein Netz bei 1200ms. Zweiter Versuch: warten, bis `#wer`
     Text hat -- SOFORT wahr, dort steht `…` als Platzhalter. Dritter:
     auf Stabilitaet warten -- nach 0ms und 500ms gleich gross, also
     "fertig". Erst die Mindestwartezeit (1200 aus kopf.js plus Luft)
     davor machte die Messung echt.
Bewiesen an der Gegenprobe: mit dem alten Fehler meldet sie jetzt
"kopf-teilen ist 77px -- die anderen im Schnitt 43px", vorher blieb sie
gruen.

Statt einer festen Hoehe wird gefragt, ob EIN Teil aus der Reihe faellt
(> 1,6x der Schnitt seiner Nachbarn). Das waechst mit, wenn die Leiste
groesser wird, und muss bei keinem neuen Knopf nachgezogen werden.

Gruen: namen, kopf-messen, sicht, css-klassen, struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 18:59:19 +02:00
DogFatherGitandClaude Opus 5 e54c6829f1 Talente: der Trichter bekommt einen Ausgang
Gemessen vor dem Bau: talentNaechste kettet aufgefallen -> beobachtet ->
angesprochen -> probe -> imteam, und danach kommt nichts. Eine Suche nach
"beenden|abgesagt|verworfen|archiv" in workspace-entwicklung.js fand
nichts. Der Trichter hatte genau einen Ausgang -- obwohl der Text der
Probe-Stufe woertlich verspricht: "Nach 30 Tagen: uebernehmen -- der
Zugang entsteht dabei -- oder sauber beenden."

Wer nicht passte, blieb also auf seiner Stufe stehen, mit wachsender
Standzeit und rotem "liegt"-Zeichen. Nach einem Jahr hat die Liste mehr
Karteileichen als Kandidaten, und dann schaut niemand mehr hin.

DREI SPALTEN, KEINE NEUE STUFE. Eine neue Stufe haette einen
CHECK-Umbau auf laufenden Daten verlangt -- und eine Auskunft zerstoert:
Die Stufe haelt fest, WO es geendet hat. "Beendet in der Probe" und
"beendet nach dem ersten Hinsehen" sind zwei verschiedene Saetze, und
genau der Unterschied ist die Frage, wenn dieselbe Person in einem
halben Jahr wieder auffaellt.

DER SATZ IST PFLICHT (10 Zeichen, wie beim Ablehnen einer Anfrage) --
aus zwei Richtungen: Nach vorn, weil beim zweiten Anlauf niemand mehr
weiss, was damals war. Nach innen, weil wer schreiben muss, anders
entscheidet als wer klickt. "Passt nicht" hat neun Zeichen.

WIEDER AUFNEHMEN setzt auf "aufgefallen" zurueck -- Menschen aendern
sich, ein Urteil von damals gilt nicht weiter -- und rettet den alten
Satz in die Notiz, statt ihn zu loeschen.

AM BILDSCHIRMFOTO GEFUNDEN, nicht an einer Zahl: Auf einer Karte auf
"Im Team" stand "Nichts mehr zu tun -- der Zugang steht" und direkt
darunter "Passt doch nicht?". Ein Beenden dort haette die Karte
stillgelegt und den ZUGANG offengelassen -- eine halbe Handlung, die
sich wie eine ganze anfuehlt. Jetzt steht dort der Weg zu "Personen &
Zugaenge", und der Server weist es mit 409 ab.

pruef-nachwuchs 152 -> 200, davon 21 im echten Browser (der erste
Browserblick auf diese Seite ueberhaupt -- mit einer Messung, ob Name
und Datum bei 390 px uebereinanderliegen, statt einer Zahl im CSS).
Sechs Gegenproben, jede genau auf ihr Ziel:
  Grenze auf 0          -> 3 rot
  Beendete bleiben drin -> 2 rot
  beendete: []          -> 5 rot
  alter Grund verworfen -> 1 rot
  Serverriegel imteam   -> 5 rot
  Browserzweig imteam   -> 3 rot
Dazu gruen: css-klassen, struktur, entwicklung, uebergang.

Nebenbefund behoben: absage() im Browser warf einen erklaerenden Satz
des Servers lautlos weg und zeigte "Ging nicht." -- die Auskunft war da.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 18:39:06 +02:00
DogFatherGit 3a49e30aa4 Die Probezeit hat einen Inhalt -- und man sieht, wer was gesehen hat
Filipe: "wie talente bewertet werden, aufgaben bekommen, analysiert
werden von vanvan und mir, alles moegliche, wie gesagt ich will hoch
profissionel arbeiten."

WAS GEMESSEN FEHLTE

  Die Stufe "Probe" hatte eine Frist von 30 Tagen, einen Buddy, ein
  Datum -- und einen Satz: "Nach 30 Tagen: uebernehmen oder sauber
  beenden." Worauf diese Entscheidung sich gruenden soll, stand
  nirgends. Eine Probezeit ohne Inhalt ist keine Probe, sondern eine
  Wartezeit; am dreissigsten Tag entscheidet dann das Bauchgefuehl
  dessen, der zuletzt etwas gesehen hat.

  Und: `von_id` stand seit dem Bau in talent_merkmal und wurde nie
  ausgeliefert. Man sah, DASS ein Merkmal gesetzt ist -- nicht, von
  wem. Bei zwei Leuten, die unabhaengig beobachten, ist genau das die
  Auskunft.

DER PROBEPLAN

  Zwoelf Schritte in drei Phasen: mitlaufen -> selbst machen -> allein.
  Die Reihenfolge ist der Punkt (Discord empfiehlt sie so, in der
  Ausbildung heisst sie "see one, do one"). Wer die mittlere Stufe
  ueberspringt, hat am Tag 30 zwei Sorten Kandidaten, die man nicht
  unterscheiden kann.

  JEDER SCHRITT HAT EINEN ZUSTAENDIGEN -- sechs das Talent, drei der
  Buddy, drei die Leitung. Ohne diese Angabe wandern in jeder Probezeit
  dieselben drei an niemanden: Der Buddy denkt, die Leitung macht es.

  KEINE PUNKTZAHL. Am Ende stehen drei Fragen, die ein Mensch
  beantwortet; die Haken sagen nur, ob er genug gesehen hat. Und
  "entscheidbar" haengt an DREI Schritten, nicht an einer Anzahl: Wer
  nie allein gearbeitet hat und wen das Team nie beurteilt hat, ueber
  den weiss man nichts, egal wie viele andere Haken stehen. Neun von
  zwoelf reichen nicht, drei genuegen -- wenn es die richtigen sind.

WAS DAS HINSEHEN GEFUNDEN HAT

  `.t-schritt` gibt es auf dieser Seite schon -- es ist die Zeile mit
  dem naechsten Schritt der Trichterstufe. Meine Regeln standen
  SPAETER in derselben Datei und haetten sie ueberschrieben. Gefunden
  hat das keine Ueberlegung, sondern das Nachzaehlen im Browser: 13
  Elemente mit `.t-schritt`, obwohl der Plan zwoelf hat.

ZWEI PRUEFUNGEN WAREN SCHON VORHER ROT (gemessen mit git stash)

  pruef-schritt (6 rot) und pruef-befinden (4 rot) -- seit den
  Erweiterungen von heute frueh: aus sechs Befinden-Fragen wurden
  zwoelf, aus vier Kategorien sechs, und die Personenkachel zaehlt seit
  heute in Kaesten statt in einem Satz. Die Zahlen standen als feste
  Werte in den Pruefdateien.

  Nicht die Zahlen angepasst, sondern ABGELEITET: aus
  ENTWICKLUNG_BLOECKE und ENTWICKLUNG_PUNKTE.befinden. Eine feste Zahl
  ist eine Rechnung von gestern; wer sie nachtraegt, traegt sie beim
  naechsten Mal wieder nach.

GEPRUEFT

  pruef-nachwuchs 123 -> 152. Vier Gegenproben, jede trifft ihr Ziel:
  Liste auch vor der Probe -> 1 rot, Abhaken ohne Stufenpruefung -> 7
  rot, "entscheidbar" nach Anzahl statt nach den drei -> 3 rot, Name
  nicht mitgeliefert -> 1 rot.

  Dazu gruen: schritt 65, befinden 75, entwicklung 43, uebergang,
  neue-seiten, rechtetafel, css-klassen, struktur, deutsche-texte,
  modi-wortleck.
2026-09-17 16:15:21 +02:00
DogFatherGit 470c65a46b Anfragen fuer Modi: ein Fragebogen, vier Wege, eine Bruecke
Filipe, mit dem Bildschirmfoto des Bretts "Mitmachen": "ich will dass
die leute sich da anonym bei mir melden koennen ... wie ein fragebogen
wieso die person modi werden will warum sie sollte, positiv negative
sachen ... und dan soll ich annehmen ablehnen, in warteschlange stellen
oder sofort kommunizieren koennen. und wenn ich annehme dan soll diese
person automatisch zu talente kategorie weiter geleitet werden."

Seine zwei Entscheidungen auf Rueckfrage: "Vertraulich, aber nicht
namenlos" und "Du und die rechte Hand".

WAS ES GIBT

  15 Fragen in 6 Gruppen, 9 davon Pflicht. Vier davon standen nicht auf
  seinem Zettel und kommen aus der Recherche zu Moderator-Bewerbungen:
  Alter, frühere Sperren, "ein Freund bricht die Regeln - was machst
  du?" und "was kannst du nicht so gut?". Die letzte ist die
  aussagekraeftigste: Wer darauf "nichts" schreibt, hat sich gerade
  selbst beantwortet.

  Vier Wege: Reden - Warteschlange - Annehmen - Ablehnen. "Reden" steht
  vorne, weil die haeufigste richtige Antwort auf eine Bewerbung eine
  Rueckfrage ist und keine Entscheidung; stuende "Annehmen" oben, wuerde
  es geklickt.

  "Sofort kommunizieren" ist ein Satz, den sie liest. Kein Chat: Ein
  Zugang aus der Community steht ausdruecklich in keiner Chatliste
  (AUSSEN_ROLLEN). Der Satz ist damit der einzige Weg, dieser Person
  etwas zu sagen -- deshalb ist er bei "Reden" und "Ablehnen" Pflicht,
  und WELCHE Wege ihn verlangen, steht im Katalog und nicht zweimal.

  Nach "Annehmen" entsteht ein Talent auf der Stufe "Angesprochen". Die
  ersten beiden Stufen fragen, ob ueberhaupt Interesse besteht; wer sich
  selbst meldet, hat das beantwortet.

WAS DABEI HERAUSKAM, DAS NICHT GESUCHT WAR

  aufgaben.js entschied mit `p.rolle === 'modi' || p.rolle === 'hand'`,
  wer eine Katalogaufgabe bekommen kann. Diese Datei ist ohne Anmeldung
  aus dem offenen Netz lesbar -- damit stand der verborgene Zugang darin
  nachzulesen. Jetzt entscheidet es der Server und schickt ein Ja/Nein.
  Gefunden von der Wortleck-Pruefung, nicht vom Auge.

  pruef-struktur meldete teilen.html seit heute frueh als "von nirgendwo
  verlinkt" -- und lag falsch: Auf sie zeigt `share_target.action` im
  Manifest. Die Manifeste sind jetzt Verweisquelle, nicht die eine Seite
  eine Ausnahme.

  Und im Bildschirmfoto stand der Schriftzug der Buehne mitten im Text
  einer Anfrage: `color-mix(..., transparent)` mischt mit DURCHSICHTIG.
  Deckend ist `#ffffff 6%`, so wie es .t-karte macht. Dieselbe Stelle
  hat mich heute schon einmal erwischt.

GEPRUEFT

  pruef-bewerbung 77, davon 14 im Browser. Vier Gegenproben, jede trifft
  genau ihr Ziel: Bruecke ohne "genau einmal" -> 2 rot, Vertraulichkeit
  weg -> 5 rot, Nachricht-Pflicht weg -> 2 rot, Knopf ohne Rollenfrage
  -> 1 rot.

  Dazu unveraendert gruen: rollen 315, modi-verborgen 80, modi-katalog
  49, entwicklung 43, treff, bereiche-lesend, haus-seiten, alle-wege,
  rechtetafel, css-klassen, struktur, deutsche-texte, start-ansicht,
  sicht, aufgabenbrett, womit, kanaele.
2026-09-17 15:58:28 +02:00