Commit Graph
167 Commits
Author SHA1 Message Date
DogFatherGitandClaude Opus 5 9f5dbb42e3 Support: melden mit Bild, und für die Leitung ein Eingang
Filipe: „da fehlt auch eine support kachel. die jeder sieht. jeder
benutzen kann. jeder kann da probleme von der seite melden und
hinweisen. fotos mit schicken mit einem text. … so einfach wie
möglich, will nichts kompliziertes oder zu viel. kurz und knapp …
bei dogfather und der rechten hand soll die kachel anders gebaut sein
weil die sind die die sich um die probleme kümmern."

WARUM DAS NICHT DER VORHANDENE MELDEWEG IST. Es gibt ihn schon
(hilfe.html) und er sieht aehnlich aus. Drei Unterschiede machen ihn
zu etwas anderem:
  1. Er ist NICHT fuer alle -- in rechte.js steht
     `["gast","hand","admin"]`. Modis, Creator, Scouts, Manager und
     die linke Hand hatten gar keinen Weg, einen kaputten Knopf zu
     melden.
  2. Er kann keine Bilder. Bei „der Knopf tut nichts" ist ein
     Bildschirmfoto die halbe Antwort.
  3. Er ist bewusst schwer: strikter Wechsel, hoechstens drei offene
     Faelle, ein Betreff. Richtig bei einem Vorfall zwischen
     Menschen, zu viel fuer „das Datum steht falsch da".

Deshalb eigen und sehr kurz: EIN Feld, EIN Bild, fertig. Kein
Betreff, keine Kategorie, keine Dringlichkeitsstufe -- wer ein
Formular mit fuenf Feldern sieht, meldet den kleinen Fehler nicht,
und genau die kleinen erfaehrt sonst niemand.

DIE LEITUNG SIEHT ETWAS ANDERES: einen Eingang mit Zahlenband
(neu / in Arbeit / erledigt), drei Filtern und zwei Handgriffen --
„Ich kuemmere mich" und „Erledigt …". Zwei, nicht fuenf; eine
Zuweisung an eine Person und Prioritaeten waeren ein Ticketsystem
fuer zwei Menschen, die nebeneinander sitzen. Das Melde-Feld bleibt
auch fuer sie da, rutscht aber unter den Eingang.

Wer zumacht, schreibt einen Satz dazu -- der Melder sieht nur diesen
Satz, und ohne ihn weiss er nicht, ob etwas behoben wurde oder ob
niemand Zeit hatte. Beide Seiten bekommen eine Benachrichtigung.

UEBERNOMMEN STATT NEU ERFUNDEN:
  * `dateiErkennen` aus workspace-chat.js -- EXPORTIERT, nicht
    abgeschrieben. An ihr haengt die ganze Sicherheit der Uploads
    (der Typ kommt aus den ersten Bytes, nicht aus Name oder
    Content-Type), und eine zweite Fassung waere die, die beim
    naechsten Dateiformat vergessen wird.
  * Die zweigeteilte Sicht und `meldungFuer()` (gibt den Datensatz
    oder null zurueck, nie true/false) aus dem vertraulichen
    Meldeweg.
  * Der Upload-Weg (express.raw, Text im Kopf, Ordner unter
    DATEN_ORDNER, damit die Sicherungspruefung ihn findet).

DIE KACHEL BEKOMMT JEDER -- an EINER Stelle angehaengt: `bereicheFuer`
haengt sie an jede Rollenliste, statt sie in fuenf Listen
einzutragen. Genau so ist heute der Benachrichtigungs-Knopf auf 14
Seiten verschwunden. Dazu der Eintrag in rechte.js (ohne ihn
verschwindet die Kachel lautlos, `nurOffeneKacheln` filtert dagegen)
und in der Browser-Kachelliste fuer die Agentur-Rollen.

TON 44 GERECHNET, NICHT GEWAEHLT -- und dabei zweimal danebengelegen:
  * Ich habe erst einen eigenen Modus in kachel-farben.mjs gebaut.
    `tools/kachel-farbe-einzeln.mjs` gibt es aber seit dem 22.09. fuer
    genau diesen Zweck. Meine Dopplung ist wieder weg.
  * Von Hand hatte ich #bcdbff eingetragen. pruef-kachelfarben lehnte
    es ab (Buntheit 0,060, verlangt sind 0,12) -- und das vorhandene
    Werkzeug verteidigte es trotzdem, weil sein Abstand gut war. Ein
    Werkzeug, das einen regelwidrigen Zustand haelt, weil er zufaellig
    gut misst, behebt genau den Fehler nicht, fuer den es da ist.
    Behoben: Zuerst die Regeln, dann der Abstand. Ergebnis #fd6401,
    Abstand 0,0914 (engstes vorhandenes Paar: 0,0154).

DREI MESSFEHLER VON MIR, die wie schwere Befunde aussahen: `fetch`
verwirft den Host-Kopf (die Community kommt nur auf crew. herein),
die Community bestaetigt ihr Alter (`alter_ok`), und die Startroute
heisst /api/ich. Alle drei stehen in pruef-treff.mjs richtig.

Ein ECHTER Fehler kam dazu: support.html lud bereiche.js nicht, und
kopf.js stuerzte mit „Cannot read properties of undefined (reading
'LEITUNG')" ab -- sichtbar nur in der Browserkonsole. Und
pruef-css-klassen fand sofort, dass auch wahl.js fehlte.

Gemessen: pruef-support 45 Pruefungen, 0 Fehler (alle neun Rollen
kommen herein, jede sieht die Kachel, als Bild getarntes HTML wird
abgelehnt, eine fremde Meldung bleibt fremd, erledigt bleibt
erledigt). Dazu 24 Messungen am Bild in drei Groessen. Gruen:
pruef-kachelfarben (22), pruef-css-klassen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-24 01:32:55 +02:00
DogFatherGitandClaude Opus 5 a9d920e7d0 Vier stillgelegte Pruefungen, zwei kaputte Zeichen -- und die Wache dagegen
Gefunden beim Vorbereiten der KLIPY-Anbindung, nicht gesucht.

DER VERLORENE BACKSLASH
In fuenf Dateien stand in einem Suchmuster das BYTE 0x08 statt der
zwei Zeichen \ und b. Gemeint war die Wortgrenze; 0x08 ist das
Rueckschritt-Zeichen und kommt in keinem Text vor. Gemessen:

  /<0x08>modis?<0x08>/i.test("Die Modis sind da")  ->  false
  /\bmodis?\b/i        .test("Die Modis sind da")  ->  true

Folgen, je Stelle:

  pruef-nachwuchs         Das Muster stand in einer VERNEINUNG. Die
                          Zeile lautete damit ok(!false) -- dauerhaft
                          gruen, ohne etwas zu messen. Ausgerechnet
                          die Zeile, die das Durchsickern des
                          Rollennamens verhindern soll.
  pruef-personen-formular dasselbe Muster, dieselbe Verneinung
  pruef-nachfrage         hatDialogMitFeld war immer falsch. Seiten
                          mit einem Formular-Dialog galten als "totes
                          Gewicht" -- der Kommentar direkt darueber
                          warnt woertlich vor genau diesem Schaden.
  pruef-entwicklung       zwei von drei Alternativen tot
  workspace-treff.js      nur ein Kommentar, aber unlesbar

ZWEI KAPUTTE ZEICHEN, BEIDE SICHTBAR
  content: "<0x15>C9<0x00>A0"  in chat.css. Gemeint war U+25C9 und
  ein geschuetztes Leerzeichen. Live stand woertlich "C9 A0" vor
  jedem hervorgehobenen @rudel -- am echten Server nachgemessen.

  content: "¹3"  in chat.css UND entwicklung.css. Gemeint war ein
  Haken. Auf der gewaehlten Kachel stand "¹3"; zu sehen in Filipes
  Bildschirmfoto.

Repariert wird mit der Escape-Schreibweise ("\2713"), nicht mit dem
Zeichen selbst: Sie besteht nur aus ASCII und ueberlebt jede
Kodierung.

WAS DIESE FEHLERART BESONDERS MACHT
Niemand sieht sie beim Lesen. Der erste war committet, ausgeliefert
und lag live -- und als ich in der Datei danach suchte, meldete grep
"Binary file matches" und zeigte die Zeile gar nicht erst an. Wer den
Unterschied durchsieht, liest content: "C9 A0" und denkt sich nichts.

Deshalb neu: server/pruef-zeichen.mjs (7 Pruefungen). Sie sucht rohe
Steuerzeichen in allen ausgelieferten und allen Serverdateien, dazu
Ersatzzeichen und Kodierungstruemmer in CSS-content-Angaben. Mit
Gegenprobe in beide Richtungen -- sie weist an einer selbst gebauten
Datei nach, dass sie anschlaegt, UND dass sie bei einer sauberen
schweigt.

Die erste Fassung der Regel war zu weit: Sie meldete acht KORREKTE
Zeichen (✓, ↯, ↻, „, ⚠). Eine Warnung, die immer kommt, ist keine
Warnung mehr. Die engere Regel kommt aus dem Befund selbst -- der
Latin-1-Block U+0080..U+00BF, in dem echte Typografie nie steht.
Nachgemessen ueber alle 203 content-Angaben im Haus: keine einzige
benutzt ihn.

GEHEIMNISSE STEHEN NICHT MEHR IM PROTOKOLL
einstellungSetzen() schrieb immer Name UND Wert. Nachgemessen in der
echten Datenbank: kopie_schluessel steht vollstaendig drin,
vapid_paar wurde bei 120 Zeichen abgeschnitten -- kurz VOR dem
privaten Teil. Dass der heil blieb, lag an einer Laengengrenze, nicht
an einer Absicht. Keine offene Tuer (das Protokoll liegt hinter
nurAdmin), aber der Wert wandert in jede Sicherung.

Es ist eine REGEL und keine Liste: Wer eine Einstellung so benennt,
meint ein Geheimnis. Stehen bleibt, DASS sich etwas geaendert hat,
wann und durch wen -- nur der Wert fehlt.

EINE VERALTETE PRUEFUNG, UMGEDREHT STATT GELOESCHT
pruef-nachwuchs verlangte, dass die rechte Hand keine Zugaenge
anlegen kann. Das war bis zum 22.09. richtig; dann hat Filipe es
umgedreht ("damit sie das auch machen kann wenn er live ist"). Die
Pruefung war seither rot, ohne dass es auffiel -- sie lief nicht.
Jetzt prueft sie beides: dass die rechte Hand es darf UND dass die
Grenzen stehen (sperren 404, Protokoll 404). Eine Erlaubnis ohne
Grenze ist keine Entscheidung, sondern ein Loch.

Und tools/nachtlauf.mjs wird nachgetragen -- bisher unversioniert.

Zahlen: pruef-nachwuchs 260, pruef-entwicklung 48,
pruef-personen-formular 43, pruef-zeichen 7 (neu), pruef-ports 8.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 14:29:32 +02:00
DogFatherGitandClaude Opus 5 e736a12cff Vorlagenbrett: Modis bewerben sich, DogFather und die rechte Hand entscheiden
Filipe: "die modis sollen bei all diesen voschlaegen auch nur bewerben
koennen. die aufgaben aus der vorlage, da sollen die modis sich nur
bewerben koennen und nur dogfather und die rechte hand sollen annehmen
oder ablehnen koennen, mit einem text als notiz."

WAS SICH AENDERT
----------------
Auf dem Vorlagenbrett steht fuer einen Modi jetzt "Bewerben" statt
"Uebernehmen". Wer sich beworben hat, sieht das an der Karte -- samt
dem Satz, WER antwortet, und einem Weg zurueck. DogFather und die
rechte Hand sehen die Bewerbung an derselben Karte, mit Namen und dem
Wort dazu, und daneben "Annehmen" und "Ablehnen". Beide fragen nach
einer Notiz.

"ALSO NUR" GILT AUCH AM SERVER, nicht nur im Browser: Die alte Tuer
antwortet einem Modi mit 403 und dem Satz, was stattdessen geht. Ein
ausgeblendeter Knopf ist eine Bitte, abgelehnt wird in der Route.

DIE LINKE HAND STEHT ABSICHTLICH NICHT BEI DEN ENTSCHEIDERN
------------------------------------------------------------
Sie gehoert seit dem 22.09. ueberall dazu ("ich will dass die linke
hand auch ueberall zu sehen ist"). Hier hat Filipe genau zwei genannt.
Das ist keine Vergesslichkeit von mir, sondern seine Aufzaehlung -- und
dieselbe Grenze zieht das Haus schon bei den Aufgaben-Bewerbungen
(entscheidetUeberAufgaben). Sie darf weiter VERTEILEN; das hat er nicht
angefasst.

Sie ist deshalb die schaerfste Probe in der Pruefung: Wer statt "darf
entscheiden" nur "darf verteilen" abfragt, laesst sie mitentscheiden --
und niemandem faellt es auf, weil alles funktioniert.

DIE AUFGABE ENTSTEHT ERST MIT DER ZUSAGE
----------------------------------------
Der naheliegende Weg waere gewesen, beim Bewerben gleich die Aufgabe
anzulegen und die vorhandene Bewerbung aus aufgaben_zuteilung
daranzuhaengen. Dann stuende nach zwoelf Absagen zwoelfmal Arbeit auf
dem Brett, die niemand bestellt hat -- und um das einzufangen, muesste
das Ablehnen Aufgaben LOESCHEN. Loeschen als Nebenwirkung einer Absage
ist genau die Sorte Regel, die irgendwann das Falsche trifft.

Also eine eigene, kleine Tabelle (vorlagen_bewerbungen). Bis jemand ja
sagt, gibt es nur eine Zeile. Die Woerter sind dieselben wie drueben
(zustand, entscheid_text, entschieden_von) -- zwei Namen fuer dieselbe
Sache waeren zwei Sprachen im selben Haus.

Und die Zusage legt die Aufgabe ueber DIESELBE Funktion an wie das
Uebernehmen (katalogAufgabeAnlegen, neu, aus dem Katalog-Zweig
herausgeloest). Damit sieht eine erbetene Aufgabe aus wie eine
verteilte: gleiche Frist, gleiche Kategorie, gleiche Kennung. Ein
zweiter Weg waere ein zweiter Satz Regeln.

KLEINIGKEITEN, DIE SONST WEHTUN
-------------------------------
  * "Alle 12 uebernehmen" gibt es nur fuer die, die verteilen. Ein
    "Alle bewerben" waere der schnellste Weg, zwoelf Bitten auf einmal
    loszuschicken -- und damit zwoelf Entscheidungen fuer jemand anderen.
  * Wer eine Aufgabe schon hat, bekommt keinen Bewerben-Knopf. Der
    Server lehnt das ohnehin ab; ein Knopf, der eine Absage holt, ist
    schlimmer als keiner.
  * Nach einer Absage darf man sich wieder bewerben. Der eindeutige
    Index gilt deshalb nur fuer OFFENE Bewerbungen -- ueber alle
    Zustaende waere eine Absage ein Bann.
  * Gesucht wird ueber den SCHLUESSEL der Vorlage, nicht ueber die
    Nummer in der Liste. Die Nummer verschiebt sich, sobald jemand eine
    Vorlage einfuegt -- genau dieser Fehler ist am 16.09. schon einmal
    passiert.

GEPRUEFT
--------
pruef-modi-katalog: 95 Pruefungen, 0 Fehler (vorher 49).

Die Pruefung ist beim Umbau ROT geworden -- 9 Zeilen, alle dort, wo ein
Modi sich selbst etwas nahm. Richtig so, sie hat die Aenderung bemerkt.
Sie steht jetzt auf dem neuen Weg und misst ihn ganz:

  * der Modi kommt an die alte Tuer nicht mehr heran (403, erst_bewerben)
  * die Bewerbung legt NOCH KEINE Aufgabe an
  * die linke Hand darf verteilen, aber nicht entscheiden (403)
  * der Bewerber selbst erst recht nicht (403)
  * die Zusage erzeugt die Aufgabe -- mit Kategorie, Frist, Besitzer
  * die Notizen stehen in der Datenbank, samt WER entschieden hat
    (direkt gelesen: ein Feld, das der Server annimmt und nirgends
    speichert, saehe von aussen genauso aus)
  * nach einer Absage geht es wieder
  * am Bildschirm: alle Knoepfe heissen "Bewerben", kein einziger
    "Uebernehmen" mehr, die wartende Karte nennt, wer antwortet --
    und DogFather klickt sich durch Annehmen samt Notizfeld, bis die
    Aufgabe auf dem Brett steht

Die Gegenprobe in Abschnitt 7 lief mit dem Zugang des Modis und haette
ab heute nur noch bewiesen, dass die Rechtepruefung greift -- sie
benutzt jetzt DogFather. Genau so verliert eine Pruefung still ihren
Sinn.

pruef-aufgaben-vorlagen: unveraendert gruen.

ZWEI FUNDE NEBENHER, BEIDE AELTER ALS DIESE AENDERUNG -- gemessen, nicht
vermutet (mit gestashten Aenderungen gegengeprueft):
  * pruef-modi-wortleck ist seit dem 22.09. rot: Der Rollenname steht
    in team.css und teamlage.js, also in Dateien, die jeder bekommt.
  * pruef-zuteilung stuerzt seit laengerem ab (#neu-oeffnen ist
    verborgen). Beides kommt als naechstes, getrennt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 10:59:51 +02:00
DogFatherGitandClaude Opus 5 5e503463f5 Chat: die GIF-Kiste des Rudels -- und eine Luecke in der Sicherung
Filipe: "dan will ich auch dass man im chat auch sprachnachrichten und
gifts reinschicken kann. also nur die modis rechte linke hand und
dogfather."

ICH LESE "gifts" ALS GIFs -- die bewegten Bildchen -- und sage das
ausdruecklich, statt es stillschweigend anzunehmen. Im Zusammenhang
("im chat reinschicken", direkt neben Sprachnachrichten) passt nichts
anderes. Sollte er Geschenke gemeint haben, sagt er es, und dann baue
ich das.

EINE EIGENE KISTE STATT GIPHY ODER TENOR
----------------------------------------
Beide brauchen ein Konto und einen Schluessel und bekommen bei jedem
Tastendruck mit, wonach hier gesucht wird -- an eine fremde Firma, aus
einem Arbeitsplatz heraus, in dem sonst nichts nach aussen geht. Dazu
kosten sie ab einer Menge Geld. Beides steht quer zu dem, wie dieses
Haus gebaut ist.

Die Kiste laeuft auf demselben Server wie alles andere, kostet nichts
und wird mit der Zeit besser statt schlechter: Was darin liegt, hat das
Team ausgesucht. Zehn gute GIFs, die alle kennen, sind im Alltag mehr
wert als zehn Millionen fremde -- ein Katalog mit allem ist nicht mehr
Auswahl, sondern weniger.

HABEN WIR DAS SCHON? WIRD AM INHALT BEANTWORTET
-----------------------------------------------
Der Schluessel ist der SHA-256 der Datei. Ueber den NAMEN zu
vergleichen waere die naheliegende Abkuerzung -- und sie versagt genau
dort, wo Dateien "giphy.gif", "giphy(1).gif" und "download.gif"
heissen, also fast immer. Dasselbe Bild waere dreimal dieselbe Kachel.

Dasselbe GIF zweimal hineinzulegen ist deshalb KEIN Fehler: Es ist
drin, und genau das wollte man. Eine Absage waere formal richtig und im
Erleben falsch.

DAS WICHTIGSTE STUECK: ES WIRD KOPIERT, NICHT VERWIESEN
-------------------------------------------------------
Eine Nachricht zurueckzunehmen entfernt ihre Datei von der Platte. Laege
ein Kachel-GIF in demselben Ordner und mehrere Nachrichten zeigten
darauf, naehme das Zuruecknehmen EINER Nachricht das GIF fuer alle
anderen mit -- und in drei Gespraechen stuende ab da ein kaputtes Bild.
Das ist die Sorte Fehler, die erst Wochen spaeter auffaellt und dann
nicht mehr zu reparieren ist.

Deshalb liegt die Kiste in einem eigenen Ordner (chat-gifs/), und beim
Verschicken wird kopiert. Danach ist es ein ganz normaler Anhang: im
Verlauf, in der Suche, zuruecknehmbar, unter derselben Nachtruhe. Keine
zweite Sorte Nachricht mit eigenen Rechten und eigenem Loeschen.

Geprueft wird genau das: GIF hineinlegen, verschicken, aus der Kiste
nehmen -- und danach steht das verschickte immer noch im Gespraech.

"ALSO NUR" GILT AUCH HIER
-------------------------
Ansehen, hineinlegen, verschicken: alle drei nur fuer Team Dogi und
DogFather (istTeamDogi). Der Satz stand im selben Atemzug wie die
Sprachnachrichten; es gibt keinen Grund, warum er fuer das eine gelten
sollte und fuer das andere nicht. Gemessen auch am Knopf vorbei:
403/403/403.

AUGENSCHONEND -- HIER EINE ECHTE FRAGE, KEINE FORMSACHE
--------------------------------------------------------
Zwoelf gleichzeitig laufende Bildchen sind das Gegenteil von ruhig. Wer
"Bewegung reduzieren" gesetzt hat, bekommt deshalb STEHENDE Bilder: das
erste Einzelbild, im Browser auf eine Zeichenflaeche gemalt (kostet
keine zweite Datei), und es laeuft erst, wenn man es anfasst oder mit
der Tastatur darauf steht.

Fuer alle anderen laufen sie. Eine GIF-Auswahl, in der sich nichts
bewegt, ist eine, in der man nicht sieht, was man verschickt -- deshalb
steht dazu eine Gegenprobe in der Pruefung.

NEBENBEFUND, UND ER WIEGT SCHWERER ALS DIE GIFS
-----------------------------------------------
Weil die Kiste einen neuen Datenordner braucht, lief
tools/wiederherstellung-proben.mjs -- und meldete, dass der Ordner
"material" seit dem 22.09. NICHT gesichert wird. 2,4 MB
Materialbibliothek auf dem Server, nach einem Plattenausfall weg, ohne
dass die taegliche Meldung je etwas gesagt haette. Genau die Luecke,
wegen der diese Probe ueberhaupt gebaut wurde -- und sie hat sie
gefunden, weil sie die Ordner aus dem QUELLTEXT liest statt aus einer
gepflegten Liste.

Eingetragen. Danach frisch geholt und zurueckgespielt: 18 von 18 gruen,
"DIE SICHERUNG LAESST SICH ZURUECKSPIELEN" (vorher 3 Fehler).

Dabei war die Gegenprobe daneben selbst kaputt: Sie prueft, ob ein
erfundener Ordner als fehlend erkannt wird, und verlangte dafuer
`=== 1`. Das setzt voraus, dass sonst nichts fehlt. An dem Tag, an dem
wirklich etwas fehlte, wurde sie rot und zeigte damit auf sich selbst
statt auf den Fund -- zwei Meldungen, eine Ursache, und die zweite
lenkt von der ersten ab. Jetzt zaehlt sie die Differenz.

GEPRUEFT
--------
pruef-chat-anhaenge: 109 Pruefungen, 0 Fehler (vorher 86, davor 60).
pruef-chat, pruef-chat-aufloesen (126), pruef-chat-optik: gruen.
tools/wiederherstellung-proben: 18 von 18.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 02:07:56 +02:00
DogFatherGitandClaude Opus 5 2d14907d0d Chat: Sprachnachrichten -- und ein stiller Fehler, der jedes Foto betraf
Filipe: "dan will ich auch dass man im chat auch sprachnachrichten und
gifts reinschicken kann. also nur die modis rechte linke hand und
dogfather."

Dieser Commit macht die Sprachnachrichten. Die GIFs kommen als
naechstes -- ich lese "gifts" als GIFs und sage das ausdruecklich,
statt es stillschweigend anzunehmen.

AUFNEHMEN: TIPPEN, NICHT HALTEN
-------------------------------
Gedruecktbleiben ist der bekanntere Weg und der schlechtere: Wer beim
Sprechen verrutscht, verliert die ganze Aufnahme, und mit einer Hand am
Kaffee haelt niemand neunzig Sekunden still. Einmal tippen startet, das
Haekchen schickt, das Kreuz verwirft.

Drei Minuten Hoechstdauer, danach stoppt sie von selbst -- und schickt
NICHT von selbst ab. Wer die Grenze erreicht, hat gerade mitten im Satz
aufgehoert; das ungefragt zu verschicken waere die schlechteste Sekunde
dafuer.

Unter einer Sekunde wird gar nichts geschickt: Das ist ein Versehen,
kein Inhalt.

Die Aufnahmespur wird beim Beenden UND beim Verlassen der Seite
geschlossen. Ein Mikrofon, das offen bleibt, ist ein Vertrauensbruch,
auch wenn niemand zuhoert.

DREI BEHAELTER, WEIL DIE GERAETE DREI LIEFERN
---------------------------------------------
WebM/Opus (Chrome, Android), MP4/AAC (Safari, iPhone), Ogg/Opus
(Firefox). Wer nur einen nimmt, baut eine Funktion, die bei der Haelfte
des Teams stumm bleibt -- und zwar ohne Fehlermeldung.

DER BEHAELTER ALLEIN GENUEGT NICHT: WebM und MP4 tragen genauso gut
Video. Ein Video, das als "Ton" durchginge, landete in einem
Abspielgeraet ohne Bild -- es liefe, man hoerte etwas, und niemand
wuesste, dass die Haelfte fehlt. Die Erkennung sieht deshalb auf die
KENNUNG DER SPUR: Videospur -> abgelehnt, keine Tonspur -> abgelehnt.

Kein MP3: Kein Aufnahmegeraet im Browser erzeugt MP3. Es zuzulassen
hiesse, eine Tuer fuer Musikdateien aufzumachen, nach der niemand
gefragt hat.

"ALSO NUR" IST DER PUNKT
------------------------
Fotos und PDF darf jeder schicken, auch Creator -- das war eine
Entscheidung vom 09.09. und bleibt. Ton nicht. Geprueft wird in der
Route (istTeamDogi), nicht nur im Browser: Ein ausgeblendeter Knopf ist
eine Bitte, abgelehnt wird erst am Server.

Eigene Byte-Grenze fuer Ton (4 MB statt 12). Zwoelf Megabyte sind fuer
ein Foto richtig und fuer eine Sprachnachricht sinnlos -- das waeren
rund fuenfzig Minuten am Stueck.

Die Laenge kommt vom Absender und ist damit eine BEHAUPTUNG, keine
Messung; das steht so an der Spalte. Sie dient nur der Vorschau, bis
das Abspielgeraet die wahre Laenge kennt. Was schuetzt, sind die Bytes.

"FOTO"/"PDF" STAND AN VIER STELLEN
----------------------------------
Dieselbe Aufzaehlung in Gespraechsliste, Zitat, angehefteter Nachricht
und Benachrichtigung -- jede mit ihrem eigenen Fragezeichen-Doppelpunkt.
Mit der Sprachnachricht waeren es vier Aenderungen gewesen, und die
vierte ist die, die man vergisst. Jetzt anhangWort() an einer Stelle.

DER FUND: JEDES FOTO MELDETE "KEINE VERBINDUNG"
-----------------------------------------------
Beim Anfassen derselben Funktion aufgefallen: In `anhangSchicken` stand
seit dem 19.09. `const { nachricht } = e.daten;` -- ein `e`, das es
dort nicht gibt (gemeint war `ergebnis`). Die Zeile wirft, der `catch`
daneben faengt, und der Absender liest:

    "Keine Verbindung -- der Anhang wurde nicht geschickt."

Das Foto war aber da. Es kam Sekunden spaeter ueber den Ereignisstrom
in den Verlauf, mit einer roten Meldung darueber, die das Gegenteil
behauptet -- und der getippte Begleitsatz blieb im Feld stehen, also
schickt man es noch einmal.

WARUM DAS VIER TAGE UNBEMERKT BLIEB, und das ist der lehrreiche Teil:
pruef-chat-anhaenge war die ganze Zeit gruen. Sie schickt mit `fetch`
an die Route -- der bequeme Weg, und er prueft den Server gruendlich.
Sie prueft aber nicht den Weg, den ein Mensch geht. Der Fehler lag
hinter der Bueroklammer, und dort hat nie jemand hingesehen. Dazu
fuehlt er sich wie ein Netzproblem an -- und Netzprobleme sucht niemand
im Programm.

Jetzt geht ein Block durch das Dateifeld selbst und sieht auf das, was
der Mensch danach sieht: steht dort eine Meldung, und ist das Feld
leer? Gegenprobe gefahren -- mit dem alten Fehler wieder eingesetzt
werden genau diese zwei Zeilen rot, mit dem Wortlaut von oben.

Uebernommen wird eine frisch geschickte Nachricht jetzt an EINER
Stelle (nachrichtUebernehmen), fuer Anhang und Sprachnachricht. Zwei
Fassungen waeren zwei Gelegenheiten fuer denselben Fehler.

AUGENSCHONEND
-------------
Kein Blinkpunkt waehrend der Aufnahme -- der ist genau das, was die
Hausregel ausschliesst. Der Punkt atmet langsam (1,8 s, 45 bis 100 %)
und steht bei prefers-reduced-motion ganz still; die laufende Zeit
daneben traegt die Auskunft ohnehin.

Die Farben der Sprachnachricht-Blase kommen aus `--blase-leise`, der
fuer DIESE Blase ausgerechneten leisen Schrift. Eine feste Farbe waere
dieselbe Wette, die am 22.09. beim Loeschknopf 1,91:1 auf Babyblau
ergeben hat.

GEPRUEFT
--------
pruef-chat-anhaenge: 86 Pruefungen, 0 Fehler (vorher 60).
Aufgenommen wird mit MediaRecorder im echten Browser ueber den echten
Knopf, mit Chromiums erfundenem Mikrofon. Damit prueft der Abschnitt
nebenbei das, was keine gebastelte Datei pruefen koennte: ob die
Erkennung im Server versteht, was ein Browser wirklich erzeugt
(gemessen: 35 829 Bytes audio/webm, 2743 ms).

  * DogFather sieht den Mikrofonknopf, der Scout nicht
  * der Scout schickt dieselbe Aufnahme an der Oberflaeche vorbei:
    403, und nichts davon ist gespeichert
  * ein Video im Ton-Behaelter: 415
  * Laenge, Vorlesewort, Bedienbarkeit, preload=metadata, Breite
  * "Sprachnachricht" steht in der Gespraechsliste statt einer leeren
    Zeile

pruef-chat, pruef-chat-optik: unveraendert gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 01:51:56 +02:00
DogFatherGitandClaude Opus 5 28b0143166 Chat: "@rudel" ruft das ganze Team -- und nur die vier duerfen es
Filipe: "dan will ich auch dass nur die modis, rechte hand, linke hand
und dogfather, alle auch auf einmal markieren koennen im chat mit
einem, @rudel ,dann sollen alle eine benarichtigung bekommen."

DAS WAR EINE OFFENE FRAGE, UND ER HAT SIE BEANTWORTET
-----------------------------------------------------
In chat-erwaehnung.js stand seit dem 20.09. woertlich: "KEIN @alle. Es
waere in fuenf Minuten gebaut und ist der zuverlaessigste Weg, dass alle
die Benachrichtigungen abschalten -- und dann kommt auch die an, die
wirklich fuer einen bestimmten Menschen gedacht war. Wenn Filipe es
ausdruecklich will, gehoert dazu eine Entscheidung, WER es benutzen
darf; das ist eine Frage an ihn, keine, die ich hier beantworte."

Seine Antwort ist genau diese Entscheidung, und sie ist die Sicherung:
Team Dogi und DogFather duerfen rufen, sonst niemand.

WEN DER RUF ERREICHT: DAS TEAM IM RAUM, NICHT DEN RAUM
------------------------------------------------------
"Rudel" heisst das Team -- dieselben vier Gruppen, die auch rufen
duerfen. In einem Team-Kanal ist das jeder Anwesende, also "alle auf
einmal". Sichtbar wird der Unterschied im TREFF, und dort haette die
andere Lesart wehgetan: Dort sitzt die Community. Ein Ruf, der jeden
Zuschauer weckt, waere etwas anderes als der bestellte -- und beim
zweiten Mal haetten sie die Benachrichtigungen abgeschaltet.

WO WAS ENTSCHIEDEN WIRD
-----------------------
chat-erwaehnung.js bleibt ohne Abhaengigkeiten (die Pruefung soll sie
lesen koennen, ohne einen Server hochzufahren). Sie sagt nur, DASS
gerufen wurde; der Aufrufer sagt ihr, ob der Schreibende darf. Wer zum
Rudel gehoert, entscheidet workspace-chat.js ueber istTeamDogi().

Das Schluesselwort gewinnt gegen einen Menschen, der "Rudel" heisst.
Heute heisst niemand so -- aber das ist eine Tatsache von heute, kein
Gesetz. So herum verliert niemand eine Meldung (wer so heisst, ist im
Rudel dabei); andersherum haette ein einziger Zugang den Ruf ans Team
stillschweigend abgeschaltet.

istTeamDogi() NEU IN workspace.js
---------------------------------
Derselbe Ausdruck ("admin oder TEAM_DOGI_ROLLEN") stand dort dreimal
wortgleich: siehtModis, kanaeleFuer, kategorienFuer. Drei gleiche
Ausdruecke sind drei Gelegenheiten, dass einer beim naechsten
Rollenzuschnitt nicht mitgeht. Jetzt eine Stelle, die drei benutzen.

DIE NACHRICHT MERKT SICH DEN RUF (Spalte chat_nachrichten.rudel)
----------------------------------------------------------------
Beim Lesen muesste der Browser sonst wissen, ob der Absender es DAMALS
durfte. Er kennt nur dessen heutige Rolle -- wechselt jemand die Rolle,
verschwaende die Hervorhebung rueckwirkend aus einem Satz von vorletzter
Woche. Und es waere die zweite Rechnung ueber dieselbe Frage.
Vorgabe 0; alle alten Nachrichten haben kein Rudel gerufen, und das ist
keine Annahme, sondern eine Tatsache: Das Wort gab es noch nicht.

DIE MELDUNG SAGT, WAS LOS IST
-----------------------------
"X hat das Rudel gerufen", nicht "X hat dich erwaehnt" -- letzteres
stimmt beim Rudel nicht, und wer dreimal liest, dass er gemeint sei,
und jedes Mal merkt, dass es alle betraf, glaubt beim vierten Mal auch
dem echten nicht mehr. Auf DEMSELBEN Schalter wie die Erwaehnung: Ein
vierter Schalter waere der, den jemand abschaltet und der dann genau im
wichtigen Moment fehlt. Jeder Ruf steht im Protokoll (chat_rudel) --
"@rudel wird zu oft benutzt" soll eine Zahl sein koennen, kein Gefuehl.

DIE FARBE WIRD ABGELEITET, NICHT GESETZT
----------------------------------------
Eine Nachricht liegt in der Blase, deren Farbe ihr Absender AUSGESUCHT
hat -- siebzehn Moeglichkeiten. Eine feste Farbe darauf ist eine Wette,
und genau die habe ich am 22.09. beim Loeschknopf verloren (1,91:1 auf
Babyblau, gemessen, nachdem es live war). Die Marke nimmt deshalb
`--blase-text` -- die Schrift, die schriftFuer() fuer DIESE Blase mit
mindestens 7:1 ausgerechnet hat. Unterschieden wird ueber Form statt
Farbton: Toenung, Kante, Gewicht 700, ein Zeichen davor. In der
Auswahlliste darf es einen eigenen Ton haben -- sie liegt auf der
Flaeche des Hauses, deren Farbe feststeht.

DER VORSCHLAG ERSCHEINT NUR, WO ER ETWAS BEWIRKT
------------------------------------------------
In einem Zweier-Gespraech mit einem Creator ist ausser mir niemand aus
dem Team. `darf_rudel` fragt deshalb beides: darf ich, und sitzt hier
noch jemand aus dem Team. Dieselbe Ueberlegung wie beim eigenen Namen,
den die Liste auch nicht anbietet. Die Schranke beim Schreiben haengt
nicht daran -- wer es von Hand tippt, ruft eben niemanden.

GEPRUEFT
--------
pruef-erwaehnung: 119 Pruefungen, 0 Fehler (vorher 66).
Neu darin, und die zweite ist die wichtigere:
  * der Modi ruft im Treff genau das Team -- die Liste wird aus der
    Besetzung ABGELEITET, nicht abgeschrieben
  * der Gast im selben Raum ruft NICHTS: kein Eintrag, kein Merkmal,
    kein Vorschlag. Ohne diese Pruefung stuende Filipes "nur die
    modis, rechte hand, linke hand und dogfather" bloss im Kommentar
  * beide Fassungen der Regel (Server und Browser) an 14 zusaetzlichen
    Proben nebeneinander, mit beiden Rechten -- samt Gegenprobe, dass
    der Vergleich einen Unterschied ueberhaupt sehen kann
  * am Bildschirm: der Ruf steht oben in der Liste, sagt daneben, was
    er bedeutet, Enter setzt ihn ein, und im Satz ist er an Gewicht
    und Rahmen erkennbar -- nicht nur an der Farbe

Beim Bauen gemessen statt vermutet: Ein Scout und ein Modi kommen gar
nicht in denselben Raum (403, Haeusertrennung) -- deshalb prueft der
Verhaltenstest im Treff. Und ein Gast meldet sich nur mit
Altersbestaetigung an (400 ohne).

Die Nachtruhe des Treffs wird in dieser Pruefung abgeschaltet (gleiche
Stunden = keine Nachtruhe). Sonst waere sie zwischen Mitternacht und
sechs rot und danach gruen -- ein Test, der die Wanduhr misst.

pruef-chat, pruef-treffchat (110), pruef-chat-kanaele (81),
pruef-chat-ausbau (64): alle unveraendert gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 01:36:09 +02:00
DogFatherGitandClaude Opus 5 54d069c2b8 screen2: Die Aufgaben-Kachel ist Glitzer-Silber
"ich will dass diese kachel einen richtig geilen silber hat als farbe
bitte. mach es richtig geil, ein glitzer silber."

WARUM DUNKLES SILBER UND KEIN HELLES

"Silber" denkt man sich hell. Auf dieser Wand waere es das Ende der
Lesbarkeit: Die Beschriftung jeder Kachel ist HELL (--text), und eine
helle Flaeche darunter laesst davon nichts uebrig. Ein zweiter Satz
Schriftfarben nur fuer diese eine Kachel waere eine Sonderregel, die
beim naechsten Umbau niemand kennt.

Silber ist deshalb als METALL gebaut, nicht als Farbflaeche: Gunmetal,
dunkel und kuehl, mit hellen Kanten und einer Glanzbahn. Das ist, was
gebuerstetes Metall im Halbdunkel macht -- es liest sich sofort als
Silber, ohne zu blenden.

FUENF EBENEN, VON OBEN NACH UNTEN
  1. Der Lesesaum liegt ZUERST, also obenauf -- er ist der Grund,
     warum die Flaeche funkeln darf, ohne dass die Schrift leidet.
     Dieselbe Bauart wie bei der Regenbogen-Kachel.
  2. Das Funkeln: sechzehn helle Punkte, jeder mit Hof, unregelmaessig
     gesetzt (ein Raster saehe aus wie ein Muster, nicht wie Glitzer).
     STATISCH -- blinkende Punkte waeren genau das, was die Hausregel
     verbietet.
  3. Eine diagonale Glanzbahn.
  4. Gebuerstetes Metall: 3-px-Streifen bei 4,5 % Weiss. Man sieht es
     nicht als Streifen, man sieht es als Oberflaeche.
  5. Der Grundverlauf, oben heller als unten.

ALS EIGENES MERKMAL, NICHT ALS TON. Silber hat eine Buntheit nahe
null; als Ton eingetragen haette pruef-kachelfarben es zu Recht
abgelehnt (Mindestbuntheit 0,12). `ton: 13` bleibt deshalb stehen und
ist der Rueckfall -- genau so macht es die Willkommenskachel mit
`regenbogen`. Zwei Stellen tragen das Merkmal, weil die Kacheln fuer
die Modis aus dem Server kommen und die fuer alle anderen aus
bereiche.js.

NACH DEM ERSTEN BILD NACHGEBESSERT: Kantenlicht, Eckwinkel und
Schiene blieben gruen -- sie ziehen ihre Farbe aus `--ton`. Eine
gruene Linie um eine silberne Flaeche ist keine silberne Kachel.
`--ton` wird jetzt fuer diese eine Kachel ueberschrieben, NUR in der
Anzeige: `data-ton="13"` bleibt am Element, die Farbwerkzeuge rechnen
weiter mit Zahlen.

GEMESSEN am echten Bildschirm (pruef-kachelfarben): 32 Kacheln, kein
Paar sieht gleich aus, und jeder Kacheltext erreicht 4,5:1 --
schlechtester 5,86:1. Die silberne ist nicht darunter.

Mitgelaufen: pruef-kachelraster (15/0), pruef-css-klassen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 00:55:20 +02:00
DogFatherGitandClaude Opus 5 24ef154a2c pruef-haus-seiten: zwei gepflegte Seitenlisten durch eine Ableitung ersetzt
GEFUNDEN BEIM NACHGEHEN DER ALTLASTEN

    FEHL  calls.html ist auf crew. noch offen (200)
    FEHL  alle 8 Agenturseiten sind auf der Team-Adresse zu

Richtig gemessen und trotzdem kein Befund: Die Seite SOLL dort offen
sein. Am 22.09. hat Team Dogi die Kachel "Calls & Protokolle"
bekommen; seither gehoert calls.html zum Team. Rot war die Liste,
nicht das Haus.

Es waren ZWEI Listen von Hand -- neun Agenturseiten in Abschnitt 2,
fuenfzehn Teamseiten in Abschnitt 3 -- und in beiden fehlte dieselbe
Aenderung. Zwei gepflegte Listen fuer dieselbe Frage sind zwei
Gelegenheiten, eine zu vergessen.

ABGELEITET STATT GEPFLEGT

Welche Seiten es auf einer Adresse gibt, entscheidet
`gehoertAufDieseAdresse`: Eine Seite gehoert hierher, wenn sie unter
den KACHELN dieser Person steht. Die Pruefung fragt jetzt dieselben
Kacheln (`bereicheFuer` + `zusatzBereicheFuer`) und misst danach ueber
HTTP.

Das beweist NICHT, dass die Regel richtig gedacht ist -- das steht in
der Regel selbst. Es beweist, dass die Schranke tut, was die Kacheln
versprechen, und dass keine Seite durchrutscht, die auf keiner Kachel
steht. Und es gibt keine Zahl mehr, die morgen falsch ist.

ZWEI SORTEN GEHOEREN WEDER DEM EINEN NOCH DEM ANDEREN HAUS

Beim ersten Anlauf zaehlte die Ableitung `crew-index.html`,
`index.html` und `start.html` als Agenturseiten -- und verlangte damit
etwa, dass crew-index.html auf der Agenturadresse steht, wo sie zu
Recht ein 404 ist.

  1. DIE EINGANGSWAENDE (OHNE_ANMELDUNG): jede gehoert zu IHRER
     Adresse, auf der anderen gibt es sie nicht.
  2. DIE SEITEN OHNE KACHEL (OHNE_KACHEL_UEBERALL): der eigene
     Steckbrief, die Regeln des Treffs -- sie gehoeren dem Menschen,
     nicht dem Haus.

Mein erster Versuch las beide Listen mit einem regulaeren Ausdruck aus
dem Quelltext. Das ging schief (leere Mengen, vier neue Fehlalarme)
und war auch der falsche Gedanke: Eine Liste, die man PARST, ist eine
Abschrift mit Zwischenschritt. `OHNE_KACHEL_UEBERALL` ist jetzt
ausgeleitet, beide werden importiert.

Gemessen: 10 Seiten gehoeren nicht zu Team Dogi (automation, content,
leistung, profil, report, scouting, startcheck, team, teilen,
uebersicht), 21 gehoeren dorthin. 38 Pruefungen, 0 Fehler.

Dazu eine Gegenprobe zur Ableitung selbst: `calls.html` darf nicht
mehr unter den Agenturseiten stehen. Stuende es dort, waere die
Ableitung kaputt -- und die Pruefung wuerde denselben Fehlalarm wie
zuvor melden, nur mit mehr Umweg.

NEBENBEI GEKLAERT: team.html schickt einen admin auf der Team-Adresse
auf start.html. Am 22.09. als "auffaellig, nicht untersucht" notiert
-- nachgesehen ist es RICHTIG: team.html ist die Teamuebersicht der
Agentur, Team Dogi hat teamlage.html. Die Umleitung ist die
Haustrennung bei der Arbeit, kein Fehler. Sie steht jetzt in der
abgeleiteten Liste der zehn.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 00:32:48 +02:00
DogFatherGitandClaude Opus 5 4a5c69cfc6 Die drei Altlasten: ein echter Befund, zwei Pruefungen mit Zahlen von gestern
Alle drei standen seit dem 22.09. in der Notiz und waren mit `git
stash` als vorbestehend nachgewiesen. Nachgemessen, einzeln behoben.

1. pruef-jeder-hat-eine-seite -- EIN ECHTER BEFUND
   "alle 9 Rollen sind zugeordnet -- fehlt: linke"

   Die LINKE HAND fiel im Steckbrief in den Sammelplatz "Weitere":
   Auf der Uebersicht ueber die Menschen des Hauses stand sie unter
   einer Ueberschrift ohne Bedeutung, neben niemandem. Sie gehoert
   dorthin, wo die rechte Hand steht -- beide fuehren Team Dogi mit.

   Beim Nachgehen fiel dieselbe Luecke an einer zweiten Stelle auf:
   In ROLLEN_GRUPPE (der Auswahl, mit wem man schreiben kann) fehlte
   sie ebenfalls und haette eine eigene Ueberschrift mit genau einem
   Namen darunter bekommen -- also die Rangordnung, die zwei Zeilen
   hoeher ausdruecklich vermieden werden sollte.

   WARUM DIE PRUEFUNG DAS FINDEN KONNTE und ein Mensch nicht: Sie geht
   ALLE Rollen des Hauses durch, nicht die vier, die zufaellig
   angelegt sind. Eine Zuordnung, die man an den vorhandenen Leuten
   prueft, ist eine Aussage ueber die Testdaten.

2. pruef-rollen -- DIE MESSUNG WAR FALSCH, NICHT DIE KACHEL
   "DogFather Kachel https://crew... LANDET AUF start.html"

   DogFather bekommt auf der Agenturadresse die Kachel "Zu Team Dogi".
   Ihr Ziel MUSS eine vollstaendige Adresse sein -- das andere Haus
   liegt auf einem anderen Rechnernamen. Im Server steht das
   ausdruecklich (`aussen: true` an der Kachel, samt Begruendung).

   Die Pruefung klebte jedes Ziel an `BASIS + "/workspace/"`. Bei einer
   vollstaendigen Adresse kommt dabei Unsinn heraus.

   Sie kannte ausserdem nur ZWEI Ausgaenge. Ob die andere Tuer
   aufgeht, laesst sich von hier nicht sagen -- der Browser kennt nur
   BASIS. Das ist der dritte Ausgang, und er wird jetzt als solcher
   gemeldet: 314 Pruefungen, 0 Fehler, 1 nicht nachsehbar. Geprueft
   wird stattdessen, was hier zu pruefen IST: dass die Adresse zu
   einem Haus fuehrt, das dieses Haus kennt (aus CREW_ADRESSE, nicht
   abgeschrieben).

3. pruef-kachelraster -- ZWEI ZAHLEN VON GESTERN, UND EIN MESSFEHLER
   "10 Community-Kacheln" (erwartet 8) und "die doppelt breite Kachel
   steht an erster Stelle (Platz 0)"

   `=== 8` stand in der Ueberschrift, im Text und in der Bedingung. Am
   22.09. sind Kacheln dazugekommen, und die Pruefung wurde rot, ohne
   dass am Raster etwas kaputt war.

   Schwerer wog der zweite Teil: Sie suchte "die Community-Gruppe"
   ueber deren Ueberschrift, mit der letzten Gruppe als Rueckfall. Fuer
   DogFather griff der Treffer (1 Kachel), fuer einen Modi der
   Rueckfall (10) -- und beides hiess in der Meldung
   "Community-Kacheln". Eine Pruefung, die je nach Rolle etwas anderes
   misst, kann ihr Ergebnis nicht erklaeren.

   Jetzt werden ALLE Gruppen gemessen, mit Namen in der Meldung, und
   die Frage ist ueberall dieselbe: Hat das Raster ein Loch? Die
   Kachelzahl steht in der Meldung, nicht in der Bedingung. Die Regel
   "eine doppelt breite Kachel steht vorn" bleibt -- es gibt heute
   keine solche Gruppe mehr, aber sie gilt fuer die naechste, und die
   ZAHL der geprueften Gruppen steht daneben.

   Gemessen sieht DogFather 5 Gruppen (1, 6, 11, 4, 1 Kacheln), ein
   Modi 6. Kein Loch in einer davon. 15 Pruefungen, 0 Fehler.

Mitgelaufen und gruen: pruef-steckbrief, pruef-rechtetafel (19),
pruef-chat.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-23 00:29:25 +02:00
DogFatherGitandClaude Opus 5 73facb7ce9 Nachtrag zu B4: die Aufraeumung lief nie -- .changes an der falschen Stelle
WAS PASSIERT IST

Der Commit 60802170 ist um 23:33 ausgeliefert worden. Im Protokoll des
Servers stand danach:

    [workspace] undefined zurueckgenommene Nachrichten endgueltig entfernt.
    [workspace] 4 blaue Herzen auf babyblau umgestellt

Die zweite Zeile stimmt. Die erste ist der Befund: `undefined` statt
einer Zahl. Nachgesehen in der Live-Datenbank -- die fuenf
zurueckgenommenen Zeilen waren noch da.

URSACHE: `d.prepare("DELETE ...").changes` statt `.run().changes` --
also die Eigenschaft der vorbereiteten ANWEISUNG, nicht die des Laufs.
Die Anweisung wurde vorbereitet und nie ausgefuehrt. Nichts stuerzte
ab, nichts war rot, kein Fehler im Protokoll.

NEBENFOLGE, die es schlimmer gemacht haette: Die Sicherung wird VOR
dem Loeschen geschrieben. Da nie geloescht wurde, blieb die Bedingung
erfuellt -- bei JEDEM Neustart waere eine weitere Sicherungsdatei
entstanden. Genau das, wovor der Kommentar zwei Zeilen darueber warnt.
Ein Kommentar, der vor einem Fehler warnt, verhindert ihn nicht.

WAS JETZT ANDERS IST

Behoben, und die Umstellung ist eine exportierte Funktion geworden:
`loeschspurenAufraeumen(d, dbPfad)`. Nicht aus Ordnungsliebe -- eine
Umstellung, die tief im Hochfahren steckt, kann keine Pruefung
aufrufen. Eine Funktion schon.

pruef-loeschen.mjs (20 -> 25): stellt den alten Zustand her (Text leer,
weg_am gesetzt), ruft die Funktion und misst
  * dass sie eine ZAHL meldet (`typeof === "number"`) -- genau hier
    stand undefined, und 0 sieht in einer Meldung fast so aus,
  * dass die Zeile wirklich verschwindet,
  * und dass beim zweiten Aufruf nichts mehr passiert und nichts
    gesichert wird.

Ohne den ersten dieser drei Haken waere der Fehler auch beim naechsten
Mal durchgegangen: Eine Meldung mit `undefined` ist gruen, solange
niemand sie liest.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 23:36:02 +02:00
DogFatherGitandClaude Opus 5 60802170a1 B4 + B5: Loeschen heisst Loeschen, die Schrift wechselt mit, und Blau wird Babyblau
Die beiden Auftraege gehoeren zusammen, und zwar in dieser Reihenfolge:
Eine babyblaue Kachel ist HELL. Ohne mitwechselnde Schrift waere sie
unlesbar (1,63:1 gemessen). Erst B4 macht B5 moeglich.

B4a -- LOESCHEN HEISST LOESCHEN
  "Geloeschte Nachrichten verschwinden vollstaendig - keine Spur, kein
   'wurde geloescht'-Hinweis, bei niemandem, auch nicht bei DogFather."

Bis heute blieb die Zeile stehen: Text geleert, weg_am gesetzt, und im
Chat stand "Nachricht zurueckgenommen". Das war ausdruecklich so
begruendet ("ein Loch im Verlauf wirft mehr Fragen auf"). Das Argument
beantwortet aber eine andere Frage: Ein Hinweis "hier stand etwas"
MARKIERT die Stelle. Wer etwas aus Versehen schreibt, will es weg
haben und nicht unterstrichen.

Jetzt ein echtes DELETE. Vier Raender, an denen eine Spur bleiben
koennte, alle gemessen:
  1. die Zeile selbst
  2. chat_reaktionen    (ON DELETE CASCADE - nachgesehen, nicht angenommen)
  3. chat_erwaehnungen  (ebenso)
  4. letzte_am am Raum  - wird neu gerechnet, sonst stuende er oben in
                          der Liste mit einem Zeitpunkt, zu dem es
                          nichts mehr gibt
Dazu: ein Zitat auf eine geloeschte Nachricht wird weggelassen; in der
Gespraechsliste steht kein Hinweis mehr; der Knopf heisst "loeschen".

Die 5 alten zurueckgenommenen Zeilen (Text bereits leer) raeumt eine
einmalige, wiederholbare Umstellung ab - mit Sicherung davor, und nur
wenn es wirklich etwas zu tun gibt.

B4b -- WER DARF WAS
  "jeder nur seine eigenen - ausser DogFather und rechte Hand"
`darfJedeNachrichtLoeschen` = admin oder hand. NICHT fuehrtTeamDogi
(das schloesse die linke Hand ein) und nicht istLeitung (das schloesse
Spicy Media ein, die private Chats nicht einmal sehen darf). Das Recht
kommt vom Server ins Skript, nicht aus einer Rolle im Browser: chat.js
bekommt jeder, der die Seite oeffnet.

B4c -- DIE SCHRIFT WECHSELT MIT
  "am besten schwarz auf hellen Kacheln - und weiss, wenn jemand eine
   schwarze Kachel waehlt"
`schriftFuer(farbe)` waehlt zwischen zwei Paaren, gerechnet aus der
Leuchtdichte, mit denselben Schwellen wie das Rechenwerkzeug (7:1 fuer
den Text, 4,5:1 fuer die Fusszeile). Keine dritte Spalte in
CHAT_KACHELN, die jemand pflegen muesste. Flaeche und Schrift werden
im Browser in EINEM Griff gesetzt (blaseFaerben) - zwei Stellen waeren
irgendwann eine helle Kachel mit heller Schrift.

B4d -- DIE NAMEN
Der Name ist jetzt ein eigener Streifen mit Kante darunter, .84rem,
und der Rollenpunkt wird ein 3x14-Balken. Vorher stand er als erste
ZEILE in der Blase und las sich wie der Anfang des Satzes.

B5 -- BABYBLAU
  "jedes normales blaues herz durch babyblaues herz ersetzen ... jeder
   normale blaue farbe, sei es die kachel im chat oder emojis, nur
   babyblau bitte."
* Herz: U+1F499 -> U+1FA75. Nicht geglaubt, sondern gemessen: 43,9 px
  breit wie die anderen Herzen, ein Ersatzkaestchen waere 20,7. Die
  vier vorhandenen blauen Herzen in der Datenbank wandern mit - sonst
  waeren es vier Reaktionen, die ERLAUBT nicht mehr kennt: still weg.
* Kachel: neue, HELLE Kachel "Babyblau" mit dem Wert von --akzent.
  Gemessen: Text 10,78:1, Fusszeile 4,87:1. Sie steht bewusst nicht in
  der Rechnung des Werkzeugs (das rechnet elf Toene auf EINE
  Leuchtdichte) - sie hat eine andere Leuchtdichte und dafuer ihre
  eigene Schrift. Dasselbe Versprechen, anderer Weg.

PRUEFUNGEN
  pruef-loeschen.mjs (NEU, 20/0): alle vier Raender, die vier Faelle
    der Rechtegrenze (auch: die linke Hand darf NICHT), das babyblaue
    Herz am laufenden Server, und dass der Satz "Nachricht
    zurueckgenommen" nur noch in Kommentaren steht - mit Gegenprobe,
    dass die Suche diesen Unterschied wirklich macht.
  pruef-chatkachel.mjs (33/0): misst jede Kachel mit IHRER Schrift und
    fragt dafuer dieselbe Funktion wie der Server. Neu: dass die
    Schrift ueberhaupt wechselt. Die Leuchtdichte-Regel gilt jetzt fuer
    die gerechneten Toene - das Versprechen dahinter loest die
    Kontrastzeile darueber direkt ein.
  Vier alte Pruefungen umgedreht, die den alten Zustand festgeschrieben
    hatten: pruef-chat, pruef-chat-ausbau, pruef-chat-aufloesen,
    pruef-chat-optik. Alle mit scharferer Messung als vorher (Zahl
    davor/danach statt "ein Hinweis ist da").
  Mitgelaufen und gruen: pruef-alle-sehen-es, pruef-treffchat (110/0).

Gesichert: workspace-vor-loeschumbau-20260922-233313.db
(946 KB, integrity_check ok, 111 Nachrichten, 49 Reaktionen).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 23:33:43 +02:00
DogFatherGitandClaude Opus 5 3b76a9aab5 screen1 + A5 + B6: „wer zuerst Zeit hat" gilt wieder, und Aufgaben entstehen dort, wo die Person steht
DREI SACHEN, EIN ZUSAMMENHANG.

--- screen1 --------------------------------------------------------
Filipe zu meinem eigenen Satz „wer zuerst Zeit hat — genau das geht ja
nicht mehr": „falls das nicht mehr geht mach das es geht wenn es wieder
geht ist alles gut."

Er hat recht, und ich hatte zu schnell aufgegeben. „Wer zuerst Zeit
hat" muss nicht heissen, dass man sich selbst bedient -- es kann
genauso heissen, dass die ERSTE BEWERBUNG zuerst drankommt. Damit gilt
beides: Die Leitung entscheidet (sein Wunsch von vorhin), und wer
schnell ist, hat den Vorteil (sein Wunsch von eben).

Die Bewerbungen werden jetzt nach EINGANG sortiert, nicht nach Namen
-- die Abfrage sortiert sonst alphabetisch, und dann haette nicht der
Schnelle den Vorteil, sondern Frida. Der Erste bekommt die Marke
„zuerst da" (nur bei mehr als einer -- sonst ist es keine Auskunft,
sondern Fuellwerk).

Geprueft mit Absicht gegen das Alphabet: Nele bewirbt sich zuerst und
steht vorn, obwohl Frida im Alphabet vor ihr kaeme.

--- B6: der Knopf auf dem Aufgabenbrett ----------------------------
Filipe: „dieser button kann da jetzt doch endlich verschwinden, auf
dieser seite sollen ja keine aufgaben mehr verteilt werden."

ER HAT DABEI AUF DEN TEAM-DOGI-BILDSCHIRM GESEHEN, und das ist der
Unterschied zwischen „weg damit" und „weg damit, aber gemessen":

    Rolle/Haus        aufgaben.html  entwicklung.html  darfAnlegen
    manager/agentur   ja             NEIN              ja
    creator/agentur   ja             NEIN              ja
    scout/agentur     ja             NEIN              ja
    spicy/agentur     ja             NEIN              ja

Haette ich den Knopf einfach entfernt, koennten vier Rollen gar keine
Aufgabe mehr anlegen. Der Server nennt deshalb den ORT, und er leitet
ihn aus den KACHELN der Person ab -- nicht aus dem Seitenrecht (dann
haette DogFather auf der Agenturadresse den Knopf verloren, denn
oeffnen darf er die Seite, nur hat er dort keine Kachel dorthin) und
schon gar nicht aus dem Haus.

--- A5: anlegen, wo die Person steht -------------------------------
Filipe: „dieser buttion da soll nicht einen zu der seite aufgaben
fuehren sondern da in dieser seite die aufgaben erstellen und vergeben
koennen. plus man soll die aufgaben hier in dieser seite auch sehen."

Der Knopf war ein Link auf `aufgaben.html?neu=1`. Jetzt oeffnet er ein
Formular an Ort und Stelle. DREI FELDER, NICHT ZWOELF: Wer hier steht,
hat die Person schon gewaehlt; was fehlt, ist was, bis wann und ob
noch jemand mitmacht. Das grosse Formular auf dem Brett bleibt fuer
den Fall, dass man eine Aufgabe fuer irgendwen irgendwo anlegt -- zwei
vollstaendige Masken fuer dieselbe Sache waeren zwei Gelegenheiten,
eine davon zu vergessen.

Dazu die Aufgaben der gewaehlten Person, auf derselben Seite. Sie
kommen beim Auswaehlen und nicht auf Knopfdruck: Wer jemanden
durchgeht, will wissen, was bei ihm liegt.

Ohne Person ist der Knopf AUS statt weg -- sonst springt die Seite beim
Auswaehlen -- und der Satz daneben sagt, was fehlt.

Gemeldet wird, was der Server WIRKLICH gesetzt hat: `zuteilen` kann
eine Person weglassen (gesperrter Zugang). Wer das verschweigt, laesst
jemanden im Glauben, er habe drei Leute eingetragen.

--- EIN FUND AUF DEM EIGENEN BILDSCHIRMFOTO ------------------------
Die Bestaetigung „Clips vom Samstag schneiden steht jetzt bei Rieke."
stand in WARNROT -- `melde` schreibt immer in denselben Absatz, und
der heisst `.fehler`. Nicht schlimm und genau deshalb heimtueckisch:
Wer Bestaetigungen in Rot liest, sucht den Fehler, und wer sich daran
gewoehnt, ueberliest die echte Warnung. `melde` kennt jetzt eine gute
Nachricht; die Vorgabe bleibt „Fehler", damit die neun vorhandenen
Aufrufe nicht stillschweigend umgefaerbt werden.

GEPRUEFT
pruef-bewerbung-aufgaben 84/0 (von 66) -- neu: die Reihenfolge nach
Eingang mit Gegenprobe gegen das Alphabet, und ein Abschnitt, der A5
und B6 am echten Bildschirm durchspielt (Knopf weg auf dem Brett, kein
Link mehr auf der Entwicklungsseite, Formular oeffnet dort, Aufgabe
steht sofort in der Liste darunter UND wirklich in der Liste des
Servers, Bestaetigung als gute Nachricht gekennzeichnet).

Gruen: pruef-entwicklung, pruef-aufgabenbrett, pruef-css-klassen,
pruef-formulare, pruef-struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 19:09:16 +02:00
DogFatherGitandClaude Opus 5 43545e4acd A4: Bewerben statt selbst nehmen
Filipe, 22.09.2026: „die modis und linke hand sollen da nichts
uebernehmen koennen von aufgaben, ueberhaupt ueberall sollen die keine
aufgaben selber uebernehmen die ihnen nicht zugetragen sind. ich will
dass die sich fuer aufgaben bewerben koennen aber die rechte hand oder
dogfather muessen annehmen oder ablehnen koennen und das mit einem
kommentar als moeglichkeit sogar noch zum hinzufuegen."

ZWEI FRAGEN, DIE MAN AUSEINANDERHALTEN MUSS -- und das war der Schluessel:

    verteilen    eine Aufgabe an ANDERE geben
    entscheiden  bestimmen, wer sie am Ende macht

Sein Satz vom selben Tag („rechte hand linke hand und dogfather ...
koennen alle verteilen") widerspricht dem nicht, er beantwortet die
erste Frage. Die linke Hand verteilt, entscheidet aber nicht -- sie
bewirbt sich wie ein Modi. `entscheidetUeberAufgaben` steht neben
`darfAufgabenVerteilen`, und drei Stellen fragen ab jetzt dieselbe
Funktion.

DAS VERBOT HATTE DREI TUEREN, und die zweite und dritte waren beim
Planen nicht zu sehen:

  1. aus dem Pool „uebernehmen"  -- die offensichtliche
  2. beim Pool „annehmen"        -- dasselbe unter anderem Namen: Wer
                                    zusagt, nimmt sie den anderen weg.
                                    Bei „einzeln"/„mehrere" bleibt es
                                    erlaubt -- dort wurde sie ihm
                                    ZUGETRAGEN, und genau das Wort
                                    steht in seinem Satz.
  3. beim Verteilen sich selbst eintragen -- die linke Hand darf
                                    verteilen, haette sich also selbst
                                    nehmen koennen. Abgelehnt statt
                                    still gefiltert: Wer sich eintraegt
                                    und sich danach nicht findet, sucht
                                    den Fehler bei sich.

EIN FUND, OHNE DEN A4 GAR NICHT FUNKTIONIERT HAETTE
Die rechte Hand soll entscheiden -- und sah die Aufgabe nicht, um die
es ging. Gemessen an einer Pool-Aufgabe, die DogFather fuer zwei Modis
angelegt hat:

    DogFather    sieht sie    1 Bewerbung
    Modi         sieht sie    1 Bewerbung
    rechte Hand  SIEHT SIE NICHT (Liste leer)

Ihre Sichtregel sammelte Menschen mit einer TEAM_DOGI_ROLLE und fragte,
ob einer als Creator, Verantwortlicher oder Ersteller eingetragen ist.
Bei einer Pool-Aufgabe bleibt `verantwortlich_id` leer (das ist ihr
Sinn), und der Ersteller war DogFather -- der in dieser Liste nicht
steht. Alle drei Bedingungen liefen ins Leere.

Auf der Adresse von Team Dogi sehen die Haende jetzt alles. Das ist
zugleich sein Satz „sehen alle aufgaben". Die Haustrennung bleibt:
`sichtbar()` haengt fuer crew weiterhin `AND ohneAgentur(...)` davor.

WIE DIE BEWERBUNG GEBAUT IST
Kein zweiter Tisch, sondern ein weiterer Zustand derselben Zeile
(`beworben`). Die Frage „wie steht diese Aufgabe bei DIESEM Menschen"
wird dort schon beantwortet; eine zweite Tabelle haette zwei Wahrheiten
ueber dieselbe Beziehung.

Die Worte der Person (`grund`) und der Kommentar der Leitung
(`entscheid_text`) stehen in ZWEI Feldern. In dasselbe waere bequemer
und wuerde die Frage mit der Antwort ueberschreiben -- danach wuesste
niemand mehr, worum jemand gebeten hat. Dasselbe gilt, wenn eine
Bewerbung wegfaellt, weil jemand anders die Aufgabe bekommt: Der
Hinweis kommt in das Feld der Leitung, ihre Worte bleiben stehen.

Der Kommentar ist FREIWILLIG. Die Begruendung beim Ablehnen einer
zugeteilten Aufgabe bleibt Pflicht -- dort sagt jemand ab, der gefragt
wurde. Hier bittet jemand; ein „bitte" braucht keine Begruendung.
Filipes Wort ist „als moeglichkeit".

Die CHECK-Regel wurde ueber `checkListeErweitern` erweitert -- den Weg,
der seit dem 09.09. an einer Stelle steht, mit Sicherung vorher,
Spaltenliste aus PRAGMA und Indizes, die mitgehen.

UND EIN SATZ, DER NICHT MEHR STIMMTE
„Frei fuer 3 Leute — wer zuerst Zeit hat" war die Beschreibung des
Pools, solange sich jeder selbst bedienen durfte. Er sagt jetzt jedem,
was FUER IHN gilt.

GEPRUEFT
Neu: server/pruef-bewerbung-aufgaben.mjs, 66/0 -- die Regel selbst,
alle drei Tueren, der erlaubte Weg, die zwei Felder, das Zurueckziehen,
und ein Abschnitt am echten Bildschirm (ein Modi sieht „Ich bewerbe
mich" statt „Ich uebernehme das"; die rechte Hand sieht die Bewerbung
mit Annehmen und Ablehnen; die Bewerberin sieht KEINEN Block zum
Entscheiden -- sonst waere das Verbot einen Knopf weiter offen).

pruef-zuteilung auf die neue Regel umgestellt (sie hielt „Bea
uebernimmt sie" fest und wurde zu Recht rot) -- misst jetzt denselben
Effekt ueber den neuen Weg. Dazu gruen: pruef-aufgabenbrett,
pruef-meldungen, pruef-sicht, pruef-css-klassen.

ALTLAST, nicht von hier: pruef-rollen meldet einen Fehler an der
Kachel „Zu Team Dogi" (absolute Adresse). Mit `git stash` nachgemessen
-- vorher und nachher identisch.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 18:55:06 +02:00
DogFatherGitandClaude Opus 5 b79b75ab70 A3: Calls & Protokolle gibt es jetzt auch bei Team Dogi
Filipe, 22.09.2026: „ich will diese kachel vom workspace auch im team
dogi seite. ich will dass jeder immer nur seine eigenen sachen von
seinem kalender sieht mehr nicht. perfektioniere das bitte. jeder der
einen kalender hat soll auch sowas haben danke."

GEMESSEN, BEVOR GEBAUT WURDE:

    Rolle   Kacheln   Kalender   Calls
    admin      31       ja        NEIN
    hand       31       ja        NEIN
    linke      30       ja        NEIN
    modi       26       ja        NEIN
    gast       12       nein      nein

Die Community hat keinen Kalender. Sein Satz „jeder der einen kalender
hat" beschreibt die Lage also genau -- „alle bekommen es" waere falsch
gewesen.

ES IST EINE REGEL, KEINE VIERFACHE EINTRAGUNG. Hinter jeden Kalender
einer Liste kommt eine Calls-Kachel, in derselben Gruppe. Vier Stellen
von Hand zu pflegen waere die Stelle, an der es beim naechsten neuen
Rollenzuschnitt auseinanderlaeuft. Erkannt wird der Kalender am ZIEL,
nicht am Namen -- Namen sind im Haus schon gewandert, Ziele nicht.

„JEDER SIEHT NUR SEINE EIGENEN" GAB ES SCHON, seit dem 07.09.
(`termineSichtbar`). Es wird jetzt aber nicht mehr GELESEN, sondern am
laufenden Server ausprobiert: Zwei Leute legen je einen Call an und
sehen den des anderen nicht -- auch DogFather nicht. Wer als
Teilnehmer eingetragen ist, sieht ihn schon; das ist die Gegenprobe,
ohne die „niemand sieht etwas" auch bei einer kaputten Liste gruen
waere.

DER TON WAR EINE RECHNUNG UEBER DREI ANLAEUFE

  1. Ton 15, derselbe wie im anderen Haus. Als Zahl frei, auf dem
     BILDSCHIRM nicht: 0,0139 zu „Was ansteht", unter der Grenze 0,02.
  2. Ton 16, ausgerechnet als der entfernteste brauchbare. Die Pruefung
     kennt aber zwei Regeln mehr, die ich nicht beruecksichtigt hatte:
     Rohabstand >= 0,090 (er lag bei 0,0854) und Buntheit >= 0,12 (er
     lag bei 0,116). Und Ton 16 gehoert im anderen Haus zu
     „Start-Check" -- ihn umzufaerben haette dort eine Kachel
     veraendert, nach der niemand gefragt hat.
  3. Unter allen elf freien Toenen erfuellte KEINER alle drei Regeln.
     Eine 32. Kachel braucht einen 32. Ton. Also einen neuen gerechnet,
     additiv, ohne einen vorhandenen anzufassen:

         Ton 43  #027afb   Abstand 0,0925  Buntheit 0,212  Kontrast 4,63:1

     Es bleibt ein Blau -- die Kachel ist damit als dieselbe
     wiedererkennbar wie im anderen Haus.

EIN WIDERSPRUCH IM HAUS, DABEI GEFUNDEN
`tools/kachel-farbe-einzeln.mjs` suchte die Buntheit von 0,30 bis
herunter auf 0,04, `pruef-kachelfarben` verlangt mindestens 0,12. Das
Werkzeug lieferte fuer Ton 43 zuerst ein blasses #bcdbff (Buntheit
0,060) mit dem besten Abstand weit und breit -- und die Pruefung lehnte
es ab. Beide hatten recht; zwei Zahlen fuer dieselbe Regel in zwei
Dateien, die nichts voneinander wissen. Ein Werkzeug, dessen
Vorschlaege die Pruefung danach verwirft, ist schlimmer als keines --
man haelt das Ergebnis fuer fertig.

Die Schwellen stehen jetzt in tools/kachelton-regeln.mjs, und beide
Seiten lesen sie von dort.

NEU: server/pruef-calls-rudel.mjs, 32/0. Sie prueft die REGEL (Calls
genau dann, wenn Kalender -- und direkt dahinter, in derselben
Gruppe), dass Kachel und Zutrittsrecht zusammenpassen, und am
laufenden Server, dass jeder nur seine eigenen sieht.

pruef-kachelfarben 22/0, pruef-start-ansicht, pruef-willkommen,
pruef-struktur, pruef-treff, pruef-modi-checkliste gruen.

ZWEI ALTLASTEN DABEI GEFUNDEN, nicht von dieser Aenderung und noch
nicht behoben (beide vorher schon rot, nachgemessen mit `git stash`):
  pruef-kachelraster        3 Fehler (erwartet acht Community-Kacheln,
                            es sind zehn)
  pruef-jeder-hat-eine-seite 1 Fehler („fehlt: linke" -- die Rolle kam
                            dazu, die Pruefung nicht mit)

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 15:15:00 +02:00
DogFatherGitandClaude Opus 5 25de892fdb screen5: Aus dem Treff wird das Rudel, aus der Zentrale die IrrenAnstalt
Filipe, 22.09.2026: "ersetze die zentrale durch, Die IrrenAnstalt.
genau so geschrieben bitte. und alles was treff heißt oder wo treff
steht soll durch Rudel ersetzt werden bitte."

Die Schreibweise "IrrenAnstalt" mit grossem A in der Mitte ist so
gewollt. Das steht als Hinweis daneben, damit sie beim naechsten Mal
niemand "korrigiert".

WAS UMBENANNT WURDE: alles, was jemand LIEST -- Kachelnamen,
Ueberschriften, Markenzeilen, Saetze, Meldungen, Aufgabenvorlagen.
116 Zeilen in 42 Dateien.

WAS BLEIBT: Adressen (treff-regeln.html), Bezeichner (TREFF_ROLLEN),
Datenbankwerte (bereich = 'treff'), Abfrageteile (b=treff). Eine
Adresse umzubenennen bricht jedes Lesezeichen, und ein Datenbankwert
umzuschreiben waere eine Umstellung ohne Gegenwert. Dieselbe
Entscheidung wie heute frueh bei Dogi-Media, wo material.html auch
material.html geblieben ist.

DREI GRAMMATIKFEHLER IM EIGENEN ENTWURF, alle vor dem Ausliefern
gefunden -- ein blindes Ersetzen reicht hier nicht:

1. "der Treff" ist maennlich, "das Rudel" saechlich. Ohne Tabelle
   waere ueberall "Der Rudel" gestanden. (Und "Treffer" waere zu
   "Rudeler" geworden, "Treffen" zu "Rudelen" -- deshalb greift die
   Regel nur bei Wortgrenze und nie vor einem Kleinbuchstaben.)

2. BINDESTRICH-ZUSAMMENSETZUNGEN. In "der Treff-Chat" gehoert der
   Artikel zu "Chat", nicht zu "Treff". Der erste Durchlauf machte
   daraus "das Rudel-Chat", "das Rudel-Kacheln" und "ein Rudel-Raum".
   Jetzt greift die Artikelregel nur, wenn das Wort allein steht.

3. GESCHUETZTE LEERZEICHEN. In den Markenzeilen steht
   `Der&nbsp;Treff`, damit die zwei Woerter nicht umbrechen. Das
   Muster hat daran vorbeigegriffen: "Der&nbsp;Rudel", auf fuenf
   Seiten. Jetzt wird das Trennzeichen mitgefasst und unveraendert
   wieder eingesetzt.

Gefunden wurden alle drei, weil jede einzelne der 116 Zeilen vor dem
Schreiben als ALT/NEU ausgegeben und gelesen wurde -- und danach
gezielt nach falschen Artikeln gesucht ("den Rudel", "der Rudel",
"einen Rudel"). Uebrig blieben sechs Treffer, und die sind alle
richtig: "einen Rudel-Raum", "der Rudel-Chat", "den Rudel-Regeln" --
Zusammensetzungen, bei denen der Artikel zum letzten Wort gehoert.

UND ZWEI PRUEFUNGEN, die die Umbenennung nicht mitbekommen haetten:
`/Treff/.test(...)` und `/Treff/i.test(...)`. Ein regulaerer Ausdruck
ist keine Zeichenkette -- sie haetten ab sofort nach einem Wort
gesucht, das die Seite nicht mehr sagt, und waeren still rot geworden,
ohne dass etwas kaputt ist.

Geprueft, alle gruen: pruef-treff, pruef-treffchat,
pruef-deutsche-texte, pruef-uebernahme, pruef-crew-adresse,
pruef-willkommen, pruef-wege-nach-draussen, pruef-vorlagen,
pruef-start-ansicht, pruef-struktur.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 14:25:56 +02:00
DogFatherGitandClaude Opus 5 fc823240ab screen4: Dogi-Media — bearbeiten, entfernen, von wann bis wann
Filipe, 22.09.2026: "wenn wir in der kategorie material was hochladen
will ich dass die rechte und linke hand es auch bearbeiten und loeschen
koennen. dogfather auch fals es ein fehler gab. ... uebrigens ersetz das
wort material durch Dogi-Media. und mach kategorien welche sind benutzt
welche nicht welche sind noch offen, welche laufen von wan bis wann."

WAS JETZT GEHT
- Rechte Hand, linke Hand und DogFather bearbeiten und entfernen jedes
  Stueck, nicht nur ihr eigenes. Bearbeitet wird Text und Zeitfenster,
  nicht die Datei: Sonst zeigte dieselbe Nummer etwas anderes als das,
  was sich jemand gerade angesehen hat.
- Ein vergebenes Stueck bleibt unberuehrt (409). Wer es genommen hat,
  hat sich auf diesen Text verlassen.
- Vier Zustaende, gerechnet statt gespeichert: jetzt frei, kommt noch,
  abgelaufen, schon benutzt. Die Kategorieleiste zeigt zu jedem die
  Anzahl aus den echten Daten und filtert BEIDE Listen.
- "Material" heisst ueberall "Dogi-Media", der Dateiname bleibt.

DREI FEHLER AUS DEM EIGENEN ENTWURF, ALLE VOR DEM AUSLIEFERN GEMESSEN

1. `tagLokal()` ohne Argument gab "NaN-NaN-NaN" zurueck -- eine
   Zeichenkette, die aussieht wie ein Datum. Im Vergleich gewinnt das N
   gegen jede Ziffer, also galt JEDES Stueck mit Enddatum vom ersten Tag
   an als abgelaufen, und "Kommt noch" gab es nie. Kein Absturz, keine
   Meldung. Die drei Kopien der Funktion waren hier auseinandergelaufen;
   alle drei haben jetzt die Vorbelegung und werfen bei einer Zahl, die
   keine ist.
2. `frageNach` liefert bei einer reinen Rueckfrage `true`, nicht
   `{ ok: true }`. Der Entwurf prueft auf `erg?.ok` -- "Entfernen" waere
   ein Knopf gewesen, der nichts tut.
3. Drei erfundene Klassennamen (`knopf--leise`, `m-kat__knopf`,
   `m-karte__weg-knopf`) statt der vorhandenen des Hauses. Jetzt
   `.knopf-still`, `.knopf-still--warn` und die Filterleiste `.filter`.

EIN FUND IM BESTAND, ZWEI WOCHEN ALT

In start.css fehlten an einer Stelle die zwei Zeichen, die einen
Kommentar schliessen. CSS-Kommentare schachteln nicht: Der Block lief
bis zum naechsten Abschluss weiter und verschluckte `.kacheln {`; die
Fehlerbehebung des Browsers nahm danach auch die Regel `.kachel` mit.
In Chromium gemessen, beide Fassungen nacheinander: 738 statt 740
Regeln.

Der Entwurf, der dadurch nie gewirkt hat, ist NICHT wiederhergestellt
worden: Seine Flaeche mischte den Kachelton mit 30/11/3 Prozent ein --
pruef-kachelfarben fiel sofort von 36,5 % auf 4,1 % angekommene Farbe,
und 31 Toene sahen gleich aus. Das ist das Gegenteil dessen, was am
22.09. verlangt war. Er ist geloescht, mit dem Grund daneben. Offen
bleibt eine Frage an Filipe, keine Entscheidung von mir: zu demselben
Entwurf gehoerte ein schmaleres Kachelraster (fuenf bis sechs statt
drei pro Reihe). Das aendert das Aussehen der Startseite sichtbar und
bleibt deshalb, wie es ist.

GEMEINSAME BAUSTEINE AUS DEN SEITENDATEIEN GEHOLT
`.filter` stand Zeichen fuer Zeichen doppelt in dateien.css und
bereich.css, `.feld-hinweis` in aufgaben.css und leistung.css (und die
zwei waren schon auseinandergelaufen). Dogi-Media war jeweils die
dritte Seite, die sie braucht, und laedt keine davon. Derselbe Fehler
wie damals bei .knopf-still und beim Schalter -- jetzt in gate.css
bzw. start.css.

GEPRUEFT
pruef-material 155/0 (von 126, neu: Zeitfenster, Bearbeiten, Entfernen,
Rechte in der Liste und ein Abschnitt am echten Bildschirm mit Browser).
pruef-css-klassen um eine Pruefung erweitert, die genau den
start.css-Fehler findet -- mit sieben Gegenproben, darunter der echte
Fall. pruef-kachelfarben 22/0, pruef-start-ansicht, pruef-struktur,
pruef-meldungen, pruef-zeitraum, pruef-content, pruef-serien 69/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 13:59:55 +02:00
DogFatherGitandClaude Opus 5 80dee4d0c8 Highlights nach vorn, kraeftige Chatfarben, alle Farben in einer Kachel
screen1 -- HIGHLIGHTS AUF ANSCHLAGBRETTS PLATZ
  Kein Tausch, sondern ein Aufruecken: Highlights nimmt die Stelle,
  alle anderen wandern eine weiter. Inhaltlich stimmt das auch --
  was die Leute selbst gemacht haben, steht vor dem, was ihnen
  angesagt wird.

screen2 -- DIE CHATFARBEN SIND GERECHNET, NICHT GEGRIFFEN
  Gemessen, was drinstand: Buntheit 0,002 bis 0,048, im Mittel 0,028
  -- auf dem Bildschirm zwoelf Grautoene. Das lag nicht an fehlendem
  Mut, sondern an der Fusszeile der Blase: Sie stand auf der leisen
  Hausschrift, und gegen die darf die Flaeche kaum Farbe haben.

  Deshalb ZUERST die Schrift (--blase-text/--blase-leise, eigene
  Farben der Blase), DANN die Flaeche. Andersherum waere es der
  Fehler vom selben Vormittag gewesen, als 27 von 31 Startkacheln
  unlesbar wurden.

  tools/chat-kacheln-rechnen.mjs liest beide Schriftfarben aus dem
  CSS und rechnet daraus die hellste Flaeche, die sie noch tragen.
  Ergebnis: Buntheit 0,072 bis 0,268, alle zwoelf auf DERSELBEN
  Leuchtdichte -- also exakt demselben Kontrast (7,02 bis 7,13:1).

  Zwei Anlaeufe waren falsch und stehen im Werkzeug begruendet:
    - hoechste Buntheit nehmen, dann Kontrast pruefen. Musste
      scheitern: gesaettigtes Gelb ist bei gleicher empfundener
      Helligkeit viel heller als Blau.
    - gleiche OKLab-Helligkeit statt gleicher Leuchtdichte. Das
      Versprechen der zwoelf lautet "ueberall gleich gut lesbar",
      und Lesbarkeit haengt an der Leuchtdichte, nicht am Eindruck.

  WER NICHTS EINSTELLT, BEKOMMT TROTZDEM EINE FARBE. Gemessen an der
  Live-Datenbank hatten vier von fuenfzehn eine gewaehlt -- der Chat
  war fuer alle anderen einfarbig. Jetzt vergibt der Server einen der
  elf bunten Toene aus der Personennummer, stabil. Schrittweite 4:
  elf ist prim, also laufen alle Toene durch, und vier Schritte sind
  131 Grad im Farbkreis -- aufeinanderfolgende Nummern landen so weit
  auseinander wie moeglich. Mit id % 11 sassen zwei Nachbarn im
  selben Gespraech magenta und rot nebeneinander.

  Niemand verliert seine Wahl: veilchen, ziegel und moos sind die
  drei gewaehlten und behalten ihren Farbbereich.

  Dazu: Blasen mit 22px runden Kanten (nur die Ecke zur Person bleibt
  spitz -- sie sagt, wer spricht), Lichtsaum oben innen, weicher
  Schatten. Der Name hell und fett mit Rollenpunkt davor; er stand
  auf leisem Grau mit 85 Prozent Deckung und war der schwaechste Text
  der Seite, ausgerechnet der, der sagt, wer spricht.

  ZWEI REGELBLOECKE FUER DIESELBE BLASE ZUSAMMENGELEGT. Der untere
  gewann und hat an einem Tag zweimal Schaden angerichtet: Er stellte
  die runden Kanten auf 16px zurueck (die Aenderung waere wirkungslos
  ausgeliefert worden), und er mischte 26 Prozent Akzentfarbe in die
  eigene Blase -- die hatte damit eine Farbe, die in CHAT_KACHELN
  nicht vorkommt und die die Kontrastpruefung nie angesehen hat.

screen3 -- ALLE FARBEN DES HAUSES IN EINER KACHEL
  tools/kachel-regenbogen.mjs leitet die 31 benutzten Toene ab
  (bereicheFuer/zusatzBereicheFuer ueber alle Rollen und beide
  Haeuser) und schreibt daraus einen Streifenverlauf mit harten
  Kanten -- "nicht gemischt" war die eigentliche Ansage. Ein Verlauf
  ergaebe Zwischentoene, die es im Haus nicht gibt.

  Gegen einen deckenden Grund gemischt, nicht gegen --flaeche: Die
  ist halbdurchsichtig, und durch 31 schmale Baender schien das
  Buehnenbild -- sie verloren genau das, wofuer sie da sind.

  Der Lesesaum ist staerker als auf den anderen Kacheln, und zwar
  gemessen: Mit deren Werten kam der Text auf 4,45:1, fuenf
  Hundertstel unter der Grenze. Gefunden hat das pruef-kachelfarben,
  nicht der Blick -- 4,45 gegen 4,50 sieht man nicht.

pruef-buehne -- DIE ZAHL GEHOERT IN DIE BEDINGUNG
  Die Abtastung wurde nachsichtiger (fremde Flaechen zaehlen nicht
  mehr als Untergrund eines Textes). Das war richtig und hat einen
  Fehlalarm beseitigt, der seit Tagen kam. Eine Lockerung kann aber
  zu weit gehen, deshalb muss jetzt jeder gefundene Text in genau
  einem von drei Toepfen landen: gemessen, ohne freien Untergrund,
  oder aussortiert. Geht die Rechnung nicht auf, ist unterwegs etwas
  still verschwunden.

  Erster Anlauf war "mindestens 5 Stellen" -- und wurde auf
  uebersicht.html sofort rot, weil die Seite nur vier Texte hat.
  Eine feste Schwelle ist eine Rechnung von gestern; diese war keine
  fuenf Minuten alt.

Gemessen: pruef-kachelfarben 22/0 (war 18, neu: die Willkommenskachel
traegt wirklich alle benutzten Farben, in beide Richtungen geprueft),
pruef-buehne 192/0, pruef-chatkachel 32/0, pruef-chat-optik 45/0,
pruef-chat 48/0, pruef-erwaehnung 69/0, pruef-start-ansicht 153/0,
pruef-treff 80/0, pruef-willkommen 67/0, pruef-treffchat 110/0,
pruef-css-klassen 30/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 12:57:56 +02:00
DogFatherGitandClaude Opus 5 e12392a289 Die Kachelfarben kommen jetzt WIRKLICH auf dem Bildschirm an
Filipe: "ich raste aus im ernst, was verstehst du nicht darunter wenn
ich sage das alle kacheln eine andere farbe haben sollen ich seh
immer wieder sehr viele die einfach komplett die gleiche farbe haben."

ER HATTE RECHT, UND MEINE PRUEFUNG WAR TROTZDEM GRUEN.
Der Grund war ein Messfehler, und zwar meiner: pruef-kachelfarben las
`--ton` aus start.css -- die ROHFARBE. Die lag zwischen allen 31
Kacheln weit auseinander (0,0978 in OKLab). Nur steht sie so nie auf
dem Bildschirm.

GEMESSEN an echten Bildpunkten (neu: tools/kachel-echtfarbe.mjs):
  Rohfarben:              0,0978 auseinander
  Auf dem Bildschirm:     0,0141
  Es kamen an:            14,4 Prozent
  Fuer ein Auge gleich:   ACHT Paare

Drei Stellen haben die Farbe geschluckt, alle in .kachel:
  1. Eine Wolke mit 16 Prozent -- in immer DEMSELBEN Blau, auf jeder
     Kachel. Der staerkste Gleichmacher der ganzen Wand. Sie traegt
     jetzt den Ton der Kachel.
  2. Die Vignette legte bis zu 55 Prozent Dunkelblau darueber.
  3. Der Grund trug den Ton zu 24 Prozent und ging ab 58 Prozent in
     fast reines Schwarz. Zwei Drittel jeder Kachel waren damit
     dieselbe Farbe, egal welcher Ton darueber stand.

Danach: 51,1 Prozent kamen an, NULL ununterscheidbare Paare.

UND DANN HAETTE ICH EINEN FEHLER GEGEN EINEN ANDEREN GETAUSCHT.
Gemessen an jedem einzelnen Kacheltext: VORHER war 1 von 31 unter
4,5:1, DANACH 27 von 31. Also genau das, was Filipe schon zweimal
gemeldet hat ("man bekommt fast nichts gelesen"). Kein Messwert hat
es angezeigt -- pruef-buehne nimmt Stichproben und traf die
Kacheltexte nicht.

Behoben mit einem Lesesaum: ein dunkler Verlauf VON UNTEN, der genau
den Streifen abdunkelt, auf dem gelesen wird, und die oberen zwei
Drittel in Ruhe laesst. Dasselbe Mittel, mit dem jede Bildunterschrift
auf einem Foto lesbar gemacht wird.

  Texte unter 4,5:1:   1 -> 27 -> 0
  Farbe kommt an:      14,4 % -> 51,1 % -> 36,5 %

VERTRAULICH MELDEN IST JETZT KNALLROT.
Filipe: "nicht die kachel draussen soll rot sein sondern die kachel
vertraulich melden nur die soll knall rot sein!!!" Ich hatte screen5
und screen6 vertauscht. Ringtausch ohne neue Farbe:
  Vertraulich melden  28 -> 38  (#ff1a1a, knallrot)
  Draussen            38 -> 39  (die Farbe, die Regeln & Hilfe hatte)
  Regeln & Hilfe      39 -> 28  (das frei gewordene Gruen)

NEU, UND DER EIGENTLICHE LERNEFFEKT:
server/helfer-kachel-echtfarbe.mjs misst beides in EINER Messung --
Farbunterschied UND Lesbarkeit. Wer sie trennt, verbessert das eine
und verliert das andere; genau das ist heute passiert. Benutzt von
der Pruefung und vom Werkzeug, damit es nur eine Fassung gibt.

pruef-kachelfarben 18/0 (war 13), davon fuenf am echten Bildschirm:
  - kein Paar sieht auf dem Bildschirm gleich aus (0,0357)
  - mindestens ein Drittel der Rohfarbe kommt an (36,5 %)
  - jeder Kacheltext erreicht 4,5:1 (schlechtester: 4,80:1)
Mit drittem Ausgang: kein Browser heisst "konnte nicht nachsehen",
nicht "in Ordnung".

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 10:26:49 +02:00
DogFatherGitandClaude Opus 5 65d278a18e Der Handy-Rundgang ist zum ersten Mal bei null Befunden
SECHS SACHEN, UND KEINE DAVON WAR DAS, WONACH ICH GESUCHT HABE.

1. ZWEI NATIVE prompt() IN teamlage.js -- die letzten im Haus.
   Sie halten die ganze Seite an, sehen auf jedem Browser anders aus
   als der Rest und koennen nicht sagen, was BLEIBT, wenn man absagt.
   Genau das ist dort die Frage, die jemand vor dem Klicken hat. Jetzt
   derselbe Dialog wie an den 42 anderen Stellen.

2. UND DER GRUND, WARUM SIE NIEMAND GEFUNDEN HAT.
   pruef-nachfrage suchte mit `(?:^|[^.\w])(confirm|prompt)\s*\(`.
   Das `[^.\w]` sollte fremde Methoden ausschliessen -- `angebot
   .prompt()` ist die Installations-Aufforderung des Browsers und kein
   nativer Dialog. Nur trifft dieser Ausschluss ausgerechnet die
   HAEUFIGSTE Schreibweise: `window.prompt(` hat einen Punkt davor.
   Die Pruefung war gruen, waehrend zwei native prompt() dastanden.
   Genau das Muster, vor dem dieses Haus warnt: eine Pruefung, die
   laeuft, gruen ist und das Falsche prueft. Die Gegenprobe kennt
   jetzt beide Schreibweisen -- haette sie das vorher getan, waere es
   am selben Tag aufgefallen.

3. willkommen.html LUD nachfrage.js NICHT.
   Gefunden von der geschaerften Pruefung. kopf.js ruft `frageNach(`
   ohne Absicherung -- auf dieser einen Seite haette ABMELDEN einen
   Absturz ausgeloest. Die Seite ist vom 21.09., die Luecke also
   einen Tag alt.

4. ZWEI FEHLALARME IM HANDY-RUNDGANG ABGESTELLT.
   Er meldete bei JEDEM Lauf dieselben drei Befunde: `button.schnitt
   bis 481px`, die Rechtetafel `table bis 877px`, `a.k-pille 8x8`.
   Nachgemessen bei 390 px: Das Dokument ist exakt 390 px breit,
   NICHTS laeuft ueber -- beide stehen in einem Kasten mit
   `overflow-x: auto`, und der rollt absichtlich. Die Kalenderpunkte
   tragen `pointer-events: none`; der Tipp gehoert der Tageszelle.
   Eine Warnung, die immer kommt, ist keine Warnung mehr (Hausregel
   vom 03.09.). Beide Regeln sind SCHMAL: nur ausdrueckliches
   `overflow-x: auto|scroll` (nicht `hidden` -- dort ist der Inhalt
   wirklich weg), nur ausdrueckliches `pointer-events: none`.
   Die Gegenprobe hat jetzt vier Faelle statt zwei: zwei, die gemeldet
   werden MUESSEN, und zwei, die es NICHT duerfen. Eine engere Messung
   kann auch zu eng sein.

5. DER LETZTE ECHTE BEFUND: 404 BEI JEDEM MODI.
   Der Rundgang meldete "404 (Not Found)" ohne Adresse -- eine
   Pruefung, die einen Fehler findet, ihn aber nicht auffindbar macht,
   kostet mehr Zeit als sie spart. Sie nennt jetzt die Adresse, und
   damit war es in einer Minute klar: `/workspace/api/werdegang/liste`.
   Der Code BEHANDELTE den 404 richtig, der Browser protokolliert ihn
   trotzdem -- derselbe Fall wie am 19.09. bei /anruf/adressen.
   Jetzt sagt der Server in /api/ich, ob jemand Team Dogi fuehrt.
   EIGENES FELD, kein Stellvertreter: `darf_verteilen` sieht aehnlich
   aus, ist aber nicht dasselbe -- ein Manager darf verteilen und
   fuehrt Team Dogi nicht.

   Dabei EINE Wartestelle statt zwei: `window.wennIchDaBin()`.
   `window.__ich` kommt ueber das Netz; zwei Seiten hatten dafuer
   jeweils ein eigenes setInterval. Zwei Fassungen desselben Wartens
   altern unterschiedlich.

6. pruef-werdegang MASS AUF DER FALSCHEN ADRESSE.
   Drei Pruefungen waren dauerhaft rot (`data-ton=null`) -- an einer
   Seite, die in Ordnung ist. Sie oeffnete `127.0.0.1`, also die
   Adresse der AGENTUR; dort ist `person.haus` nicht "crew" und die
   Kachelliste eine andere. Nachgemessen: Alle vier Rollen HABEN die
   Kachel, sobald das Haus stimmt. Jetzt derselbe https-Vorbau wie in
   pruef-willkommen und pruef-zuteilung.

   Beinahe haette ich hier etwas "repariert", das nicht kaputt war:
   Meine erste Messung rief `bereicheFuer(p, "crew")` auf -- das Haus
   wird aber aus `person.haus` gelesen, nicht als Argument. Sie sagte
   "DogFather hat keine Kachel". Eine plausible Herleitung ersetzt
   keine Messung, und eine falsch aufgesetzte Messung auch nicht.

GEMESSEN: pruef-handy-teamdogi 214 Seitenaufrufe, 108.564 Elemente,
4.126 Bedienelemente -- 0 Befunde. Alle vier Rollen, beide Breiten.
Zum ersten Mal.

pruef-werdegang 103/0 (war 100/3), pruef-nachfrage 51/0 (war 49),
pruef-stelle 15/0, pruef-entwicklung 48/0, pruef-start-ansicht 153/0,
pruef-wege-nach-draussen 67/0, pruef-tippziele 11/0, pruef-treff 80/0,
pruef-willkommen 67/0, pruef-sackgassen 13/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 10:14:25 +02:00
DogFatherGitandClaude Opus 5 227c6c0425 screen5 und screen4: zwei Farben gesetzt, 14 auseinandergezogen
screen5 (ausdruecklich VOR screen4, wie gewuenscht):
  "Vertraulich melden" traegt jetzt Ton 28 -- die Farbe, die "Regeln
  & Hilfe" hatte. Beide gehoeren zusammen: Wer Hilfe sucht, landet
  bei einem von beiden. "Regeln & Hilfe" bekam dafuer einen eigenen
  Ton; zwei Kacheln mit derselben Farbe in derselben Ansicht waeren
  genau das, was screen4 abschaffen soll.
  "Draussen" ist knallrot: Ton 38 = #ff1a1a, voll gesaettigt,
  Kontrast 4,84:1 gegen den Grund. Gemessen, nicht geschaetzt -- von
  zehn Rotwerten zwischen #ff0000 und #ff5555 erfuellen alle die
  4,5:1, dieser ist der knalligste, der auf dunklem Grund nicht
  flimmert. Er traegt ab 20 Uhr den LIVE-Punkt.
  Beide sind ab jetzt GESETZT: pruef-kachelfarben wird rot, wenn ein
  Farblauf sie anfasst. Eine Festlegung, die nur im Kommentar steht,
  ist eine Bitte.

screen4: neues Werkzeug tools/kachel-farben-entzerren.mjs.
  Der Unterschied zu den zwei vorhandenen: Es rechnet nur mit den
  BENUTZTEN Toenen. In start.css stehen 42, benutzt werden 31 -- die
  anderen Werkzeuge weichen also Farben aus, die kein Mensch sieht,
  und machen dadurch die Abstaende zwischen den sichtbaren unnoetig
  klein. Welche benutzt werden, wird aus den Kachellisten ABGELEITET.
  Von jedem aehnlichen Paar aendert sich genau EINER -- der, der
  nicht gesetzt ist.
  Ergebnis: engstes Paar 0,0741 -> 0,0978 (Faktor 1,32), 14 Toene
  geaendert, alle 31 erreichen 4,5:1.

ZWEI DINGE, DIE ERST DAS MESSEN GEZEIGT HAT
1. Der erste Lauf schlug fuer "Dateien" ein #ffe5ae vor -- Buntheit
   0,076, ein helles Creme. Rechnerisch die beste Stelle im Farbraum,
   auf dem Bildschirm genau das, was Filipe seit Wochen abschafft.
   Mindestbuntheit eingebaut, Schwelle GEMESSEN: Median aller Toene
   0,168, die fuenf blassesten 0,064-0,088. 0,12 liegt dazwischen.
2. Die Abstandsrechnung fasst einen Ton nie an, der weit weg von
   allen liegt -- auch wenn er blass ist. So blieben drei benutzte
   Toene unter 0,12 stehen. Zweite Runde: jeder blasse wird kraeftig
   gemacht, solange das Minimum ueber 0,095 bleibt. Gemessener Preis
   0,1028 -> 0,0978, also 5 Prozent; auf dem Bildschirm nicht zu
   sehen, waehrend Filipes Klage ueber helle Kacheln konkret ist.

NEU: pruef-kachelfarben 13/0 -- getrennt, eindeutig je Ansicht,
festgelegt, lesbar und nicht blass. Mit vier Gegenproben, damit sie
auch rot werden KANN.
NEU: tools/farben-blick.mjs -- sieht die Wand mit echten Augen an und
misst das, was eine Abstandstabelle nicht beantwortet: ob zwei
NEBENEINANDER liegende Kacheln aehnlich aussehen. Gemessen bei
DogFather und Community: kein Nachbarpaar unter 0,09.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 09:21:54 +02:00
DogFatherGitandClaude Opus 5 06f3fecaa7 Material: Bilder und Videos zum Posten, jedes nur einmal
Filipe, 22.09.2026: "ich brauch auch noch eine neue kachel im bereich
community, wo wir als team ... bilder reinschicken koennen, mit text
und wo die leute sei es community oder modis sich die bilder nehmen
koennen zum posten. die community soll keine posten koennen ... sobald
ein bild oder ein video ... runtergeladen wurde, soll direkt blockiert
werden ... damit nie ein bild zwei mal gepostet wird ... und die rechte
hand und dogfather, nur die beiden sollen auch immer sehen koennen wer
das bild oder video runtergeladen hat."

DER KERN IST DIE EINMALIGKEIT, und deshalb sind Nehmen und Laden ZWEI
Schritte. "nehmen" schreibt in EINER Abfrage fest, wer es hat -- mit
`WHERE genommen_von IS NULL` in der Bedingung. Wer zu spaet kommt,
aendert null Zeilen und bekommt 409. Ein einziger Schritt ("laden und
dabei markieren") haette dieselbe Luecke wie ein Pool ohne Sperre:
zwei Anfragen, beide sehen "frei", beide laden.

UND DIE SPERRE GILT AUCH FUER DIE VORSCHAU. Waere sie offen
geblieben, waere sie der Weg, ein vergebenes Bild doch noch zu
bekommen (Rechtsklick, speichern) -- und die ganze Einmaligkeit eine
Behauptung. Ausnahme: wer es selbst genommen hat, sieht es weiter.

WER WEN SIEHT, entscheidet der Server, nicht die Seite. Fuer alle
ausser DogFather und der rechten Hand fehlt das Feld `genommen_von`
ganz -- nicht `null`: Ein Feld, das da ist und leer bleibt, laedt
dazu ein, es spaeter "zu fuellen".

pruef-material.mjs (70 Pruefungen, 0 Fehler) misst den ganzen Weg,
mit Gegenprobe zu jeder Grenze. Die Zahl der vergebenen Stuecke steht
in der BEDINGUNG -- ohne sie waere "keine Namen dabei" trivial wahr.

DREI DINGE HAT ERST DER BLICK MIT ECHTEN AUGEN GEFUNDEN
(tools/material-blick.mjs, drei Rollen, vier Bildschirmbreiten):

  * "hat es genommen am 22.09.." -- eine deutsche Datumsangabe endet
    selbst auf einen Punkt. Kein Pruefprogramm haette danach gefragt.
  * Die Knoepfe standen auf drei verschiedenen Hoehen (1127, 1155,
    1176), weil der eine Text zwei Zeilen hatte und der naechste
    keine. `margin-top: auto` am Fuss statt einer geratenen
    Mindesthoehe.
  * "Schon benutzt" nahm 273 px Hoehe je Stueck fuer ein einziges
    Zeichen -- das Bild ist dort ohnehin nicht mehr abrufbar. Jetzt
    eine Zeile mit 96 px.

Am Handy (412 px) blieb es bei EINER Spalte: 3062 px Seitenhoehe fuer
fuenf Stuecke. Filipe: "es ist alles so lang gezogen, muss ewig
scrollen". Statt einer festen Umbruchschwelle -- die am 06.09. schon
zweimal teuer war -- waechst die Spaltenbreite jetzt mit:
`max(160px, 22%)`. Gemessen 360/412/768/1500 px: 2/2/3/3 Spalten,
nirgends ein Ueberlauf, 412 px jetzt 2014 statt 3062 px.

Dazu neun Saetze in meldung.js. Der wichtigste ist "schon_genommen",
und er ist bewusst kein Fehler: Wer ihn liest, hat nichts falsch
gemacht. pruef-meldungen fand dabei einen Rest aus dem Aufgaben-Block
-- `nur_leitung_legt_an` hatte keinen Satz, ein Modi mit altem Tab
haette rohen Maschinentext gelesen.

pruef-material 70/0 · pruef-meldungen 8/0 · pruef-treff 80/0
pruef-rechtetafel 19/0 · pruef-sackgassen 13/0 · pruef-css-klassen ok
pruef-zwischenspeicher 27/0

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-22 02:27:21 +02:00
DogFatherGit 82335c783d Die rechte Hand legt selbst Personen an -- und sieht die Codes
Filipe: "dan will ich dass die rechte hand auch neue personen
hinzufuegen kann. also neue erstellen kann und die codes genau so
sieht wie dogfather, damit sie das auch machen kann wenn er live ist."

WAS SIE DARF: Modis und Community anlegen, und deren Codes neu setzen.
Die Liste ist ABGELEITET aus ROLLEN_ZUM_AENDERN -- dieselben zwei
Rollen, die sie ohnehin vergeben darf. Zwei Listen waeren zwei
Gelegenheiten, eine davon zu aendern und die andere zu vergessen.

WAS SIE NICHT DARF: eine zweite rechte Hand, eine linke Hand oder
einen zweiten DogFather anlegen -- und an einer linken Hand auch
nichts aendern. Ohne die zweite Schranke haette sie den Code einer
linken Hand neu setzen koennen und damit einen Zugang in der Hand, der
fast so viel darf wie sie selbst. Die alte Schranke kannte nur "admin"
und "manager".

NUR DIE RECHTE, NICHT DIE LINKE. `istHand()` haette beide getroffen;
fuer die linke Hand ist "legt niemanden an" eine ausdrueckliche
Entscheidung vom 21.09.

VIER STELLEN IN DER OBERFLAECHE, die alle an Rollennamen hingen:

  `nurLesen = ich.rolle === 'hand'` -- sie bekam die Liste und kein
  Formular. Jetzt abgeleitet aus `darf_anlegen`.

  Die Wache darueber warf sie auf die Startseite, sobald `nurLesen`
  falsch wurde. Die Seite ging fuer sie einfach nicht auf, ohne
  Meldung.

  Der Sendeweg hing an `ich.rolle === 'admin'`. Fuer sie gab es damit
  GAR KEINEN: Die Seite antwortete "Fuer die Rolle modi gibt es hier
  keinen Weg" -- ein Satz, der wie ein Formularfehler klingt und eine
  fehlende Zeile war.

  UND EIN ECHTER FUND: `rollenwahlErgaenzen()` hing jede Zusatzrolle an
  das Formular, die mit der Personenliste kam -- ohne zu fragen, ob man
  sie anlegen darf. Solange nur DogFather das Formular sah, fiel es
  nicht auf: Er darf sie alle. Der rechten Hand bot es "rechte Hand"
  und "linke Hand" an. Der Server haette es abgelehnt -- aber der Knopf
  verriet eine Rolle, die sie nicht vergeben soll.

Zwei Pruefungen waren dabei selbst kaputt: pruef-personen-formular
erwartete sieben Rollen (seit "linke" am 21.09. sind es acht) und
suchte den Namen im sichtbaren Text -- die Abschnitte sind zugeklappt
und zeigen nur Anfangsbuchstaben. Beides abgeleitet statt gezaehlt.

Geprueft: pruef-personen-formular 43/0 (war 34 ok / 2 FEHL), davon
neun am echten Bildschirm auf der Crew-Adresse -- anmelden, Formular
oeffnen, anlegen, Code lesen, Person in der Liste wiederfinden.
pruef-haus-trennung 81/0 (war 72 ok / 2 FEHL), pruef-rollen-anlegen
11/0.
2026-09-22 01:39:12 +02:00
DogFatherGit 39c0b4dc1f Ein Modi sieht nur SEINE Aufgaben -- und gibt sich selbst keine
Filipe, unmissverstaendlich und mehrfach: "die modis sollen immer nur
ihre aufgaben auch sehen und nicht die von anderen, so wie bei den
daten ... damit wir endlich den modis aufgaben anstaendig verteilen
koennen und sie sich nicht selber aufgaben geben."

DAS DREHT DIE ENTSCHEIDUNG VOM 09.09. AUSDRUECKLICH UM. Damals: "ja,
sie sind untereinander ein team", damit ein Schichttausch ohne Umweg
geht. Beides steht jetzt im Code nebeneinander, damit niemand spaeter
die aeltere findet und fuer die gueltige haelt.

VIER AENDERUNGEN:

  Die Sicht. Ein Modi sieht nur `a.verantwortlich_id = ich`. Was ihm
  ueber aufgaben_zuteilung gegeben wurde, haengt mitZugeteilten() an --
  ein Pool, in dem er steht, bleibt also sichtbar, bis ihn jemand
  uebernimmt. Die rechte und die linke Hand behalten die Uebersicht.

  Das Anlegen. Im Team Dogi legt nur an, wer auch verteilen darf. In
  der AGENTUR bleibt es, wie es war -- dort ist eine Aufgabe eine
  Notiz an sich selbst, kein Auftrag von jemandem. Eine Regel, die
  beide Haeuser ueber einen Kamm schert, waere falsch.

  Der Knopf. "Neue Aufgabe" steht fuer einen Modi gar nicht mehr da.
  Ein Knopf, der mit 403 antwortet, ist schlimmer als keiner: Die
  Meldung erscheint ganz oben, und wer weiter unten steht, sieht nur,
  dass nichts passiert.

  Die Kacheln. Ein Modi sieht jetzt den Bereich "Entwicklung &
  Nachwuchs" mit denselben zwei Kacheln wie die Leitung -- nicht mehr
  zwei eigene mit anderem Namen. Zwei Namen fuer dieselbe Sache ist
  genau der Fehler, der am 19.09. zwei Kacheln "Chat" ergeben hat.
  "Talente" bleibt draussen: Dort stehen Notizen ueber Zuschauer, die
  nichts davon wissen.

UND DIE LINKE HAND SIEHT "DEIN TEAM" NICHT MEHR (Filipes Wunsch).
Abgeleitet, nicht nachgebaut: Ihre Liste ist die der rechten Hand
MINUS dieser einen Kachel, erkannt am ZIEL statt am Namen -- der Name
ist am 17.09. schon einmal gewandert.

Gemessen: admin 30 Kacheln, hand 30, linke 29 (ohne "Dein Team"),
modi 25 (mit dem Bereich, ohne Talente).

Zwei Pruefungen hielten die alte Regel fest und wurden dadurch rot --
genau ihre Aufgabe. Beide umgedreht, mit der alten Entscheidung im
Kommentar. pruef-zuteilung 65/0, pruef-verteilen 19/0 (war 15),
pruef-aufgabenbrett 49/0.
2026-09-22 01:17:11 +02:00
DogFatherGit 66789aabcd Willkommen: eine Seite, die erklaert, was es hier gibt
Auftrag vom 21.09.2026, Abschnitte 7 und 8. Aus der Kachel "Der Treff"
wird die Willkommensseite.

WARUM DAS NICHTS VERLIERT, gemessen am echten Bestand: Das Brett
"treff" hatte NULL Eintraege, der Treff-Chat daneben 29 Nachrichten.
Geredet wird im Chat; das Brett war eine Kachel ohne Inhalt.

DIE SEITE ERKLAERT NICHT "DIE WEBSITE", SONDERN DEINE. Sie baut sich
aus derselben Kachelliste wie die Startseite, durch denselben Filter
(darfSeite). Wer morgen eine Kachel bekommt, bekommt automatisch auch
ihre Erklaerung -- und wer eine nicht hat, liest nicht davon. Eine
Liste von Dingen, die man nicht darf, ist keine Orientierung.

Gemessen: DogFather 30 Kacheln, Modi 25, Community 11 -- und keine
einzige davon ist fuer den Betreffenden gesperrt.

DREI FEHLER, DIE ERST DAS BILDSCHIRMFOTO GEZEIGT HAT:

  body class="gate" ist die ANMELDEWAND (display:flex, zentriert).
  Kopfleiste und Inhalt standen dadurch NEBENEINANDER -- am Handy
  blieben dem Text 260 von 390 Pixeln.

  .huelle gibt es im Haus gar nicht. Der Inhalt stand linksbuendig
  statt mittig, ohne Sicherheitsrand an randlosen Geraeten. Jetzt
  .inhalt wie jede andere Seite.

  Der Text stand direkt auf dem Buehnenbild: Kontrast 1.68:1 am
  Rechner, 2.23:1 am Handy (noetig 4.5). Die Hausregel stand daneben
  in start.css -- "der Text steht auf eigenen Flaechen" -- und diese
  Seite hielt sich als einzige nicht daran. Jetzt 5.19 und 7.73.

UND EIN LECK, ZUM DRITTEN MAL DIESELBE URSACHE:

Die Kachel umzuleiten nahm dem Brett "treff" die Zugehoerigkeit --
TREFF_BRETTER wird aus Kachelzielen abgeleitet. Die Schranke laesst
eine AGENTURROLLE unbesehen durch, wenn ein Brett in keiner Liste
steht: Eine Creatorin konnte das Brett des Treffs lesen.

Behoben, und diesmal dauerhaft laut gemacht: Nachgemessen ist die
Trennung exakt und in beide Richtungen deckungsgleich -- die Bretter
mit `fuerAlle` sind genau die des Treffs plus die Agenturablage. Das
ist eine Eigenschaft des BRETTS und wandert nicht, wenn jemand eine
Kachel umleitet. pruef-treff prueft das jetzt.

Mein erster Entwurf der Regel war zu breit und meldete `content` und
`schutz` -- beides Agenturbretter, die eine Agenturrolle zu Recht
liest. Eine Pruefung, die zu viel meldet, wird abgeschaltet.

AUSSERDEM: 16 Kennungen aus workspace-zuteilung.js hatten keinen
deutschen Satz -- auf dem Bildschirm haette woertlich "nicht_zugeteilt"
gestanden. Gefunden von pruef-meldungen am selben Tag.

Und zwei Erwartungen in pruef-treff abgeleitet statt gezaehlt: die
Zahl der Rollenkacheln auf der Wand (die Anmeldung sucht WHERE rolle=?,
eine Rolle ohne Kachel ist unerreichbar) und "die breite Kachel steht
vorne" ueber die Eigenschaft statt ueber den Namen.

Geprueft: pruef-willkommen 66/0 (neu), pruef-treff 80/0 (war 59 ok /
13 FEHL), pruef-buehne fuer die neue Seite 10/0, pruef-meldungen 8/0,
pruef-css-klassen 30/0, pruef-rechtetafel 19/0.
2026-09-22 00:00:14 +02:00
DogFatherGit ef0fddc724 Aufgaben an Menschen: zuteilen, annehmen, ablehnen, bewerten
Auftrag vom 21.09.2026, Abschnitte 2 bis 5 -- der Serverteil.

DREI ARTEN ZU VERTEILEN, und der Unterschied zwischen den letzten
beiden ist der ganze Punkt:

  einzeln   eine Person, sie macht es
  mehrere   mehrere Personen, JEDE macht ihren Teil
  pool      mehrere sehen es, EINE nimmt es -- danach ist es fuer die
            anderen weg, damit niemand doppelt arbeitet

EINE EIGENE TABELLE, KEINE SPALTEN AN DER AUFGABE. Abschnitt 4
verlangt ausdruecklich: *"Die Aufgabe muss in der Auswertung auf die
einzelnen zugewiesenen Personen aufgeteilt werden"* -- und gleichzeitig
soll "die urspruengliche gemeinsame Aufgabe ihre uebergeordnete
Struktur" behalten. Eine Aufgabe hat EINEN Titel und EINE Frist, aber
je Mensch einen eigenen Stand, einen eigenen Grund beim Ablehnen, ein
eigenes Erledigt-Datum und eine eigene Rueckmeldung. Das in Spalten zu
pressen hiesse, dieselbe Aufgabe mehrfach anzulegen.

`aufgaben.status` bleibt daneben unberuehrt. Zwei Ebenen, weil es zwei
Fragen sind: "Wie steht die Aufgabe?" und "Wie steht sie bei IHM?" Ein
einziges Feld koennte bei drei Leuten nicht gleichzeitig "angenommen"
und "abgelehnt" sein.

DER WICHTIGSTE EINZELNE HANDGRIFF -- und er steht nicht im Auftrag:
Wer eine Aufgabe BEKOMMEN hat, sieht sie jetzt immer. Bei "mehrere"
und "pool" bleibt `verantwortlich_id` leer, und die alten Sichtregeln
fragen genau danach. Ohne die Erweiterung stuende eine Aufgabe im
Resuemee der Leitung und waere fuer den, der sie machen soll,
unsichtbar -- der unangenehmste denkbare Fehler in einem
Aufgabensystem, und man sieht ihn nirgends. Die Erweiterung ist ein
ODER, kein UND: Sie erweitert die Sicht, die Haustrennung darueber
bleibt ein UND und wirkt weiter.

WAS SONST NOCH ENTSCHIEDEN WURDE, mit Grund im Code:

  - Ablehnen braucht eine Begruendung (mind. 3 Zeichen). Ein leeres
    Nein ist fuer den, der verteilt hat, keine Information -- er muss
    dann nachfragen, und genau das sollte die Nachricht ersparen.
  - "Verbesserungsmoeglichkeiten" braucht einen Text. Ein leeres
    "kann besser" sagt nichts ausser, dass jemand unzufrieden war.
  - Bewertet wird erst, wenn jemand FERTIG ist. Eine Rueckmeldung auf
    etwas, das noch laeuft, ist keine Bewertung, sondern eine
    Einmischung.
  - Beim Pool wird VOR dem Schreiben gefragt, ob schon jemand zugesagt
    hat -- sonst nehmen zwei im selben Moment dieselbe Aufgabe und
    beide sehen "hat geklappt".
  - Wer schon geantwortet hat, behaelt seinen Stand, wenn die Aufgabe
    noch einmal gespeichert wird. Sonst muesste er ohne Grund erneut
    zusagen.
  - Wer nicht mehr dabei ist, faellt raus -- aber nur, solange er noch
    nicht geantwortet hat. Jemandem eine angenommene Aufgabe
    wegzunehmen, ohne dass er es erfaehrt, waere die unangenehmste Art,
    Arbeit zu verlieren.
  - "pool" mit einer Person wird "einzeln". Ein Pool aus einem
    Menschen ist keiner.

`verantwortlich_id` bleibt und wird mitgefuehrt (einzeln = die Person,
pool = der Uebernehmer, mehrere = leer): Brett, Startseite und
Uebersicht gruppieren danach. Drei gewachsene Ansichten gleichzeitig
umzubauen waere der groessere Eingriff -- und im haeufigsten Fall
sagen beide dasselbe.

KEIN CHECK an der nachgetragenen Spalte `verteilart`, mit Absicht: Ein
CHECK auf einer nachgetragenen Spalte hiesse, die Tabelle neu zu bauen
-- der Weg, der in diesem Haus am 11.09. und heute schon Spalten
gekostet hat. Geprueft wird beim Schreiben.

pruef-zuteilung.mjs, 48 Aussagen -- ein Arbeitstag durchgespielt.

Ein Fehlschlag beim ersten Lauf, und er war lehrreich: "Cem hat keinen
eigenen Stand" schlug fehl, weil Cem die Aufgabe gar nicht SIEHT
(`null?.x` ist `undefined`, nicht `null`). Die Zusicherung konnte
"sieht sie nicht" und "sieht sie ohne Stand" nicht unterscheiden --
also pruefte sie beides nicht richtig. Dass er sie nicht sieht, ist
genau Abschnitt 1: *"Eine Modi darf nicht automatisch die
vollstaendige Aufgabenuebersicht aller anderen Modis sehen."* Beide
Faelle stehen jetzt einzeln da, mit einer Gegenprobe, dass seine Liste
ueberhaupt laedt.

Nachbarn gruen: pruef-verteilen 16/0, pruef-aufgabenbrett 49/0,
pruef-umstellung 18/0.
2026-09-21 17:52:52 +02:00
DogFatherGit 21793b6c36 Neue Rolle: die linke Hand
Aus dem Auftrag vom 21.09.2026, Abschnitt 6: "Die linke Hand erhaelt
grundsaetzlich dieselben Rechte wie die rechte Hand in allen Bereichen,
die die Modis, Aufgaben, Aufgabenzuweisungen, Uebersichten,
Kommunikation und Auswertungen betreffen. Die linke Hand darf keine
neuen Personen oder Accounts hinzufuegen. Die linke Hand darf keine
privaten bzw. persoenlichen Bereiche oder Informationen von Dogfather
sehen."

GEMESSEN VOR DEM BAUEN: Die Rolle "hand" steht an 35 Stellen im
Servercode und 17-mal in der Rechtetafel. Haette ich ueberall ein
"linke" danebengeschrieben, waere die naechste Stelle, die jemand
hinzufuegt, die erste, die es vergisst -- und eine vergessene Stelle
heisst hier: Die linke Hand sieht etwas nicht, ohne dass jemand merkt,
warum.

DESHALB EINE REGEL STATT DREISSIG ABSCHRIFTEN:

  WIE_RECHTE_HAND = new Set(["hand", "linke"])   in workspace.js
  istHand(person)                                fuer die Faehigkeiten
  eine Schleife ueber SEITEN                     fuer die Rechtetafel

Die Schleife gibt der linken Hand jede Seite der rechten -- ausser
fuenf, und jede davon steht mit Grund da:

  personen.html      legt Personen an
  bewerbungen.html   fuehrt zu neuen Personen
  talente.html       fuehrt zu neuen Personen
  hilfe.html         vertraulicher Meldeweg
  rechte.html        Rechteverwaltung

Gemessen: 25 Seiten fuer die rechte Hand, 20 fuer die linke. Als
Kacheln: 30 gegen 26 -- die vier verbotenen erscheinen gar nicht erst,
statt beim Antippen abgelehnt zu werden.

ZWEI DINGE, DIE ERST DAS MESSEN GEZEIGT HAT:

(1) OHNE KACHEL AUF DER ANMELDEWAND GIBT ES DIE ROLLE NICHT. Die
    Anmeldung sucht `WHERE rolle = ?` auf die angetippte Kachel -- es
    gibt keinen rollenuebergreifenden Sonderweg, auch nicht auf der
    Crew-Wand. Eine linke Hand haette sich mit dem richtigen Code
    NIEMALS anmelden koennen, und der Fehler haette ausgesehen wie ein
    falscher Code.

(2) DIE REIHENFOLGE DER DATENBANK-UMSTELLUNG ZAEHLT.
    `checkListeErweitern` baut die CHECK-Regel NEU aus der Liste, die
    man ihm gibt. Mein Schritt stand zuerst bei der rechten Hand --
    der Schritt fuer "gast" darunter nahm die Rolle damit wieder
    heraus, denn seine Liste kennt sie nicht. Die Kette ist kumulativ;
    neue Schritte gehoeren ans ENDE. Das steht jetzt auch dort.

Dazu zwei kleinere Funde beim Bauen:

  - Meine erste Ableitung aenderte die Rollenliste AN ORT UND STELLE.
    Mehrere Seiten teilen sich dieselbe Liste (`ALLE`) -- das haette
    die Rolle allen Seiten gegeben, die sie benutzen, auch einer
    Ausnahme. Faellt nicht auf, solange keine Ausnahme `ALLE` benutzt.
    Jetzt eine Kopie je Seite.
  - ROLLEN_NAME fehlte der Eintrag: Die linke Hand haette ueberall
    "linke" geheissen statt "Linke Hand". Gefunden hat das
    pruef-rechtetafel, weil sie diese Tabelle gegen ROLLEN haelt.
    Ihre Meldung nennt jetzt, WELCHE Liste was vermisst -- vorher
    zeigte sie beim Fehlschlag nur eine der beiden.

NICHT BEKOMMEN -- und jedes einzeln begruendet im Code:
Personen anlegen (ANLEGBAR.linke = []), Rollen aendern
(darfRollenWechseln), Bewerbungen, der vertrauliche Meldeweg. Beim
Meldeweg ist es bewusst das kleinere Recht: Ein Wort von Filipe
oeffnet ihn, eine versehentlich gelesene Meldung laesst sich nicht
zurueckholen.

UNBERUEHRT GEBLIEBEN, obwohl dort "hand" steht:
workspace-leistung.js:406 -- dort heisst "hand" nicht die Rolle,
sondern "von Hand eingetragen".

Am laufenden System gemessen: Datenbank nimmt die Rolle, Anmeldung
HTTP 200, 26 Kacheln, darf_verteilen = true, personen/hilfe/rechte
antworten mit 302, aufgaben und teamlage mit 200.

pruef-rechtetafel 19/0 (war 18/1), pruef-schranke 39/0,
pruef-umstellung 18/0.
2026-09-21 17:44:48 +02:00
DogFatherGitandClaude Opus 5 8a214ecd0e Keine Mischung mehr -- Team Dogi nur noch bei Team Dogi
Filipe: "ich will dass du im workspace alles von team dogi weg nimmst.
nur was ich im kalender eintrage soll ich im workspace sehen und im
team dogi. aber die kacheln von team dogi soll ich nur bei team dogi
sehen und die von workspace nur bei workspace bitte. ich will keine
mischung mehr von kacheln. wie gesagt nur die der kalender soll
verbunden sein von dogfather sonst nichts."

GEMESSEN, WIE SCHLIMM ES WAR: Auf der Agenturadresse bekam DogFather
0 eigene Kacheln ueber die Schnittstelle und 17 fremde -- Dein Team,
Ideen-Board, Rueckmeldung, Wer sieht was, Entwicklung, Werdegang,
Talente und den ganzen Treff samt Moderation. Zwei Betriebe auf einer
Seite.

Das Bittere daran: Dieselbe Datei hatte den Fehler fuer die ANDERE
Richtung am 10.09. schon erkannt und behoben ("Fuenfundzwanzig
Kacheln, von denen zwei Drittel Creator, Scouts und Agentur betreffen,
waeren dort Fenster in ein Haus, in dem er gerade nicht ist"). Nur
andersherum stand es weiter so.

DIE AUSNAHME BRAUCHTE NICHTS: Nachgemessen filtern die Terminabfragen
in workspace-kalender.js NICHT nach Haus. Was er eintraegt, steht
ohnehin auf beiden Adressen. Die Verbindung, die er will, existierte
schon -- sie musste nur nicht zerschnitten werden.

STATT SIEBZEHN BRETTERN STEHT DORT EINE TUER. Ohne sie waere von der
Agenturadresse aus kein Weg mehr zu Team Dogi sichtbar; er muesste die
Adresse tippen. Das ist die Sorte Sackgasse, die dieses Haus nicht
baut. Eine Tuer ist keine Mischung: Sie zeigt kein Brett, sie geht
hinueber. Und sie kommt vom Server, nur fuer `admin` -- in keiner
ausgelieferten Datei steht sie.

MEIN ERSTER ENTWURF GAB SIE AUCH DER RECHTEN HAND UND DER MODERATION.
pruef-modi-checkliste hat es sofort gemeldet: "Modi bekommt 1
Zusatzkachel(n), erwartet keine". Wer NUR zu Team Dogi gehoert, hat
auf der Agenturadresse nichts zu suchen -- die Tuer waere dort seine
einzige Kachel gewesen, also eine Seite, die aus nichts als einem
Ausgang besteht.

VIER PRUEFUNGEN VERLANGTEN DANACH DIE ALTE WELT. Keine davon war ein
Mangel; alle vier haben am falschen Ort gesucht:

  pruef-haus-trennung  verlangte woertlich, dass die Team-Kachel AUCH
     auf der Agenturadresse steht. Sie prueft jetzt die Trennung in
     beide Richtungen -- kein Brett von Team Dogi drueben, aber die
     eine Tuer -- und leitet die Namen aus der Antwort von crew. ab,
     statt sie abzuschreiben.
  pruef-start-ansicht  zaehlte acht Gruppennamen in fester
     Reihenfolge. Gemeint war eine Ordnung ("die Community steht ganz
     unten, denn dort stehen Namen und Saetze von Zuschauern"), und
     die wird jetzt als Regel geprueft -- bedingt, mit drittem Ausgang
     auf Adressen, wo es diese Gruppen gar nicht gibt.
  pruef-treff und pruef-rueckmeldung fragten ueber die Agenturadresse
     nach Brettern, die dort nicht mehr stehen. Sie fragen jetzt dort,
     wo diese Bretter zuhause sind.

EINE HALBE STUNDE WAERE DABEI FAST VERLOREN GEGANGEN: `fetch` kann den
Host-Kopf nicht setzen -- er ist ein verbotener Kopfzeilenname und
wird STILLSCHWEIGEND verworfen. Die Anmeldung ueber die Crew-Wand
genuegt nicht; jede einzelne Abfrage braucht die Adresse. Deshalb geht
die Messung jetzt ueber http.request, so wie es `anmelden()` in
derselben Datei laengst tut.

pruef-haus-trennung 74/0 · pruef-modi-checkliste 75/0 · pruef-treff
72/0 · pruef-rueckmeldung 30/0 · pruef-start-ansicht 153/0 ·
pruef-haus-seiten 34/0 · pruef-entwicklung 46/0 · pruef-befinden
113/0 · pruef-rechte-umstellen 46/0

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-21 14:00:14 +02:00
DogFatherGitandClaude Opus 5 eca9aed279 Der Treff sagt jetzt, ob gerade gestreamt wird
Filipe zu dieser Seite: "mach was anderes daraus oder mach es viel
krass und geiler ... erstell was was mich von den socken schmeisst. es
soll wirklich sogar ein wow effekt fuer die community ergeben." Dazu
die eine Auflage: die Kachel bleibt.

WAS SIE WAR: zwei Karten mit zwei Adressen. Sauber gebaut, richtig
beschriftet -- und niemand kam ein zweites Mal wieder. Wer im Treff
ist, kennt die Website. Den Rabattcode merkt man sich beim ersten Mal.

DIE FRAGE, DIE WIRKLICH JEMAND HAT, IST EINE ANDERE: Laeuft er
gerade? Und wenn nicht -- wie lange noch? Die Antwort kennt das Haus
seit dem 20.08.: postfach.dogfather-universe.com/live-status, derselbe
Dienst, von dem der oeffentliche Streamplan lebt. Im Treff gab es sie
bisher nicht.

Jetzt steht oben ein Puls: ein Ring, der sich ueber den Tag bis zur
naechsten Sendezeit fuellt, darin der Countdown auf die Sekunde. Sendet
er, wird die Karte rot, atmet im Ruhepuls und traegt den Titel des
Streams plus einen Weg hin. Darunter die drei Accounts und -- wenn die
Verwaltung eines eintraegt -- das besondere Event mit eigener Uhr.

DREI AUSGAENGE, NICHT ZWEI. Das ist der eigentliche Unterschied zur
oeffentlichen Seite: streamplan.js faengt dort jeden Fehler ab und
setzt `istLive = false`. Aus "wir konnten nicht fragen" wird "er sendet
nicht" -- und wer das liest, macht die Seite zu und verpasst den
Stream. Der Dienst liefert `autoHealthy` sogar mit; gelesen wird es
draussen nicht. Hier schon: Bei einer Stoerung steht "Konnten wir
gerade nicht nachsehen", dazu der Hinweis, dass das NICHT heisst, dass
kein Stream laeuft. Der Countdown laeuft dabei weiter -- er braucht
kein Netz.

NICHTS IST ABGESCHRIEBEN. Die drei Accounts kommen ueber
/workspace/api/draussen aus derselben KANAELE-Liste, an der die
Aufgabenverteilung haengt; die Adressen baut der Steckbrief. Die
Sendezeit steht im Server, und pruef-draussen haelt sie gegen
FIX_STUNDE in streamplan.js -- verschiebt jemand den Termin und aendert
nur einen Ort, wird die Pruefung rot.

Gemessen, bevor gebaut wurde: der Dienst antwortet und meldet sich
gesund, CORS steht auf *, und `connect-src` der Treff-Seiten fuehrt
postfach bereits. Ohne das Letzte waere der Abruf still blockiert
worden und haette ausgesehen wie ein toter Dienst.

Die Kachel heisst jetzt "Draussen" statt "Unsere Seiten" -- drei Dinge
statt zwei Adressen. Ziel und Datei bleiben gleich.
pruef-wege-nach-draussen schreibt den Namen nicht mehr ab, sondern
verlangt, dass Kachel und Seitenueberschrift uebereinstimmen. Zwei
Namen fuer denselben Ort waren schon einmal ein echter Fehler.

Nebenbefund, dort gleich behoben: Dieselbe Pruefung verlangte, dass
die Community-Kacheln restlos in Dreierreihen aufgehen -- obwohl ihr
eigener Kommentar sagt, eine freie Zelle am Ende sei erlaubt. Sie war
rot bei einwandfreiem Raster. Gemessen wird jetzt, was wirklich
schiefgeht: eine doppelt breite Kachel, die in der letzten Spalte
beginnt und die Zelle davor leer laesst. Mit Gegenprobe.

pruef-draussen: 39 Pruefungen, alle vier Lagen im echten Browser --
die Stoerung wird dafuer absichtlich hergestellt.
pruef-wege-nach-draussen: 67 statt 66, keine Fehler mehr.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-21 12:06:23 +02:00
DogFatherGitandClaude Opus 5 9a71f3a242 Eine Null zu viel -- HasiDog-Videos waeren abgelehnt worden
In KANAELE stand "@hasidog00804". Der Account heisst "@hasidog0804".
Nachgemessen bei TikTok selbst: der richtige hat 65 Follower, der
andere liefert "Couldn't find this account".

Das war nicht kosmetisch. `kanalVonHandle` ordnet ein hochgeladenes
Video ueber genau diesen Text einem Kanal zu. Ein echtes
HasiDog-Video waere mit 403 abgelehnt worden -- und die Begruendung
haette gelautet: "ist keiner deiner Kanaele. Moeglich sind:
@dogfather0804, @hasidog00804, @dogis.modi.gang." Eine Sackgasse, die
zusaetzlich eine Adresse nennt, die es nicht gibt.

WARUM ES KEINE PRUEFUNG GEFUNDEN HAT: pruef-kanalzeile und
pruef-teilen hatten denselben Handle abgeschrieben. Zwei Abschriften
desselben Tippfehlers bestaetigen sich gegenseitig -- beide waren
gruen. Sie leiten ihn jetzt aus KANAELE ab und koennen ihn damit gar
nicht mehr eigenstaendig falsch haben.

Gefunden hat es ein Vergleich: Die oeffentliche Website verlinkt
dieselben Accounts und hatte die richtige Schreibweise. Genau das ist
jetzt Abschnitt 7 von pruef-kanaele -- alle Handles muessen auch
draussen vorkommen, mit Gegenprobe, dass eine falsche Adresse
durchfaellt. Ohne Netz, damit eine Stoerung bei TikTok nicht zu einem
roten Alarm im Haus wird.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-21 11:51:06 +02:00
DogFatherGitandClaude Opus 5 acd3e1f385 Zwei Tabellenumbauten haetten 15 Spalten still geloescht
`personen` und `aufgaben` wurden beim Freischalten eines neuen
CHECK-Werts von Hand neu gebaut -- die Spaltenliste stand zweimal im
Code abgeschrieben (CREATE und INSERT). Gemessen:

  aufgaben: 23 Spalten, 18 aufgezaehlt -> vorlage, kategorie,
            aus_eintrag_id, aufwand, aus_punkt weg
  personen: 19 Spalten,  9 aufgezaehlt -> bild, ueber_mich, tiktok,
            instagram, youtube, twitch, chat_kachel, code_kennung,
            stufe, alter_bestaetigt_am weg

Bei `personen` haengen daran die Profilfotos und die
Altersbestaetigung: Alle waeren nach einem Rueckspielen still wieder
unbestaetigt gewesen, ohne Fehlermeldung, bei unveraenderter
Zeilenzahl. Die Zeilenzaehlung, die als Sicherung gedacht war, kann
einen Spaltenverlust gar nicht sehen.

Es ist derselbe Fehler wie am 11.09. an der Eintragstabelle (24 hinein,
21 heraus). Damals wurde `checkListeErweitern` gebaut, das die Spalten
aus PRAGMA table_info ABLEITET -- eine Liste, die niemand pflegt, kann
nicht veralten. Diese beiden Bloecke waren aelter und wurden bei der
Umstellung uebersehen. Jetzt gehen alle 16 Umstellungen denselben Weg,
kein Neubau zaehlt mehr von Hand.

Auf dem laufenden Server ist nichts verloren (24 Spalten, CHECK
vollstaendig) -- die Falle stand fuer den Tag, an dem jemand eine
Sicherung zurueckspielt.

Gefunden hat es nicht das Lesen, sondern pruef-abbrechen: Sie baut
absichtlich eine ALTE Datenbank und liess die Umstellung darauf laufen
-- danach meldete der Server "no such column: a.aufwand".

Neu: pruef-umstellung.mjs (18 Pruefungen) haelt die Fehlerklasse
dauerhaft zu. Sie baut eine echte alte Datenbank mit gefuellten
Spalten, laesst die Umstellung laufen und zaehlt danach Spalten UND
Inhalte. Mit Gegenprobe: ein absichtlich fehlerhafter Umbau zeigt, dass
die Zeilenzahl dabei stimmt und trotzdem Daten fehlen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-21 11:44:45 +02:00
DogFatherGitandClaude Opus 5 67a0eb8717 DogFather konnte einen zweiten DogFather nicht mehr herabstufen
Gefunden beim Durchsehen der schnellen Pruefungen: pruef-haus-trennung
stand auf 60 ok / 6 Fehler. Drei Ursachen, eine davon ein echter
Rueckschritt von gestern.

--- 1. DER RUECKSCHRITT ---------------------------------------------

In darfRolleAendern stand seit gestern:

  if (person.rolle === "admin") return ziel.rolle !== "admin";

Das macht aus "DogFather ist nicht mehr VERGEBBAR" ein "an einem
DogFather ist nichts mehr zu aendern". Ein zweiter Zugang liess sich
damit nie wieder zuruecksetzen -- er waere fuer immer DogFather
geblieben. Die Pruefung sagte es woertlich: "solange es zwei gibt,
darf einer wechseln (403)".

Die beiden echten Gefahren haengen woanders und bleiben unberuehrt:
Niemand KANN 'admin' vergeben, und der LETZTE DogFather laesst sich
nicht herabstufen.

--- 2. ZWEI SCHLOESSER FUER DIESELBE TUER ---------------------------

Ich hatte gestern `rollenZumAendern` mit 403 VOR die vorhandene
Pruefung gesetzt, die mit 400 "Unbekannte Rolle." antwortet. Damit war
die Luecke wieder offen, vor der der Kommentar vom 17.09. direkt
daneben warnt: Zwei verschiedene Antworten -- "gibt es nicht" gegen
"darfst du nicht" -- verraten beim Durchprobieren, WELCHE Rollen
existieren.

Jetzt eine Regel an einer Stelle. `darfAnlegen` ist dort raus, weil
Vergeben und Anlegen seit gestern verschiedene Dinge sind. Gemessen:

  admin   anlegen = aendern (sieben Rollen)
  spicy   anlegen = aendern (vier)
  hand    anlegen = —        aendern = modi, gast
  manager anlegen = creator  aendern = —

Und die eigene Zeile bekommt jetzt 400 mit einem Satz statt 403:
Es ist keine Rechtefrage, sondern eine unsinnige Bitte.

--- 3. DREI ERWARTUNGEN, DIE AELTER WAREN ALS DIE REGEL --------------

Die Pruefung verlangte 403, wo seit dem 17.09. 400 richtig ist --
ihre Zeile stammt vom 10.09., sieben Tage aelter als die Regel. Und
sie verlangte 404 fuer "die rechte Hand vergibt keine Rolle", was bis
vorgestern stimmte.

Dabei fiel auf, dass NICHTS geprueft hat, ob die rechte Hand ihre neue
Faehigkeit ueberhaupt ausueben kann -- nur, dass sie es nicht darf.
Eine Pruefung, die nur das Verbotene misst, laesst offen, ob das
Erlaubte geht. Jetzt beide Richtungen:

  an einer anderen rechten Hand aendert sie nichts (403)
  und an DogFather erst recht nicht (403)
  einen Modi macht sie sehr wohl zur Community (200)
  und es steht so in der Datenbank (gast)
  eine zweite rechte Hand ernennt sie nicht (400)

Nebenbei: `unbekannte_kachel` (gestern eingefuehrt) hatte keinen Satz
in meldung.js -- die Kennung waere woertlich auf dem Bildschirm
gelandet. pruef-meldungen hatte es gemeldet.

Und ein Absturz beim Bauen: `const anlegen = await hole(...)` weiter
unten im selben Block verdeckt die gleichnamige Funktion im GANZEN
Block, auch oberhalb seiner eigenen Zeile.

pruef-haus-trennung: 70 ok, 0 Fehler (vorher 60/6).
Dazu gruen: rollen-anlegen 11/0, personen-loeschen 40/0,
rechte-umstellen 46/0, verteilen 11/0, meldungen 8/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-20 23:13:27 +02:00
DogFatherGitandClaude Opus 5 9d086eccaf Chat: das Buehnenbild scheint durch, jeder Account bekommt seine Kachel
Hinter jeder Seite steht ohnehin eine Buehne (neun Szenen, fuer den
Chat die Lounge). Sie lag bisher hinter einer deckenden Flaeche --
vorhanden, geladen, unsichtbar. Sie durchscheinen zu lassen kostet
keine einzige Datei mehr, und auf der Adresse von Team Dogi kommt
damit von selbst deren eigene Fassung.

Das geht aber NUR, wenn der Text auf einer deckenden Kachel steht.
Sonst liegt Schrift auf einem Foto: an der dunklen Stelle lesbar, an
der hellen nicht, und beim Scrollen wechselt es. Filipes zweiter Satz
("die texte sollen immer in einer kachel sein") ist deshalb kein
Zusatzwunsch, sondern die Bedingung fuer den ersten.

Und jeder Account waehlt seinen Ton. Zwoelf Stueck, alle gleich
dunkel und gleich gesaettigt -- sie unterscheiden sich im Farbton und
in sonst nichts. Ein freier Farbwaehler klingt grosszuegiger und ist
die schlechtere Loesung: Mit ihm laesst sich Schwarz auf Schwarz
einstellen oder Neongelb, das allen anderen in die Augen sticht. Die
Kachel gehoert einem selbst, GESEHEN wird sie von allen anderen.
Gemessen: der schlechteste Kontrast liegt bei 13,9:1 (noetig 7).

Drei eigene Fehler beim Bauen, alle von der Pruefung gefunden:

1. Es gibt ZWEI Regeln fuer dieselbe Kachel (Grundform und
   Feinschliff). Ich hatte nur die erste umgestellt, die zweite gewann
   -- die eigene Kachel waere durchsichtig geblieben.
2. Die Pruefung las backgroundColor und pruefte den Alphawert. Eine
   Kachel mit einem VERLAUF hat dort rgba(0,0,0,0); sie meldete
   "durchsichtig" bei einer Kachel, die voellig deckt. Jetzt werden
   zwei Bildpunkte verglichen, einmal mit und einmal ohne Buehnenbild
   -- das misst die Sache selbst, nicht ihren Stellvertreter.
3. Dieselbe Pruefung suchte nur die rgba-Schreibweise. Chrome gibt
   das Ergebnis von color-mix als color(srgb r g b / a) zurueck; der
   Rueckfall war "Alpha 1", und sie meldete "deckt" bei einer
   Flaeche, die durchscheint. Genau das Gegenteil.

pruef-chatkachel.mjs: 27 Pruefungen, mit eingebauter Gegenprobe (auf
der freien Flaeche MUSS sich etwas aendern, sonst misst der Vergleich
nichts). pruef-chat-optik und pruef-erwaehnung unveraendert gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-20 19:58:50 +02:00
DogFatherGitandClaude Opus 5 01151574ae Die rechte Hand verteilt Aufgaben und wechselt Rollen
Filipe: "jeder soll sich selber aufgabe vergeben koennen aber nur die
rechte hand und dogfather aufgaben an andere verteilen." Und: "ich will
dass ich da auch die rollen der leute wechseln kann ohne dass ich denen
einen neuen account machen muss ... perfektionier das fuer die rolle
dogfather und rechte hand."

---- AUFGABEN VERTEILEN ---------------------------------------------

Die Regel gab es schon -- sie fragte `istLeitung`, und darin steht die
rechte Hand NICHT. Sie konnte also keine Aufgabe weitergeben.

`hand` DORT EINZUTRAGEN WAERE FAHRLAESSIG GEWESEN: `istLeitung` wird an
57 Stellen in 19 Dateien gefragt -- unter anderem im vertraulichen
Meldeweg, in der Personenverwaltung und in den Auswertungen ueber
Menschen. Das haette in einem Zug ueber Einsicht in fremde Meldungen
entschieden, und das hat niemand gewollt.

Stattdessen `darfAufgabenVerteilen` -- eine eigene Regel mit eigenem
Namen. Man sieht an der Aufrufstelle, worum es geht, und wer sie
spaeter aendert, aendert genau diese eine Sache.

Wer nicht verteilen darf, bekommt KEINE Absage: Die Aufgabe landet bei
ihm selbst. Das ist genau, was Filipe wollte ("jeder soll sich selber
aufgabe vergeben koennen") und freundlicher als ein Fehler.

---- ROLLEN WECHSELN ------------------------------------------------

Auch das gab es schon, samt dem wichtigen Satz in der Rueckfrage: "Der
Zugangscode bleibt derselbe." Es konnte nur DogFather (und Spicy
Media).

DREI GRENZEN, JEDE MIT GRUND:
  * Niemand wird zu "admin" -- unveraendert seit dem 11.09.2026.
  * Die rechte Hand ernennt keine zweite rechte Hand. Wer jemanden auf
    die eigene Ebene hebt, vergibt Vertrauen, das ihm nicht gehoert.
    Und wer eine Rolle UEBER sich aendern koennte, koennte sich selbst
    befoerdern, indem er zuerst den anderen herabstuft.
  * Niemand aendert die eigene Rolle -- sonst waere jede Grenze nur ein
    Umweg.

SPICY MEDIA BEHAELT, WAS SIE HATTE. Beim ersten Anlauf waere sie durch
die neue Regel ausgesperrt gewesen -- ein Rueckschritt, den ich selbst
verursacht haette. Sie steht jetzt ausdruecklich in der Tabelle.

---- UND DIE OBERFLAECHE RECHNET NICHT MEHR SELBST ------------------

Die Rollenwahl nahm die Knoepfe des ANLEGE-Formulars. Fuer die rechte
Hand ist das leer -- sie legt niemanden an. Die Wahl waere leer
geblieben, das Recht unbenutzbar.

Der Server schickt jetzt zwei Listen mit: wozu ich machen darf
(`rollen_zum_aendern`) und wessen Rolle ich anfassen darf
(`rollen_anfassbar`). Beide aus denselben Funktionen wie die Schranke.
Damit kann die Seite weder zu streng sein (ein Recht, das niemand
findet) noch zu grosszuegig (ein Knopf, der eine Absage bringt) -- der
Fehler vom 10.09.2026, als zwei Listen drei Zeilen auseinander
einander widersprachen.

Dabei fast hineingelaufen: `ROLLEN_REIHE` ist die SORTIERUNG, und
darin fehlt "gast" mit Absicht. Wer sie fuer eine Aufzaehlung nimmt,
verliert die Community still -- genau diese Verwechslung hat am
17.09.2026 schon einmal verhindert, dass sich jemand zu "Community"
machen liess.

---- AUSSERDEM ------------------------------------------------------

Screen 2: "Unsere Seiten" und "Regeln & Hilfe" haben die Plaetze
getauscht -- nur diese zwei.

GEPRUEFT: pruef-verteilen 11/0 (neu, inkl. der Abgrenzung "darf
verteilen, ist aber NICHT Leitung"), pruef-rollen-anlegen 11/0,
pruef-personen-formular 36/0, pruef-personen-liste 33/0,
pruef-personen-loeschen 40/0, pruef-rechtetafel 19/0, pruef-treff 72/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-20 18:56:03 +02:00
DogFatherGitandClaude Opus 5 e378514bb4 Einmal anmelden reicht -- und beim Zurueckgehen bleibt die Seite stehen
Filipe: "kannst du bitte machen dass die leute sich nur einmal anmelden
muessen und dan nur noch abgemeldet werden wenn sie sich selbst
abmelden. damit sie auch die benarichtigungen sofort kriegen ... und
auch sofort die anrufe annehmen koennen."

---- 1. DIE ANMELDUNG BLEIBT ----------------------------------------

VORHER: zwoelf Stunden, feste Frist ab dem Anmelden. Wer morgens um
acht anfing, flog abends um acht raus -- mitten im Betrieb. Und wer
abgemeldet ist, hat die Seite nicht offen; ein Anruf erreicht ihn dann
nur noch ueber die Benachrichtigung, und bis er sich wieder angemeldet
hat, ist das Klingeln vorbei. Genau das beschreibt Filipe.

JETZT: ein gleitendes Fenster von 180 Tagen, das sich bei jeder Nutzung
verlaengert. Wer die Seite benutzt, bleibt angemeldet -- ohne Ende.

NICHT UNENDLICH, und das ist Absicht: In diesem Haus liegen
vertrauliche Meldungen ueber Menschen. Ein Zugang, der nie ablaeuft,
ist auf einem verlorenen Handy fuer immer offen. Ein halbes Jahr ohne
Besuch schliesst das Geraet und ist niemandem zu viel zugemutet.

An EINER Stelle gebaut: `sitzungLesen` -- durch die gehen alle 26
Fachmodule. Ein Parameter mehr haette 26 Aufrufe geaendert und beim 27.
Modul vergessen werden koennen; `req.res` haengt ohnehin an der
Anfrage. Verlaengert wird erst, wenn weniger als die Haelfte des
Fensters uebrig ist -- sonst waere das ein Schreibzugriff bei jedem
Bild und jedem Herzschlag des Ereignisstroms.

Drei Texte, die noch "zwoelf Stunden" behaupteten, sagen es jetzt
richtig -- inklusive der Abmelde-Nachfrage, die jetzt dazusagt, dass
man angemeldet bleiben SOLLTE, um Anrufe zu bekommen.

---- 2. BEIM ZURUECKGEHEN BLEIBT DIE STELLE -------------------------

Filipe, zum dritten Mal und in Grossbuchstaben. Also erst gemessen:

    gescrollt auf:  900
    gemerkt:        900
    gelandet:      1054      <- 154 px daneben, zuverlaessig

Die Wiederherstellung LIEF also -- sie traf nur nicht. Ursache ist
Chromes Scroll-Verankerung: Waechst Inhalt OBERHALB der Stelle,
verschiebt der Browser den Bildlauf mit, damit das Sichtbare stehen
bleibt. Im Alltag genau richtig; beim Wiederherstellen das Gegenteil.

Sie wird jetzt fuer die Dauer des Wiederherstellens abgeschaltet und
danach wieder eingeschaltet -- nicht dauerhaft, sonst spraenge einem im
Chat der Text unter dem Finger weg. Dazu wird die Stelle nachgesetzt,
solange die Seite noch waechst, und aufgehoert, sobald sie 400 ms lang
ruhig ist. Ergebnis: 900 -> 900, und es bleibt dort.

DAZU, und das ist der groessere Teil: Der Ereignisstrom in kopf.js
laeuft auf 32 Seiten und wird jetzt beim Weggehen geschlossen. Eine
offene EventSource sperrt den Vor-/Zurueck-Speicher des Browsers aus --
deshalb wurde bisher JEDE Rueckkehr ein vollstaendiger Neuaufbau.
Filipe hat genau das beschrieben ("OHNE DASS DIE SEITE ... NEU LAEDT").

EHRLICH DAZU: Playwright schaltet diesen Speicher fuer Tests ab, und er
liess sich hier nicht einschalten. Ich kann also NICHT messen, dass er
jetzt greift -- die Aenderung ist trotzdem richtig (eine offene
Verbindung ist die dokumentierte Sperre, und ein Strom, der beim
Weggehen offen bleibt, ist ohnehin ein Zuhoerer, den niemand mehr
liest). Gemessen und abgesichert ist der Weg OHNE diesen Speicher --
also der schlechteste Fall.

---- 3. DABEI GEFUNDEN: pruef-schranke mass seit neun Tagen nichts --

Sie suchte `const GESCHUETZT = {` per Textmuster in workspace.js. Diese
Tabelle ist am 11.09.2026 nach rechte.js umgezogen -- seitdem fand das
Muster nichts, und die Pruefung meldete "0 geschuetzte Seiten", "alle 0
Seiten leiten um", "0 Schreibweisen ausprobiert". Drei rote Zeilen, die
nach einem Zaehlfehler aussahen und in Wahrheit hiessen: hier wird
nichts mehr geprueft.

Jetzt wird die Tabelle IMPORTIERT. Ein Textmuster auf fremden
Quelltext reisst beim naechsten Umzug still; ein import reisst laut.
Ergebnis: 33 geschuetzte Seiten, 363 Schreibweisen -- alles gruen.

GEPRUEFT: pruef-rollstelle 8/0 (neu, mit Spur ueber die Zeit und zwei
Gegenproben), pruef-schranke (war rot), pruef-code 17/0,
pruef-haerte 20/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-20 18:48:34 +02:00
DogFatherGitandClaude Opus 5 2a26a49f91 Mit "@" jemanden im Chat ansprechen
Filipe: "ich will das man die leute mit @ markieren kann im chat."

MARKIEREN IST KEINE FARBE, SONDERN EINE ANSPRACHE. Sie funktioniert
nur, wenn drei Dinge zusammen stimmen: Der Richtige ist gemeint, er
MERKT es, und man sieht es im Satz. Fehlt eines davon, ist es eine
Attrappe -- und zwar eine, die gut aussieht.

WER GEMEINT IST, ENTSCHEIDET DER SERVER. Der Browser schickt nur Text.
Damit wirkt ein von Hand getipptes "@VanVan" genauso wie eines aus der
Auswahlliste, und niemand kann jemanden ansprechen, der gar nicht im
Raum sitzt -- auch nicht ueber die Schnittstelle.

Die Regeln stehen in server/chat-erwaehnung.js, jede mit Begruendung.
Zwei davon sind keine Feinheit, sondern der Unterschied zwischen
brauchbar und laestig:

  * Das Zeichen VOR dem "@" darf kein Buchstabe sein. Sonst piepst
    jede E-Mail-Adresse im Chat jemanden an
    ("[email protected]").
  * Das Zeichen DANACH auch nicht, und der laengste Name gewinnt.
    Sonst spricht "@Tilikum" Tili an.

MAN MERKT ES AUCH OHNE OFFENEN RAUM. Eine Zahl in der Gespraechsliste
sagt "hier ist etwas" -- nicht, ob es an dich war. Wer morgens vier
Raeume mit Zahlen sieht, macht den lautesten zuerst auf, und dort
steht selten das, was auf ihn wartet. Jetzt steht ein "@" daneben.

UND DIE MELDUNG AUFS HANDY SAGT ES: "VanVan hat dich erwaehnt" statt
"Nachricht von VanVan". Als EIGENE Art, die sich getrennt abschalten
laesst -- wer den lauten Chat stumm stellt, will trotzdem wissen, wenn
ihn jemand direkt anspricht. Ohne Ausnahme von der Ruhezeit: Ein Anruf
wartet auf eine Antwort, ein "@Anna" nicht.

DIE AUSWAHL BEIM TIPPEN loest drei Dinge, die man sonst selbst wissen
muesste: wie die Person genau heisst, wer ueberhaupt im Raum ist, und
ob man sich vertippt hat. Tastatur zuerst (Pfeile, Enter, Tab, Escape).
Sie erzwingt nichts -- wer weitertippt, schreibt einfach weiter.

ZWEI RECHNUNGEN, EINE ANTWORT: Der Browser braucht dieselbe Aufloesung,
um sofort hervorzuheben. Genau dort laufen Dinge auseinander, und dann
haette die Seite jemanden hervorgehoben, den niemand benachrichtigt
hat. pruef-erwaehnung LIEST die Browserfassung aus der Datei und fuehrt
sie aus -- ein Nachbau wuerde pruefen, ob ich zweimal dasselbe
schreiben kann.

---- DABEI GEFUNDEN: "gelesen bis 999999" ----------------------------

Der Server nahm fuer den Lesestand JEDE ganze Zahl an. Wer einmal eine
Zahl hinter allem Vorhandenen schickte, sah in diesem Gespraech nie
wieder einen Zaehler und nie wieder ein @-Zeichen: Alles Kuenftige galt
als gelesen, bevor es geschrieben war. Das faellt niemandem als
Zusammenhang auf -- man merkt nur, dass "die Benachrichtigungen nicht
gehen".

Der Browser schickt heute immer die letzte gesehene Nummer, ist also
nicht der Grund. Aber eine Grenze, die nur davon lebt, dass der
Aufrufer sich benimmt, ist keine. Jetzt wird auf die juengste
Nachricht des Raums begrenzt -- abgeleitet, nicht geraten.

Gefunden hat es meine eigene Pruefung: Sie setzte zum Aufraeumen 99999
und wunderte sich danach, warum das frische "@" nicht leuchtete.

WOHER MAN ERFAEHRT, DASS ES DAS GIBT: Im Chat gibt es keinen
Hilfeknopf. Der Hinweis steht deshalb im Leersatz einer neuen Gruppe --
dort, wo man beim ersten Oeffnen ohnehin hinsieht, und nur ab drei
Leuten. In einem Zweiergespraech waere er Ballast.

GEPRUEFT: pruef-erwaehnung 67/0 (neu) -- 13 Regelfaelle ohne Server,
der Weg durch die Schnittstelle, das Zeichen in der Liste samt
Gegenprobe bei jemandem, der dabei aber nicht gemeint war, beide
Aufloesungen nebeneinander, und der ganze Ablauf am echten Bildschirm
bis "Enter waehlt und schickt NICHT ab".
Dazu pruef-chat 48/0, pruef-chat-optik 36/0, pruef-treffchat 110/0,
pruef-chat-kanaele 79/0, pruef-glocke 31/0, pruef-push 24/0,
pruef-anruf-klingelt, pruef-css-klassen, pruef-meldungen,
pruef-nachfrage, pruef-tippziele.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-20 17:54:16 +02:00
DogFatherGitandClaude Opus 5 409ed551f3 "Review" heisst jetzt "Zur Freigabe" -- und Datumsfelder sind so hoch wie alle anderen
Im Code stand die Begruendung selbst: "«Review» allein sagt einem Neuen
nichts." Das Wort ist englisch, ein Hauptwort ohne Handlung, und es
verraet nicht, WER jetzt dran ist. "Zur Freigabe" sagt beides: fertig
von mir, wartet auf jemanden.

Geaendert wurde nur, was ein Mensch LIEST -- der Zustandsschluessel
bleibt `review`, der gehoert der Datenbank. Betroffen: Spalte und
Weiterknopf im Aufgabenbrett, Dateien-Filter, Startseiten-Zaehler,
Kachel-Unterzeile, Hinweis "Datei wartet auf Freigabe", Report.

NICHT geaendert: der Kalender. Dort ist `review` eine TERMINART (ein
Gespraech, in dem man zurueckschaut), kein Zustand. Ich hatte das beim
Umbenennen selbst verwechselt und wieder zurueckgenommen -- ein
Kommentar an der Stelle haelt die zwei Bedeutungen jetzt auseinander.

pruef-sprung hing an der Wortwahl (`/review/i` auf der Beschriftung)
und wurde rot, obwohl der Filter richtig stand. Sie prueft jetzt
`data-status` -- den Schluessel, der sich nicht mit der Sprache aendert.

DAZU, unabhaengig gefunden: Datumsfelder waren 48 px hoch, alle anderen
Felder 44. Gemessen auf drei Seiten bei 390 px. Alle liegen auf dem
44-px-Beruehrziel -- nur das Datumsfeld drueckte sich darueber, weil
Chromium in `::-webkit-datetime-edit` eine eigene Innenpolsterung setzt,
die sogar ein gesetztes `height: 44px` ueberstimmt.

Zwei Anteile, einzeln nachgemessen (jeder allein 48->46, erst beide
zusammen 48->44): 1 px Polsterung oben und unten im Feldkasten, und
eine Zeilenhoehe von 24 statt 22. Keine feste Hoehe gesetzt -- die
Zeilenhoehe wird aus Beruehrziel und Polsterung gerechnet, damit sie
mitwandert, wenn sich eines davon aendert.

Geprueft: pruef-formulare 19/0 (war 16 mit 3 Fehlern), pruef-sprung
43/0, pruef-start-ansicht 151/0, pruef-aufgabenbrett 49/0,
pruef-uebersicht 35/0, pruef-uebersicht-browser 20/0,
pruef-deutsche-texte, pruef-css-klassen.

Ausserdem: vorlagen.js geloescht (8,2 KB). `vorlagenBlock(` wurde in
ca104799 eingebaut und in 9267797d wieder ausgebaut -- seither laedt
die Datei auf zwei Seiten, ohne dass jemand sie aufruft.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-20 17:27:09 +02:00
DogFatherGit 0f5faf7ee6 Eine Seite, die nicht laedt, sagt es -- und bietet einen Weg zurueck
Fuenf Suchlaeufe parallel, ihre Funde selbst nachgemessen und behoben.

DER GROESSTE: 13 VON 21 SEITEN SCHLUCKTEN JEDEN NETZFEHLER.
Jede Seite beginnt mit `try { await hole('/api/ich') } catch { return; }`.
Faellt das Netz aus -- Aufzug, U-Bahn, Funkloch --, bricht der Block ab,
und die Seite bleibt fuer immer auf "wird geladen …" stehen. Gemessen:
0 von 32 Stellen setzten `aria-busy` im Fehlerfall zurueck, und es gab
KEINEN EINZIGEN "Nochmal versuchen" auf allen 21 Seiten.

Im Code stand der richtige Satz dazu -- an genau einer Stelle:
"Ein Platzhalter, der nie ersetzt wird, ist eine Luege mit
Fortschrittsanzeige." Er galt ueberall ausser dort.

Neu: window.ladefehler() in meldung.js. Sie ersetzt alles, was gerade
"laedt", durch drei Dinge: was los ist, was das bedeutet, und einen
Knopf, der es noch einmal versucht -- ohne die Seite neu zu laden.
21 Dateien angeschlossen. Neu: server/pruef-ladefehler.mjs, 26/0, mit
abgeklemmtem Netz im echten Browser.

UND DIE STARTSEITE WARF BEI EINEM FUNKLOCH AUF DIE ANMELDUNG.
`catch { location.assign('/workspace/') }` -- der Mensch glaubt, er sei
rausgeworfen, und tippt seinen Code neu. Dabei haelt seine Sitzung 12
Stunden; nur die Anfrage kam nicht durch. Umgeleitet wird jetzt nur
noch bei einer ANTWORT, die das sagt (401).

DER ANMELDEHINWEIS FUEHRTE MODIS IN DIE SPERRE.
Nach zwei Fehlversuchen stand: "Stimmt die Auswahl oben? Ein Code
gehoert immer zu genau einer davon." Auf der Crew-Wand ist das FALSCH
-- `stillerZugang()` sucht ueber die Codekennung, die angetippte
Kachel spielt fuer hand/modi keine Rolle. Sie probieren alle vier
durch, sammeln vier Fehlversuche, und nach acht in zehn Minuten ist
ihre Adresse gesperrt. Ein Hinweis, der die Sperre herbeifuehrt, gegen
die er helfen soll. Auf der Agenturwand stimmt der Satz weiter --
deshalb wird gefragt, auf welcher Wand man steht.
Dazu: Die Crew-Wand nannte nur der Community einen Weg ("Frag im Live
nach"). Wer zum Team gehoert und dessen Code nicht geht, fand dort
niemanden.

SACKGASSE AUF DER KERNSEITE EINES MODI.
treff-moderation sagte: "Zugaenge legst du in 'Personen & Zugaenge'
an" -- eine Seite, die ein Modi nicht oeffnen darf. Am ersten Tag, bei
leerer Community, war das der einzige Satz im Abschnitt. Jetzt fragt
die Seite ueber `window.__ich.seiten`, ob es den Weg fuer DIESEN
Menschen gibt. Und ein 404 wirft ihn nicht mehr wortlos auf die
Startseite.

TOTE KNOEPFE AN FREMDEN KARTEN.
"◀ zurueck" und "▶ In Arbeit" standen an JEDER Aufgabenkarte, auch an
fremden. Ein Modi sieht das Brett des ganzen Teams; er tippt, der
Server lehnt mit 403 ab, und die Meldung erscheint GANZ OBEN. Bei
einer Karte weiter unten sieht er nichts. Zwei Zeilen tiefer stand die
Regel im Klartext: "niemandem etwas anzubieten, das dann abgelehnt
wird." Der Server schickt jetzt `darf_aendern` mit.

13 STELLEN ROLLTEN GEGEN DEN WILLEN DES NUTZERS.
`scrollIntoView({ behavior: 'smooth' })` beachtet "Animationen
reduzieren" NICHT. Wer das eingestellt hat, hat es meist wegen
Schwindel getan. Zwei Stellen fragten vorher, dreizehn nicht.
Jetzt `window.sanft()`, einmal statt dreizehnmal.

DAS WORT UEBER DEN BRETTERN EINES MODI HIESS "BETREUUNG".
Fest im HTML, ueberschrieben nur bei Brettern mit eigenem `ober` --
sechs haben keines. Jetzt faellt es auf die GRUPPE der Kachel zurueck,
ueber die er hergekommen ist. Je Rolle richtig, ohne zweite Liste.

DER HINWEIS-ZU-KACHEL-WEG WAR DOPPELT KAPUTT.
`bereichZu` suchte nur in GRUPPEN -- der Liste der AGENTUR. Die
Kacheln von Team Dogi schickt der Server; fuer einen Modi fand die
Zeile entweder nichts oder eine fremde Kachel und uebernahm deren
Farbe. Und sie suchte ueber den NAMEN: "LIVE-Analyse" heisst auf der
Crew-Adresse "Live-Ablauf". Beim Beheben erst den Namen umgedreht --
und damit die Agenturseite kaputt gemacht (pruef-start-ansicht sofort
rot). Jetzt ueber das ZIEL, das in beiden Haeusern dasselbe ist.

UND EIN BRETT WAR SEIT GESTERN GESPERRT.
`TREFF_BRETTER` wird aus Kachelzielen abgeleitet. Als die Kachel
"Regeln & Hilfe" am 19.09. auf `treff-regeln.html` umgelenkt wurde,
fiel `regeln` heraus -- und `treff-regeln.html` verweist weiterhin
darauf ("Haeufige Fragen stehen auf dem Brett Regeln & Hilfe").
Gefunden hat es pruef-treff, die seit gestern rot war. 72/0.

NEBENBEI 7 SEITEN LEICHTER: meldung.js wird jetzt abgeleitet
eingebunden -- nur dort, wo sagWas/ladefehler/sanft wirklich
gebraucht werden. Die Anmeldewand traegt es nicht mehr.

Gruen: pruef-ladefehler 26/0, pruef-sackgassen 11/0 (582 Wege, 0 ins
Leere), pruef-start-ansicht, pruef-treff 72/0, pruef-treffchat,
pruef-community-sicht 10/0, pruef-aufgabenbrett, pruef-code 17/0,
pruef-chat-optik, pruef-nachfrage 49/0, pruef-meldungen 8/0,
pruef-css-klassen, pruef-tippziele 11/0, pruef-leerzustand 13/0,
pruef-rechtetafel.
2026-09-20 15:49:57 +02:00
DogFatherGitandClaude Opus 5 18a5231b70 Die Tuer ohne Klingel, der Anruf ohne Ende, die Glocke ohne Liste
Siebter Durchgang durch die Team-Dogi-Seiten aus Benutzersicht. Alles am
Code belegt, die Groessenangaben nachgerechnet.

=== DIE ANMELDUNG ===

WOHER BEKOMMT MAN EINEN CODE? Stand nirgends. Vier Kacheln, ein Feld,
ein Knopf -- wer keinen Code hatte, fand keinen einzigen Satz dazu. Fuer
die Community besonders teuer: Sie ist die einzige Rolle, die von
aussen kommt und niemanden im Haus kennt.

"BITTE KURZ WARTEN" SIND BIS ZU ZEHN MINUTEN (VERSUCHE_FENSTER_MIN).
Wer nach zwanzig Sekunden nachsieht und dieselbe Meldung liest, haelt
die Seite fuer kaputt. Jetzt steht die Zahl da.

EIN RICHTIGER CODE AN DER FALSCHEN KACHEL fiel in dieselbe Absage wie
ein erfundener -- der Server sucht nur unter der gewaehlten Rolle. Wer
aus der Community kommt und auf "Modi" tippt (das klingt ja danach),
tippt seinen richtigen Code dreimal Buchstabe fuer Buchstabe. Ab dem
zweiten Fehlversuch kommt jetzt ein Hinweis auf die Auswahl -- ohne zu
sagen, welche die richtige waere.

=== DER ANRUF: VIER FEHLER, EINE ERFAHRUNG ===

DAS FREIZEICHEN LIEF UNENDLICH. Es gab keinen Zeitgeber, der aufhoert.
Wer niemanden erreichte, sass vor einem piependen Kasten mit "02:47"
darauf, als telefoniere er laengst. Der Server schickt den Verfallszeit-
punkt sogar mit (`laeuft_bis`) -- benutzt hat ihn nie jemand.

DER KLINGELKASTEN VERSCHWAND NACH 46 SEKUNDEN, waehrend der Server 120
gibt. Wer beim Klingeln das Handy aus der Tasche holt und in Sekunde 50
hinsieht, fand nichts mehr -- kein Kasten, keine Knoepfe -- waehrend der
Anrufer noch siebzig Sekunden Freizeichen hoerte. Die 120 Sekunden sind
im Server ausdruecklich damit begruendet, dass man Zeit zum Entsperren
braucht; eine Zeile im Browser hat diese Entscheidung aufgehoben.

DAS FREIZEICHEN PIEPTE WEITER, waehrend daneben "Keine Verbindung."
stand. Ton sagte "es klingelt noch", Text sagte "vorbei".

DIE UHR ZAEHLTE AB DEM WAEHLEN. Wer 30 Sekunden klingeln liess und 12
Sekunden sprach, las im Kasten "00:42" und danach im Chat "Anruf . 12
Sekunden". Der Server rechnet es richtig; der Kasten hat es wieder
kaputtgemacht.

Dazu: Die Mikrofon-Absage verwies auf "das Schloss-Symbol neben der
Adresse" -- in der installierten App gibt es weder Adresszeile noch
Schloss. Das Haus kennt diesen Fehler und hat ihn beim Weg zur
Anruf-Probe schon behoben; hier stand er noch.

Und die Anruf-Probe: Ihr einziger Punkt ohne Handlungsanweisung war
"Antwort 503." -- auf einer Seite, die ausdruecklich fuer jemanden
gebaut ist, der nicht technisch ist. Ihr Rueckweg fuehrte ausserdem
immer in den Chat, auch wenn man von der Startseite kam.

=== DER TREFF ===

EIN EINZEILER MACHTE SECHS ERKLAERTEXTE UNSICHTBAR. bewerben.js las
`g.unter`, der Server schickt `g.text` -- also immer undefined. Damit
fehlten ALLE SECHS Gruppeneinleitungen des Fragebogens ("Kein Test mit
richtigen Antworten"), und die CSS-Regel dafuer lief ins Leere. Uebrig
blieben sechs nackte Ueberschriften ueber fuenfzehn Fragen.

DIE EINZIGE "SO LAEUFT DAS HIER"-SEITE WAR FAST UNERREICHBAR. Die
Kachel "Regeln & Hilfe" zeigte auf ein Brett, das am ersten Tag leer
ist. Die Regeln, die es wirklich gibt (Begruessung, fuenf Regeln, drei
Stufen, Mindestalter), stehen auf treff-regeln.html -- erreichbar ueber
genau einen kleinen Textlink auf einer Brettseite. Die Kachel zeigt
jetzt dorthin.

FIEL /api/treff/lage AUS, versprach die Seite einem Zuschauer
Schreibrechte, die der Server ablehnt: Die Pruefung fiel bei `lage ===
null` auf `true` durch -- von "darf auf keinem Brett" auf "darf
ueberall". Formular auf, getippt, 403.

Dazu: hilfe.js hatte eine eigene kleine Fehlertabelle fuer zwei
Kennungen und endete sonst bei "Ging nicht." -- ausgerechnet die Seite,
auf der jemand mit einem Problem sitzt, hatte die inhaltsleerste Absage
im Haus. Und der gesperrte "Neue Meldung"-Knopf erklaerte sich nur im
Maus-Tooltip; die Community kommt von TikTok, also vom Handy.

=== DIE STARTSEITE ===

DIE COMMUNITY BEKAM EIN WORT. Unter dem Titel steht bei jeder Rolle ein
Satz -- beim Community-Mitglied stand "Community". Woertlich derselbe
Mangel, den der Kommentar bei MODI_ROLLENTEXT beschreibt und fuer den
Modi behebt.

DER RING MELDETE 100 %, bevor man irgendetwas getan hat. Am ersten Tag,
ohne eine einzige Aufgabe, stand das groesste Element der Seite auf
"100 % -- HEUTE NICHTS OFFEN". Gelesen wird zuerst die Zahl, und 100 %
heisst fuer jeden "fertig", nicht "leer".

UND BEI EINER STOERUNG BLIEB "wird geladen" FUER IMMER STEHEN -- der
fruehe `return` liess den Platzhalter unberuehrt.

=== DIE ZUGANGSVERWALTUNG ===

Der Code-Kasten sagte "jetzt weitergeben" und gab die Haelfte nicht
mit, die man weitergeben muss: WO sich die Person anmeldet. DogFather
ruft den Code durchs Zimmer, der andere fragt "und wo?". Die Adresse
kommt jetzt vom Server (anmeldeAdresseFuer, abgeleitet aus derselben
Weiche), dazu ein Knopf "Code und Adresse kopieren".

Er verschwieg ausserdem den Rettungsweg: "danach nicht mehr abrufbar"
stimmt fuer DIESEN Code -- man kann jederzeit einen neuen vergeben. Wer
das nicht weiss, glaubt, er habe einen Menschen angelegt, der nie
hereinkommt. Und das Fenster liess sich wortlos schliessen, waehrend
der Code offen stand.

=== OPTIK: NACHGERECHNET, NICHT VERMUTET ===

DIE GLOCKE STAND NICHT IN DER LISTE. Sie ist ein echtes <button> und
wurde von der 44-px-Regel erfasst, waehrend ihre vier Nachbarn durch
einen staerkeren Selektor auf 36 px gehen. Zwischen 401 und 560 px --
also bei 412 px (haeufigste Android-Breite) und 430 px (iPhone Pro Max)
-- stand eine 44 px hohe runde Pille zwischen fuenf 36-px-Quadraten.
Der 400er-Block listet sie korrekt; genau dieses Band fiel durch beide
Rechnungen. Dasselbe Muster wie am 06.09.

DIE 9,6-px-REPARATUR IM KALENDER WAR SEIT WOCHEN WIRKUNGSLOS.
kalender.css wird NACH start.css geladen, beide Selektoren sind gleich
stark -- also gewann `.6rem` auf jeder Breite unter 760 px. Genau der
Wert, den start.css als behobenen Fehler protokolliert.

Und die Hebung selbst unterschritt ihre eigene Grenze: Die Regel, die
zu kleine Schrift hochziehen soll, zog `.k-pille` auf 11,2 px -- 0,3 px
unter die 11,5, die 33 Zeilen darueber aufgestellt werden.

Weitere nachgerechnete Groessen: Spaltenkopf und KW-Spalte im Kalender
(10,56 px), Kalenderwoche am Balken (9,92 px), Wecker-Knopf (30 px --
der kleinste im Haus, 14 unter der Vorgabe), Chat-Zurueck auf dem
Tablet (34x34, 40 % weniger Flaeche als noetig, und der einzige Weg
zurueck in die Liste), Emoji-Knoepfe (34 px bei 2 px Abstand -- wer
danebentippt, verschickt ein anderes Zeichen, und das ist sofort
abgeschickt).

IM WINDOWS-KONTRASTMODUS HATTE DIE STARTSEITE KEINE UEBERSCHRIFT.
`.ztitel` und der Team-Dogi-Schriftzug sind mit `background-clip: text`
gesetzt; faellt der Verlauf weg, bleibt durchsichtiger Text. Beide
haben jetzt den Rueckfall, den gate.css schon lange hat.

UND MEIN EIGENES STREIFENRASTER rechnete die Spaltenzahl aus der Breite
statt aus den Daten (`auto-fit`): Bei 390 px passten sechs, alles
darueber fiel in eine zweite, unbeschriftete Zeile. Das `overflow-x`
daneben konnte nie greifen -- ein auto-fit-Raster wird nie breiter als
sein Kasten. Der Kommentar beschrieb ein Verhalten, das es nicht gab.

GEMESSEN: pruef-meldungen 8/0, pruef-css-klassen ALLES IN ORDNUNG,
pruef-rechtetafel 19/0, alle Module laden, keine doppelten
Kachelnamen/-ziele/-farben in allen vier Rollen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 15:07:31 +02:00
DogFatherGitandClaude Opus 5 273318dd9c Vier Sackgassen, zwei Kacheln namens "Chat" -- und eine Seite ohne Kopf
Durchgang durch die Team-Dogi-Seiten aus der Sicht von jemandem, der
sie zum ersten Mal sieht. Alles hier ist am Code belegt und nachgemessen.

1. "KLINGELT NICHTS?" WARF ALLE DREI TEAM-ROLLEN AUF DIE STARTSEITE.

anruf-probe.html erklaert, WARUM das Telefon stumm bleibt. Sie steht in
der Rechtetafel offen, und aus dem Chat zeigen zwei Knoepfe darauf. Nur
hatte sie nie eine Kachel -- absichtlich, sie ist kein Bereich. Seit die
Adressregel vom 15.09. eine Kachel VERLANGT, landete jeder Klick wortlos
auf start.html.

Das ist die schlimmste Sorte Sackgasse: Man ruft sie auf, WEIL schon
etwas nicht geht, und sie wirft einen hinaus.

Mit derselben Zeile geheilt: Die Hinweisleiste wirft jeden Hinweis weg,
dessen Ziel es auf dieser Adresse nicht gibt -- "Bei dir klingelt nichts"
wurde auf crew deshalb NIE angezeigt. Ausgerechnet der Hinweis, der acht
von elf Leuten betrifft.

2. UND DIESE SEITE HATTE GAR KEINE GESTALTETE KOPFLEISTE.

.kopfleiste, __zurueck, __mitte, __titel stehen in KEINER Stilvorlage --
sie leben in start.css, die diese Seite absichtlich nicht laedt. Die
Leiste war nackter Text. Auf einer Seite, die man im Stoerfall aufruft,
sieht unfertig aus wie kaputt. Jetzt im <style>-Block der Seite, aus
demselben Grund wie ihr uebriges CSS.

3. EIN MODI KAM NICHT AN SEINE EIGENE AUSWERTUNG.

entwicklung.html und werdegang.html haben BEIDE eine ausgearbeitete
Eigensicht, und die Rechtetafel laesst ihn hinein. In seiner Kachelliste
stand keine von beiden -- der Weg existierte fuer ihn nicht. Die ganze
Eigensicht war toter Code, ausgerechnet fuer den, fuer den sie ist.
Mein eigener Fehler vom Vortag.

Zwei eigene Kacheln in "Fuer dich", aus den Leitungskacheln abgeleitet.
Sie loesen zugleich eine Namenskollision: Bis heute setzten BEIDE Seiten
fuer ihn die Ueberschrift "Deine Entwicklung".

4. DER KALENDER-LINK WAR FUER DIE COMMUNITY EINE SACKGASSE.

Auf jeder Brettkarte mit Termin stand "Im Kalender am 24.09." als Link.
kalender.html steht auf ALLE -- und ALLE ist ausdruecklich ohne "gast".
Jetzt fragt der SERVER die beiden Schranken (kalender_offen) und die
Karte zeigt den Termin als Text statt als Link. Die Auskunft bleibt, nur
der Weg ins Leere faellt weg. Die Regel im Browser nachzubauen waere die
vierte Stelle fuer dieselbe Frage gewesen.

5. EIN MODI KAM AN DIE TALENTE-NOTIZEN, DIE IHM VERWEHRT SIND.

BRETTER_UEBER_SEITEN war eine feste Liste ("wer die Seite darf, muss
auch dorthin kommen") und fragte nie, WER fragt. Ueber
bereich.html?b=talente kam er an Notizen zu Zuschauern, obwohl
talente.html fuer ihn gesperrt ist -- Begruendung dort: "Hier stehen
Namen von Menschen, die nichts davon wissen."

Aus der Liste wurde eine Zuordnung Brett -> Seite, gefragt wird
darfSeite(). Nachgemessen: modi/talente 404, modi/entwicklung darf,
hand+admin unveraendert.

Dazu stand in workspace-bereiche.js ein Kommentar, der das GEGENTEIL des
Codes behauptete ("entwicklung, talente bleiben 404"). Ein falscher
Kommentar an einer Rechtestelle ist schlimmer als keiner.

6. ZWEI KACHELN "CHAT", BEIDE AUF DIESELBE SEITE.

Seit dem Treff-Chat von gestern sahen Modi und rechte Hand zweimal
"Chat" mit demselben Ziel. Jetzt "Treff-Chat" mit ?raum=treff, das den
Raum direkt oeffnet -- gesucht an denselben zwei Merkmalen, an denen ihn
der Rest der Datei erkennt.

7. VERTRAUEN: "WIE GEHT'S DIR?" VERSPRACH MEHR, ALS ES HALTEN KANN.

Dort stand: "Niemand aus dem Team sieht deine Antworten -- auch
DogFather nicht." Punkt. Fast wahr und deshalb gefaehrlich: Aus
denselben Antworten entsteht eine namenlose Ampel fuer die Leitung.

Der ehrliche Satz war laengst geschrieben und wurde vom Server sogar
mitgeliefert (block.text) -- nur hat ihn nie jemand angezeigt. Er steht
jetzt im HTML, nicht im Skript: Wer die Seite oeffnet, soll ihn lesen,
BEVOR er tippt.

8. DIE NEUE AUSWERTUNG, AUS BENUTZERSICHT NACHGEBESSERT.

- Der Streifen hatte keine Zeichenerklaerung. Im Dateikopf stand "wer
  Farben schlecht unterscheidet, liest dasselbe Zeichen" -- das stimmt
  nur, wenn irgendwo steht, was die Zeichen heissen. Jetzt eine Legende,
  aus `stufen` gebaut statt abgeschrieben.
- "nie gesetzt" war ein Mittelpunkt, "Kann ich nicht sagen" ein
  Halbgeviertstrich. Zwei kurze Striche nebeneinander fuer den
  Unterschied zwischen "niemand hat hingesehen" und "jemand hat
  hingesehen und konnte es nicht sagen". Leer ist jetzt wirklich leer,
  mit gestricheltem Rahmen.
- Die Aufschluesselung der Balken stand nur im Mausueberfahren -- am
  Handy also nie, und dort steht jemand damit im Stream. Jetzt als Text.
- Die Modi-Sicht bekam Balken ohne Erklaerung, ein "Frag danach" ohne
  Adressaten und bei fehlender Bewegung ein LEERES Element. Jetzt
  Lesehilfe, ein Leerkasten mit Satz und zwei Wege weiter.

9. NEBENBEFUNDE, DIE DIE PRUEFUNG GEFUNDEN HAT.

pruef-css-klassen war schon VOR dieser Arbeit rot (nachgemessen mit
git stash). Alle drei Befunde behoben:
  - hilfe.html und unsere-seiten.html luden ihre Seitendatei NACH
    module.css und haus.css und ueberschrieben damit das Haus.
  - Zwei Schriftgroessen unter 11,5 px aus dem gestrigen Bau
    (.71rem Monatsbeschriftung, .68rem Marke) auf .75 und .72 gehoben.
  - Die Pruefung selbst war blind fuer <style>-Bloecke in der Seite und
    meldete deshalb dauerhaft drei Fehler an einer Seite, die ihre
    Stile mit Absicht selbst traegt. Eine Warnung, die immer kommt, ist
    keine Warnung mehr -- jetzt sieht sie hin, statt die Seite
    auszunehmen.

Kleinkram nebenbei: "die Antworten sieht nur du" -> "siehst nur du" auf
der Kachel zur empfindlichsten Seite des Hauses. "Bewertet wird dort" ->
"Eingeschaetzt wird dort" in teamlage.html, zwei Zeilen unter "keine
Bewertung von Menschen". "1 Aufgabe(n) angelegt" ausgeschrieben.

GEMESSEN: pruef-css-klassen ALLES IN ORDNUNG (vorher 3 Fehler),
pruef-meldungen 8/0, pruef-rechtetafel 19/0, alle Module laden,
keine doppelten Kachelnamen/-ziele/-farben mehr in allen vier Rollen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 14:57:55 +02:00
DogFatherGitandClaude Opus 5 7be85c265b Der Treff bekommt einen Chat -- mit Nachtruhe, ohne Telefon
Filipe, auf die Frage ob die Community einen Chat bekommen soll:
"eine geile mischung von punkt 2 und drei. mach es perfekt so das quasi
nach mitternacht bis morgens 6 uhr keiner schreiben kann damit auch die
privatsphaere beruecksichtig wird ueber nacht ... und die sollen nicht
anrufen koennen. nur schreiben."

Zur Auswahl standen "gar kein Chat", "nur mit Oeffnungszeiten" und
"offen wie im Team". Seine Antwort ist eine vierte, die nicht auf dem
Zettel stand, und sie ist die bessere.

1. WARUM DIE NACHTRUHE MEHR IST ALS EINE EINSTELLUNG

Sein Grund war Privatsphaere -- und zwar die der Leute, die moderieren.
Die Forschung zu ehrenamtlichen Moderatoren sagt genau das: Die beiden
meistgenannten Gruende fuers Aufhoeren sind ZU WENIG ZEIT und STREIT IM
TEAM. Ein Chat, der nachts um drei weiterlaeuft, erzeugt beides.

SIE GILT FUER ALLE, AUCH FUER DIE LEITUNG. Das ist die unbequeme
Entscheidung: Der bequeme Weg waere, DogFather auszunehmen. Aber wenn er
um halb vier schreibt, liest es jemand -- und wer liest, fuehlt sich
zustaendig. Eine Nachtruhe, von der die Leitung ausgenommen ist, ist
keine, sondern eine Bitte.

MODERIEREN GEHT WEITER. Verbergen, loeschen, herausnehmen sind keine
Nachrichten. Wer nachts etwas Schlimmes sieht, kann es wegnehmen -- er
kann nur nicht darueber diskutieren. Und der vertrauliche Meldeweg
bleibt offen: Er ist ein Fall mit einer Zustaendigkeit, kein Raum mit
dreissig Leuten.

GERECHNET IN ORTSZEIT, nicht in UTC. `getHours()` auf einem UTC-Server
haette den Chat im Sommer von 2 bis 8 geschlossen -- zwei Stunden
daneben, und nur denen sichtbar, die um diese Zeit wach sind. Dieses
Haus ist mit der Rechnung schon zweimal hereingefallen.

DER RIEGEL SITZT IM SERVER, nicht im Browser. Ein ausgegrautes Feld ist
eine Hoeflichkeit; wer die Adresse kennt, spricht die Schnittstelle
direkt an. Nachrichten UND Anhaenge werden abgelehnt -- ein offener
Anhangweg waere der Umweg, den jeder findet, der es einmal versucht.

2. KEIN TELEFON -- UND WARUM DAS EINEN EIGENEN RIEGEL BRAUCHT

Ein Anruf haengt in diesem Haus an der RAUMMITGLIEDSCHAFT, nicht an der
Rolle. Solange die Community keinen Raum hatte, war die Frage muessig.
Seit sie einen hat, waere Telefonieren erlaubt -- nicht, weil es jemand
entschieden haette, sondern weil es niemand verboten hat.

Der Riegel steht ganz vorne am Anruf-Router, nicht in den neun Routen
dahinter. Alle sieben Wege sind geprueft, einzeln.

3. DER FUND, DER DIE GANZE NACHTRUHE UMGANGEN HAETTE

Ein Gast konnte ein PRIVATES ZWEIER-GESPRAECH mit DogFather aufmachen.
Die Route antwortete mit 200 und legte den Raum an.

`ohneAussen` nimmt die Community aus den Listen ANDERER heraus -- damit
kein Creator einen Zuschauer anschreibt. Die Gegenrichtung kam nie vor,
weil die Chatseite fuer 'gast' gar nicht offen war. Seit heute ist sie
offen, und damit war die Erlaubnis da.

Ein Zweier-Gespraech ist kein Kanal: keine Nachtruhe, kein Modi liest
mit, niemand koennte moderieren. Aus "die Community bekommt einen Chat"
waere ungewollt "jeder Zuschauer bekommt eine Standleitung zu
DogFather" geworden.

GEFUNDEN HAT ES DIE PRUEFUNG, NICHT DAS LESEN -- und zwar in dem Moment,
in dem ich zwei Dateien weiter selbst vor genau dieser Sorte Erlaubnis
gewarnt hatte.

4. ZWEI TOTE WEGE, EINER DAVON MEINER

pruef-community-sicht sucht nach sichtbaren Wegen, die ins Leere
fuehren. Sie fand zwei:

  a) "Bei dir klingelt nichts" -> anruf-probe.html. Der Hinweis von
     heute Vormittag, und die Seite steht einem Gast ausdruecklich NICHT
     offen. Mein Fehler, und einer, der jedem naechsten Hinweis genauso
     passiert waere.

     AN DER WURZEL BEHOBEN: Die Hinweise pruefen jetzt auch die ROLLE
     (`darfSeite`), nicht nur die Adresse. Das ist der 15.09. noch
     einmal, eine Ebene tiefer -- damals die Adresse, diesmal die Rolle,
     und dieselbe Lehre: Die Hinweise sind eine DRITTE Stelle neben
     Seiten und Schnittstellen.

  b) Der Verweis "Kalender" im Tagesblick. Steht fest im HTML, fuehrt
     fuer die Community ins Leere -- und zwar SCHON VOR den Aenderungen
     dieses Tages. Aufgefallen nur, weil (a) daneben stand. Der Weg
     wird jetzt abgeleitet: Wer die Kachel hat, hat den Weg.

5. DIE PRUEFUNG LAEUFT ZWEIMAL

Die Nachtruhe laesst sich nicht in EINEM Lauf in beiden Zustaenden
pruefen -- die Zeiten werden beim Laden gelesen, und ein zweiter Server
braeuchte denselben Port. pruef-treffchat ruft sich deshalb selbst noch
einmal auf, mit einem Fenster, das jetzt gilt. Dieselben Pruefungen,
andere Lage.

DIE UHR WIRD NICHT GEFAELSCHT. Verschoben wird die GRENZE, nicht die
Zeit -- eine Pruefung, die an der Systemzeit dreht, faelscht danach auch
anderes mit und ist nur nachts gruen.

6. WAS SICH NEBENBEI GEAENDERT HAT

- pruef-treff war SCHON VORHER ROT (8 Fehler): Sie erwartete sieben
  Kacheln fuer die Community, es waren gestern Nacht schon zehn. Feste
  Zahlen, Rechnung von gestern. Jetzt abgeleitet -- 72 Pruefungen statt
  66, alle gruen.
- Ein 404 bei jedem Seitenaufruf der Community: `anruf.js` holte die
  Verbindungsadressen, bevor es wusste, wer fragt. Der Browser
  protokolliert das, BEVOR JavaScript abfangen kann -- also darf die
  Anfrage gar nicht erst gestellt werden. `/api/ich` sagt es jetzt
  vorher. Ein Fehler, der immer kommt, macht den naechsten echten
  unsichtbar.
- Reaktionen (Daumen) bleiben nachts erlaubt. Ausdruecklich, mit
  Begruendung im Code: Ein Daumen ist keine Nachricht, er loest keine
  Meldung aus und kann keinen Streit anfangen. Eine Luecke ohne
  Begruendung wird beim naechsten Durchsehen entweder geschlossen oder
  uebersehen -- beides falsch.

GEMESSEN: pruef-treffchat 108/0 (neu, laeuft zweimal), pruef-treff 72/0
(vorher 66 mit 8 Fehlern), pruef-chat gruen, pruef-rechtetafel 19/0,
pruef-community-sicht gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 11:47:31 +02:00
DogFatherGitandClaude Opus 5 19e9f471d3 Entwicklung: die Auswertung je Person -- und elf Seiten ohne Farbe
Filipe: "dan perfektionierst du eine neue wo diagramme texte und so zu
jedem modi gemacht wird und diese kategorie kannst du entwicklung nenen."

1. DAS EIGENTLICHE PROBLEM WAR, DASS ES KEINE VERGANGENHEIT GAB.

`entwicklung_stand` hat den Schluessel (person, punkt, beurteiler) und
wird bei jeder Aenderung UEBERSCHRIEBEN -- dort richtig, eine Beobachtung
ueber einen Menschen soll aktuell sein. Nur: Damit existierte nichts,
woraus sich ein Verlauf zeichnen liesse. Nachgemessen: 43 Zeilen Stand,
NULL Zeilen Geschichte. Ein Diagramm ueber einen einzigen Zeitpunkt ist
kein Diagramm, sondern ein Balken.

Neu: `entwicklung_lauf` haengt jede Aenderung an, statt zu ueberschreiben.
Sie steht in workspace-entwicklung.js, bei der Tabelle, zu der sie
gehoert -- die Auswertung liest nur. Andersherum gaebe es einen Ring
zwischen zwei Modulen, und Ringe halten in JavaScript genau so lange,
bis jemand eine Konstante auf oberster Ebene benutzt.

KEIN ANLASS, NIE. Neben jedem "da hakt es" steht ein Satz, woran man es
gemerkt hat -- fuer ein Gespraech aufgeschrieben. Eine Chronik dieser
Saetze waere das Belastendste, was dieses Haus speichern kann. Die Spur
hat gar keine Spalte dafuer, und die Pruefung liest die TABELLE, nicht
die Ausgabe: Eine Spalte, die es gibt, wird eines Tages gefuellt.

Die Startaufnahme uebernimmt den heutigen Stand mit seinen ECHTEN Daten,
damit die Seite am ersten Tag nicht leer ist -- und zaehlt ausdruecklich
NICHT als Bewegung. Der Tag, an dem die Spur entstand, war kein Tag, an
dem 43 Dinge gleichzeitig passiert sind.

2. WAS GEZEIGT WIRD: BEWEGUNG, KEINE NOTE.

Keine Punktzahl, kein Prozentwert, kein Durchschnitt, keine Rangliste,
kein Vergleich zwischen zwei Menschen. Das ist die Recherche, nicht
Vorsicht: Ueberrechtfertigung (Deci), sozialer Vergleich senkt die
Leistung derer, die schlechter dastehen, Schwaechenfokus ebenso.

Stattdessen das progress principle (Amabile/Kramer, ~12 000
Tagebucheintraege): Sichtbarer Fortschritt ist der staerkste einzelne
Treiber. Deshalb Diagramm 1 "Was sich bewegt hat" -- zwei Richtungen um
eine Nulllinie, ein Massstab fuer beide. Diagramm 2 der Streifen (Punkt
x Monat), fortgeschrieben, aber nach 90 Tagen sichtbar verblasst.
Und die Texte in dieser Reihenfolge: was sich bewegt hat, was traegt,
erst danach was liegt.

Selbst gezeichnet, kein Diagrammpaket: 60 kB ueber die Leitung von
jemandem, der mit dem Handy im Stream steht -- und es braechte eigene
Farben neben die Hausfarben. Jede Zelle traegt ihr Zeichen als Text,
jeder Balken seine Zahl, darunter eine Legende: Die Farbe ist nie die
Auskunft.

Zwei Gesichter: Die Leitung sieht die Karten, ein Modi ausschliesslich
die Bewegung in der eigenen -- ohne Namen, ohne Anlass, ohne Streifen.

3. NEBENBEFUND, GROESSER ALS ERWARTET: ELF SEITEN OHNE FARBE.

Der Umbau von heute frueh heisst "Jede Seite traegt die Farbe ihrer
Kachel". Nachgemessen traf das auf 18 von 34 Seiten zu. Elf Seiten mit
echter Kachel gingen leer aus -- ausgerechnet die von Team Dogi:
befinden, bewerben, bewerbungen, entwicklung, hilfe, rechte, talente,
teamlage, teilen, treff-moderation, treff-regeln, unsere-seiten.

Der Grund: `zuSeite()` sucht nur in `Bereiche.GRUPPEN`, und dort stehen
ausschliesslich die Kacheln der Agentur. Die von Team Dogi liefert der
Server (`ich.bereiche`, `ich.bereiche_zusatz`). Auffallen konnte das
nicht -- eine Seite ohne Farbe sieht aus wie eine, die eben keine hat.

kopf.js faerbt jetzt zweimal: sofort aus GRUPPEN (Agenturseiten ohne
Flackern wie bisher), und noch einmal aus den Serverkacheln, sobald
`werZeigen` sie bringt. Nur, wenn beim ersten Mal nichts gefunden wurde.

pruef-buehne misst den Kontrast an echten Bildpunkten und kannte diese
zwoelf Seiten nicht. Jetzt stehen sie in der Liste; ihre Frist waechst
mit der Laenge, statt als feste Zahl irgendwann zu reissen. Gemessen
fuer werdegang.html: 4,83:1 am Computer, 6,22:1 am Handy.

4. TON 38 SAH FREI AUS UND WAR ES NICHT.

Erster Anlauf war Ton 38, weil 37 die hoechste Nummer in workspace.js
ist. Gezaehlt in start.css sind es 39, alle vergeben. Genau davor warnt
das Farbwerkzeug im eigenen Kopf ("Ton 22, weil er frei AUSSAH").

Dabei aufgefallen: Die zwei Kacheln von heute Nacht wurden ohne das
Werkzeug gesetzt. Ton 39 lag 0,0362 von Ton 15 entfernt -- der engste
Abstand im ganzen Haus, zwei praktisch gleiche Cyan-Toene. Filipe dazu
mehrfach: "keine die sich irgendwie aehnlich sind".

Neues Werkzeug `tools/kachel-farbe-einzeln.mjs`: zieht EINE Farbe nach,
ohne die anderen anzufassen. Das grosse Werkzeug haette alle 40 neu
gefaerbt -- jede Kachel im Haus, ungefragt. Es bricht ab, wenn es nicht
alle Toene lesen kann: Der erste Anlauf las 31 von 40, weil einstellige
Nummern mit ZWEI Leerzeichen dastehen, und rechnete froehlich weiter.

Ergebnis: kleinster Abstand 0,0362 -> 0,0840, durch Aendern von zwei
Kacheln, die es erst seit gestern Nacht gibt.

5. anruf-probe.html lud `basis.css` und `kopf.css` -- beide gibt es
nicht. Ausgerechnet dort faellt es nicht auf, weil die Seite ihre eigene
Stilangabe im Kopf hat. pruef-struktur war deshalb rot (5 Befunde) und
ist jetzt gruen.

GEMESSEN: pruef-werdegang 95/0 (neu), pruef-entwicklung 43/0,
pruef-befinden 75/0, pruef-rechtetafel 19/0, pruef-zwischenspeicher 21/0,
pruef-start-ansicht 0 Fehler, pruef-struktur 0 Fehler (vorher 5),
pruef-buehne fuer werdegang.html 0 Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 10:22:02 +02:00
DogFatherGitandClaude Opus 5 f62ade3573 Vertraulicher Meldeweg, klappbare Abschnitte, lila Stunden, Logos
Eine Nacht voller Auftraege von Filipe. Der Reihe nach:

1. VERTRAULICH MELDEN -- der groesste neue Teil.

"es soll auch eine kategorie also eine hauptkachel geben wo die
community leute sich anonym melden koennen wenn sie probleme haben ...
rechte hand und dogfather sollen zugriff auf diese anonyme nachrichten
haben. also anonym fuer die anderen."

WICHTIG, UND ES STEHT SO AUF DER SEITE: "anonym" heisst hier
VERTRAULICH. DogFather und die rechte Hand sehen den Namen -- so
bestellt und auch richtig, ohne Namen kann man niemandem helfen.
Anonym ist es gegenueber allen anderen: kein Modi, kein anderes
Mitglied. Wer glaubt, er schreibe unerkannt, schreibt anders und fuehlt
sich hinterher getaeuscht -- deshalb steht der Satz im Formular, bevor
jemand tippt.

Der strikte Wechsel (melden -> warten -> antworten -> warten) ist im
SERVER erzwungen, nicht nur im Knopf. Ein ausgegrauter Knopf ist keine
Regel. Geschlossen wird nur von der Leitung; abgeschlossene Faelle
werden nach 90 Tagen samt Nachrichten geloescht -- hier stehen die
empfindlichsten Texte des Hauses.

Modis sind ausdruecklich AUSSEN VOR: Sehr oft geht es in diesen
Meldungen um eine Moderationsentscheidung.

2. JEDE KATEGORIE LAESST SICH ZUKLAPPEN.

"man soll auf dieser seite jede kategorie auf und zu klappen koennen
mit einem button ... ueberall wo so eine liste entstehen kann."

Das Muster gab es auf der Startseite schon; es steht jetzt als
`abschnittKlappbar` in kopf.js und wird von den Brettern und dem
Zeitstrahl benutzt. Die Koepfe sind echte <button> (fuer die Tastatur),
der Zustand haelt in localStorage, und er haengt je Brett UND Art --
sonst waere "Regel zugeklappt" ueberall gleichzeitig zu.

3. DIE SPRUNGLEISTE SIEHT AUS WIE ETWAS ZUM ANFASSEN.

Vorher unterstrichene Woerter, die aussahen wie eine Fusszeile. Jetzt
Marken mit Rahmen in einem eigenen Block.

4. DIE STUNDEN SIND LILA.

UMGERECHNET, NICHT NEU GEWAEHLT: Jeder der fuenf Verlaufsstopps wurde
nach OKLCH zerlegt, der Farbton auf 303 Grad gedreht, zurueckgerechnet.
Helligkeit und Buntheit blieben gleich -- eine frei gegriffene Palette
waere heller oder bunter geworden, und die Uhr damit unruhiger.

5. DIE KARTEN "UNSERE SEITEN": babyblau und lila, mit schwebenden Logos.

Beide Logos wurden zu MASKEN gerechnet (tools/logo-maske.mjs): Die PNG
tragen nur Alpha, die Farbe kommt aus dem CSS. Dadurch passt dasselbe
Logo in jede Kachel, egal welchen Ton sie hat -- und VanVans 378-KB-
Logo wurde dabei zu 109 KB. Vier Stueck je Karte, verschieden gross,
zwei Bahnen, 26 bis 41 Sekunden Umlauf. Der erste Versuch war mit 5-9 %
Deckkraft praktisch unsichtbar; jetzt 10-16 %.

6. "ENTWICKLUNG" HEISST JETZT "EURE AUFGABEN".

Filipe hat recht: Die Kachel fuehrt seit dem 11.09. auf den Katalog --
eine Aufgabenliste. Der Name blieb stehen, weil beim Umhaengen des
Ziels niemand ihn angefasst hat. Der Name "Entwicklung" ist damit frei
fuer das, was er darunter versteht (Auswertung je Person mit Verlauf
und Text) -- das ist noch NICHT gebaut.

DREI PRUEFUNGEN, DIE ZUFAELLIG GRUEN WAREN, sind nebenbei aufgefallen:
- pruef-kachelraster wartete feste 500 ms auf eine gestaffelte
  Einblendung und mass vier Reihen, wo drei sind. Jetzt reducedMotion.
- pruef-start-ansicht scrollte 600 px und nahm an, danach liege keine
  Kachel mehr unter dem Zeiger.
- pruef-wege-nach-draussen zaehlte das Kachelraster ueber ALLE Gruppen
  statt je Gruppe.

GEMESSEN: pruef-hilfe (neu) 55/0, pruef-wege-nach-draussen 64/0,
pruef-jeder-hat-eine-seite 65/0, pruef-community-sicht 10/0,
pruef-bereiche-lesend, pruef-steckbrief, pruef-start-ansicht,
pruef-kachelraster alle gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 02:04:03 +02:00
DogFatherGitandClaude Opus 5 63f2b2bc55 Jeder hat einen Steckbrief -- und die Kacheln stehen in der richtigen Reihenfolge
Filipe: "jeder soll ein steckbrief haben, jeder der ein account hat,
rechte hand, modis und community, jeder soll genau wie ich foto und so
hinzufuegen koennen." Und: "ich will das oben die sachen fuer dogfather
sind, dan die sachen fuer modis und dan community bereich."

1. JEDER HAT EINEN STECKBRIEF.

In rechte.js fehlte "gast" -- und damit ausgerechnet die groesste
Gruppe. Die Seite selbst konnte es die ganze Zeit: `/mein` fragt nach
der eigenen Nummer und kennt gar keine Rolle. Es fehlte nur die Tuer
und die Kachel.

DABEI EIN ZWEITER FUND, der schon laenger da war: In
assets/js/steckbrief.js stand eine Liste aus drei Gruppen (Management,
Scouting, Creator). Wer in keine passte, verschwand LAUTLOS aus der
Uebersicht -- betroffen waren die rechte Hand und die Modis. Ein Modi,
der die Seite oeffnete, sah seine eigenen Leute nicht. Kein Fehler,
keine leere Liste, sie waren einfach nicht da.

Die Zuordnung kommt jetzt vom Server (`abschnittFuer`). Damit kann sie
nicht mehr veralten, und in der ausgelieferten Datei steht keine Liste
von Rollennamen mehr -- was ohnehin Hausregel ist. Wer kuenftig
vergessen wird, landet sichtbar unter "Weitere" statt zu verschwinden;
die Gegenprobe dafuer steht in der Pruefung.

"Wer hier mitarbeitet" heisst jetzt "Wer hier dabei ist" -- ein
Mitglied arbeitet nicht mit, es schaut zu.

2. DIE REIHENFOLGE.

Die Moderationskachel trug dieselbe Gruppe wie die sieben Bretter und
landete deshalb HINTER ihnen: Wer moderiert, musste an der ganzen
Community vorbeiscrollen. Sie hat jetzt eine eigene Gruppe und steht
davor.

ERST ZU VIEL GEMACHT, DANN KORRIGIERT: Mein erster Entwurf schrieb auch
die Reihenfolge der Arbeitsgruppen fest. Die ist an mehreren Stellen
bewusst gewaehlt und begruendet -- pruef-start-ansicht hat es sofort
gemeldet, zu Recht. Jetzt wandern nur noch Moderation, Community und
"Fuer dich" ans Ende; alles andere bleibt, wo es war.

3. ZWEI PRUEFUNGEN, DIE ZUFAELLIG GRUEN WAREN.

pruef-kachelraster zaehlte Reihen ueber die Y-Koordinate und wartete
feste 500 ms. Die Kacheln laufen aber gestaffelt ein -- mit einer
Gruppe mehr war die Messung zu frueh und meldete vier Reihen, wo drei
sind. Das Bildschirmfoto derselben Seite zeigte ein makelloses Raster.
Jetzt misst sie mit `reducedMotion: reduce`, also den Endzustand.

pruef-start-ansicht scrollte 600 px und nahm an, danach liege keine
Kachel mehr unter dem Zeiger. Dieselbe Falle wie eine feste
Umbruchschwelle: eine Rechnung von gestern. Sie fragt jetzt, was
gemeint ist -- leuchtet die ALTE Kachel noch?

GEMESSEN: pruef-jeder-hat-eine-seite (neu) 65 Pruefungen 0 Fehler,
pruef-steckbrief, pruef-start-ansicht, pruef-kachelraster,
pruef-community-sicht alle gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 01:40:16 +02:00
DogFatherGitandClaude Opus 5 f30227c873 Unsere Seiten, klickbare Video-Karten -- und coturn, das nie vermittelt hat
Drei Sachen von Filipe, und eine davon war ein Fehler von mir.

1. DER VERMITTLUNGSSERVER HAT NIE EINEN ANRUF GETRAGEN.

Am 18.09. habe ich gemeldet, coturn laufe und sei "von aussen
nachgewiesen". Das war falsch. Im Protokoll: null Zuteilungen, jemals.
Beim ersten echten Versuch "check_stun_auth: Cannot find credentials"
-- in /etc/turnserver.conf fehlte `static-auth-secret`, also suchte
coturn die Zugangsdaten in seiner eigenen Datenbank und wies jeden ab.

Und mein eigenes Werkzeug meldete die ganze Zeit gruen:
"Eingetragen, Geheimnis lesbar, Server antwortet." Jedes Wort wahr --
und keins beantwortete die Frage, um die es geht. Eine STUN-Bindung
fragt "bist du da?", eine Zuteilung fragt "traegst du meinen Anruf?".

`tools/turn-sprache.mjs` (neu) versucht jetzt eine ECHTE Zuteilung und
schickt ein Paket darueber. `turn-einrichten.mjs` benutzt sie und hat
drei Ausgaenge statt zwei: traegt / traegt nicht / konnte nicht
nachsehen. Nach Filipes Reparatur auf dem Server gemessen: Zuteilung
auf Port 49199, Paket angekommen -- von Luxemburg durch Deutschland.

2. UNSERE SEITEN -- die erste Kachel, die HINAUSFUEHRT.

Website und VanVans Shop, mit dem Rabattcode DOGI10. Der Code wurde
nachgesehen, nicht abgeschrieben: partnercodes.json, 10 Prozent,
aktiv, "zum weitergeben an Community" -- und giltAufSale: false,
weshalb der Satz zu reduzierten Artikeln danebensteht. Der zweite Code
dort ist als "nur fuer Filipe persoenlich" vermerkt und steht nirgends.

Auch Name und Beschreibung des Shops stammen von der Seite selbst.
Meine erste Fassung hiess "Van's DIY Bastelbedarf" und nannte "Perlen,
Anhaenger, Werkzeug" -- ausgedacht und falsch. Er heisst mit "&" und
verkauft Haekelwerke, Plushies, Schmuck.

Der Ton der Kachel wurde GESUCHT, nicht gewaehlt: sieben geratene
Blautoene schafften den noetigen Abstand nicht, also 372 600
Kombinationen abgesucht. #087ce7, Abstand 0.310, Kontrast 4.51:1.

3. DIE GANZE VIDEO-KARTE KLICKT -- "egal wo man drauf drückt".

Und hier steckte der lehrreiche Fehler: Zuerst stand der Klick-Block
unten vor `return k`. Diese Funktion hat DREI Rueckgabepunkte, und der
erste lautet `if (!darfEintragen()) { ...; return k; }` -- also genau
fuer die Mitglieder, fuer die Filipe es wollte. Beim Team ging es, bei
der Community nicht. Jetzt haengt er dort, wo `videoWeg` entsteht.

Nicht klickbar bleiben Karten ohne Video und solche, deren Video bei
TikTok geloescht wurde -- sonst fuehrt der Klick auf eine Fehlerseite,
und wir sehen kaputt aus.

GEMESSEN: pruef-wege-nach-draussen (neu) 63 Pruefungen, 0 Fehler, auf
1400 und 412 px. Mit Gegenproben: der Kopierknopf oeffnet nichts, der
eigene Knopf wirkt genau einmal, auf einer Karte ohne Video passiert
nichts. pruef-community-sicht 10/0 auf jetzt 11 Seiten, 0 tote Wege.

Nebenbei: Der Pfeil klebte bei langen Untertiteln am Text (auf dem
Bildschirmfoto gesehen). 0.45rem Abstand.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-19 01:17:09 +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 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
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
DogFatherGitandClaude Opus 5 8f0a184b9f Was DogFather eintraegt, sehen jetzt auch die anderen -- und 113 fertige Inhalte
Vier Bildschirmfotos, vier Auftraege. Vor dem Bauen gemessen
(server/mess-sichtbarkeit.mjs): alle Bereiche, alle vier Rollen.

ZWEI FEHLER, DIE NIEMAND GEMELDET HAETTE
Beide sahen auf DogFathers eigenem Bildschirm vollkommen richtig aus --
und das ist das Tueckische: Ein leeres Brett sieht nicht nach Fehler
aus, sondern nach "da ist eben noch nichts".

1. DIE FREIGABE. "Was ansteht" und "Highlights" zeigen der Community
   nur, was freigegeben ist. Ein aus dem Vorschlagskasten uebernommener
   Eintrag hatte keine Freigabe. Gemessen:

       Brett      DogFather  rechte Hand  Modi  Community
       ansteht        4           4         4        0
       highlight      3           3         3        0

   Filipe konnte fuellen, so viel er wollte -- fuer die Community
   blieben genau die zwei Bretter leer, auf die es ankommt. Wer aus dem
   Team uebernimmt, gibt jetzt zugleich frei: Die Freigabe fragt "hat
   das Team diesen Text gesehen?", und die Antwort ist beim Uebernehmen
   ja. Eine zweite Entscheidung daneben waere keine Sicherheit, sondern
   ein Klick.

2. TEAM_DOGI_ROLLEN IST {hand, modi} -- OHNE "admin". Die
   Sichtbarkeitsregel fuer Team Dogi lautete damit woertlich "Eintraege
   von hand oder modi". Folge: ALLES, was DogFather in Live, Technik,
   Community, Ideen, Angebote oder Rueckmeldung schreibt, war fuer sein
   eigenes Team unsichtbar. Das ist nicht erst seit dem Startkatalog so
   -- der hat es nur sichtbar gemacht, weil vorher ueberall Null stand
   und Null gleich Null aussieht, egal aus welchem Grund.

   Die Liste wird genau dort erweitert, wo es um Sichtbarkeit geht --
   NICHT in TEAM_DOGI_ROLLEN selbst: Diese Menge entscheidet auch,
   welches Haus jemand bewohnt. Ein Eintrag dort haette DogFather
   stillschweigend zur Crew umgezogen.

113 FERTIGE INHALTE IN DEN LEEREN KATEGORIEN
Gemessen waren elf Bereiche ausserhalb des Treffs komplett leer -- fuer
JEDE Rolle. Der Startkatalog kannte nur die sieben Treff-Bretter; die
Oberflaeche war die ganze Zeit bereit, es fehlten nur die Texte.
workspace-arbeit-start.js fuellt neun davon: Live, Content, Technik,
Community, Schutz, Ideen, Rueckmeldung, Angebote, Agentur.

"talente" und "entwicklung" bekommen ABSICHTLICH nichts: Dort waere ein
"fertiger Inhalt" ein erfundener Mensch -- ein Testdatensatz in einem
System, das echte Menschen bewertet. Die Talente-Seite bekommt ihre
Hilfe anders (siehe unten).

DER ENTWICKLUNGSKATALOG: 28 -> 68 PUNKTE, VIERTE STUFE
Filipe: "wieso ist da immer noch nicht perfektionniert wie bei den
anderen mit fortgeschritten und so, und VIIIIIEEEELLLLLL mehr aufgaben."
  * Neue Stufe "Fortgeschritten" zwischen "nach ein paar Monaten" und
    "wofuer man jemanden fragt" -- genau die Mitte fehlte.
  * Stufenleiter als FILTER ueber den Kategorien, wie die Checkliste es
    seit dem 10.09. vormacht. Aus r.erwartung gebaut, nicht aufgezaehlt.
  * Zwei neue Bloecke, die Filipe ausdruecklich wollte: "Clips, Schnitt
    und Kommentare" und "Waehrend der Stream laeuft" -- seine
    Wunschkategorien vom 17.09. ("videos schneide, kommentieren,
    markierungen").
  * Keine Note, keine Punktzahl, keine Rangliste. Unveraendert.

DAS BEFINDEN: 6 -> 12 FRAGEN, UND SIE MELDET SICH VON SELBST
Den 14-Tage-Rhythmus gab es schon -- er wirkte aber nur, WENN jemand die
Seite aufmachte. Wer sie vergisst, wurde nie wieder gefragt: Das war
eine Anzeige, keine Anfrage. Jetzt kommt sie ueber dasselbe Push-System
wie faellige Aufgaben, hoechstens einmal je sieben Tage, und sie fragt
rhythmus() aus workspace-befinden.js -- dieselbe Funktion wie die Seite,
keine zweite Formel daneben.
Sechs neue Fragen zu Erholung, Sinn, Klarheit, Anfeindung, Entwicklung
und dem Blick nach vorn, jede mit ihrer Einordnung.
Und an acht Stellen stand "sechs Fragen" ueber zwoelf Fragen -- wo ein
Skript den Text baut, wird jetzt gezaehlt; in den festen Seiten steht
gar keine Zahl mehr.

DIE TALENTE-SEITE, WENN NIEMAND DARAUF STEHT
Statt "Noch niemand auf der Liste" stehen dort jetzt die fuenf Gruppen
mit ihren 21 Anzeichen -- die gab es laengst, sie waren auf der leeren
Seite nur nie zu sehen. Dazu der Weg in beide Richtungen: woher ein
Talent kommt (der Treff) und wo es endet (die Entwicklung).

DIE PRUEFUNG (server/pruef-alle-sehen-es.mjs, 42 Pruefungen)
Sie prueft BEIDE Haelften von Filipes Satz. Nur zu zaehlen, ob alle
alles sehen, waere gruen, wenn man saemtliche Schranken entfernte --
Abschnitt 4 belegt, dass 19 Bereich-Rollen-Paare zu bleiben und die
Community an keinen der elf Arbeitsbereiche kommt.

ZWEI GEGENPROBEN, weil 42 von 42 im ersten Lauf kein Beweis ist:
  a) "admin" aus der Team-Sicht entfernen  -> 13 Pruefungen rot
  b) Freigabe beim Uebernehmen abschalten  ->  2 rot, genau ansteht
     und highlight
Jede trifft ihr Ziel und nicht alles.

UND EINE LUECKE IN EINER ALTEN PRUEFUNG
pruef-deutsche-texte war gruen -- und hatte die 113 neuen Texte, die 40
neuen Entwicklungspunkte und die 6 neuen Fragen nie gesehen: Sie stehen
in Dateien, die sie nicht kannte. Jetzt 391 statt 174 geprueften
Texten. (Meine erste Untergrenze stand auf 400 und war sofort rot --
geraten statt gemessen.)

Stempel 202609171318.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 13:18:45 +02:00
DogFatherGitandClaude Opus 5 f05783ebc8 Link einfuegen, Video steht in der App -- Stufe A des Video-Plans
Filipe: "damit meine videos auch da auf der app rein kommen ... sobald
ich ein video poste erscheint es sofort in der app fuer die ganze
community ... dass man das Coverbild und den Text sieht ... fuer meinen
Account, dann DogFather Clips und HasiDog."

Der Weg, der HEUTE funktioniert -- ohne Freigabe, ohne Geheimnis, ohne
Wartezeit: Adresse einfuegen, alles andere geht von allein.

  Link -> oEmbed (Titel, Cover-Adresse, Account)
       -> Cover HERUNTERLADEN und bei uns ablegen
       -> Eintrag mit Bild, Text und Knopf zum Video

DAS COVER WIRD KOPIERT, NICHT VERLINKT -- der wichtigste Satz.
TikToks Bildadresse ist signiert und laeuft ab. Heute an einem echten
Video nachgemessen: x-expires = 1789812000, also in 48 Stunden. Wer sie
nur speichert, hat uebermorgen schwarze Kacheln. Beim Bauen merkt man
das nicht und beim Testen auch nicht -- es faellt erst am uebernaechsten
Tag auf, und dann sieht die ganze App kaputt aus.

Deshalb wandert das Bild in dieselbe Ablage wie jeder Anhang und geht
durch dieselbe Bytepruefung. Ein heruntergeladenes Cover ist eine
FREMDE Datei; dass der Typ hier von einem fremden Server behauptet wird
statt vom eigenen Browser, macht ihn nicht glaubwuerdiger.

NUR SEINE EIGENEN KANAELE. Der Account aus der Antwort wird gegen
KANAELE geprueft (kanalVonHandle). Genommen wird author_url (.../@name),
nicht author_name -- der Anzeigename aendert sich, wenn jemand ihn
umstellt. Ein fremdes Video in Filipes Highlights waere nicht bloss
falsch einsortiert, es waere fremder Inhalt unter seinem Namen: 403.

DIE PRUEFUNG SCHALTET TIKTOK AB (server/pruef-video.mjs, 37 Pruefungen)
Ein nachgebauter Dienst auf 127.0.0.1 antwortet wie TikTok, mitsamt
Ablaufstempel. Im letzten Abschnitt wird er ABGESCHALTET. Danach muss
die alte Cover-Adresse ins Leere laufen und unsere weiterhin ein Bild
liefern -- beides wird gemessen, nebeneinander. Waere das Bild nur
verlinkt, waeren beide tot, genau wie uebermorgen im Betrieb.

Die Adresse des Dienstes kommt aus TIKTOK_OEMBED_BASIS. Steht sie nicht
da, gilt TikTok -- kein Verhalten, das sich still aendert. Eine
Pruefung, die das echte TikTok braucht, misst fremde Verfuegbarkeit
statt unseren Code und wird irgendwann rot, ohne dass etwas kaputt ist.

VIER GEGENPROBEN, weil 37 von 37 im ersten Lauf kein Beweis ist:
  a) Cover nicht mehr kopieren      -> 9 Pruefungen rot
  b) author_name statt author_url   -> 22 rot
  c) Bytepruefung entfernen         -> 2 rot (genau Abschnitt 5)
  d) Dublettenpruefung entfernen    -> 4 rot (genau Abschnitt 4)
Jede schlaegt dort an, wo sie soll. Und eine fuenfte Gegenprobe ist ins
Leere gelaufen: Der Patch lief ueber python3, das es hier nicht gibt --
die Datei blieb unveraendert und der Lauf war gruen. Haette ich die
Ausgabe nicht gelesen, haette ich behauptet, die Pruefung koenne rot
werden, ohne sie je rot gesehen zu haben. Der dritte Ausgang, an mir
selbst.

DAZU:
- eintraege.quelle_url / quelle_kanal / quelle_geholt_am (Umstellung)
- KANAELE bekommt handle, dazu kanalVonHandle()
- videoRouter steht VOR bereicheRouter, sonst schluckt /:bereich ihn
- Eingabefeld und Kanal-Knopf in bereich.html/.js, Farben wie bei den
  Aufgaben-Kanaelen
- Stempel 202609171249

Nicht darin: die Kanal-Filterzeile in der Galerie, die Handy-Verknuepfung
(Teilen -> Workspace) und der Zustand "nicht mehr da" fuer geloeschte
Videos. Stufe B (Display API) braucht Filipes Entwickler-Freigabe.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 12:50:42 +02:00
DogFatherGitandClaude Opus 5 79e675b846 Stufe 6 und 7: Der Treff wird ein Gespraech, jedes Brett bekommt seine Form
Damit sind alle acht Stufen des Plans gebaut.

STUFE 6 -- DAS GESPRAECH
"Der Treff -- Hallo sagen, fragen, loben" war eine Liste aus Karten.
Der einzige Bereich, in dem Menschen MITEINANDER reden sollen, zwang
sie, nebeneinander zu reden: Jeder schrieb eine eigene Karte, niemand
antwortete jemandem.

Jetzt: Antworten eingerueckt unter ihrem Beitrag, aelteste zuerst (so
liest man ein Gespraech), mit Namen und Rolle. Das Feld steht immer da
statt hinter einem "Antworten"-Knopf -- ein leeres Feld ist die
deutlichste Einladung, die es gibt. Nur EINE Stufe eingerueckt: Auf
390 px ist bei der zweiten Schluss.

Eine EIGENE Tabelle, kein Eintrag mit "antwort_auf": Eine Antwort hat
keine Art, keinen Zustand, keine Frist und gehoert in keinen Filter.
Als Eintrag gefuehrt haette sie zwanzig immer leere Spalten -- und
tauchte in jeder Zaehlung auf, die Beitraege zaehlt.

Und nicht ueberall: nur Treff und Wunschliste. Aus dem Plan, §9 -- ein
Antwortfeld unter jedem Aushang hiesse, jeder Aushang muss betreut
werden.

ZWEI FEHLER, BEIDE VON DER PRUEFUNG GEFUNDEN

1. EIN PFAD, DER AUSSAH WIE EIN BEREICH.
   `/api/bereich/antwort/:id` lief in die Middleware auf
   `/api/bereich/:bereich` -- "antwort" ist kein Bereich. Fuer
   DogFather ging es (ein frueherer Zweig liess ihn durch), fuer einen
   Modi kam 404. Ein Weg, der je nach ROLLE an voellig anderer Stelle
   scheitert, sucht man lange. Liegt jetzt unter `/api/antwort/:id`.

2. UND EIN ECHTES LOCH.
   Die Loeschregel hiess `!darfSchreiben(req.person, "treff")` -- also
   "wer schreiben darf", und das duerfen Gaeste ab der Stufe "dabei".
   JEDER GAST HAETTE JEDE FREMDE ANTWORT LOESCHEN KOENNEN.

   Gefunden hat es eine Pruefung mit einer FALSCHEN Erwartung: Sie
   verlangte, dass ein Modi keine fremde Antwort loeschen kann. Das war
   falsch -- er moderiert ja --, aber der Weg dorthin hat das echte
   Problem freigelegt. Jetzt entscheidet TREFF_TEAM_ROLLEN.

   Der Gast-Fall ist ueber HTTP nicht messbar (er kommt nur ueber die
   crew-Adresse herein, und den Host-Kopf kann fetch nicht setzen).
   Statt stillschweigend zu ueberspringen prueft die Pruefung die REGEL
   selbst -- und dass die Route wirklich diese Menge benutzt.

STUFE 7 -- JEDES BRETT BEKOMMT SEINE FORM
- "Regeln & Hilfe" ist ein DOKUMENT: Sprungmarken oben, vier
  Abschnitte (Regel, Was passiert wenn, Hilfe, Haeufige Frage). Man
  schlaegt es im Streitfall auf und will FINDEN, nicht scrollen.
  scroll-margin-top, sonst verschwindet die angesprungene Ueberschrift
  unter der Kopfleiste und der Sprung sieht aus wie ins Leere.
- "Anschlagbrett" zeigt grosse AUSHAENGE statt Zeilen -- gemessen
  21 px Titel statt 17. Ein Aushang zwischen dreissig anderen ist kein
  Aushang.
- "Mitmachen" gruppiert nach Art, die drei Schritte zuerst.

UND EINE SCHRIFT, DIE ZU KLEIN WAR: Die Rollen-Marke an einer Antwort
stand auf 11,2 px, die Hausgrenze liegt bei 11,5. Die Grenze anzuheben
waere der bequeme Weg gewesen -- und ab da haette pruef-css-klassen
nichts mehr gehalten.

NEU: pruef-gespraech (27 Pruefungen)
pruef-treff-start jetzt 34 (Stufe 7 mitgeprueft)
Alle Community-Pruefungen gruen: gespraech 27, treff-start 34,
kreislauf 23, countdown 22, wunschliste 30, galerie 26, bremse 16,
treff 66, bereiche-lesend, css-klassen, deutsche-texte 12.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 12:12:21 +02:00