Commit Graph
70 Commits
Author SHA1 Message Date
DogFatherGit 079cf8c74f Drei Quellen fuer OBS und TikTok Studio -- ohne Anmeldung, mit Schluessel
Filipe: "ich will das alles auch so perfekt dass ich es ganz einfach
und easy mit obs oder mit tiktok studio verbinden kann. also so dass
man dan nur die kamera und das video sieht."

WARUM OHNE ANMELDUNG -- nachgesehen, nicht angenommen

OBS speichert die Anmeldung einer Browser-Quelle NICHT zuverlaessig;
im OBS-Forum stehen dazu Meldungen bis in die aktuelle Fassung 31.
Eine Quelle, bei der man sich nach jedem Programmstart neu anmelden
muss, ist mitten in einer Sendung unbrauchbar.

Deshalb ein SCHLUESSEL in der Adresse -- derselbe Weg, den jedes
Alert-Werkzeug im Netz geht. 32 Byte aus dem Zufall des Systems,
verglichen wird zeitgleich (`timingSafeEqual`): Ein gewoehnlicher
Vergleich bricht beim ersten falschen Zeichen ab, und aus den
Bruchteilen einer Millisekunde laesst sich ein Schluessel Zeichen
fuer Zeichen erraten.

DREI QUELLEN, WEIL DREI DINGE VERSCHIEDEN SIND

  buehne.html   Das laufende YouTube-Video, auf die Sekunde genau wie
                bei allen anderen. Stumm (der Ton kommt aus dem
                Mischpult) und ohne jede Bedienung -- was hier zu
                sehen ist, geht in den Stream.

                DIE EIGENE KAMERA IST ABSICHTLICH NICHT DRIN. Sie ist
                in OBS direkt als Geraet verfuegbar, in besserer
                Qualitaet und frei in Groesse und Lage -- genau das,
                was Filipe will ("meine kamera groesser machen video
                kleiner"). Den Umweg ueber den Browser zu nehmen
                hiesse, Qualitaet gegen nichts einzutauschen und die
                Groesse festzulegen statt sie freizugeben.

  tafel.html    Nur die Spendenkarten, auf DURCHSICHTIGEM Grund.
                Groesse und Lage stehen in der Adresse (`&g=1.6`,
                `&pos=or`): Wer in OBS eine Quelle einrichtet, hat die
                Adresse ohnehin vor sich -- ein Wert, den man
                stattdessen im Regiepult suchen muesste, waere ein
                Fensterwechsel mitten im Einrichten. Alles rechnet in
                `rem`, ein Wert nimmt Schrift, Bild und Polsterung
                gleichmaessig mit.

  Buehnenmodus  `reaktion.html?nur=buehne` -- dieselbe Seite, nur ohne
                alles Bedienbare. Fuer den Fall, dass GAESTE im Bild
                sind: Deren Kameras kommen ueber eine
                Direktverbindung an, und die braucht eine angemeldete
                Seite. Diese eine wird als Fenster aufgenommen.

                ES IST DIESELBE SEITE UND NICHT EINE ZWEITE. Eine
                eigene muesste Video, Kameras, Verbindungsaufbau und
                Nachfuehrung noch einmal enthalten -- und beim
                naechsten Umbau saehe eine von beiden anders aus.

WAS HERAUSKOMMT, IST DIE EIGENTLICHE FRAGE

Wer den Schluessel hat, sieht genau das, was ohnehin im Stream
steht: Video, Stand, Sekunde, Titel -- und die Spendenkarten. Kein
Chat, keine Namen von Zusehenden, keine Zahlen ueber das Haus. Die
Pruefung zaehlt die Felder der Auskunft EINZELN auf und weist jedes
verbotene namentlich nach; eine Auskunft, die "ungefaehr das
Richtige" enthaelt, ist bei einem Weg ohne Anmeldung keine.

Ein neuer Schluessel macht die alten Adressen sofort tot -- und
schliesst die laufenden Quellen. Sonst liefe eine mit dem alten
weiter, obwohl er zurueckgezogen ist, und man haelt sich fuer
sicher, ohne es zu sein.

SIE MUESSEN TAGE LAUFEN, OHNE DASS JEMAND HINSIEHT

Das ist der Unterschied zu einer Seite im Browser: Wer eine Seite
offen hat, merkt, wenn sie haengt. Eine Quelle in OBS laeuft im
Hintergrund, und ein Stillstand faellt erst auf, wenn die erste
Spende nicht erscheint -- mitten in der Sendung. Deshalb ein
Lebenszeichen alle 25 Sekunden, eine eigene Wache (70 Sekunden ohne
alles = neu verbinden) und ein sofortiger Neuaufbau, wenn der
Rechner aus dem Ruhezustand kommt.

Und: Ein Fehler wird angezeigt, aber nur der, der etwas bedeutet --
ein falscher Schluessel. Alles andere bleibt still, weil jede
Flaeche hier im Stream zu sehen waere.

ZWEI EIGENE FEHLER, BEIDE VON DER MESSUNG GEFUNDEN

1. Die Quellen kamen mit 401 zurueck, obwohl die Seiten laengst
   geladen waren: `aufgabenRouter` haengt eine Schranke ueber ALLE
   Pfade unter /workspace/api. Genau dafuer stehen `sicherungRouter`
   und der Weg fuers Profilbild schon davor -- die Buehne ist der
   dritte Fall derselben Art und steht jetzt dort.

2. `waitUntil: "networkidle"` auf einer Seite mit Ereignisstrom. Der
   Strom endet absichtlich nie; die Messung wartete auf einen
   Zustand, der nicht eintreten kann, und brach nach 30 Sekunden ab.
   Dieselbe Falle wie am 06.09. beim Regressionslauf.

ZWEI PRUEFUNGEN WURDEN DABEI GENAUER

  `pruef-struktur` verlangte von den zwei OBS-Quellen ein Symbol fuer
  den Startbildschirm, ein Manifest und eine Leistenfarbe. Sie
  laufen in einem Programmfenster und werden nie installiert -- sie
  fallen aus dieser Frage heraus, benannt und mit Grund.

  Die Namensstreit-Regel zaehlte jede Klasse, die irgendwo in einem
  Selektor vorkommt. Damit galt auch
  `body[data-nur="buehne"] .kopfleiste { display: none }` als eigene
  Klasse -- dabei ist das das Gegenteil: eine absichtliche
  Bezugnahme, um sie im Buehnenmodus wegzunehmen. Gezaehlt wird
  jetzt nur, was am ANFANG einer Regel steht, also als eigenes
  Bauteil gemeint ist. Mit Gegenprobe in beide Richtungen -- sonst
  haette ich eine Regel nur so lange geschaerft, bis sie schweigt.

GEMESSEN

  mess-buehne     (neu) Ein Browserfenster OHNE jeden Keks: beide
                  Quellen arbeiten, 0 Kekse, Grund durchsichtig
                  (rgba(0,0,0,0)), Karte laeuft an (25 EUR,
                  Rudel-Legende, 348x178). Falscher Schluessel: kein
                  Inhalt, Grund im Bild. Neuer Schluessel: alter 404,
                  neuer 200. Buehnenmodus: Kopf, Chat, Pult und
                  Schild weg, Leinwand da, Saal 720 von 720.
  pruef-buehne    (neu) 36 Punkte, 0 Fehler
  pruef-reaktion  156 (war 154), spenden 46, haus-trennung 100,
                  haus-seiten 38, struktur 35, css-klassen 33,
                  verborgen 25, rechtetafel 19, portnummern 15,
                  ports 8 -- alle 0 Fehler.
2026-09-28 09:08:42 +02:00
DogFatherGit dcd0298700 Spenden: vier Knoepfe, eine Karte im Bild -- und die Wahrheit ueber PayPal
Filipe: "ich will dass das richtig perfekt gemacht wird so dass die
leute so einfach wie moeglich eine spende aufs paypal machen koennen.
und wenn jemand spendet soll auch der betrag erscheinen mit einem
bild."

WAS GEHT UND WAS NICHT -- NACHGESEHEN, NICHT ANGENOMMEN

Hinterlegt ist ein PayPal.me-Link auf ein PRIVATES Konto. Daraus
folgt zweierlei, und beides bestimmt den ganzen Aufbau:

  ES GEHT: `paypal.me/<name>/5EUR` oeffnet PayPal mit schon
  eingetragenem Betrag. Ein Tipp, fertig. Belegt an PayPals eigener
  Hilfeseite zu PayPal.Me.

  ES GEHT NICHT VON SELBST: PayPal meldet eine Zahlung nur, wenn ein
  Webhook oder IPN eingerichtet ist -- beides braucht Zugangsdaten,
  die nur Filipe selbst anlegen kann. Ob ein PRIVATES Konto das
  ueberhaupt kann, sagt PayPals eigene Doku nicht eindeutig; ich habe
  es gesucht und nicht gefunden, und etwas zu behaupten, das ich
  nicht belegen kann, waere hier das Gefaehrlichste.

DESHALB DREI HERKUENFTE UND NICHT EINE

  "hand"      Filipe sieht die PayPal-Meldung auf dem Handy und tippt
              den Betrag ins Pult. Geht immer, braucht nichts, ist in
              drei Sekunden getan, und die Karte laeuft sofort.
  "gemeldet"  Der Zuschauer sagt nach dem Spenden selbst Bescheid.
              Landet als OFFEN und wird erst gezeigt, wenn die
              Leitung es bestaetigt.
  "paypal"    Kommt automatisch, sobald ein Webhook eingerichtet ist.
              Bis dahin steht dieser Weg leer da -- die Tabelle und
              die Sperre gegen doppelte Zahlungsnummern sind schon
              fertig.

WARUM EINE MELDUNG NICHT SOFORT ERSCHEINT: Sonst tippt irgendwer
"500 Euro" und steht damit gross im Bild. Eine Spende ist eine
Aussage ueber Geld; die gehoert bestaetigt, bevor sie oeffentlich
wird. Der Weg dahin ist EIN Tipp -- billig genug, dass niemand in
Versuchung kommt, ihn abzukuerzen. Beim Bestaetigen darf der Betrag
berichtigt werden: Die Leitung hat die PayPal-Meldung vor sich und
weiss es besser als die Behauptung.

FUER DIE ZUSCHAUER

Vier Betraege im Chat (2, 5, 10, 25 EUR) statt eines Links. Wer eine
Liste sieht, rechnet; wer vier Knoepfe sieht, tippt. Die Adresse wird
NICHT zweimal gepflegt -- sie steht auf der Unterstuetzen-Seite, und
von dort wird sie gelesen. Steht dort nichts oder ist der Weg auf
unsichtbar, gibt es hier auch keine Knoepfe. An einer Adresse, die
kein paypal.me ist, wird kein Betrag angehaengt: Er fuehrte sonst zu
einer Seite, auf der etwas anderes steht als auf dem Knopf.

DIE KARTE

Betrag gross, Name, Gruss, ein Bild dazu -- und eine Farbe, die von
der Stufe kommt. Drei Stufen ab Werk: Danke (ab 1), Starke Runde (ab
5), Rudel-Legende (ab 20), je mit eigener Vorlage, Farbe und Dauer.
Gilt immer die HOECHSTE, die noch passt; mit Ober- UND Untergrenze je
Stufe waere die doppelte Gelegenheit, eine Luecke zu lassen -- durch
die faellt dann ausgerechnet der grosse Betrag.

EINE NACH DER ANDEREN. Drei Spenden in zehn Sekunden sind keine
Seltenheit; uebereinander gelegt waere keine mehr lesbar, und
ausgerechnet die groesste ginge unter. Bei voller Schlange werden die
Zeiten gekuerzt, nicht die Karten weggeworfen -- wer gegeben hat,
soll es sehen.

DIE KARTE IST EIN EIGENES STUECK (spendenkarte.js/.css) und haengt an
nichts aus der Reaction. Dieselbe Karte laeuft spaeter als eigene
Seite fuer OBS und TikTok Studio; zweimal gebaut hiesse, sie sieht
nach der naechsten Aenderung an einem der beiden Orte anders aus --
und man merkt es erst im Livestream.

DER BETRAG STEHT IN CENT

Nie als Kommazahl. 0.1 + 0.2 ist in keiner Programmiersprache 0.3,
und bei Geld faellt das irgendwann jemandem auf -- meistens dem, der
zahlt. Formatiert wird erst auf dem Bildschirm.

DREI EIGENE FEHLER, VON DEN PRUEFUNGEN GEFUNDEN

1. Ein Weg aus einer Verzweigung: `/spenden/${id}/${ja ?
   "bestaetigen" : "ablehnen"}`. `pruef-struktur` hat das zu Recht
   beanstandet -- ein Tippfehler im selteneren Zweig faellt erst auf,
   wenn er mitten in einer Sendung gebraucht wird. Beide Wege stehen
   jetzt ausgeschrieben da.

2. "Genau 5 Register" -- zweimal am selben Tag dieselbe feste Zahl,
   in der Messung UND in der Pruefung. Beim sechsten Register wurden
   beide rot, obwohl nichts kaputt war. Jetzt wird gezaehlt: zu jedem
   Reiter gehoert eine Tafel, und keine steht ohne Reiter da.

3. Die Messung war zu ungeduldig: Die erste Karte laeuft elf
   Sekunden (die hoechste Stufe steht am laengsten), die zweite
   wartet in der Schlange -- richtig so. Die Messung wartete 1,6
   Sekunden und meldete "laeuft nicht". Jetzt wird auf das Merkmal
   gewartet, nicht auf die Uhr.

GEMESSEN

  mess-reaktion   4 Betragsknoepfe mit richtiger Adresse.
                  25 EUR von Hand -> Karte "Rudel-Legende" bei der
                  Zuschauerin. 500 EUR gemeldet -> steht NICHT im
                  Bild, wartet im Pult. Bestaetigt mit berichtigten
                  10 EUR -> Karte "Starke Runde". Stufe passt zum
                  Betrag, beide Male.
  pruef-spenden   46 Punkte, 0 Fehler (neu) -- darunter die
                  Gegenprobe, dass ohne Zahlungsnummer beliebig viele
                  Zeilen nebeneinander stehen duerfen (sonst liesse
                  sich nur EINE Spende von Hand eintragen).
  pruef-reaktion  154, unterstuetzung 70, aufbewahrung 45,
                  struktur 35, css-klassen 33, portnummern 15,
                  tippziele 11, ports 8, meldungen 8 -- alle 0 Fehler.

SCHEMA: zwei Tabellen (spenden, spenden_stufen) mit einem
Einmalig-Index auf die Zahlungsnummer. Auf einer Kopie der echten
Datenbank durchgespielt: 20 Personen, 227 Chatnachrichten, keine
Tabelle verliert eine Spalte.
2026-09-28 08:34:42 +02:00
DogFatherGit 5d89d108f9 Die Reaction: zusammen schauen, live, mit Kamera und Chat
Filipes Kurznotiz vom 28.09.2026, von links nach rechts:

    Kachel sichtbar -> geschlossen -> Vorbereitung -> Wartebereich/
    Chat -> Countdown -> LIVE -> Reaction + Gaeste + Chat + PayPal
    -> Ende

DREI STAENDE, NICHT SIEBEN

„Wartebereich" und „Countdown" sind keine eigenen Zustaende, sondern
das, was „Vorbereitung" auf dem Bildschirm TUT. Drei Staende, die
sich gegenseitig ausschliessen, sind pruefbar; sieben, von denen sich
vier ueberlappen, sind es nicht.

DAS VIDEO LAEUFT NICHT UEBER DIESEN SERVER

Naheliegend waere: Der Host spielt ab, alle sehen seinen Bildschirm.
Das waere aus zwei Gruenden falsch. Rechtlich ist ein
weitergesendetes YouTube-Video eine oeffentliche Wiedergabe -- genau
die Sache, fuer die Kanaele gesperrt werden. Und technisch kostet es
Bandbreite und Qualitaet.

Jeder Zuschauer laedt das Video deshalb SELBST. Uebertragen wird nur
der Spielstand: Kennung, laeuft/pausiert, Sekunde. Das sind ein paar
Byte, jeder sieht es in voller Qualitaet, und alle sind auf derselben
Sekunde. Nachgefuehrt wird erst ab anderthalb Sekunden Abweichung --
ein Player, dem man jede Sekunde eine neue Position gibt, ruckelt
sichtbar.

DIE KAMERAS LAUFEN DIREKT VON MENSCH ZU MENSCH

Ueber denselben Weg wie die Anrufe im Haus (seit 18.09.), nur mit
mehr Empfaengern. Das hat eine Grenze, und sie ist gerechnet, nicht
geraten: Bei 360p und rund 350 kbit/s sind zwoelf Zuschauer etwa
4 Mbit/s Upload beim Host. Darueber schaltet die Sendung von selbst
auf Ton um -- wer keine Kamera mehr bekommt, hoert alles, sieht das
Video und kann schreiben. Ehrlicher als eine Verbindung, die stockt,
und sichtbar im Regiepult.

Heute sind es elf Menschen im ganzen Haus (gemessen: 1 admin, 1 hand,
1 linke, 4 modi, 4 gast). Die Grenze ist weit weg -- sie steht
trotzdem drin, weil sie sonst erst auffaellt, wenn es zu spaet ist.

DIE SEITE IST ANDERS GEBAUT ALS JEDE ANDERE IM HAUS

Ueberall sonst: Kacheln, Karten, Listen -- man liest, entscheidet,
geht wieder. Hier sitzt man. Eine Stunde, mit anderen, auf EINE
Sache schauend. Deshalb kein Raster, sondern ein SAAL: grosse Flaeche
fuer das Video, Kamerabilder als schwebende Fenster darueber, der
Chat als Schiene daneben. Die Seite scrollt nicht -- ein Video, das
beim Tippen im Chat nach oben rutscht, ist der schnellste Weg, dass
jemand aufhoert zu schreiben.

Fuer den Host ein REGIEPULT: vier senkrechte Regler nebeneinander wie
an einem Mischpult, darueber die Sendung, daneben Gaeste und
Anordnung, unten drei grosse Knoepfe. Es SCHIEBT den Saal, es deckt
ihn nicht zu.

Die Kachel traegt ihren Zustand als Farbe: grau geschlossen,
bernstein in Vorbereitung, rot auf Sendung. Keine Ton-Nummer -- der
Farbraum ist bei 46 voll, und sie braucht auch keine.

PAYPAL: EINE QUELLE

Der Knopf nimmt den Weg, der auf der Unterstuetzen-Seite hinterlegt
ist -- derselbe Eintrag, dieselbe Pflege. Ist dort nichts eingetragen
oder steht er auf unsichtbar, erscheint hier kein Knopf. Eine
geratene Adresse ist an dieser Stelle die gefaehrlichste aller
Abkuerzungen.

=======================================================================
ACHT FEHLER, DIE OHNE MESSUNG LIVE GEGANGEN WAEREN
=======================================================================

1. `data-live` WAR SCHON VERGEBEN. Die Draussen-Kachel bekommt es,
   sobald Filipe auf Twitch sendet. Meine Regel haette ihr waehrend
   jedes Streams die Farbe genommen -- genau dann, wenn sie wichtig
   ist. Heisst jetzt `data-sendung`, und pruef-reaktion haelt beides
   auseinander.

2. DIE INHALTSRICHTLINIE HAETTE YOUTUBE LAUTLOS GESPERRT. Die Datei
   warnt an genau dieser Stelle selbst davor: Am 27.08.2026 hat
   `frame-src 'none'` den Musik-Knopf stillgelegt -- der Knopf
   reagierte, das Feld ging auf, und wo die Player sein sollten,
   blieb es leer. Hier waere das Ergebnis eine schwarze Leinwand vor
   Publikum gewesen. youtube-nocookie.com fuer den Rahmen (setzt keine
   Werbekennungen), www.youtube.com fuer die Einbett-API,
   i.ytimg.com fuer die Vorschaubilder.

3. KAMERA UND MIKROFON WAREN GESPERRT. Dieselbe Falle, vor der
   index.js selbst warnt -- und die am 18.09. schon einmal zugeschlagen
   hat. Die Ausnahme ist jetzt eine benannte MENGE statt eines zweiten
   Sonderfalls, und pruef-kamera-richtlinie.mjs haelt sie GEGEN DEN
   QUELLTEXT: Welche Seite laedt ein Skript, das getUserMedia
   aufruft? Genau die muss drinstehen -- und keine andere. Eine
   Liste, die abgeleitet wird, kann nicht veralten.

4. ZWEI ANRUFE AN DIESELBE PERSON. Zwischen `await kameraHolen()` und
   dem Anlegen der Verbindung laeuft alles andere weiter; jeder Takt
   sagte wieder „den kenne ich noch nicht". Der Empfaenger antwortete
   auf beide Angebote, und die zweite Antwort traf eine Verbindung,
   die laengst stand.

5. DAS ANGEBOT GING HINAUS, BEVOR DER EMPFAENGER ZUHOEREN KONNTE.
   Gemessen:

       [spur] an [3] reaktion_signal | offen: [2,1]
       ...
       [spur] Strom auf fuer 3 Lenny

   Die Anmeldung ist ein gewoehnlicher Abruf und sofort durch, der
   Ereignisstrom eine stehende Verbindung. Der Host erfaehrt vom
   Neuankoemmling also zuverlaessig, BEVOR der zuhoeren kann.
   Die Richtung ist jetzt umgedreht: Wer bereit ist, BITTET um den
   Anruf -- er ist der Einzige, der das sicher weiss. Dazu ein
   eigener, schneller Takt (2,5 s) und eine Ruecknahme, wenn ein
   Angebot bei niemandem ankommt.

6. EIN VIDEO MIT TON STARTET NICHT VON ALLEIN. `videoWidth` war 640,
   das Bild kam also an -- und das Fenster blieb schwarz. Kein
   Fehler, keine Meldung, es passiert einfach nichts. Die Kameras
   starten jetzt stumm (stumm darf losgehen), ein Knopf schaltet den
   Ton frei, und die erste Beruehrung der Seite tut es ohnehin.

7. DIE LADE AM HANDY GING NICHT AUF. Gemessen: ein 390x775 grosser
   Saal mit 219 px Video und 556 px Leere darunter. Statt den Knopf
   zu reparieren, ist die Lade weg -- unter Kopfleiste und Video
   bleiben auf einem Telefon rund 550 px, das ist mehr Chat, als eine
   Lade je zeigen wuerde. Ein Zustand weniger ist besser als ein
   Zustand, der funktioniert.

8. `sendBeacon` KANN NUR POST. Beim Schliessen des Fensters wird ein
   gewoehnlicher Abruf abgebrochen; mein DELETE waere nie angekommen,
   und jeder haette zwei Minuten lang als anwesend gegolten.

Dazu drei Funde der Hauspruefungen, alle von mir verursacht:
17 Schriftgroessen unter der Lesbarkeitsgrenze von 11,5 px, elf
Maschinenworte ohne deutschen Satz, und ein Aufbewahrungseintrag ohne
Rechtsgrundlage.

=======================================================================

GEMESSEN

pruef-reaktion            74 Punkte, 0 Fehler (11 Abschnitte)
pruef-kamera-richtlinie   10 Punkte, 0 Fehler (neu, abgeleitet)
mess-reaktion             beide Kameras kommen an, 640 px, laufen --
                          beim Zuschauer UND beim Host. Diese Messung
                          hat einen Rueckgabewert: Alles andere kann
                          gruen sein, und trotzdem sitzt jeder vor
                          einem schwarzen Rechteck.
pruef-handy               180 (vorher 177), pruef-notizen 79,
pruef-aufbewahrung        45, pruef-meldungen 8, pruef-css-klassen 33,
pruef-struktur            35, pruef-crew-adresse 161,
pruef-haus-trennung       100, pruef-start-ansicht 160 -- alle 0 Fehler.
2026-09-28 01:52:22 +02:00
DogFatherGitandClaude Opus 5 150555bc33 Der Notizblock -- und eine Pruefung, die zwoelf Kacheln nie angesehen hat
Filipe: „fuer die modis, rechte und linke hand und dogfather eine
kachel hinzufuegst, sie soll: Notizen, heissen. ich will dass du das
auch wie ein notizblock erstellst. ich will dass es uebelst geil und
einzigartig ist."

=================================================================
TEIL 1: DIE FARBE -- UND WAS DABEI AUFFIEL
=================================================================

Fuer die neue Kachel braucht es einen Ton. Beim Suchen fiel auf, dass
tools/kachelton-entzerren.mjs zwoelf der 45 Farben fuer FREI hielt.

Sie sind es nicht. bereicheFuer() gibt fuer die fuenf Rollen des
Agenturhauses null zurueck -- das heisst „nimm die Liste aus dem
Browser", und die steht in workspace/assets/js/bereiche.js. Dort
stehen die Toene 1 bis 22 und 44: Dashboard, Zahlen, Team-Lage,
Scout-Pipeline. Kacheln, die jeden Tag jemand ansieht.

pruef-kachelfarben hatte denselben blinden Fleck. Sie meldete seit
Wochen „33 benutzte Toene" und war gruen. Was sie dadurch NICHT sah:

  * Der Farblauf von gestern Nacht hat zwoelf dieser Kacheln
    verschoben und drei davon unter die Buntheitsgrenze gedrueckt.
    Gruen geblieben.
  * Ton 7, 16 und 22 lagen SEIT JEHER unter der Grenze (0,112 / 0,116
    / 0,068). Nie gemeldet.

Das ist die Sorte gruener Haken, vor der die Hausregel warnt: Er sagt
nur, dass die Bedingung erfuellt war -- nicht, dass sie das Richtige
angesehen hat.

BEHOBEN, und zwar an der Wurzel: Die REGELN (Kontrast, Buntheit)
gelten jetzt fuer jeden Ton, der irgendwo an einer Kachel steht --
gelesen aus denselben fuenf Dateien, die auch pruef-kachel-universum
liest. Dazu die Namen der Kacheln, damit „Ton 1 traegt Dashboard"
ueberhaupt pruefbar ist.

DIE PALETTE WURDE NEU GERECHNET, mit dem dritten Verfahren an einem
Tag -- die ersten zwei stehen als Fehler im Kopf des Werkzeugs:

  1. Alle 45 neu verteilt. Lief ueber zwei ausdrueckliche Wuensche
     hinweg (#ff1a1a, #a8d8ff).
  2. Nur die Kollisionen, aber immer nur EINEN der beiden bewegt.
     Ergebnis: Ton 1 sprang vom Tuerkis ins Altrosa, 0,197 weit.
  3. BEIDE duerfen sich bewegen, und zwar beide nur ein bisschen.
     Zwei Toene, die 0,02 auseinanderstehen und 0,09 brauchen, teilen
     sich das -- jeder rueckt 0,045, und beide bleiben, was sie waren.

  kleinster Abstand   0,0154  ->  0,0905
  zu blass                 4  ->  0
  sichtbar veraendert           7 Kacheln (ueber 0,05)
  kaum zu sehen                28 (13 zwischen 0,02 und 0,05, 15 darunter)

EINE AUSNAHME MIT ZAHL, keine mit Achselzucken: Ton 1 (Dashboard)
bleibt acht Tausendstel unter der Buntheitsgrenze. Gemessen ueber ALLE
16,7 Millionen sRGB-Farben ist die naechste, die alle Regeln haelt,
#7a75c8 -- ein Blauviolett, 0,113 entfernt. Tuerkis erreicht in sRGB
schlicht keine hoehere Buntheit, und das schmale Band teilen sich
schon sieben Toene. Eine Kachel, die ihre Farbfamilie behaelt, ist die
bessere Antwort auf „richtig geil und speziell" als eine, die acht
Tausendstel bunter ist und niemand wiedererkennt. blassBis sagt jetzt
bei jeder Ausnahme, WIE WEIT sie reicht -- vorher hiess blassErlaubt
schlicht „hier wird weggesehen".

DIE NEUE FARBE IST GRUEN UND WOLLTE BERNSTEIN SEIN. Gesucht war die
Farbe von Papier. Gemessen gibt es sie nicht mehr: Der beste Bernstein
im ganzen Farbraum haelt 0,0799 Abstand -- unter der Hausgrenze. Und
Platz schaffen hilft nicht: Setzt man ihn fest, muss ein warmer Ton
das Band verlassen (Ton 45 waere 0,212 weit ins Magenta gewandert).
Die groesste wirklich freie Luecke liegt im Gruen, bei 0,0917. Ein
linierter Block in Gruen ist Papier, seit es Papier gibt.

=================================================================
TEIL 2: DER BLOCK
=================================================================

DREI ENTSCHEIDUNGEN, AUS DENEN DER REST FOLGT:

1. ES GIBT KEINEN SPEICHERN-KNOPF. Nirgends. Wer einen Block
   aufschlaegt und lostippt, drueckt hinterher nicht auf „sichern";
   er klappt ihn zu. Gesichert wird 800 ms nach dem letzten
   Tastendruck. Geht das nicht, bleibt der Text im Browser liegen und
   wird nachgereicht -- und der Fuss sagt ehrlich „noch nicht
   gesichert", statt einen Verlust zu melden, den man gerade nicht
   verhindern kann.

2. DAS BLATT IST EIN SCHREIBFELD MIT EINER DECKSCHICHT. Das Feld
   traegt Text und Cursor und ist unsichtbar; darueber zeichnet eine
   zweite Schicht denselben Text noch einmal -- mit Kaestchen,
   Ueberschriften, Strichen und Links.

   DARAUS FOLGT EINE EISERNE REGEL, und sie steht dreimal im Code:
   KEINE Auszeichnung darf die BREITE eines Zeichens aendern. Kein
   Fettdruck, keine andere Groesse, keine Sperrung. Erlaubt sind nur
   Farbe, Flaeche, Rahmen und Durchstreichen. Ein einziges
   font-weight: 700 verschoebe den Umbruch, und ab der zweiten Zeile
   stuende der sichtbare Text neben dem Cursor.

   pruef-notizen misst das am echten Umbruch: eine Probe mit allen
   Auszeichnungen und einer Zeile, die umbrechen MUSS. Sind beide
   Schichten verschieden hoch, sitzt der Umbruch woanders. Mit
   Gegenprobe -- Fettdruck auf der Deckschicht bricht die Deckung um
   genau eine Zeile (30 px), und die Zeile wird rot.

3. DIE TASTATUR FUEHRT DIE LISTE FORT, NICHT EINE LEISTE. Ein
   Spiegelstrich und Enter macht den naechsten Punkt, ein leeres
   Kaestchen und Enter das naechste Kaestchen -- und ein GESETZTER
   Haken wird dabei nicht mitgenommen, die naechste Aufgabe ist ja
   noch nicht erledigt. Zweimal Enter beendet die Liste. Ein Klick
   aufs Kaestchen hakt ab. Es gibt keine Werkzeugleiste, weil man beim
   Schreiben nie den Stift wechselt.

UND: NIEMAND SIEHT DIE NOTIZEN EINES ANDEREN. Auch DogFather nicht.
Es gibt in workspace-notizen.js keinen siehtAlles()-Zweig, keinen
Umschalter, keine fremde Liste -- jede Abfrage hat person_id = ? fest
eingebaut. Die Kachel steht deshalb in „Fuer dich" und nicht in
„Taeglich": Die Gruppe sagt die wichtigste Eigenschaft, bevor man sie
anfasst.

NUR AUF DER TEAM-ADRESSE. Auf der Agenturadresse ist die Seite ein
404 -- auch fuer DogFather. Das ist dieselbe Trennung wie bei Chat,
Kalender und Aufgaben, und sie steht an zwei Stellen: in
GEHOERT_ZU_ADRESSE (die Datei) und in der Schnittstelle (die Daten).
Die Seite ist nur HTML; die Daten sind die Sache.

Dazu: sechs Papierfarben, Anheften, Suche mit Hervorhebung im Text,
Papierkorb mit dreissig Tagen und einem Eintrag in der
Aufbewahrungsliste (ohne den waere die Frist ein Satz in einem
Kommentar -- genau das ist dem Support am 24.09. passiert).

=================================================================
EIN FUND BEIM BAUEN, DER ALLEN GEHOERT
=================================================================

DELETE /workspace/api/notizen/:id gab es schon -- in
workspace-aufgaben.js, fuer die Notizen AN einer Aufgabe. Weil jener
Router frueher eingehaengt ist, hat er jeden Loeschversuch des Blocks
abgefangen und mit 404 beantwortet.

Von aussen sah das aus wie ein Fehler im neuen Modul: Anlegen ging,
Aendern ging, Loeschen nicht. Man sucht dann im eigenen Code, und dort
ist nichts. Express meldet so etwas nicht -- es nimmt die erste Route,
die passt, und schweigt ueber die zweite.

Der Block liegt jetzt unter /workspace/api/notizblock. Und
pruef-notizen geht seitdem den Routenbaum von express durch und meldet
jedes Paar aus Methode und Pfad, das zweimal vergeben ist. Gemessen:
307 Wege, keine Dublette. Die Pruefung gilt fuers ganze Haus, auch
wenn sie in dieser Datei steht -- hier ist sie gefunden worden.

Nebenbei berichtigt: pruef-crew-adresse verlangte von jedem Eintrag
der Haustafel HTTP 200 mit Inhalt. Das stimmte, solange dort nur
oeffentliche Dateien standen. notizen.html ist die erste Seite hinter
der Anmeldung -- sie antwortet mit 302, und das ist richtig. Gefragt
wird jetzt, was die Tafel wirklich meint: GIBT es das hier.

GEMESSEN, alles nach den Aenderungen:

  pruef-notizen             76 Punkte, 0 Fehler (neu)
  pruef-kachelfarben        31 Punkte, 0 Fehler (vorher 26)
  pruef-kachel-universum    13 Punkte, 0 Fehler
  pruef-crew-adresse       157 Punkte, 0 Fehler
  pruef-buehne             230 Punkte, 0 Fehler -- notizen.html neu in
                           der Liste, schlechtester Kontrast 6,73:1,
                           also 50 % ueber der Grenze
  pruef-rechtetafel, -haus-seiten, -struktur, -css-klassen,
  -jeder-hat-eine-seite, -workspace-seiten, -kachelraster,
  -rueckmeldung            alle 0 Fehler

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-26 12:42:59 +02:00
DogFatherGitandClaude Opus 5 aa2e1a4ae2 Eine Kachel "Unterstuetzen" -- und die Gespraechsliste neu gebaut
=== 1. UNTERSTUETZEN (neue Kachel im Community-Bereich) ===

Filipe: "ich brauch auch noch eine kachel im community bereich. wo mein
paypal und meine amazon liste sein wird. wo die leute alle supporten
koennen auf andere art anstatt nur tiktok. jeder soll diese kachel sehen
aber nur dogfather soll sie veraendern koennen oder vieles mehr sehen."

Neu: unterstuetzen.html + css + js, server/workspace-unterstuetzung.js,
server/unterstuetzung-tabellen.js. Ton 45 (#7567fe) ist gerechnet, das
Kachelzeichen ist ein Herz ueber zwei offenen Haenden.

DIE WEGE STEHEN IN DER DATENBANK, nicht im Quelltext -- ein Recht, das
man nur ueber einen Entwickler ausueben kann, ist keines. DogFather
schreibt Titel, Text, Knopf und Adresse selbst, blendet Wege aus und
nimmt neue dazu.

DER PAYPAL-LINK STEHT LEER UND UNSICHTBAR DA. Filipe schrieb "mein
paypal kennst du ja schon" -- gesucht im ganzen Haus und im Vault,
nirgends gefunden. Eine Zahlungsadresse zu RATEN waere der
gefaehrlichste Fehler dieser Seite: Geld an einen Fremden, und niemand
merkt es. Also steht dort nichts, der Weg ist ausgeblendet, und die
Seite sagt genau EINER Person, dass er fehlt.

DREI ARTEN, UND DIE DRITTE IST DIE WICHTIGSTE: geld, geschenk, frei.
"Kostet nichts" bekommt dieselbe Kartenform und dieselbe Groesse.
Waeren die freien Wege kleiner oder weiter unten, waere die Aussage
"das ist zweite Wahl" -- und die Mehrheit derer, die hier lesen, waere
damit zweite Wahl.

DIE ZAEHLUNG IST ANONYM, UND ZWAR VON DER TABELLE HER. DogFather sieht,
wie oft ein Weg geoeffnet wurde (7/30 Tage/gesamt). Was er NICHT sieht,
ist WER -- weil es in unterstuetzung_striche keine Spalte dafuer gibt.
Geprueft wird das ueber PRAGMA table_info, nicht ueber eine Abfrage:
eine Abfrage liesse sich morgen erweitern, eine fehlende Spalte nicht.

Schreiben haengt an istDogFather, nicht an istLeitung -- die rechte Hand
fuehrt dieses Team mit und kommt trotzdem nicht an diesen Link. Jede
Adresse wird beim SCHREIBEN geprueft (nur https:// oder eine Seite
dieses Hauses); javascript:, data:, http:// und // werden abgewiesen.

Neu: server/pruef-unterstuetzung.mjs -- 70 Pruefungen, alle gruen.
Sie misst ueber die CREW-ADRESSE: Beim ersten Lauf waren vier Rollen
gruen und der Zuschauer rot, und es sah nach einem Rechtefehler aus.
Es war ein Messfehler -- ueber 127.0.0.1 landet man still im
Agenturhaus, und dort gibt es die Rolle "gast" gar nicht.

=== 2. DIE GESPRAECHSLISTE (screen1 + screen2) ===

Filipe: "ich will dass die komplette kachel viel krasser und geiler
aussieht. der hintergrund der kachel soll gleich bleiben."

Der Hintergrund ist unangetastet. Zwei echte Fehler auf seinem Bild:

  - Bei "Das Rudel" stand das "@" rechts oben und die orange "6" eine
    ZEILE TIEFER. Der Knopf ist ein Raster mit DREI Spalten und bekam
    VIER Kinder -- das vierte fiel um. Ausgerechnet die wichtigste
    Auskunft der Liste landete an der unauffaelligsten Stelle.
  - Jedes Gespraech mit Profilbild haengte das Bild ZWEIMAL ein: ein
    Block stand Zeichen fuer Zeichen doppelt da. Zu sehen war nichts,
    gekostet hat es die doppelte Ladelast bei jedem Neuzeichnen.

Und eine tote Regel: `.chat-raum__knopf[data-an="ja"]` beschrieb die
Schiene am offenen Gespraech -- gesetzt wird aber `data-offen` am <li>.
Die Regel griff nie, und daneben stand eine zweite, blassere Fassung
derselben Sache. Jetzt steht alles einmal, und die Schiene ist da.

Dazu: Zeilen als Karten, 44px-Gesichter, ein Zaehler neben "Gespraeche",
Suchfeld als Pille mit Lupe, runder Farbfleck statt Quadrat, und der
leere Raum rechts bekommt eine Mitte statt eines Satzes in der Ecke.

=== 3. VIER FUNDE NEBENBEI ===

  - supportAufraeumen() war exportiert und wurde NIRGENDS gerufen. Die
    Meldungen samt Bildschirmfotos waeren fuer immer liegen geblieben,
    obwohl "90 Tage" dokumentiert ist. Jetzt im Loeschkonzept.
  - aufgaben_zuteilung fehlte ebenfalls im Loeschkonzept (seit 21.09.).
    pruef-aufbewahrung ist damit wieder gruen.
  - pruef-start-ansicht war rot, seit "Aufgaben" am 23.09. die silberne
    Kachel bekam -- die ueberschreibt ihr --ton absichtlich. Die
    Pruefung nimmt sie jetzt aus UND prueft die Ausnahme selbst.
  - pruef-buehne meldete auf entwicklung.html 1,79:1 Kontrast bei "Wen
    gehst du durch?" -- die Ueberschrift lag direkt auf dem Foto. Sie
    steht jetzt auf einer deckenden Flaeche.

OFFEN: pruef-buehne meldet treff-regeln.html mal "0 von 40", mal "3 von
40" -- dieselbe Seite, verschiedene Antworten. Eine Pruefung, die
schwankt, ist schlimmer als eine rote. Nicht in diesem Zug behoben.

Gemessen: pruef-unterstuetzung 70, pruef-start-ansicht, pruef-buehne
(bis auf den Wackler), pruef-workspace-seiten, pruef-aufbewahrung 45,
pruef-rechtetafel 19, pruef-css-klassen, pruef-chatkachel 36,
pruef-chat-ausbau, pruef-entwicklung-kacheln 31 -- gruen.

Neu: server/mess-chat-liste.mjs (zeigt die Liste mit sieben Gespraechen
verschiedener Art, prueft nichts).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-24 14:14:25 +02:00
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 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 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
DogFatherGitandClaude Opus 5 25b5cf6224 "Unveraenderlich" stand auch auf Adressen, die sich aendern
Beim Nachmessen der Crew-Sperre von vorhin: Der Ursprung lieferte
korrekt 404 und eine bereinigte gate.css -- Cloudflare lieferte
weiterhin die ALTE Fassung, 27 806 Byte, `cf-cache-status: HIT`.

DIE URSACHE STAND IM EIGENEN KOMMENTAR. In index.js hiess es:
"`originalUrl` steht hier nicht zur Verfuegung -- geprueft wird
deshalb die Dateiart." Nachgemessen stimmt das nicht: `res.req
.originalUrl` ist da und liefert "/start.html?v=123". Die Annahme war
nie geprueft worden, und aus ihr folgte eine Zusage, die das Haus
nicht halten kann: JEDE CSS- und JS-Datei ging mit
`max-age=31536000, immutable` hinaus -- auch unter ihrer Adresse OHNE
Stempel.

"immutable" heisst woertlich: Der Inhalt unter DIESER Adresse aendert
sich nie. Fuer `gate.css?v=...` stimmt das, der Name wechselt ja mit
dem Inhalt. Fuer `gate.css` ist es falsch -- und dort haette die alte
Fassung ein Jahr im Zwischenspeicher gelegen, waehrend der Server
laengst etwas anderes sagt. Ein Zwischenspeicher, der etwas Falsches
zeigt, ist schlimmer als gar keiner: man glaubt ihm.

Jetzt haengt die Zusage an der Bedingung, die sie traegt. Mit Stempel
bleibt alles wie bisher -- die Seiten rufen ohnehin immer `?v=...`
auf, dort kostet es nichts. Ohne Stempel wird nachgefragt. Die
oeffentliche Seite benutzt ebenfalls `?v=` (mit Buchstabe am Ende);
geprueft wird nur, OB einer da ist, nicht wie er aussieht.

DIESELBE SORTE FEHLER GLEICH NEBENAN: pruef-zwischenspeicher hat einen
Abschnitt "Was einen Stempel traegt, darf liegenbleiben" -- und rief
die Dateien OHNE Stempel ab. Auch hier beschrieb der Text etwas, das
der Code nicht tat. Er liest den Stempel jetzt aus der Seite und misst
damit genau die Adresse, die ein Browser anfordert. Dazu vier neue
Zeilen fuer den umgekehrten Fall, mit Gegenprobe an derselben Datei --
sonst waere "ohne Stempel: no-cache" auch dann gruen, wenn ALLES auf
no-cache stuende, und jeder Seitenaufruf waere unnoetig langsam.

UND MEIN EIGENER FEHLER VON GESTERN, behoben: Die Stempelpruefung
verglich seit dem 20.09. den Stempel mit dem ZEITPUNKT des letzten
Commits an assets/. Das kann gar nicht aufgehen -- der Stempel wird
immer VOR dem Committen gezogen, die Commit-Zeit ist also immer die
juengere. Stempeln um 12:59 und Committen um 13:00 genuegte fuer einen
Fehlalarm; heute ist genau das passiert.

Gefragt wird jetzt die REIHENFOLGE der Commits, die hat keine Uhr:
Liegt der letzte Commit an den HTML-Seiten (dort steht der Stempel)
auf oder nach dem letzten an assets/? `merge-base --is-ancestor`
beantwortet das ohne Zeitstempel. Mit Gegenprobe ueber das Elternteil
-- und mit drittem Ausgang, wenn es keines gibt.

pruef-zwischenspeicher: 27 Pruefungen, 0 Fehler (war 22, davon 2 rot)

NOCH OFFEN und nur von Filipe zu machen: Cloudflare haelt die alten
Fassungen unter den stempellosen Adressen weiter im Zwischenspeicher.
Der Ursprung ist sauber; geleert werden muss der Rand einmal von Hand.

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

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

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

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

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

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

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

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

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

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

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

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

Die Farben bleiben, ihre ZUTEILUNG aendert sich:

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

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

=== 2. TELEFONIEREN IM CHAT ===

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

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

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

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

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

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

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

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

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

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-18 10:10:04 +02:00
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 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 d4730deb30 Wie geht's dir? bekommt eine eigene Seite
Filipe, zum Bildschirmfoto der Kachel: "ich will dass du diese seite
perfektionnierst den gerade wenn ich drauf druecke geht die
entwicklungsseite auf."

Der Fehler war schlimmer als ein falscher Verweis. Auf der Kachel
steht "die Antworten sieht nur du" -- und sie oeffnete eine Seite
voller Namen und Beobachtungen ueber ANDERE Menschen. Wer ihr glaubt
und drauftippt, sieht im ersten Moment das Gegenteil dessen, was
draufsteht.

Jetzt: eine Seite, ein Zweck.

  workspace/befinden.html + assets/js/befinden.js   die eigene Seite
  server/workspace-befinden.js                      Rhythmus + Verlauf
  entwicklung.html                                  nur noch ein Verweis

Was die Recherche zu Puls-Abfragen ergeben hat (Quellen im Kopf des
Moduls): kurz halten (fuenf bis fuenfzehn Fragen -- sechs bleiben
sechs), WIEDERHOLEN (zweiwoechentlich), und der VERLAUF ist die
Auskunft, nicht der Einzelwert. Bisher beantwortete man die sechs
Fragen einmal, und die Antwort stand fuer immer -- ein Befinden von
vor drei Monaten ist keine Auskunft mehr, sondern ein Andenken.

Der Verlauf gehoert ihr allein: eigene Tabelle, kein von_id, kein
anderer Weg im Haus liest sie. Im Protokoll steht nur, DASS eine
Runde war, nie was darin stand. Die Ampel zaehlt weiterhin nur den
aktuellen Stand und kennt keine Namen.

Zwei Dinge, die erst die Pruefung gefunden hat:

  - Wer die neue Seite oeffnete, ohne dass vorher jemand die
    Entwicklungsseite besucht hatte, bekam "no such table" und eine
    503. entwicklung_stand wird beim ersten Aufruf angelegt, nicht
    beim Start. Die Tabelle wird jetzt angefordert, nicht ein zweites
    Mal abgeschrieben.
  - pruef-entwicklung suchte die Kachel ueber ziel ===
    "entwicklung.html" und hat den gemeldeten Fehler damit
    mitgetragen. Sie sucht jetzt die eigene Seite -- und prueft
    zusaetzlich, dass keine Kachel mehr ersatzweise dorthin fuehrt.

Ausserdem weg: die tote Funktion meins() in entwicklung.js (sie
zeichnete in drei Stellen, die es nicht mehr gibt) und der Titel
"Wie geht's dir?", den diese Seite fuer einen Modi trug -- er
versprach etwas anderes als die Seite zeigt, also derselbe Fehler
wie an der Kachel.

  server/pruef-befinden.mjs   48 Pruefungen, 0 Fehler (Port 4419)
  pruef-entwicklung           43 (vorher 40), 0 Fehler
  pruef-nachwuchs 123, pruef-rechtetafel 19, pruef-rechte-umstellen 46,
  pruef-css-klassen -- alle 0 Fehler

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 13:45:56 +02:00
DogFatherGitandClaude Opus 5 d2210fdd77 Der Erklaerkasten auf jeder Seite ist weg
Filipe, mit dem Kasten im Bild: "das muss sofort weg. ueberall das ist
scheisse."

Entfernt, nicht ausgeblendet:
  - workspace/assets/js/erklaerung.js
  - server/workspace-erklaerung.js samt Router-Einbindung in index.js
  - server/pruef-erklaerung.mjs
  - der Stilblock in start.css
  - die Skript-Zeile auf allen 25 Seiten

AUSGEBLENDET WAERE KEIN ENTFERNEN. Der Weg haette weiter geantwortet,
das Skript waere weiter geladen worden, und beim naechsten Umbau waere
der Kasten irgendwo wieder aufgetaucht. Was weg soll, wird weggenommen.

NACHGEMESSEN STATT ANGENOMMEN:
  - kein Verweis auf die geloeschten Dateien mehr im Repo,
  - der Server startet ohne Fehler (frische Datenbank, Protokoll leer),
  - keine Reste (erkl__, erklaerung.js) in Seiten oder Stilvorlagen.

Vier andere Pruefungen nennen ebenfalls "Erklaerung" -- sie meinen
ANDERE: den Satz im Neu-Fenster des Chats, die Stufen-Seite, die
Rollenkarten. Die bleiben unberuehrt; nachgesehen, nicht vermutet.

pruef-workspace-seiten, pruef-css-klassen und pruef-lesbarkeit laufen
gruen. Die Zahl der Pruefungen sinkt um die der geloeschten Datei --
das ist hier richtig: Sie prueften etwas, das es nicht mehr gibt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 12:52:13 +02:00
DogFatherGitandClaude Opus 5 d76d9aa5da Aus einer Idee wird Arbeit -- mit einem Knopf statt mit Abtippen
Stufe 9 aus dem Plan zur Perfektion: "Idee -> Aufgabe/Termin".

WARUM DAS MEHR IST ALS EINE BEQUEMLICHKEIT

Das ganze Haus steht auf einem Satz: "Was hier nicht steht, passiert
nicht." Ein Ideenbrett, aus dem keine Aufgabe werden kann, ist der eine
Ort, an dem dieser Satz nicht gilt -- dort steht etwas, und passieren
tut es trotzdem nicht. Wer eine Idee umsetzen wollte, tippte sie ein
zweites Mal ab. Und was man abtippt, tippt man irgendwann nicht mehr ab.

DREI ENTSCHEIDUNGEN

  GENAU EINMAL. Ein zweiter Versuch fuehrt nicht zu einer zweiten
  Aufgabe, sondern zum Verweis auf die vorhandene (409). Gefragt wird
  an der AUFGABE, nicht an der Idee: Dort steht die Tatsache, und sie
  kann nicht auseinanderlaufen.

  DIE IDEE BLEIBT STEHEN. Sie wird nicht verschoben und nicht geloescht
  -- wer nachsieht, was aus einem Gedanken geworden ist, soll den
  Gedanken noch finden, und daneben die Antwort.

  DIE AUFGABE WEISS, WOHER SIE KAM. `aus_eintrag_id` mit echtem
  Fremdschluessel, nicht als Text im Beschreibungsfeld. Ein Verweis, den
  nur ein Mensch lesen kann, ist kein Verweis. ON DELETE SET NULL, nicht
  CASCADE: Wird die Idee geloescht, bleibt die Arbeit.

NICHT AUS JEDEM BRETT

Aus einem Beitrag im Treff wird keine Aufgabe. Was jemand aus der
Community schreibt, gehoert ihm; daraus stillschweigend Arbeit zu
machen waere eine Verwendung, mit der er nicht rechnet. Welche Bretter
es sind, entscheidet der Server -- die Oberflaeche fragt nach, statt
eine zweite Liste zu fuehren.

WAS ABSICHTLICH NICHT MITWANDERT: die Frist. Eine Idee hat keinen
Termin; wer ihr beim Uebernehmen automatisch einen gaebe, erfaende ihn.
Die Dringlichkeit wandert dagegen mit -- dieselben drei Stufen.

ZUSTAENDIG IST, WER UEBERNIMMT, nicht wer die Idee aufgeschrieben hat.
Eine Aufgabe, die jemandem ohne sein Zutun zugeteilt wird, wird nicht
angefangen.

ZWEIMAL AM FALSCHEN ORT GELANDET

Der Knopf stand erst in `if (lage.team)`, dann immer noch innerhalb von
`if (treffBrett && lage)` -- also beide Male ausgerechnet am Treff und
an keinem Arbeitsbrett. Gefunden hat das beide Male die Pruefung im
Browser ("0 Knoepfe auf dem Ideenbrett"), nicht das Lesen. Jetzt steht
er in der allgemeinen Knopfreihe, hinter `darfEintragen()` -- eine
Uebernahme ist ein Schreibvorgang.

Und die Gegenprobe zur Brettliste lief anfangs ins Leere: Sie fragte
nach `BEREICHE[b].treff`, ein Merkmal, das es nicht gibt, und fand null
Treff-Bretter -- eine Gegenprobe, die nichts gegenprueft. TREFF_BRETTER
steht in workspace.js.

PRUEFUNGEN: pruef-uebernahme neu mit 39, davon 4 im Browser (der Klick
muss eine Aufgabe in der DATENBANK erzeugen, nicht nur eine Meldung).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 12:25:36 +02:00
DogFatherGitandClaude Opus 5 6643e530a8 Auskunft auf Knopfdruck -- und die Quellenliste pflegt sich selbst
Zweite Haelfte von Stufe 8, Art. 15 DSGVO. Jeder Mensch hier darf
wissen, was ueber ihn gespeichert ist: DogFather, die rechte Hand,
jeder Modi, jede Creatorin -- und jedes Mitglied der Community.

DIE LISTE DER QUELLEN WIRD ABGELEITET, NICHT GEPFLEGT

Eine Auskunft, die eine Tabelle vergisst, ist schlimmer als keine: Sie
ist eine falsche Aussage ueber die Daten eines Menschen. Eine
handgeschriebene Liste "wo Personendaten liegen" waere in dem Moment
falsch, in dem jemand eine Tabelle dazubaut -- und genau diese Bauart
ist im Projekt schon dreimal schiefgegangen.

Deshalb fragt das Modul die Datenbank selbst: `PRAGMA foreign_key_list`
liefert jede Spalte, die auf `personen` zeigt. Gemessen: 62 Spalten in
38 von 42 Tabellen.

VIER SPALTEN ZEIGEN AUF ETWAS, OHNE ES ZU SAGEN

Es gibt genau vier Spalten im Haus, die auf `_id` enden und keinen
Fremdschluessel deklarieren:

  eintraege.saeule_id          keine Person
  treff_entfernt.eintrag_id    keine Person
  protokoll.person_id          IST eine Person
  treff_entfernt.autor_id      IST eine Person

Beide Personenspalten haben denselben Grund, keinen Fremdschluessel zu
haben: Sie sollen eine geloeschte Person ueberdauern. Sie stehen
namentlich im Modul -- und pruef-auskunft schlaegt an, sobald eine
fuenfte dazukommt, die niemand eingeordnet hat. Die Liste ist damit
klein genug, um richtig zu sein, und kann nicht heimlich veralten.

ZWEI DINGE STEHEN NIE DRIN

  Zugangsgeheimnisse (Hash, Salt, Kennung) -- Risiko ohne Nutzen.
  Andere Menschen -- wer eine Massnahme gesetzt hat, ist dessen Datum,
  nicht meines. Eine Regel fuer alle Tabellen, keine Ausnahmeliste:
  Steht in einer Zeile ueber mich die Nummer eines anderen, wird daraus
  "eine andere Person". Meine eigene bleibt stehen, sonst waere die
  Auskunft unbrauchbar -- und genau das ist die Gegenprobe dazu.

DER KNOPF STEHT AUF ZWEI SEITEN

Steckbrief und Treff-Regeln -- die beiden Seiten, die einem Menschen
selbst gehoeren. Die Community hat keinen Steckbrief; ohne die zweite
Stelle haette ausgerechnet die groesste Gruppe mit den wenigsten
Rechten auch dieses nicht. Die Pruefung liest das aus der Rechtetafel
nach, statt es zu behaupten.

Die Datei entsteht im Browser aus der Antwort -- es bleibt also nichts
auf dem Server liegen. Wer ueber wen Auskunft gezogen hat, steht im
Protokoll: Eine vollstaendige Sammlung der Daten eines Menschen ist das
Empfindlichste, was dieses Haus herausgibt.

NEBENBEI GEFUNDEN

Ich hatte `.block__kopf` und `.block__frage` geliehen -- die stehen in
automation.css, und keine der beiden Seiten laedt die. Der Kasten waere
ohne Abstaende dagestanden. Gefunden von pruef-css-klassen, nicht vom
Auge. Jetzt eigene Klassen in start.css.

PRUEFUNGEN: pruef-auskunft neu mit 46.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 01:00:11 +02:00
DogFatherGitandClaude Opus 5 e975983ad1 Das Loeschkonzept ist kein Dokument, sondern eine Tabelle, die sich durchsetzt
Stufe 8 aus dem Plan zur Perfektion: "Loeschkonzept je Datenart ·
IP-Adressen im Protokoll nach 30 Tagen weg. Je mehr Daten, desto teurer
das Nachholen."

WARUM NICHT ALS NOTIZ

Ein Loeschkonzept als Dokument ist nach dem ersten neuen Feld falsch,
und niemand merkt es. workspace-aufbewahrung.js ist beides: die
Uebersicht, was wie lange aufgehoben wird -- UND das Programm, das es
tut. Was dort nicht steht, wird nicht geraeumt; was dort steht, wird
geraeumt.

GEMESSEN, BEVOR ETWAS GEBAUT WURDE

42 Tabellen durchgesehen. Drei halten IP-Adressen:

  versuche.ip    wird beim Anmelden im Fenster geraeumt        ok
  sitzungen.ip   nur beim Abmelden -- ABGELAUFENE Sitzungen
                 standen ewig da, samt IP und Browser          Luecke
  protokoll.ip   wurde nirgends geraeumt, wuchs ewig           Luecke

Zwei echte Luecken also, nicht fuenf vermutete.

DREI SORTEN EINTRAG, UND DIE DRITTE IST DIE WICHTIGSTE

  raeumen   Diese Datei loescht selbst.
  fremd     Eine andere Stelle loescht -- hier wird nur GEZAEHLT.
            Bricht die andere Stelle, steht die Zahl trotzdem da.
  bleibt    Wird absichtlich aufgehoben, mit Begruendung.

Ein Loeschkonzept, das nur Loeschungen auffuehrt, ist ein halbes: Die
begruendete Aufbewahrung ist der Teil, nach dem gefragt wird. Jede
Zeile nennt Frist, Zweck, Rechtsgrundlage und Wirkung.

SICHTBAR, NICHT NUR WIRKSAM

Auf automation.html -- dort steht alles, was ohne Zutun laeuft, und
genau das ist es. Bei jeder Zeile die Zahl, wie viele Datensaetze sie
gerade betrifft, und ein Knopf "Jetzt aufraeumen", damit es kein
schwarzer Kasten ist. Die Sorte steht als WORT daneben, nicht nur als
Farbe.

BEI ETWAS, DAS LOESCHT, IST DIE WICHTIGERE HAELFTE: WAS ES NICHT LOESCHT

Zu jeder Loeschung eine Gegenprobe:

  IP nach 30 Tagen weg        -> und die von vor 29 Tagen bleibt
  IP weg                      -> und die ZEILE bleibt (nur das Feld)
  abgelaufene Sitzung weg     -> und die gueltige bleibt
  abgelaufene Sitzung weg     -> und ich bin danach noch angemeldet

Die letzte ist die unbequemste und die wichtigste: Ein Aufraeumlauf,
der die eigene Anmeldung mitnimmt, wirft im Betrieb alle hinaus -- und
zwar einmal taeglich. Dazu: ein zweiter Lauf muss NICHTS mehr finden
(sonst waere "aufgeraeumt" nicht von "nichts getan" zu unterscheiden),
und eine Zaehlung ueber eine fehlende Tabelle ergibt `null`, nicht 0.

NEBENBEI: EINE EIGENE DOPPLUNG VON GESTERN

Drei der Seitenerklaerungen sagten in "Wofuer" und "Du tust" fast
dasselbe (report 80 %, treff-regeln 67 %, startcheck 50 %). Gestern
hatte ich nur den Fall geprueft, an dem ich mich verbrannt hatte --
"Wofuer" gegen die Unterzeile -- und die naheliegendere Dopplung
uebersehen. Jetzt gemessen, schlechtester Wert 25 %.

PRUEFUNGEN: pruef-aufbewahrung neu mit 41, davon 7 im Browser
(der Knopf muss eine Zahl wirklich fallen lassen, und die IP muss
danach in der Datenbank weg sein). pruef-erklaerung 44 -> 47.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 00:36:57 +02:00
DogFatherGitandClaude Opus 5 de19684883 Jede Seite erklaert sich selbst -- drei Zeilen, und die dritte rechnet sich aus
Filipe: "ich will in jeder seite auch eine kleine detaillierte aber
schnelle erklaerung kurz und knapps noch zu jeder seite."

DREI ZEILEN AUF JEDER DER 25 SEITEN

  WOFUER    was auf dieser Seite steht
  DU TUST   was man hier konkret macht
  MERKE     nur dort, wo es etwas gibt, das man falsch versteht
  SIEHT     wer diese Seite ueberhaupt oeffnen kann

Offen sichtbar und nicht hinter einem Aufklapper: "schnell" war seine
Bedingung, und eine Erklaerung, die man erst aufklappen muss, ist
genau dann nicht da, wenn man sie braucht.

DIE ZEILE "SIEHT" IST GERECHNET, NICHT GESCHRIEBEN

Sie kommt aus der Rechtetafel -- aus derselben, aus der auch die
Schranke ihre Entscheidung holt. Haette ich sie danebengeschrieben,
waere sie beim ersten Umstellen in "Wer sieht was" still falsch
geworden, in einem Satz, der behauptet, wer etwas sieht. Die Pruefung
stellt die Tafel deshalb wirklich um und sieht nach, ob der Satz
mitwandert.

Die Erklaerung haengt hinter derselben Schranke wie die Seite: Wer sie
nicht oeffnen darf, bekommt 404 -- nicht 403, sonst waere dieser Weg
eine Landkarte des Hauses.

Eingebunden ist sie nicht ueber eine Liste von Dateinamen, sondern
ueber "wer kopf.js laedt": die 26. Seite ist damit automatisch dabei.
Fuenf Seiten haben keine Kopfzeile (Chat, Kalender, Start, Team,
Teamlage) -- dort haengt der Kasten an <main>, sonst waeren
ausgerechnet die haeufigsten Seiten lautlos leer geblieben.

ZWEI EIGENE MAENGEL, GEFUNDEN DURCH HINSEHEN, NICHT DURCH DIE PRUEFUNG

Die erste Fassung war gruen -- und stand mitten auf dem Buehnenbild,
mit einem Lichtfleck hinter "SIEHT". Und "Wofuer" sprach fast woertlich
die Unterzeile darueber nach. Beides misst die Pruefung jetzt: Kontrast
mit dem dritten Ausgang ("steht auf der Buehne" ist kein Ergebnis) und
die Wortueberschneidung mit der Unterzeile.

ZWEI BEFUNDE, DIE SCHON VORHER ROT WAREN

1. pruef-tempo-workspace verglich die UNKOMPRIMIERTE Groesse gegen eine
   Grenze, die fuer die Leitung gedacht war -- waehrend der Kommentar
   daneben "das ist, was wirklich ueber die Leitung ging" behauptete.
   Live steht Caddy davor. Nachgemessen an der echten Adresse:
   start.css 345 KB -> 111 KB zstd. Die Pruefung wog also 1,2 MB, wo
   Filipe 500 KB bekommt. Jetzt wird Komprimierbares im Pruefstand
   gzip-gepackt (115 KB gegen 111 KB live -- auf vier Prozent genau),
   geurteilt wird ueber die uebertragene Groesse, berichtet werden
   beide. Dabei prompt in die dokumentierte Falle getappt: `body()` auf
   einen Ereignisstrom endet nie, der Lauf blieb stehen. Jetzt
   ausgenommen, plus Notbremse je Koerper.

2. pruef-ueberlappung konnte seit Tagen nicht mehr zeigen, dass sie
   eine Ueberlappung ueberhaupt findet: Ihre Gegenprobe legt einen Knopf
   auf einen anderen, traf aber 6 px daneben. Zwei Ursachen in einer
   Zeile -- `position: fixed` bezieht sich auf einen Vorfahren mit
   `transform`, und die `transition` der Knoepfe liefert beim sofortigen
   Messen die Lage von vorher. Jetzt `transform` + `transition: none`:
   34x36 px erkannt, 20 Seiten-Breiten-Paare, 0 Befunde.

PRUEFUNGEN: pruef-erklaerung neu mit 44, davon 8 im Browser (Seite mit
und ohne Kopfzeile, Handy, Kontrast, Echo). Mein Schild stand auf
10,88 px und lag unter der Hausgrenze von 11,5 -- gefunden von
pruef-css-klassen, nicht vom Auge.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-14 18:20:30 +02:00
DogFatherGitandClaude Opus 5 44e5ace109 "Wer sieht was" auf beiden Adressen — und die Tafel lässt sich umstellen
Filipe: "ich will die kategorie auch auf der team dogi seite für die
dogfather und rechte hand rollen ... und wenn man drauf drückt,
perfektionieren so dass ich die da auch manuell wechseln und speichern
kann."

DIE KACHEL STAND NUR AUF DER AGENTURSEITE. Auf der Team-Dogi-Seite
arbeitet ihr aber täglich; dort nicht nachsehen zu können, wer was darf,
hieße, die Frage an dem Ort zu stellen, an dem man gerade nicht ist. Sie
steht jetzt auf beiden — einmal beschrieben, zweimal benutzt.

ANSEHEN BEIDE, UMSTELLEN NUR DOGFATHER. Die rechte Hand bekommt
dieselbe Tafel und keine Knöpfe; nicht weil das Skript sie versteckt,
sondern weil der Server darf_aendern: false schickt. Wer Rechte vergeben
kann, kann sich Rechte vergeben — diese eine Tür bleibt bei ihm.

WAS GESPEICHERT WIRD, IST NUR DER UNTERSCHIED. In der Datenbank steht
eine Zeile nur, wenn sie vom Grundstand in rechte.js abweicht. Damit
bedeutet der Code weiterhin etwas: Man sieht, was gedacht war, und
daneben, was jemand daraus gemacht hat. "Zurück auf Grundstand" ist ein
DELETE, und eine neue Seite erbt automatisch den Grundstand — eine
vollständige Kopie in der Datenbank hätte sie nicht gekannt und sie wäre
für alle zu gewesen, ohne dass es jemand entschieden hätte.

DREI FELDER SIND FEST: DogFather kann sich die Rechte-, die Personen-
und die Startseite nicht selbst wegnehmen. Eine Einstellung, aus der man
sich aussperren kann, ist keine Einstellung, sondern eine Falle — und
sie wäre genau einen Fehlklick entfernt gewesen.

GESPEICHERT WIRD SOFORT, mit jedem Klick. Kein "Speichern" am Ende: Bei
zweihundert Feldern ist das die Stelle, an der eine halbe Änderung
verlorengeht, und eine halbe Änderung an Rechten ist die gefährlichste
Lage von allen. Rückfrage gibt es nur beim ÖFFNEN — etwas wegzunehmen
sieht sofort jemand, etwas aufzumachen unter Umständen lange niemand.

DER BEFUND, DEN DIE PRÜFUNG GEFUNDEN HAT: Nimmt man einem Modi eine
Seite weg, greift die Schranke sofort — und die KACHEL blieb stehen. Ein
Knopf, der auf die Startseite zurückwirft. Der Satz "Kachel und Tür
gehören zusammen" steht seit dem 06.09. im Code; bis heute war er eine
Bitte an den, der beides pflegt. Jetzt ist er eine Rechnung: Beide
Kachellisten — die des Servers und die im Browser — werden gegen
dieselbe Tafel gefiltert, aus der die Schranke ihre Entscheidung holt.

Geprüft wird nicht, ob die Antwort 200 lautet, sondern ob sich das
VERHALTEN ändert: Der Modi kommt danach wirklich nicht mehr hinein —
mit Gegenprobe davor. Und eine Umstellung überlebt einen Neustart; ohne
tafelLaden() beim Start hätte wieder der Grundstand gegolten, und es
hätte ausgesehen wie vorher.

Geprüft: rollen 315 · start-ansicht 147 · crew-adresse 132 · sicht 84 ·
modi-verborgen 80 · neue-seiten 70 · treff-werkzeuge 70 · nachwuchs 69 ·
treff 58 · rechte-umstellen 46 · entwicklung 40 · css-klassen 30 ·
zwischenspeicher 21 · alle-wege 19 · rechtetafel 19 — alles grün.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-11 22:42:21 +02:00
DogFatherGitandClaude Opus 5 dfd951861a Entwicklung & Nachwuchs: zwei Kataloge zum Anklicken statt zwei leerer Formulare
Filipe: "ich will dass diese zwei kategorien perfektionniert werden, ich
will dass fertige aufgaben da stehen und so ... so dass dogfather und
rechte hand es so einfach wie möglich haben aber so professionell wie
auch nur möglich."

Bis heute waren beide Kacheln ein leeres Formular: Titel tippen, Art
wählen, Text schreiben. Ein leeres Feld beantwortet keine Frage — es
stellt sie noch einmal.

ENTWICKLUNG: 34 Beobachtungen in fünf Blöcken, vier Antworten je Zeile
(Läuft · Wächst gerade · Da hakt es · Kann ich nicht sagen). Es sind
BEOBACHTUNGEN, keine Eigenschaften — "Absagen kommen rechtzeitig" statt
"ist zuverlässig". Eine Eigenschaft kann man nur bestätigen oder
bestreiten; ein Verhalten kann man gesehen haben oder nicht.

TALENTE: 21 Merkmale in fünf Gruppen, 6 Warnzeichen getrennt geführt,
fünf Trichterstufen mit je GENAU EINEM nächsten Schritt. Eine Liste
wächst und wird nie wieder angesehen; ein Trichter fragt bei jeder Karte
"und jetzt?". Die Standzeit steht dabei — "seit 41 Tagen beobachtet"
ist eine Auskunft über uns, nicht über den Kandidaten.

VIER RIEGEL, JEDER MIT GEGENPROBE:
 · Block 5 ("Wie geht es dir damit?") gehört der Person — lesend UND
   schreibend, auch vor DogFather. Er kommt gar nicht erst aus dem
   Server; Schreiben gibt dasselbe 404 wie ein erfundener Schlüssel.
   Nach außen dringt eine Ampel OHNE Namen, und die schweigt, solange
   das Team so klein ist, dass "jemandem geht es zu viel" dasselbe wäre
   wie ein Name.
 · Der Stand des anderen kommt erst nach dem eigenen Klick — sonst
   klickt man dasselbe. Sichtbar ist nur, DASS es einen gibt: sonst
   sähen "noch niemand" und "du darfst es nicht sehen" gleich aus.
 · "Da hakt es" ohne Anlass wird abgelehnt. "Läuft" nicht — 28
   Pflichtfelder je Person wären das Gegenteil von "so einfach wie
   möglich".
 · Talente gehört DogFather und der rechten Hand. Ein Modi bekommt 404
   auf Seite UND Schnittstelle.

WAS NICHT GEBAUT IST, UND WARUM: keine Punktzahl, kein Durchschnitt,
keine Rangliste, keine Gesamtnote. Eine Zahl über einem Menschen wird
gelesen, verglichen und weitererzählt. Und kein Rot — "da hakt es" ist
eine Beobachtung, kein Alarm.

DER PLAN LAG AN EINER STELLE FALSCH, gemessen statt vermutet: Er sagte
"keine neue Tabelle, der Stand liegt in punkt_stand". Dort ist der
Schlüssel (bereich, schluessel, creator_id) — genau EIN Stand je Punkt
und Person. Zwei unabhängige Augenpaare passen da nicht hinein, ohne
eine lebende Tabelle neu zu bauen. Also eine eigene.

EIN RÜCKSCHLAG, DEN NUR DIE PRÜFUNG GEFUNDEN HAT: Die Liste der
Bretter, die ein Modi oder die rechte Hand öffnen darf, wird aus den
KACHELZIELEN abgeleitet. Als die Kacheln auf die neuen Seiten zeigten,
fielen beide Bretter heraus — und die Seite verlinkte auf ein 404. Kein
Fehler im Riegel, sondern in seiner Quelle.

Dazu zwei kleinere Funde vom Hinsehen statt vom Messen: Die Ampel sagte
"Solange ihr zu 1 seid" (jetzt drei Sätze für drei Lagen), und die
Fußzeile der Talente-Seite lag auf der Bühne — die Kontrastprüfung hatte
sie übersprungen, weil ein Link darin steht. Beide behoben, und die
Prüfung hat den stillen Aussetzer gleich mit verloren.

Geprüft: rollen 314 · start-ansicht 147 · crew-adresse 132 · neue-seiten
70 · nachwuchs 69 · entwicklung 40 · css-klassen 30 · zwischenspeicher
21 · alle-wege 19 · rechtetafel 19 — alles grün.

Was noch fehlt, steht in der Notiz, Abschnitt 9: die eigene Karte für
die Person, der Übergang "Probe" → Zugang, der Vorlagentext zum
Ansprechen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-11 22:20:09 +02:00
DogFatherGitandClaude Opus 5 39dd666b17 Der Treff zieht in Team Dogi ein — die dritte Adresse ist wieder weg
Filipe, nachdem er die dritte Wand gesehen hatte: "das soll keine app
für sich sein, dass soll in der crew seite adaptiert werden, da rein
perfektionniert."

WAS VERSCHWINDET: treff.dogfather-universe.com samt Weiche
(treff-adresse.js), Zugangswand, Manifest und acht Bühnenbildern. Kein
DNS-Eintrag, kein zweiter Caddy-Block, kein zweites App-Symbol.

Die Gründe, die DAFÜR sprachen, stehen jetzt als Kommentar in
crew-adresse.js statt als Code -- sie gelten weiter, und beim nächsten
Mal wird jemand dieselbe Idee haben: eine App je Ursprung, und ein
Schloss mehr zwischen der Community und den Daten der Agentur.

WAS DER VERZICHT KOSTET, benannt statt übersehen:
 · Die Community steht vor derselben Wand wie das Team und liest dort
   die Namen der drei Team-Rollen. Filipes Entscheidung auf die Frage:
   vierte Kachel "Community" statt gar keiner Kacheln.
 · Ein Schloss weniger. Was vorher die Adresse getrennt hat, muss jetzt
   jede einzelne Regel halten -- deshalb prüft pruef-treff-werkzeuge
   seit heute zehn Dinge mehr (70 statt 60).

EINE LÜCKE, DIE DABEI AUFGEFALLEN IST -- und die es schon vorher gab:
Ein Mitglied der Community stand in der Auswahl, wen man zu einem
Termin einlädt, wem man eine Aufgabe gibt und mit wem man einen Chat
anfängt. Für DogFather bedeutet fast jede Liste "alle". Jetzt zu, über
eine Hülle (ohneAussen) um die fünf Listen, die von Zusammenarbeit
handeln -- damit sie auch für die Listen gilt, die es noch nicht gibt.
Die Verwaltungsliste in "Personen & Zugänge" zeigt sie weiterhin, sonst
legt er einen Zugang an und der verschwindet im selben Moment.

DREI BEFUNDE AUS DEN PRÜFUNGEN, wieder keiner vom Lesen:
 · Mein eigener Kommentar auf der Wand nannte eine Rolle der Agentur --
   in einer Datei, die jedes Community-Mitglied im Quelltext liest.
   Zum zweiten Mal an einem Tag, und zum zweiten Mal ausgerechnet in
   einem Kommentar, der erklärt, warum man das nicht tut.
 · Die Prüfung "der Satz nennt die Modis" durchsuchte den QUELLTEXT und
   wäre grün geblieben, obwohl der Satz auf dem Bildschirm längst ein
   anderer ist -- sie fand ihn in einem Kommentar. Sie misst jetzt die
   sichtbare Unterzeile.
 · Der erste Entwurf der Adressregel sperrte die Community auch auf
   localhost aus -- eine Bedingung durch AUSSCHLUSS, zum dritten Mal an
   einem Tag. Jede Zeile nennt jetzt die Adresse, FÜR DIE sie gilt.

Und zwei feste Zahlen weniger: Die Kachelreihe wird nicht mehr gezählt,
sondern beim Namen genannt (admin, hand, modi, gast) -- eine Zahl war
dort schon zweimal rot, ohne dass etwas kaputt war. Der App-Name wird
nicht nur geprüft, sondern der UNTERSCHIED zur Agenturadresse.

Die App heißt auf crew. jetzt "DogFather Universe" statt "Team Dogi" --
sie gehört ab heute beiden (Entscheidung Filipe).

Geprüft: rollen 312 · crew-adresse 132 · kalender 104 · sicht 84 ·
modi-verborgen 80 · chat-kanaele 79 · treff-werkzeuge 70 · haus-trennung
62 · treff 58 · chat 48 · treff-seiten 42 · bereiche-lesend 37 ·
start-ansicht 147 · css-klassen 30 · zwischenspeicher 21 · alle-wege 19 ·
rechtetafel 19 -- alles grün.

Die 58 bei pruef-treff sind elf weniger als gestern: Mit der dritten
Adresse fallen ihre 26 Weichen-Prüfungen weg, ersetzt durch 10 für die
eine Wand plus die neuen in 7b.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-11 18:38:05 +02:00
DogFatherGitandClaude Opus 5 7b21f247eb Der Treff: eine eigene Tür für die Community, und sie sieht nur, was dasteht
Filipe: "eine community rolle und community kategorie, wo die community
auch dann nur die sieht" · "wieso nur eine kachel — ich will mehrere,
mit mehreren optionen" · "egal welche rolle hinzugefügt wird soll immer
nur das sehen was ich erlaube".

DIE DRITTE ADRESSE. treff.dogfather-universe.com bekommt eine eigene
Weiche (treff-adresse.js), eine eigene Zugangswand, ein eigenes Manifest
und acht eigene Bühnenbilder. Ohne sie stünde dort die Wand der Agentur:
Spicy-Logo, "Creator Workspace", fünf Rollenkacheln mit den Namen Admin,
Manager, Scout, Creator — die komplette Struktur des Unternehmens, vor
der Anmeldung, für jeden mit der Adresse.

Welche Wand zu welcher Tür gehört, steht jetzt in EINER Tafel
(istFremdeWand) statt als Sonderfall im Code. Bei zwei Wänden war ein
Sonderfall richtig; bei drei wären es drei geworden, bei vier sechs.

SIEBEN BRETTER UND EIN ACHTES NUR FÜRS TEAM. Anschlagbrett, Was ansteht,
Der Treff, Wunschliste, Highlights, Regeln & Hilfe, Mitmachen — dazu
"Meldungen & Maßnahmen", das ausdrücklich NICHT in TREFF_BEREICHE steht:
dort wäre es lautlos bei der Community gelandet und hätte ausgesehen wie
die anderen sieben.

WAS AUF DEN BRETTERN PASSIERT: "Will ich auch" (eine Stimme je Person,
erzwungen durch den Schlüssel, nicht durch eine Prüfung) · Anheften,
höchstens drei, gezählt IN der Transaktion · Freigabe vor Sichtbarkeit
für Termine und Highlights, wobei Abwesenheit der Ruhezustand ist ·
Melden mit Pflicht-Grund (DSA Art. 16) · Entfernen mit Grund, der den
Beitrag ÜBERLEBT (DSA Art. 17) · drei Stufen, gerechnet statt
gespeichert · die Bannleiter: Modi bis 7 Tage, dauerhaft nur DogFather
(seine Entscheidung) · "Mitmachen" wird zum Talent, genau einmal.

Der Ausschluss wirkt in sitzungLesen() — also nicht nur beim Schreiben.
Wer ausgeschlossen ist, ist weg, nicht stumm.

ZWEI SEITEN MEHR. treff-regeln.html holt seine ZAHLEN vom Server
(Mindestalter 18, Fristen, Anschläge) — ein Regeltext, der eine andere
Zahl nennt als die Regel, ist schlimmer als keiner. rechte.html rechnet
"Wer sieht was" aus derselben Tafel aus, aus der die Schranke ihre
Entscheidung holt. Die Community steht dort bei 3 von 23.

SECHS BEFUNDE, KEINEN HAT DAS LESEN GEFUNDEN:
 · Ein Modi kam über den verborgenen Zugang in den Treff — die Bedingung
   war durch Ausschluss formuliert und nahm die neue Wand automatisch mit
 · /api/personen gab einem Mitglied Namen und Rolle von DogFather
 · Ein DELETE mit Körper wird von Nodes HTTP-Parser mit einem leeren 400
   abgewiesen, bevor Express ihn sieht (gemessen). Der Grund reist jetzt
   in der Adresse
 · Der Kommentar, der erklärt, warum die Zugangswand keine Rollennamen
   nennt, nannte selbst einen — in einer ausgelieferten Datei
 · Zwei Listen für "welche Seiten sind ohne Anmeldung offen". Sie
   stimmten, weil beide am selben Tag entstanden
 · Ein Portkonflikt, den ich selbst gebaut hatte (4391 gehört
   pruef-chat-aufloesen)

Dazu zwei feste Zahlen abgeschafft (die 20 in pruef-rechtetafel, die
Kachelzahl in pruef-treff) und zwei Werkzeuge, die jetzt SUCHEN statt
aufzuzählen: Der Versionsstempel findet seine Manifeste selbst — das
dritte hätte sonst keinen bekommen, und die neue App hätte bis zu vier
Stunden lang das falsche Zeichen getragen. Das Bildwerkzeug baut beide
Zugangswände aus einer Vorlage mit zwei Werten.

Zwei neue Kacheltöne, gemessen statt gewählt: #2f2f7f (Abstand 31,4 in
Lab) und #7c2771 (29,7). Das schwächste Paar der vorhandenen 34 liegt
bei 24,9.

Geprüft: treff 69 · treff-werkzeuge 60 · rollen 312 · start-ansicht 147 ·
crew-adresse 129 · sicht 84 · modi-verborgen 80 · haus-trennung 62 ·
bereiche-lesend 37 · css-klassen 30 · zwischenspeicher 21 · alle-wege 19 ·
rechtetafel 19 — alles grün.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-11 17:58:34 +02:00
DogFatherGitandClaude Opus 5 3cda64568d Die Modi-App bekommt ihre eigene Adresse: crew.dogfather-universe.com
Filipe: "ich will dass es eine eigene app wird" -- und dann "subdomain
machen jetzt sofort". Name von ihm gewaehlt: crew. (unauffaellig).

Auf einem Ursprung laesst sich genau EINE App installieren (w3c/manifest
Nr. 1180). Derselbe Grund, aus dem der Workspace am 06.09. umgezogen ist.
Getrennt wird ueber den HOSTNAMEN: ein Dienst, eine Datenbank, ein
Verzeichnis wie bisher.

DIE REGEL STEHT AN EINER STELLE
crew-adresse.js beantwortet: Darf diese Rolle auf dieser Adresse
angemeldet sein? Eingehaengt in sitzungLesen() -- durch die Funktion geht
jedes der 26 Fachmodule und jede Seitenschranke. Eine Middleware daneben
kann man in einem neuen Modul vergessen, und ein vergessener Rechteschutz
faellt nicht auf, weil dann alles geht.

  crew.      nur Modis; jeder andere bekommt 401 wie bei einem Tippfehler
  workspace. keine Modis mehr; sie bekommen den Weg zur neuen Adresse
  localhost  UNVERAENDERT

Die dritte Zeile ist der Kern: Die Regel ist eine AUFZAEHLUNG der drei
echten Adressen, nicht "alles ausser crew". Sonst wuerden sieben andere
Pruefdateien ab sofort messen, dass ein Modi nirgends hereinkommt -- gruen,
weil sie nichts mehr finden.

ZWEI APPS, ZWEI NAMEN
Beide Adressen liefern dieselben HTML-Dateien. Auf crew. wird
/workspace/app.webmanifest serverseitig auf crew.webmanifest umgebogen --
so braucht keine der 30 Seiten eine zweite Zeile, die man bei der 31.
vergisst. "Team Dogi" statt "Creator Workspace", eigenes Zeichen:
derselbe Husky, aber ohne Chili (die gehoert zu Spicy Media, nicht zu
ihnen) und im Modi-Ton #5f8a9f.

tools/crew-symbol.mjs erzeugt die sechs Symbole und bricht ab, wenn sie
sich zu weniger als 10 % vom Workspace-Symbol unterscheiden. Gemessen:
43 bis 53 %.

GEMESSEN
pruef-crew-adresse    74 Pruefungen, 0 Fehler -- mit Gegenprobe: der Modi
                      bekommt in der Datenbank die Rolle 'manager', danach
                      MUSS dieselbe Sitzung auf crew. ins Leere laufen
pruef-rollen          245, unveraendert (die Regel ist lokal wirkungslos)
pruef-workspace-umzug 31 Faelle
pruef-zwischenspeicher 21 -- ein Stempel im Haus, jetzt ueber 23 Dateien

Der Server kennt die Adresse damit. DNS und Caddy bleiben Filipes Schritt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-10 13:07:12 +02:00
DogFatherGitandClaude Opus 5 6122ea6972 Eigene Checklisten fuer die Modis -- und eine Seite fuer euch beide
Wunsch Filipe (10.09.2026): *"diese kategorien mussen auf dieser seite
auch noch auf die modis perfektionniert werden, da mussen lauter sachen
sein die vanvan und ich danach verteilen können und da anpassen können
ob gut oder nicht."* Und: *"da soll es eine kategorie geben für uns
beide nur sonst keinen wo wir dass alles sehen und behandeln können."*

=== TEIL 1: SEIN EIGENER PUNKTESATZ ===

101 Punkte in workspace-modi-punkte.js -- Live-Ablauf 40, Community 36,
Technik 25. Die vorhandenen sagen "Upload messen", "Sendeplan
festlegen", "Verweildauer vergleichen": Ein Modi sendet nicht, er
moderiert. Ihm dieselbe Liste vorzulegen hiesse, ihn an Dingen zu
messen, die nicht seine Arbeit sind.

DIESELBE EINTEILUNG (Vor/Waehrend/Nach usw.), nur andere Punkte darin.
Zwei verschiedene Einteilungen waeren zwei Dinge zum Lernen statt
einem, und die Oberflaeche kaeme ohne Umbau nicht damit zurecht.

DIE SCHLUESSEL BEGINNEN MIT "m-". Der Stand haengt an (bereich,
schluessel, person) -- ohne Praefix koennte ein Modi-Punkt eines Tages
denselben Namen tragen wie ein Creator-Punkt und dessen Bewertung
erben.

BEIDE SAETZE STEHEN IN GUELTIG. Stuenden dort nur die Creator-Punkte,
kaeme die Liste an und jeder Klick darauf brachte einen 404 -- die
Sorte Fehler, die man erst beim Benutzen merkt.

Ein Modi sieht SEINE Liste, ohne jemanden auszuwaehlen (wie ein
Creator), und bewertet sich nicht selbst. Ohne diese Zeile waere er in
den Betreuer-Zweig gefallen, haette eine Auswahl fremder Creator
vorgesetzt bekommen und seine eigene Liste gar nicht gesehen.

DER HEIKELSTE PUNKT WAR EIN ANDERER: `darfCreator` sagt bei
siehtAlles() pauschal ja -- und darin steckt auch Spicy Media. Wer die
Modi-Auswahl daran haengt, oeffnet sie ihr nebenbei mit, ohne dass an
der Stelle etwas davon steht. Deshalb eine eigene Regel (darfPerson),
und die Pruefung versucht es ueber die Liste, ueber die Adresse UND
ueber das Bewerten.

Die Auswahl heisst bei der DogFather-Rolle jetzt "Person" statt
"Creator" -- ein Feld namens "Creator", in dem ein Modi steht, ist
falsch beschriftet. Das Wort kommt vom Server; ein Rollenvergleich im
Browser waere die Stelle, an der der Name in einer ausgelieferten Datei
landet.

=== TEIL 2: DIE GEMEINSAME SEITE ===

teamlage.html, nur fuer die DogFather-Rolle -- also Filipe und VanVan.
Fuer alle anderen gibt es weder die Kachel noch die Seite noch die
Schnittstelle (404, wie bei einer Adresse, die es nicht gibt). Zwei
Schloesser, absichtlich: die Schranke und die Abfrage. Faellt eines
weg, haelt das andere.

Je Person: offene und ueberfaellige Aufgaben, beigetragene Ideen,
Rueckmeldungen, und je Bereich gut/verbessern/offen. Jede Zeile fuehrt
in den Bereich -- MIT DER PERSON VORAUSGEWAEHLT. Dafuer liest die
Checkliste jetzt `creator_id` aus der Adresse; ohne das landet man auf
der erstbesten Person und weiss beim zweiten Suchen nicht mehr, warum
man hier war.

SIE ZAEHLT, SIE BEWERTET NICHT. Bewertet wird dort, wo die Punkte
stehen. Eine zweite Stelle dafuer waere eine zweite Stelle, an der es
auseinanderlaeuft.

UND SIE IST KEINE UEBERWACHUNG. Ueber team.html steht schon, dass eine
Seite mit Zahlen ueber Kollegen als Kontrolle gelesen wird -- und dann
arbeitet niemand mehr offen damit. "Offen" heisst hier deshalb
ausdruecklich: darueber habt ihr noch nicht geredet. Eine Merkliste
fuer euch beide, keine Note.

ALLES IN VIER ABFRAGEN, nicht vier je Person -- bei zehn Modis waeren
das vierzig. Denselben Fehler hat das Haus bei den Terminen schon
gemacht und ihn dort vermerkt.

KEINE NEUEN CSS-KLASSEN: Fuer genau diese Karten gibt es sie schon
(tperson, tz, schritt -- aus team.html). Elf neue haetten gepflegt
werden muessen fuer ein Aussehen, das bereits da ist.

ZUSATZKACHELN sind ein neuer, kleiner Mechanismus: `bereiche` ERSETZT
die Liste im Browser (fuer Rollen, die dort nicht vorkommen),
`bereiche_zusatz` HAENGT an. Gebraucht fuer Kacheln, die nur eine
einzige Rolle bekommt -- in bereiche.js duerften sie nicht stehen, weil
eine Kachel, die nur bei einem erscheint, die Frage aufwirft, fuer wen
sie ist. Findet sich die genannte Gruppe nicht, wird eine eigene
angelegt: Sonst faellt die Kachel lautlos weg, sobald jemand eine
Gruppe umbenennt.

EHRLICH ZUM UMFANG: Technik ist mit 25 Punkten der duennste Bereich.
Das ist Absicht -- der technische Spielraum eines Moderators ist
kleiner als der eines Streamers. Auffuellen haette Fuellmaterial in
eine Liste gebracht, die Filipe und VanVan durchgehen muessen.

GEPRUEFT: pruef-modi-checkliste (39, neu), pruef-rollen (244 statt 243
-- die neue Kachel wird angeklickt und muss ankommen),
pruef-modi-verborgen (75), pruef-workspace-seiten.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-10 03:10:04 +02:00
DogFatherGitandClaude Opus 5 b45de940e8 Rund um das Team -- die Arbeitslage von Managern und Scouts
Filipe: "so eine kategorie wie ueber die creator will ich dass nur fuer
die spicy und dogfather rolle auch ueber manager und scouts gibt ...
ich will dass es so ultra krass gut ist dass die spicy und dogfather
rolle einen kompletten teil haben mit daten ueber die arbeit von den
manager und scout. keine geheimen sachen also termine, chats und
geheime dateien soll auch so bleiben dass keiner."

--- ZUERST DIE KOPFLEISTE ---

Filipe meldete, die Kopfleiste sei bei DogFather "nicht gemacht".
Nachgemessen auf ALLEN 18 Seiten, in allen fuenf Rollen, bei drei
Breiten: einzeilig, Spanne 4 px. Und die neuen Dateien liegen
nachweislich auf dem Server (a70bc4f, `abmelden__zeichen` in der
ausgelieferten kopf.js). Das Bild war vor dem Ausliefern entstanden.

Die Messung hat aber zwei echte Sachen gefunden, die vorher niemand
gesehen hatte -- beide bei 320 px auf UNTERseiten, wo links der
Zurueck-Knopf und rechts zusaetzlich die Glocke steht: 305 px
gebraucht, 294 verfuegbar. Eine Stufe kleiner (34 px je Knopf, 4 px
Abstand) macht 283 und passt; 34 px bleiben weit ueber den 24 px
Mindestmass fuer ein Beruehrziel.

Ausserdem die Auslieferung geordnet: HTML wird immer nachgefragt,
Dateien mit Versionsstempel duerfen ein Jahr liegenbleiben (vorher
bekam ALLES `no-cache`, also auch jede Stilvorlage bei jedem Aufruf).
sw.js ausgenommen -- er wird ohne Stempel geladen, ein Fehler darin
bliebe sonst ein Jahr stehen.

--- DIE NEUE SEITE ---

workspace/team.html, nur fuer `spicy` und `admin`. Aufbau:

  DIE LUECKEN ZUERST. Creator ohne Betreuung, Scouts ohne Manager,
  Leute ohne einen einzigen Creator -- mit NAMEN, nicht nur als Zahl.
  Eine Kennzahl sagt, wie es laeuft; eine Luecke sagt, wo etwas fehlt,
  und nur das Zweite kann man heute abstellen.

  DANN DIE LAGE in fuenf Zahlen, dann JEDE PERSON EINZELN: betreute
  Creator, laufende und ueberfaellige Aufgaben, in 30 Tagen erledigte,
  Durchlaufzeit, Startcheck-Fortschritt der betreuten Creator,
  LIVE-Tage und Diamanten. Bei Scouts zusaetzlich die Pipeline mit
  Uebernahmequote und Zeit bis zur Uebergabe.

  EIN MANAGER TRAEGT DIE CREATOR SEINER SCOUTS MIT. Ohne das saehe
  einer mit fuenf Scouts aus wie jemand ohne Arbeit.

--- DREI ENTSCHEIDUNGEN, DIE ALLES TRAGEN ---

1. TERMINE, CHATS UND DATEIEN KOMMEN NICHT VOR -- weder Inhalte noch
   Zaehlungen. Ausdruecklicher Wunsch, und der richtige: Ein Kalender
   verraet, wann jemand nicht da war; ein Chatzaehler, mit wem jemand
   oft spricht.

   Das ist keine Zusicherung im Kommentar. pruef-team liest den
   Quelltext von workspace-team.js und schlaegt an, wenn eine dieser
   Tabellen darin auftaucht -- mit Gegenprobe, dass die Suche `aufgaben`
   und `leads` auch wirklich findet. Der Weg ueber die Antwort allein
   waere schwaecher: Ein leerer Testbestand kann ein Feld verstecken.

2. SEGMENTIEREN, NICHT MITTELN. Aus der Recherche zu
   Arbeitslast-Dashboards: Ein Durchschnitt versteckt genau die Person,
   bei der es klemmt. Markiert wird gegen den MEDIAN der eigenen Rolle
   -- ein Manager traegt naturgemaess mehr als ein Scout, und ihn daran
   zu messen waere unfair und nutzlos.

3. ES IST EINE ARBEITSLAGE, KEINE UEBERWACHUNG. Das steht so auf der
   Seite, im Kopf, in einem eigenen Kasten. Wer das nicht dazuschreibt,
   baut ein Kontrollwerkzeug, auch wenn er es nicht wollte. Deshalb
   zeigen die Kennzahlen auf ZUSTAENDE (unbetreute Creator,
   liegengebliebene Kontakte) und nicht auf Anwesenheit oder Fleiss.

--- WAS DIE MESSUNG UNTERWEGS GEFUNDEN HAT ---

* Die Lead-Status hiessen anders, als ich angenommen hatte: "kontakt"
  gibt es nicht. Die CHECK-Bedingung der Datenbank hat es sofort
  abgelehnt -- ohne sie waere "offen" still zu klein gewesen.

* Die Pruefung fand ihr eigenes Hinweisschild: Die Antwort traegt ein
  Feld `ausgenommen: ["Termine","Chats","Dateien"]`, aus dem die Seite
  den Satz baut. Es wird jetzt herausgenommen UND eigens geprueft --
  ignorieren waere bequem gewesen und haette kuenftig jedes Feld unter
  diesem Namen durchgelassen.

* Die Lektion vom Vorlagenbrett gleich mitgenommen: alle Karten haben
  einen DECKENDEN Grund. Eine Karte mit sieben Prozent Farbe auf
  durchsichtigem Grund laesst das Buehnenfoto durch -- dort waren es
  3,61:1. Gemessen jetzt: 6,61 bis 14,80:1. Eine der Regeln hatte den
  deckenden Grund selbst wieder aufgehoben (zwei Regeln, die spaetere
  gewinnt) -- gefunden, bevor es jemand sehen musste.

* "1 Scouts" statt "1 Scout". Eine Kleinigkeit, und das Erste, was
  auffaellt: Eine Seite, die ihre eigene Sprache nicht beherrscht, wird
  auch bei den Zahlen nicht geglaubt.

--- Pruefung ---

server/pruef-team.mjs, neu, 51 Pruefungen, alle gruen. Darunter: alle
fuenf Rollen an Schnittstelle UND Seite (Manager, Scout und Creator
bekommen 404 bzw. eine Umleitung), Spicy sieht VanVan nicht (mit
Gegenprobe an der Personenliste), die Zahlen an einem gebauten
Bestand, acht Kontrastmessungen an der wirklichen Flaeche, Handy.

server/pruef-zwischenspeicher.mjs, neu, 15 Pruefungen: was liegenbleiben
darf und was nicht -- an echten Kopfzeilen gemessen, nicht am
Quelltext. Sie meldete zuerst drei Fehler, und das war sie selbst: Sie
fragte unangemeldet und bekam Umleitungen. Eine Pruefung braucht ihre
Voraussetzung, bevor sie misst.

Ausserdem gruen: pruef-handy (das Handy fand die 320-px-Sache),
pruef-workspace-seiten, pruef-alle-wege, pruef-sicht, pruef-css-klassen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-09 15:42:14 +02:00
DogFatherGit ec55b6c8d3 WIP Zentrale-Kachel nach VanVans Werktisch — NOCH NICHT FERTIG
Aufbau steht (Ring links, Titel mittig, Uhr rechts), aber
pruef-start-ansicht meldet 3 Befunde am MAUS-LICHT der Kacheln.
Gemessen: alter Stand 0 Befunde, dieser Stand 3 — kommt also von hier.
Kein JS-Fehler (pageerror/console sind still), also Zeitverhalten:
Die zusaetzliche Abfrage /api/zentrale verzoegert vermutlich den Aufbau
der Kacheln ueber den Zeitpunkt hinaus, an dem kopf.js lichtFolgen ruft.

Ausserdem offen: 2 Schriftgroessen unter 11,5 px (pruef-css-klassen).

NICHT ausliefern.
2026-09-08 01:44:36 +02:00
DogFatherGitandClaude Opus 5 233cd76d78 Der Handy-Durchgang: drei echte Bedienfehler, alle vom selben Ursprung
Filipe: "ich will dass du die komplette seite auf dem handy abcheckst.
ich will dass alles perfekt aussieht und bedienbar ist."

DER SCHWERSTE FUND: Auf ZWOELF Seiten war der "Meine Sicht"-Umschalter
nicht bedienbar -- wer darauf tippte, landete im Chat.

Bei 412 px (der haeufigsten Android-Breite ueberhaupt) brach die
Kopfleiste nicht um, der Umschalter wurde auf 50 px zusammengedrueckt,
sein Knopf behielt aber seine 104 px Mindestbreite und lag damit quer
ueber dem Chat-Knopf. Sichtbar war davon nichts.

Und die Ursache steht seit dem 05.09. woertlich im Kommentar daneben:
"Die Rechnung ging genau auf, solange rechts VIER Dinge standen. Mit der
Glocke sind es FUENF, und bei 320 px passte es nicht mehr." Am 06.09.
habe ich den Chat-Knopf dazugesetzt -- SECHS -- und die Schwelle bei 380
gelassen. Derselbe Fehler, eine Position weiter.

Die Lehre ist nicht "380 auf 430 erhoehen"; das waere er ein drittes
Mal, nur mit einer anderen Zahl. Eine feste Schwelle ist eine Rechnung,
die jemand einmal aufgestellt hat und die beim naechsten Knopf still
falsch wird. `flex-wrap: wrap` OHNE Schwelle rechnet nicht, sondern
misst -- es bricht genau dann um, wenn der Platz nicht reicht.

DASSELBE NOCH EINMAL, am anderen Ende: Bei 1280 px brauchte die Leiste
1235 px (Marke 375 + Bedienelemente 844 + Abstand 16) und hatte 1200.
Auch hier war der Chat-Knopf der Tropfen. Sie brach um, sobald das
Skript die Bedienelemente eingehaengt hatte, und schob die ganze Seite
52 px nach unten -- CLS 0,94. Jetzt gibt die MARKE nach (sie darf
gekuerzt werden, ein Knopf nicht), und umgebrochen wird nur noch auf
sehr schmalen Geraeten.

WEITERE ECHTE FUNDE:
  * /workspace/api/chat/ungelesen wurde auf JEDER Seite ZWEIMAL geholt:
    einmal beim Laden, einmal Millisekunden spaeter beim Aufgehen des
    Ereignisstroms. Der 'open'-Zuhoerer war fuer Wiederverbindungen
    gedacht und feuerte auch beim ersten Mal.
  * Drei Kacheln teilten sich einen Farbton mit einer anderen (18 Farben
    auf 21 Kacheln). Filipe wollte ausdruecklich, dass jede ihre eigene
    hat. Nicht eine Farbe dazuerfunden -- der ganze Farbkreis ist mit
    tools/kachel-farben.mjs neu in 21 geteilt; kleinster Abstand zweier
    Nachbarn jetzt 120 Grad (vorher 106). Dabei fiel eine feste 16 in
    der Mischschleife auf: Bei 18 Kacheln wurden die letzten beiden nie
    mitgemischt.
  * Der Agentur-Untertitel wurde auf dem Handy abgeschnitten.
  * Ein zugeklappter <details>-Kasten (Kalender-Abo) verdeckte einen
    Filter-Chip: Chromium versteckt dessen Inhalt ueber
    `content-visibility`, nicht ueber `display` -- die Kaesten behalten
    eine Groesse. Dieselbe Falle wie bei den Zeitbloecken, dieselbe
    Loesung.

UND DREI PRUEFUNGEN, DIE SELBST FALSCH LAGEN:
  * "achtzehn Kacheln" stand als feste Zahl im Test. Eine Pruefung, die
    bei jeder neuen Kachel rot wird, erzieht dazu, ihr Rotwerden zu
    ignorieren. Sie zaehlt jetzt aus bereiche.js.
  * "das Licht der Kalender-Kachel (tuerkis) muss mehr Blau als Rot
    haben" -- Wissen von aussen, und nach dem Neurechnen war der
    Kalender rosa. Gemessen wird jetzt gegen den Ton der Kachel selbst.
  * pruef-workspace-umzug meldete sein Ergebnis in eigenen Worten. Der
    Gesamtlauf las daraus NULL Pruefungen und schrieb bei JEDEM Lauf ein
    FEHL, obwohl alle 31 Punkte bestanden. Ein Fehlalarm, der immer
    kommt, macht den einen echten unsichtbar.

Und weil "BUTTON 'Meine Sicht' verdeckt" mich eine Stunde gekostet hat,
sagen pruef-handy und pruef-tempo jetzt DAZU, was verdeckt und was
springt -- mit Elternkette und Koordinaten. Ein Befund, den man nicht
verorten kann, ist ein halber.

NEU: der Kalender zum Abonnieren (Stufe 3.2). Persoenlicher, jederzeit
widerrufbarer Link fuer Google, Apple und Outlook. 36 Pruefungen, die
das ICS ZURUECKLESEN statt es anzusehen -- entfaltet, entschluesselt,
verglichen. Wichtigster Punkt: Der Weg ohne Anmeldung darf nichts
zeigen, was der Weg mit Anmeldung nicht zeigt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 23:15:37 +02:00
DogFatherGitandClaude Opus 5 c8a4e7628c Stufe 1+2: Zahlen ueber das Geschaeft, und eine Fruehwarnung
Der grosse Befund aus dem Plan vom 31.08.2026: Der Workspace
organisiert ARBEIT hervorragend, wusste ueber das GESCHAEFT aber
nichts. Keine Diamanten, keine LIVE-Tage, keine Verweildauer. Damit
hing die ganze Betreuung in der Luft -- der Start-Check bewertete ohne
zu messen, der Report fragte "was hat funktioniert" ohne Beleg, das
90-Tage-Ziel war ein Satz statt eines Fortschritts.

STUFE 1 -- LEISTUNG

Eine Zeile je Creator und TAG (nicht Woche: Feineres laesst sich immer
zusammenfassen, Groeberes nie aufteilen). Diamanten, LIVE-Dauer,
gueltiger Tag, Zuschauer im Schnitt und in der Spitze, Verweildauer,
Schenker, neue Follower -- und eine NOTIZ. Ohne sie sieht man in drei
Monaten einen Einbruch und weiss nicht mehr, dass die Person Grippe
hatte.

DIE VERWEILDAUER IST DIE LEITZAHL (Recherche 06.09.2026): 2026 haengt
der Algorithmus alles an der Completion Rate, und sie gehoert als
BETRIEBSkennzahl behandelt -- sie soll die naechste Runde steuern,
nicht die letzte erklaeren.

Jede Zahl kommt mit Vergleich, Verlauf und Einordnung. Eine Zahl ohne
diese drei ist eine Eitelkeitszahl: Sie sieht nach Auskunft aus und ist
keine, weil man nichts entscheiden kann.

Zwei Wege hinein: Schnelleingabe und CSV-Import aus dem offiziellen
Export, mit Vorschau vor dem Uebernehmen.

STUFE 2 -- FRUEHWARNUNG

Sechs benannte Signale (Zahlen fallen, LIVE-Tage brechen weg, lange
nicht angemeldet, kein Gespraech, Aufgabenstau, Start-Check haengt) und
daraus EIN ruhiger Satz: "Bei Nora wuerde ich diese Woche nachfassen."

BEWUSST KEIN SCORE. Eine Note von 1 bis 100 wirkt objektiv und ist es
nicht; sie verfuehrt dazu, Menschen nach einer Zahl zu behandeln. Am
Score kann man nichts tun, am Signal schon. Deshalb Saetze statt
Punkte, und jedes Signal einzeln nachvollziehbar.

Ein CREATOR sieht die Fruehwarnung nicht: Das ist eine
Arbeitsgrundlage fuer die Betreuung, keine Mitteilung an die
betroffene Person.

ZWEI ECHTE FEHLER, VON DER PRUEFUNG GEFUNDEN

1. ZAHLENFORMAT, Faktor tausend daneben. "1.250" wurde als 1,25
   gelesen und "1,234" als 1,234. Die Regel "das letzte Trennzeichen
   ist das Dezimalzeichen" liefert bei nur EINEM Trennzeichen fuer
   beide Faelle das Falsche -- und die Zahl sieht danach trotzdem
   plausibel aus. Jetzt entscheidet, wie viele Ziffern dahinter stehen:
   genau drei heisst Tausendertrenner.

2. DIE ZIELE-ROUTE WURDE VERSCHLUCKT. Express nimmt die erste passende
   Route, und `:tag` passt auch auf "ziele" -- ein PUT auf .../ziele
   landete in der Tages-Route und scheiterte am Datumsmuster. Die
   Meldung sagte "ungueltig", was auf die Zahlen deutet, nicht auf den
   Weg. Reihenfolge getauscht.

Beides waere still gewesen: falsche Zahlen sehen richtig aus, und ein
Ziel, das sich nicht setzen laesst, probiert man zweimal und laesst es
dann.

pruef-leistung.mjs: 47 Punkte, darunter jede Rechnung einzeln
nachgerechnet (Durchschnitte ohne Tage ohne Wert, Prozent von null,
Wochengrenzen), Import zweimal eingelesen, deutsche und englische
Zahlenformate, Rechte, und die Gegenprobe, dass die Fruehwarnung bei
Unauffaelligkeit SCHWEIGT.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 18:12:16 +02:00
DogFatherGitandClaude Opus 5 9dc35f5da6 Chat wieder einhaengen -- die Datei ist jetzt da
Nachtrag zu 09a4cfd ("AUSFALL BEHOBEN: versehentlich mitcommitteten
Import zurueckgenommen"). Das war richtig: Import und Einhaengung des
Chats waren aus einem unfertigen Stand mitgekommen, waehrend
workspace-chat.js noch gar nicht im Repo lag -- der Server fand das
Modul nicht und stuerzte in einer Schleife ab.

Seit 4637aa2 liegt die Datei im Repo. Ohne diese Zeile blieb der Chat
aber tot: Der Server startete tadellos, und JEDER Chat-Weg antwortete
still mit 404. Gemessen ueber die Browserkonsole -- die Ampelpruefung
meldete "Failed to load resource: 404" und nannte drei Adressen:
/api/chat/raeume, /api/chat/strom, /api/chat/ungelesen.

DER UNANGENEHMERE VON ZWEI FEHLERN: Fehlt die Datei, faellt der ganze
Dienst aus -- laut und sofort. Fehlt nur die Einhaengung, laedt die
Seite, der Chat bleibt leer, und niemand sieht warum. Deshalb steht
jetzt ein Kommentar an der Zeile, der beides zusammen nennt.

Nachgemessen nach der Reparatur: 0 fehlende Ressourcen (vorher 3).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 17:43:09 +02:00
DogFatherGitandClaude Opus 5 8e3eccc7a8 Alte Workspace-Adresse abgeschaltet statt weitergeleitet
Auf Filipes Wunsch: dogfather-universe.com/workspace/ soll nicht mehr
existieren, er gibt den neuen Link selbst an Creator und Scouts weiter.
Vorher stand dort eine Weiterleitung - die haette die alte Adresse auf
unbestimmte Zeit am Leben gehalten.

Der Server antwortet dort jetzt mit 410 Gone. Beides - 404 und 410 -
heisst "gibt es hier nicht"; 410 sagt zusaetzlich "gab es, ist
absichtlich weg, kommt nicht wieder". Genau der Sachverhalt.
Suchmaschinen nehmen die Adresse dadurch schneller heraus, und in einem
Protokoll ist ein 410 sofort als gewollt erkennbar, waehrend ein 404
immer nach Versehen aussieht.

Statt einer nackten Fehlermeldung kommt eine kurze Hinweisseite mit der
neuen Adresse. Wer hier landet, hat einen alten Link oder eine alte
Verknuepfung und soll erfahren, wohin der Workspace gezogen ist, statt vor
einem leeren Fenster zu sitzen. Bewusst OHNE Verweis zum Anklicken, damit
niemand aus Versehen ein neues Lesezeichen auf den alten Weg setzt.

Schnittstellen-Aufrufe unter /workspace/api/ bekommen JSON statt HTML -
ein alter, noch offener Browser-Tab wuerde sonst die Hinweisseite als
Daten zu lesen versuchen und einen unverstaendlichen Fehler zeigen.

Die Pruefung deckt weiterhin 21 Faelle ab und ist mitgezogen: Der
gefaehrlichste Fall heisst jetzt nicht mehr "Endlosschleife", sondern
"die neue Adresse mit abschalten" - wer nicht auf den Hostnamen prueft,
sperrt den Workspace fuer alle aus. Alle gruen, Gegenprobe schlaegt an.

Diesmal vor dem Commit den Diff Datei fuer Datei kontrolliert - beim
letzten Mal hatte ich hier eine fremde uncommittete Zeile mitgenommen und
damit die Website fuer zwei Minuten abgeschossen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 16:34:27 +02:00
DogFatherGitandClaude Opus 5 09a4cfdeab AUSFALL BEHOBEN: versehentlich mitcommitteten Import zurueckgenommen
Die Website war ab 16:27 unerreichbar (HTTP 502, 29 Neustartversuche).
Ursache war mein Commit 58b8ef2: Beim "git add server/index.js" habe ich
eine uncommittete Zeile einer parallel laufenden zweiten Sitzung
mitgenommen -

    import { chatRouter } from "./workspace-chat.js";
    app.use(chatRouter);

- deren Datei workspace-chat.js aber noch nicht committet war. Auf dem
Server fehlte sie deshalb, und Node bricht beim Start mit
ERR_MODULE_NOT_FOUND ab.

Warum es niemandem vorher auffiel: Der Dienst lief seit Stunden mit dem
alten Code im Speicher. Ein fehlender Import faellt erst beim NEUSTART auf
- und der erste Neustart seit dem Push war meiner fuer den Workspace-Umzug.
Der Umzug selbst war nicht die Ursache, er hat den Fehler nur ausgeloest.

Behoben durch Entfernen der beiden Zeilen - nicht durch Nachcommitten von
workspace-chat.js: Die Chat-Funktion ist unfertige fremde Arbeit
(workspace.js und workspace-push.js sind dort ebenfalls geaendert und
uncommittet). Sie gehoert von der Sitzung committet, die sie gebaut hat.
Der Server laeuft damit wieder auf dem Stand, der vorher lief - plus dem
Workspace-Umzug.

Eigene Lehre, doppelt: Bei den 17 workspace-Seiten hatte ich die fremden
Aenderungen sorgfaeltig aus dem Index herausgehalten - bei server/index.js
habe ich genau das vergessen. Und: node --check haette es nie gefunden,
ein Import auf eine nicht existierende Datei ist syntaktisch tadellos.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 16:29:20 +02:00
DogFatherGitandClaude Opus 5 58b8ef233a Creator Workspace zieht auf eine eigene Adresse um
Der Workspace laeuft ab sofort auf workspace.dogfather-universe.com. Die
alte Adresse dogfather-universe.com/workspace/ leitet dorthin weiter.

Grund: Chrome laesst neben der Hauptseite, deren Bereich "/" die ganze
Domain umfasst, keine zweite App auf derselben Adresse zu. Unter dem alten
Pfad liess sich der Workspace nur als Verknuepfung ablegen, nie als
richtige App installieren - im Menue stand "Oeffnen in DOGFATHER
UNIVERSE" statt "Seite als App installieren". Das ist kein Fehler,
sondern Absicht (w3c/manifest Nr. 1180: verschachtelte Bereiche auf einem
Ursprung sind "strongly not recommended"). Auf der neuen Adresse hat
Filipe die App erfolgreich installiert.

Der PFAD /workspace/ bleibt erhalten. An ihm haengen 150 Server-Routen,
107 API-Aufrufe und 26 Server-Dateien - ihn wegzuschneiden waere ein
grosser Umbau ohne Gewinn, denn der Konflikt entsteht durch die
gemeinsame ADRESSE, nicht durch den Pfad. Dadurch musste am Code nichts
weiter geaendert werden.

Die Entscheidung steht in einer eigenen Datei (workspace-umzug.js), weil
sie zwei Stellen hat, an denen ein Denkfehler teuer waere und die man
einer Bedingung nicht ansieht:

  1. ENDLOSSCHLEIFE - derselbe Dienst bedient beide Adressen. Ohne
     Hostpruefung leitet die neue Adresse auf sich selbst, und der
     Workspace waere sofort nach dem Neustart fuer alle unerreichbar.
  2. PRAEFIX-IRRTUM - "faengt an mit /workspace" trifft auch
     /workspaceXYZ und /workspace-alt.

Als eigene Funktion ist beides pruefbar, ohne den Server zu starten:
pruef-workspace-umzug.mjs deckt 21 Faelle ab (alte/neue Adresse, mit und
ohne www, Gross-/Kleinschreibung, Portangabe, lokale Testadressen, beide
Praefix-Fallen). Alle gruen. Gegenprobe gemacht: Baut man die
Endlosschleife absichtlich ein, meldet die Pruefung 3 Fehler; baut man den
Praefix-Irrtum ein, meldet sie 2. Sie kann also auch "nein" sagen.

Bewusst 302 und nicht 301: Ein 301 wird vom Browser dauerhaft gemerkt und
laesst sich praktisch nicht zurueckholen - waere an der Umleitung etwas
falsch, waere die alte Adresse fuer jeden, der sie einmal aufgerufen hat,
dauerhaft unbrauchbar.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 16:23:32 +02:00
DogFatherGitandClaude Opus 5 627f710d71 Aufgaben abbrechen, Teilnehmerwahl fuer alle, Benachrichtigungen
Zwei Wuensche vom 05.09.2026, dazu drei Fehler, die dabei ans Licht kamen.

ABBRECHEN (Wunsch: "in jedem status die aufgaben auch abbrechen koennen,
nur ich die manager und scouts")

Neuer Status mit Pflicht-Grund, aus jedem der vier Status heraus.
Festgehalten wird auch, WO die Aufgabe stand -- "im Review abgebrochen"
ist eine andere Aussage als "nie angefangen", und das Wiederaufnehmen
geht dorthin zurueck statt nach "offen".

Eigener Weg statt "abgebrochen" in der Statusliste: Dort entscheidet
darfAendern(), und das laesst auch den zustaendigen Creator aendern.
Der gewoehnliche PATCH kann diesen Zustand deshalb gar nicht erreichen
-- auch nicht fuer DogFather, sonst waere die Grund-Pflicht umgehbar.

Abgebrochenes steht in einem zugeklappten Bereich unter dem Brett, nicht
als fuenfte Spalte: Am Handy waeren dann alle fuenf unlesbar schmal.
Verschwinden darf es nicht, sonst waere der Abbruch ein Loeschen mit
Zwischenschritt.

Die Tabelle musste dafuer getauscht werden (SQLite kann CHECK nicht
aendern). Vorher auf einer Kopie durchgespielt: 40 von 40 Aufgaben,
Inhalte, Verweise und Indizes geprueft, Gegenprobe zeigt, dass der CHECK
noch lebt.

TEILNEHMERWAHL (Wunsch: "das soll viel besser aussehen und fuer jeden
verfuegbar sein")

Auf dem Bildschirm klebten die Namen aneinander: "DogfatherDogFather".
Ursache war, dass kalender.html das Stylesheet mit diesen Klassen nie
eingebunden hat -- sie standen in dateien.css. Vierzig gruene Pruefungen
zur Teilnehmerwahl hatten das nicht gemerkt, weil keine je gefragt hat,
ob es AUSSIEHT wie gedacht.

Jetzt eigene Klassen im eigenen Stylesheet, nach Rollen gruppiert: Die
Rolle steht einmal als Ueberschrift statt neunmal am Namen. Damit ist
das Kleben an der Wurzel weg, nicht zugepflastert.

"Fuer jeden" war mehr als ein hidden zu entfernen: darfEintragen() haette
einem Creator nur sich selbst erlaubt. Er haette seinen Scout gesehen,
angeklickt, und der Server haette ihn still weggelassen -- ein Knopf, der
nichts tut. einladbareIds() schaut jetzt in beide Richtungen, bewusst
getrennt von /api/personen: Wer die erweitert, gibt einem Creator
nebenbei die Moeglichkeit, seinem Scout Aufgaben zuzuweisen.

BENACHRICHTIGUNGEN (Wunsch: "sowas, und dass es perfekt funktioniert
fuer jeden")

Web Push nach RFC 8291/8292, ohne fremde Abhaengigkeit. Der Knopf sagt
in jeder Lage die Wahrheit, auch die unbequemen: abgelehnt (mit dem
Hinweis, wo man es zuruecknimmt), iPhone im Reiter (mit Anleitung),
Browser ohne Push. Ein Knopf, der bei abgelehnter Berechtigung nur
nichts tut, ist der sichere Weg zu "das funktioniert nicht".

DREI FEHLER, DIE DABEI AUFFIELEN

1. Ein defekter Zugangsdatensatz sperrte ALLE einer Rolle aus. Wirft
   hashe() bei einer Person, flog die ganze Anmeldung in den catch: 503
   "nicht verfuegbar" fuer jeden mit dieser Rolle. Aufgefallen durch
   einen eigenen Testfehler. Jetzt wird die defekte Person uebersprungen
   und laut protokolliert; die Gegenprobe zeigt, dass ein falscher Code
   weiterhin abgelehnt wird.

2. Die Glocke sprengte die Kopfleiste -- zweimal. Bei 320 px lag die
   Lupe des Suchknopfes auf dem Sicht-Umschalter (ein Knopf, der auf 12
   Seiten ins Leere tippt), bei 768 px wurde der Abmelden-Knopf bis zu
   15 px aus dem Bild geschoben, weil die Textgrenze auf 760 stand und
   ein Tablet 768 hat. Nachgewiesen durch Messen mit und ohne Glocke,
   nicht durch Vermuten.

3. .block__frage war viermal gestaltet und stand auf einer Seite, die
   keine dieser Dateien laedt -- derselbe Fehler wie bei der
   Teilnehmerwahl. Gefunden von der neuen Klassenpruefung beim ersten
   Lauf.

NEUE PRUEFUNGEN

pruef-css-klassen   jede gestaltete Klasse muss auf ihrer Seite ankommen
                    (unterscheidet Struktur-Anker von echtem Verlust)
pruef-dabei-optik   die Wahl im Browser, an den echten Pixeln
pruef-abbrechen     Umstellung auf einer Kopie, Rechte, Rueckweg
pruef-abbrechen-optik   Knopf, Dialog, Bereich, Handy
pruef-glocke        Zustaende, An/Abmelden, jede Rolle
pruef-push(-weg)    Rechnung gegen die RFC-Vektoren, Zustellung

pruef-struktur prueft jetzt zusaetzlich, ob sich jedes Server-Modul als
ESM laden laesst. node --check auf einer .js-Datei prueft als CommonJS
und meldete "ok", waehrend der Import scheiterte.

Gesamtlauf: 55 von 55 Dateien, 1973 von 1973 Punkten.

Was NICHT geprueft werden konnte und deshalb dasteht: Der Schritt
"Browser holt eine Adresse beim Push-Dienst" braucht eine Verbindung zu
Googles FCM, die ein Pruef-Browser nicht hat. Die Pruefung misst das
zuerst und meldet es als dritten Ausgang, statt gruen zu sein.
Verschluesselung und Zustellung sind getrennt geprueft; diese eine
Strecke beweist sich erst auf dem Server.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-05 18:05:28 +02:00
DogFatherGitandClaude Opus 5 51c3d4402b Audit des Creator Workspace, App-Symbole fuer alle Apps der Domain
AUDIT (Auftrag: vollstaendiger Durchgang, Fehler direkt beheben)

Ausgangslage waren 40 Pruefungen mit 1616 Einzelpunkten, alle gruen.
Acht neue Pruefungen kamen dazu; sie haben gefunden, was die alten nicht
sehen konnten.

Der schwerste Fund: Die Zugangsschranke verglich req.path EXAKT gegen
eine Liste. Express raeumt Punkt-Segmente selbst weg, mehrfache
Schraegstriche aber nicht. Damit kam //workspace/start.html OHNE
Anmeldung mit HTTP 200, und ein Creator bekam ueber
/workspace//personen.html die Verwaltungsseite. Die DATEN waren nie
betroffen (nachgemessen: 404 bzw. 401). Behoben durch Normalisierung
UND eine Umkehr der Logik -- jetzt ist jede .html geschuetzt ausser der
Anmeldeseite, statt nur die in der Liste. Eine vergessene neue Seite
steht damit nicht mehr versehentlich offen.

Weiter behoben:
  * Kaputter/abgebrochener Rumpf ergab 500 in HTML statt 400 in JSON --
    die Oberflaeche ruft ueberall a.json() und lief in einen zweiten
    Fehler; der Knopf hing ohne Meldung.
  * POST /zustand/sichern war der einzige von 60 schreibenden Wegen
    ohne Herkunftspruefung.
  * workspace-sicherung.js gab interne Pfade in Fehlermeldungen nach
    aussen; alle 23 anderen Module antworten neutral.
  * admin_notiz war als einziges von 14 Feldern ohne <label>.
  * Der aktive Filter hatte keinen sichtbaren Fokus (CSS-Spezifitaet
    0,3,0 schlug 0,2,0) -- genau der Knopf, auf dem man steht.
  * h1 -> h3 ohne Zwischenstufe auf zwei Seiten.
  * HSTS ging auch ueber http mit (RFC 6797, 7.2 verbietet das).
  * upgrade-insecure-requests galt auch auf 127.0.0.1 -- dadurch war
    WebKit/Safari ueberhaupt nicht pruefbar, also der Browser, den
    jedes iPhone benutzt.
  * pruef-grosscheck las readdirSync(".") und pruefte aus server/
    gestartet NULL oeffentliche Seiten -- meldete aber "ok".

Neue Pruefungen: struktur, schranke, haerte, alle-wege,
barrierefrei-workspace, breiten, tempo-workspace, browser.
Jede mit Gegenprobe und mit der geprueften Anzahl in der Bedingung.
Vier davon sind beim Bauen durch die eigene Gegenprobe aufgeflogen und
haetten sonst dauerhaft gruen gemeldet, ohne etwas zu messen.

APP-SYMBOLE (Wunsch: alle Apps der Domain, jede anders, ausser
safeaddress)

Zehn Apps, zehn Stile, zehn in OKLCH gerechnete Farben. Zusammen haelt
sie dasselbe Logo, dieselbe Eckenrundung und eine gemeinsame gedeckte
Farbreihe. Beim Bauen wird gemessen, ob sich das Logo vom Grund abhebt
(19 bis 58 Helligkeitsstufen).

Dabei aufgefallen: Das Kundenportal hatte kein eigenes Manifest und
trug Namen und Symbol der Webdesign-Seite. Der Workspace hatte gar
keins und war als App nicht installierbar. Beide haben jetzt eins.

Geaendert wurde AUSSCHLIESSLICH das Symbol. Ein Zwischenstand hatte
auch die Themenfarben gesetzt; das war mehr als bestellt und wurde
zurueckgenommen.

Werkzeuge: tools/logo-freistellen.mjs, tools/app-symbole.mjs,
tools/app-symbole-einbinden.mjs -- alles im Browser gerechnet, kein
Bildprogramm, keine neue Abhaengigkeit.

Gitea und Nextcloud sind bereits live und nachgeprueft.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-05 11:42:17 +02:00
DogFatherGitandClaude Opus 5 23429627ef Termine, die von allein weiterlaufen -- bis man sie abstellt
Wunsch: "ich will dass ich da im kalender auch sachen machen die jede
woche jeden monat automatisiert immer weiter laufen so wie ich es
auswaehle bis ich es selber deaktiviere. aktiviere diese option fuer
jeden."

Acht Rhythmen (taeglich, werktags, woechentlich, alle zwei Wochen,
monatlich am Datum, am Monatsletzten, am n-ten Wochentag, jaehrlich),
wahlweise mit Enddatum oder ohne Ende. Fuer JEDE Rolle -- Creator und
Scouts legen sie fuer sich selbst an, mit denselben Grenzen wie beim
einzelnen Termin.

WARUM ECHTE TERMINE UND KEINE GERECHNETEN AUSPRAEGUNGEN

Der naheliegende Weg waere gewesen, die Wiederholung nur beim Anzeigen
auszurechnen. Das waere ein stiller Ausfall geworden: ACHT andere Stellen
lesen die Tabelle termine direkt -- Calls, Protokolle, Berichte,
Hinweise/Ampel, Suche, Aufgaben ("naechster Termin"), Uebersicht und die
Startseite. In all diesen Ansichten haette schlicht nichts gestanden, und
aufgefallen waere es erst Monate spaeter. Stattdessen macht ein
Nachfueller aus der Regel echte Zeilen (Horizont 180 Tage) -- jedes andere
Modul sieht sie mit, ohne dass dort eine Zeile geaendert werden musste.
Beim geplanten ICS-Abo gilt dasselbe.

KEIN ZEITGEBER. Der Nachfueller laeuft beim Serverstart, beim Anlegen und
Aendern und beim Oeffnen des Kalenders (dort hoechstens alle fuenf
Minuten). Er ist idempotent. Ein Cron waere eine weitere Sache gewesen,
die stillschweigend ausfallen kann.

WAS BEIM ABSTELLEN PASSIERT: Vergangene Termine und alles, was jemand von
Hand angefasst hat (verschoben, umbenannt, abgehakt), bleibt stehen. Nur
die unberuehrte Zukunft wird aus dem Kalender genommen. Wer einen
einzelnen Tag loescht, streicht nur diesen einen -- der Tag wird als
Ausnahme vermerkt, sonst legte der Nachfueller ihn wieder an.

ZEITUMSTELLUNG: Gerechnet wird auf reinen Datumstexten in UTC-Mittag, die
Uhrzeit wird als Text angehaengt. 18:00 bleibt dadurch 18:00 und wandert
im Oktober nicht auf 17:00.

DIE SICHTBARKEITSREGEL STEHT JETZT NUR NOCH EINMAL (workspace.js,
termineSichtbar) statt zweimal fast gleich. Zwei Fassungen waeren
auseinandergelaufen -- und dann haette eine Wiederholung jemandem etwas
gezeigt, was der einzelne Termin ihm verbirgt.

IN DER OBERFLAECHE beschriften sich die Rhythmen nach dem gewaehlten
Datum ("jeden Dienstag", "jeden Monat am letzten Dienstag") statt
abstrakt ("woechentlich"), inklusive des ehrlichen Hinweises, dass "jeden
31." den Februar auslaesst. Darunter steht der ganze Satz in Worten. Eine
neue Leiste "Laeuft von allein" zeigt alle laufenden Wiederholungen mit
Abstell-Schalter -- was von selbst weiterlaeuft, muss man sehen koennen.

GEPRUEFT: 67 Pruefungen (server/pruef-serien.mjs), darunter von Hand
nachgeschlagene Datumsangaben fuer jeden Takt (der letzte Dienstag im
Dezember 2026 ist der 29., nicht der 22.; der 29. Februar nur in
Schaltjahren) und vier GEGENPROBEN, die beweisen, dass die Pruefungen
auch "nicht in Ordnung" sagen koennen. Die Anzahl der Pruefungen steht in
der Bedingung, nicht nur im Meldetext. Bestehende Pruefungen unveraendert
gruen: Kalender 84, Sicht 48, Startansicht 133, Protokoll 52, Ampel 47,
Handy 50, Aufgabenbrett 44, Sprung 43, Personen-Loeschen 40, Uebersicht
33, Workspace-Seiten 32, Formulare 19, Betreuung 18, Grosscheck 15,
Lesbarkeit 14.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-02 17:12:00 +02:00
DogFatherGitandClaude Opus 5 1c00770ec5 Lesbarere Kaesten, und DogFather kann durch fremde Augen sehen
SCREEN 1 -- "die Kachel ganz leicht dunkler, so dass man den Text besser
gelesen bekommt, aber nicht zu viel, so dass man den Hasen noch sieht."

Die Erklaerkaesten stehen jetzt auf 88 statt 78 Prozent Deckung. Zehn
Punkte sind gemessen der Unterschied zwischen muehsam und ruhig lesbar
und lassen zwoelf Prozent Bild durch -- das Motiv bleibt sichtbar.

"und die von wichtigen und neuen PDFs sollen auch staerker sein."
Das war kein Geschmack, sondern ein Fehler: `background` ist eine
Eigenschaft, keine Schicht. Die Zeile
`background: rgba(232,192,125,.045)` hat die Flaeche nicht getoent,
sondern ERSETZT -- uebrig blieben viereinhalb Prozent Deckung. Damit war
ausgerechnet die Anleitung, die jeder lesen soll, die am schwersten
lesbare der Seite. Die Toenung liegt jetzt als Schicht darueber.
Gemessen: 88 % gegen 78 % bei einer gewoehnlichen.

pruef-lesbarkeit.mjs misst das an ECHTEN PIXELN (Text kurz unsichtbar
machen, Flaeche fotografieren, WCAG-Formel) und kennt ZWEI Grenzen --
lesbar genug UND durchsichtig genug. Mit nur einer haette sie eine
schwarze Flaeche am besten gefunden, und das wollte niemand.

SCREEN 2 -- "ich will alles von den Scouts und Managern einsehen
koennen, auswaehlen, was und von wem. Ueberall, auf jeder Seite.
NUR WIR BEIDE SOLLEN DIESE OPTION HABEN."

Die naheliegende Loesung waere ein Filter je Seite gewesen -- also eine
zweite Rechteregel in zwoelf Modulen, und eine Rechteregel an zwoelf
Stellen stimmt irgendwann an elf. Stattdessen wird die PERSON getauscht,
nicht die Regel: Waehlt DogFather einen Scout, laufen alle vorhandenen
Sichtbarkeitsregeln unveraendert mit diesem Scout. Er sieht exakt dessen
Arbeitsplatz -- nicht mehr, nicht weniger. Keine neue Rechteregel.

Im Browser genauso: EIN Ort statt vierzehn. fetch wird einmal umgeleitet
und haengt den Wert an jede lesende Abfrage an. Neue Seiten sind damit
von selbst dabei; man kann es nicht vergessen.

Drei Sicherungen: nur admin (auf dem SERVER geprueft, nicht in der
Oberflaeche), nur lesend (geschrieben wird immer im eigenen Namen --
sonst staende im Protokoll der falsche Name), nur aktive Personen.

Und ein Rahmen um die Seite, solange eine fremde Sicht laeuft. Der
gefaehrlichste Fall ist nicht, dass man nicht umschalten kann, sondern
dass man vergisst, dass man umgeschaltet hat -- und drei Aufgaben statt
dreissig fuer den Bestand haelt.

FUENF FEHLER, DIE DIE PRUEFUNGEN GEFUNDEN HABEN:

1. steckbrief.html hat die Kopfleiste NIE gefuellt -- dort stand
   monatelang "…" statt des eigenen Namens. Aufgefallen, weil der
   Umschalter dort fehlte. Jetzt zusaetzlich ein Netz darunter: Meldet
   sich nach kurzer Zeit niemand, holt der Kopf sich selbst, wer
   angemeldet ist. Die naechste neue Seite kann es nicht mehr vergessen.

2. Der Umschalter sprengte die Kopfleiste (46 px am Rechner, 117 px am
   Handy) und drueckte den Abmelden-Knopf hinaus.

3. Ich habe das <select> gestaltet -- wahl.js ersetzt aber jedes
   Auswahlfeld durch einen eigenen Knopf und schrumpft das echte Feld
   auf einen Pixel. Meine Regeln haben es wieder auf 20 x 44 aufgeblasen,
   wo es als unsichtbares Hindernis ueber dem Knopf lag. Gestaltet wird
   jetzt der Knopf.

4. Ein Wettlauf: Auf profil.html rufen zwei Dateien werZeigen() auf.
   Beide kamen an "gibt es den Umschalter schon?" vorbei, bevor eine ihn
   angehaengt hatte -- zwei Umschalter uebereinander. Die Sperre gehoert
   vor das erste await.

5. Die Handy-Pruefung bemaengelte ein Schild, das dort per display:none
   gar nicht erscheint. Sie sieht jetzt nur noch sichtbaren Text an --
   eine Pruefung, die Unsichtbares anmahnt, gewoehnt man sich ab zu
   lesen.

Dazu zwei Messfehler in den Pruefungen selbst: getComputedStyle liefert
ein LEBENDES Objekt (die Farbe wurde gelesen, nachdem der Text
unsichtbar gemacht war -- gemeldet wurden 1,17:1 fuer tadellos lesbaren
Text), und ein Vergleich lief still ins Leere, weil die Vergleichsdaten
fehlten.

pruef-sicht.mjs stellt den MISSBRAUCH an den Anfang: Scout, Manager und
Creator haengen ?sicht= an und muessen ignoriert werden; erfundene
Nummern, Buchstaben und ein Einschleusversuch fallen auf die eigene
Sicht zurueck; eine abgeschaltete Person liefert keine Sicht mehr; und
was DogFather bei fremder Sicht anlegt, steht unter SEINEM Namen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 21:20:23 +02:00
DogFatherGitandClaude Opus 5 9267797d1d Feste Checklisten statt Vorschlaege - in allen vier Bereichen
"Die neuen Sachen in der LIVE-Analyse soll der Creator FEST sehen, auch
schoen kategorisiert, und der Ansprechpartner soll anklicken koennen,
wenn er findet, dass der Creator was verbessern sollte."

DER UMBAU. Vorher waren die Punkte Vorschlaege zum Uebernehmen: Man
holte sie sich und bekam einen eigenen Eintrag. Das war falsch gedacht.
Eine Checkliste, die man erst anfordern muss, ist keine Checkliste --
und schlimmer: Zwei Creator haetten unterschiedliche Listen gehabt, je
nachdem wer sich was geholt hat. Genau das macht einen Vergleich
unmoeglich, und um Vergleich geht es bei einer Betreuung.

Jetzt stehen dieselben Punkte fuer JEDEN fest da, gruppiert:

  LIVE       21 Punkte -- vor, waehrend, nach der Sendung
  Community  14 Punkte -- Moderation vorbereiten, aufbauen, wenn es kippt
  Technik    12 Punkte -- Einrichtung, Ausfall, was geholfen hat
  Content    13 Ideen  -- nach Saeule (70/20/10) statt nach Ablauf

Jede Gruppe hat einen Satz, der erklaert, wofuer sie da ist. Eine
Ueberschrift allein sagt das nicht.

Was sich je Creator unterscheidet, ist nur der STAND -- und den setzt
die Betreuung: "Passt so" oder "Verbessern". Ein Creator kann sich nicht
selbst bewerten; koennte er es, stuende alles auf gruen. "Verbessern"
verlangt einen Satz, WAS zu verbessern ist -- eine Bewertung, mit der er
nichts anfangen kann, ist nicht streng, sondern nur entmutigend.

Der Creator sieht alles: die Stufe, den Grund, den Namen und den
Zeitpunkt. Und er kann an JEDEM Punkt antworten -- das ist der Kanal,
ueber den er ueberhaupt etwas sagen kann.

Oben steht eine Bilanz in einer Zeile: wie viele passen, wie viele sind
zu verbessern, wie viele hat noch niemand angesehen. Das ist die Frage,
die beide Seiten zuerst haben.

STABILE SCHLUESSEL statt Positionen. Ein Stand haengt am Schluessel des
Punktes ("ton-geprueft"), nicht an seiner Nummer. Haenge er an der
Position, waere beim Einfuegen eines Punktes in der Mitte jede Bewertung
dahinter am falschen Punkt -- und niemand wuerde es merken, weil beides
plausibel aussieht. 64 Punkte haben jetzt einen.

"Offen" loescht den Stand, statt ihn auf "offen" zu setzen: Ein
Datensatz, der nichts aussagt, ist Ballast.

ZWEI EIGENE FEHLER, VON DEN PRUEFUNGEN GEFUNDEN:

1. DAS CSS LAG IN DER FALSCHEN DATEI. Ich hatte es in content.css
   geschrieben -- bereich.html laedt die gar nicht. Die Punkte standen
   auf drei von vier Seiten nackt und ohne Flaeche da. Es ist derselbe
   Fehler wie im August bei .knopf-still, .schalter und .kopf-zeile, und
   es gibt seitdem eine Warnung dazu in start.css. Sie hat nichts
   genutzt, solange keine Pruefung sie nachhielt.

   Jetzt gibt es eine: Sie misst, ob eine Karte wirklich eine Kante und
   Polsterung hat -- nicht nur, ob das Element existiert. Gegenprobe
   gemacht: Klasse umbenannt, Pruefung meldet "STIL FEHLT".

2. Ein Betreuer sah beim Oeffnen keine Bewertungsknoepfe, weil noch kein
   Creator gewaehlt war -- und musste erst raten, dass er oben jemanden
   auswaehlen soll. Jetzt nimmt der Server den ersten betreuten Creator,
   wenn keiner angegeben ist.

Die alte Oberflaechenpruefung fuer den Vorschlaege-Block wurde entfernt
statt angepasst: Sie verlangte etwas, das es nicht mehr gibt. Eine
dauerhaft rote Pruefung ist schlimmer als keine -- man gewoehnt sich
daran, und beim naechsten echten Fehler sieht niemand hin.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 17:12:55 +02:00
DogFatherGitandClaude Opus 5 372a0eb95a Ampel und Rueckmeldungen - bewerten darf nur die Betreuung
Der Wunsch: "der Creator sieht, ob es gut ist oder schlecht. Und wenn
nicht gut, dann muss es verbessert werden -- und nur der Ansprechpartner
kann das aendern. Die Creator koennen nur Nachrichten hinterlassen zum
Kommunizieren."

ZWEI GETRENNTE DINGE, und sie getrennt zu halten ist der ganze Punkt:

  DIE AMPEL ist eine Beurteilung. Sie gehoert dem Betreuer, und nur er
  setzt sie. Koennte ein Creator sich selbst auf gruen stellen, waere
  sie wertlos -- dann stuende ueberall gruen. Der Server lehnt es mit
  403 ab und sagt dabei, wer es kann.

  DIE NACHRICHT ist ein Gespraech. Sie gehoert beiden. Ein Creator, der
  auf eine Bewertung nicht antworten kann, bekommt ein Urteil statt
  einer Betreuung.

DREI STUFEN, NICHT FUENF. Eine Zahl von 1 bis 5 klingt genauer und ist
es nicht: Niemand kann den Unterschied zwischen 3 und 4 erklaeren, und
am Ende steht ueberall die 3. Die Frage lautet "reicht das schon?", und
darauf gibt es drei ehrliche Antworten -- passt so, noch verbessern,
noch nicht angesehen.

"NOCH VERBESSERN" VERLANGT EINE BEGRUENDUNG. Eine Bewertung, mit der der
Creator nichts anfangen kann, ist nicht streng, sondern nur
entmutigend. Der Server lehnt sie ohne Grund ab; die Oberflaeche fragt
deshalb gleich danach, statt hinterher eine Fehlermeldung zu zeigen.
"Passt so" braucht keinen -- da gibt es nichts zu erklaeren.

Die Stufe steht IMMER an der Karte, auch fuer den Creator, auch wenn sie
"noch nicht angesehen" lautet. Er soll sehen, wo er steht, ohne fragen
zu muessen. Der Grund steht daneben in voller Breite, nicht in einer
Ecke.

FREMDE NACHRICHTEN BLEIBEN STEHEN -- auch fuer DogFather. Ein Gespraech
nachtraeglich umzuschreiben waere schlimmer, als eine unbedachte
Aeusserung stehen zu lassen. Wer etwas richtigstellen will, schreibt
eine neue.

VORLAGEN AUCH FUER COMMUNITY UND TECHNIK (Screens 11 und 12): 14
Moderations-, Aktions- und Konfliktpunkte, 12 Technikpunkte. Ton steht
vorn, weil schlechter Ton der Grund Nummer eins ist, warum Leute einen
Stream verlassen. Die drei Bereiche laufen jetzt ueber EINE Zuordnung
statt drei fast gleicher Bloecke -- sonst weicht der dritte irgendwann
ab. Die beiden alten Zweige wurden entfernt: Toter Code, den man stehen
laesst, wird beim naechsten Mal fuer lebenden gehalten.

Die Ampeln einer ganzen Liste kommen in EINER Abfrage. Zwanzig
Eintraege einzeln zu fragen waeren zwanzig Anfragen, und die Seite
ruckelte sichtbar beim Aufbau. Die Sichtbarkeitspruefung laeuft dabei
je Eintrag, nicht einmal pauschal -- ein fremder Eintrag taucht auch in
der Sammelabfrage nicht auf.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 16:49:56 +02:00
DogFatherGitandClaude Opus 5 5960f6e3c4 Unterweisungen mit beidseitiger Bestaetigung - und einer echten Sperre
Der Wunsch: "jeder Scout, Manager oder DogFather muss mit seinen
Creatorn die PDFs durchgehen, und beide druecken dann auf verifiziert,
so dass wir den Beweis haben -- und das ist danach auch nicht mehr zu
aendern."

Das ist kein Haekchen, das ist ein NACHWEIS. Wer so etwas baut, muss
drei Fragen beantworten, sonst ist er wertlos:

WER hat bestaetigt? Beide Seiten getrennt, mit Name, Zeitpunkt und IP.
Eine einzelne Bestaetigung reicht nicht -- "ich habe es ihm gezeigt" und
"er hat es mir gezeigt" sind zwei verschiedene Aussagen, und erst
zusammen ergeben sie einen Beweis. Bestaetigt nur einer, steht die
Unterweisung sichtbar als HALB da, in einer eigenen warnenden Farbe.
Diese Zwischenstufe sichtbar zu machen ist der Punkt: Ein Nachweis, bei
dem nur einer unterschrieben hat, sieht sonst aus wie fertig -- und man
merkt es erst, wenn jemand danach fragt.

WORAUF genau? Nicht auf "die Regeln", sondern auf eine bestimmte Datei.
Beim Bestaetigen wird der SHA-256 der PDF-Datei mitgespeichert. Tauscht
spaeter jemand die Datei aus, passt der Fingerabdruck nicht mehr, und
die Seite sagt das auch ("Das Dokument wurde seit der Bestaetigung
ausgetauscht"). Ohne diesen Wert waere die Bestaetigung ein Zettel ohne
Bezug.

IST ES UNVERAENDERT? Eine abgeschlossene Bestaetigung laesst sich nicht
mehr aendern und nicht loeschen -- und zwar nicht, weil der Code es
nicht anbietet, sondern weil die DATENBANK es ablehnt. Zwei Trigger mit
RAISE(ABORT). Ein Schutz, der nur im Code steht, ist beim naechsten
neuen Weg zur Datenbank wieder weg.

DER VOLLZUG WURDE DURCHGESPIELT. Aus RunOne stammt die Lehre, dass ein
Weg, den man nicht rueckgaengig machen kann, tagelang live sein und NIE
gelaufen sein kann. Die Pruefung bestaetigt deshalb wirklich, schliesst
ab, und versucht dann eine Aenderung -- ueber die Schnittstelle UND
direkt auf der Datenbank. Beide werden abgelehnt.

Und die GEGENPROBE dazu: Der Trigger wird entfernt, dieselbe Aenderung
versucht -- sie geht durch -- und der Trigger wieder gesetzt. Eine
Sperre, die man nicht hat scheitern sehen, ist keine Sperre.

Der Server entscheidet anhand der ROLLE, welche Seite gesetzt wird --
nicht der Absender. Sonst koennte ein Creator die Bestaetigung seines
Betreuers eintragen, und der ganze Nachweis waere wertlos. Eine bereits
gesetzte Seite wird nie ueberschrieben; ein Datum laesst sich also auch
nicht nachtraeglich verschieben.

Die Dokumente kommen aus der Wissens-Bibliothek, es gibt keinen zweiten
Upload-Weg. Sonst gaebe es Dateien, die nur hier existieren -- und
niemand wuesste, welche Fassung die richtige ist. Eine Unterweisung wird
nie geloescht, nur abgeschaltet: Die Nachweise haengen daran.

EIN EIGENER FEHLER, VON DER BROWSERPRUEFUNG GEFUNDEN: Der Aufruf der
Zusatzbloecke stand NACH einem return. laden() steigt frueh aus, wenn
die Liste leer ist -- und dann wurden Vorlagen und Unterweisungen nie
gebaut. Also ausgerechnet auf der leeren Seite, fuer die sie gedacht
sind. Jetzt stehen sie in einem finally.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 16:39:00 +02:00
DogFatherGitandClaude Opus 5 ca10479909 Fertige Vorlagen zum Uebernehmen - Content-Ideen und LIVE-Punkte
Der Wunsch stand an fuenf Stellen gleichlautend: "ich will dass da schon
fertige Sachen stehen". Eine leere Seite mit einem Knopf "Neuer Eintrag"
verlangt vom Creator genau das, was er noch nicht kann -- zu wissen, was
ueberhaupt hineingehoert.

WARUM VORLAGEN UND KEINE VORAUSGEFUELLTEN DATEN. Man koennte beim
Anlegen eines Creators dreissig Eintraege in seine Datenbank schreiben.
Das waere falsch: Sie waeren ab dem ersten Tag "seine" Eintraege und
damit Altlast; aendert Filipe spaeter eine Formulierung, gilt sie nur
fuer neue Creator; und die Liste saehe voll aus, obwohl noch nichts
geschehen ist -- das Gegenteil einer ehrlichen Uebersicht.

Vorlagen bleiben deshalb VORSCHLAEGE, bis jemand sie uebernimmt. Sie
stehen im Code, gelten fuer alle sofort, und werden erst dann zu Daten,
wenn sie gebraucht werden. Was uebernommen ist, ist ein ganz normaler
Eintrag -- aenderbar, loeschbar, und von spaeteren Aenderungen an der
Vorlage unberuehrt.

INHALTE, fachlich begruendet:
  13 Content-Ideen, jede mit AUSFORMULIERTEM Aufhaenger und Format. Die
  ersten ein bis drei Sekunden entscheiden ueber die Verbreitung --
  "mach was Persoenliches" hilft niemandem, "Das haette ich am Anfang
  gern gewusst" kann man sagen. Verteilt nach 70/20/10 (Wert, Community,
  Eigenwerbung).

  21 LIVE-Punkte in drei Abschnitten. Der mittlere ist der wichtigste
  und gibt es sonst nirgends: Was WAEHREND der Sendung auffaellt, ist am
  naechsten Tag weg. Diese Punkte sind so formuliert, dass man sie in
  einem Moment anklicken kann, in dem man eigentlich keine Zeit hat.

  Die Vorbereitung ist die laengste Liste, weil ein LIVE dort steht und
  faellt. Ton zuerst -- der Grund Nummer eins, warum Leute wieder gehen.

"ICH BRAUCHE HILFE" wird eine AUFGABE, keine Nachricht. Eine Nachricht
ist gelesen und dann weg; eine Aufgabe bleibt stehen, bis sie jemand
erledigt, geht an den zustaendigen Betreuer (ohne Betreuer an die
Leitung -- eine Bitte um Hilfe darf nicht ins Leere laufen), traegt hohe
Prioritaet und eine Frist von drei Tagen. Ohne Frist bleibt sie liegen;
das ist der Unterschied zwischen einer Aufgabe und einem Zettel.

"CONTENT-PLANUNG" HEISST JETZT "CONTENT-IDEEN". "Planung" klang nach
Terminen und Tabellen; was dort wirklich passiert, ist das Sammeln und
Weiterentwickeln von Ideen. Der Kalender daneben plant.

EIN CREATOR DARF SEINE EIGENEN EINTRAEGE AENDERN -- aber nur im Bereich
Content. Wenn er sich eine Idee uebernimmt, ist das SEINE Idee; sie
danach nicht umbenennen zu duerfen waere absurd. LIVE, Technik,
Community und Schutz bleiben die Betreuungsakte, dort aendert er nichts.
Ein erster Anlauf hatte die Ausnahme fuer alle Bereiche erlaubt -- die
Pruefung pruef-bereiche-lesend hat das sofort gemeldet.

DREI EIGENE FEHLER, VON DEN PRUEFUNGEN GEFUNDEN:
- Der Vorlagenblock vergass nach dem Uebernehmen, was schon geholt war:
  Die Liste wird neu geladen, der Block neu gebaut, und die Markierung
  am Element war jedes Mal weg. Jetzt merkt sich das Modul die Auswahl.
- Die Regel fuer eigene Eintraege war zu breit (siehe oben).
- Die Marken im Vorlagenblock waren auf dem Handy 10,2 px klein.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 16:27:30 +02:00
DogFatherGitandClaude Opus 5 299ef0d506 Eigenes Profil fuer jeden - mit Bild und Kanaelen
SCREEN 1: Jeder im Workspace hat jetzt seinen eigenen Steckbrief --
Creator, Scout, Manager und DogFather gleichermassen. Ein Bild, ein Satz
ueber sich, und die Kanaele, auf denen er unterwegs ist. Er steht ganz
oben auf profil.html, ueber der Creator-Akte; die ist etwas anderes
(die fuehren die Betreuer, den Steckbrief fuehrt man selbst).

Das Bild erscheint sofort ueberall: in der Kopfleiste jeder Seite und in
der Begruessung. /api/ich liefert es deshalb gleich mit -- das spart auf
jeder Seite eine zweite Abfrage und verhindert, dass die Plakette erst
als Buchstabe erscheint und dann umspringt. Faellt das Bild aus, steht
der Buchstabe da: Er wird nicht ersetzt, sondern liegt darunter.

WARUM KEINE ECHTE TIKTOK-ANMELDUNG. "Mit TikTok verbinden" klingt nach
OAuth. Das waere: ein Entwicklerkonto mit App-Freischaltung, eine
Pruefung durch TikTok (Wochen, widerrufbar), je Person ein Zugriffstoken,
das ablaeuft, erneuert werden muss und -- wenn es abhandenkommt --
fremden Zugriff auf ein fremdes Konto bedeutet. Dafuer bekaeme man
Follower-Zahlen.

Gebraucht wird hier aber "Wer ist das, und wo finde ich ihn?". Dafuer
genuegt der oeffentliche Name. Gespeichert wird deshalb NUR das Handle --
kein Token, kein Passwort, nichts, was abhandenkommen kann. Daraus wird
ein Verweis auf den Kanal. Vier Kanaele: TikTok, Instagram, YouTube,
Twitch. Sollen spaeter echte Zahlen dazukommen, ist das ein eigenes
Vorhaben -- der Name hier bleibt dann trotzdem richtig.

Eingefuegt werden darf, was Leute wirklich in der Zwischenablage haben:
"@name", "https://www.tiktok.com/@name" oder der Name allein. Alles wird
auf den Namen zurueckgefuehrt, statt eine Fehlermeldung zu zeigen.

SICHERHEIT beim Bild -- die drei Stellen, an denen Profilbilder
typischerweise scheitern:
  1. Der Typ wird an der SIGNATUR der Datei geprueft, nicht am
     Content-Type, den der Absender behauptet. Ein umbenanntes SVG mit
     Skript darin kaeme sonst durch und liefe im Namen der Domain --
     mit der Sitzung des Betrachters.
  2. Auf der Platte bekommt jede Datei einen Zufallsnamen. Kein Name
     kann Pfade verlassen oder etwas ueberschreiben.
  3. Ausgeliefert mit nosniff und einer eigenen, alles verbietenden
     Inhaltsregel.
Das Bild liegt als Datei neben der Datenbank, nicht darin: Bilder in
SQLite blaehen jede Sicherung auf, und die laeuft jede Nacht.

Niemand schreibt einem anderen ins Profil -- auch DogFather nicht. Ein
Satz ueber sich und der eigene Kanalname gehoeren der Person. Wer wen
SEHEN darf, folgt der bekannten Regel: Leitung alle, Scout seine
Creator, Creator sich und seine Betreuer. Fremde Profile sind 404, nicht
403.

ZWEI FUNDE DURCH DIE PRUEFUNG:
- Der TikTok-Link, den die App beim Teilen kopiert, endet auf
  "?lang=de&is_from_webapp=1". Der wurde abgelehnt: "sieht nicht richtig
  aus" -- obwohl es der offizielle Link ist. Jetzt werden Parameter und
  Anker mit abgeschnitten.
- Ein zu grosses Bild ergab "500 Serverfehler" statt einer Ansage. Der
  PayloadTooLargeError lief bis in die allgemeine Fehlerbehandlung
  durch. Jetzt 413 mit dem Satz, wie viel erlaubt ist. Von Hand haette
  das vermutlich nie jemand probiert.

Vor der Schemaaenderung wurde eine geprueft vollstaendige Sicherung
gezogen (VACUUM INTO, Integritaet ok, 6 Personen).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 11:31:34 +02:00
DogFatherGitandClaude Opus 5 43ce6551e2 Bereiche nur lesend fuer Creator + Content-Planung als echte Strecke
ZWEI SACHEN, beide auf Wunsch vom 31.08.2026.

1) "die creator sollen da nur die sehen die wir ihnen eintragen, also
   dogfather manager und scout."

Vorher durfte ein Creator in LIVE, Content, Technik, Community und Schutz
selbst anlegen, aendern und eigene Eintraege loeschen. Das hebelt den
Zweck dieser Bereiche aus: Sie sind die Betreuungsakte. Wer eine
LIVE-Auswertung umschreiben oder eine unbequeme Notiz verschwinden lassen
kann, macht die Akte wertlos.

Der Creator SIEHT weiterhin alles, was zu ihm gehoert -- vollstaendig.
Er kann es nur nicht veraendern. Umgesetzt als EINE Schranke vor allen
schreibenden Wegen, nicht als Pruefung an drei Stellen: Genau so ist hier
schon einmal ein Loch entstanden (zwei von drei Stellen abgesichert, die
dritte vergessen). 403 mit klarem Text statt 404 -- der Bereich existiert
fuer ihn ja, er steht davor.

Vorsicht Express 4: Der Platzhalter heisst dort `*`, nicht `*name` wie in
Fassung 5. Mit der falschen Schreibweise haette die Sperre stumm nichts
getan -- kein Fehler, keine Warnung.

37 Pruefungen, Schwerpunkt auf den verneinenden Faellen: alle fuenf
Bereiche, alle drei Wege, dazu der eigene Alteintrag (der frueher
ausdruecklich erlaubt war) und der Nachweis, dass hinterher wirklich
nichts veraendert wurde.

2) Content-Planung: aus der Liste wird eine Strecke.

Recherchiert statt geraten. Die Quellen sind an drei Punkten eindeutig:

  * "A content calendar for creators is a pipeline, not a datebook" --
    eine Wand aus Terminen verbirgt genau die Stellen, an denen es hakt.
  * Die ersten ein bis drei Sekunden entscheiden ueber die Verbreitung.
    Der Hook ist deshalb ein eigenes Feld auf jeder Karte, kein Fliesstext.
  * Regelmaessigkeit schlaegt Menge. Wer regelmaessig senden will, braucht
    VORRAT -- und Vorrat ist die eine Zahl, die eine Ideenliste
    verschweigt.

Daraus:
  * Fuenf Stufen statt drei (Idee, Hook & Skript, Gedreht, Fertig &
    geplant, Veroeffentlicht). Alte 'produktion'-Eintraege werden beim
    naechsten Start auf 'gedreht' umgestellt -- ohne das fielen sie aus
    jeder Spalte heraus.
  * Neue Felder hook, format, saeule_id, geplant (ALTER TABLE, gefahrlos).
  * Content-Saeulen je Creator, drei bis fuenf, nach der 70/20/10-Regel.
    Mit Balance-Balken ueber 90 Tage, nur Veroeffentlichtes -- was auf dem
    Kanal steht, ist die Wahrheit ueber seine Ausrichtung.
  * Die Kachel VORRAT rechnet in TAGE um ("reicht noch etwa 7 Tage").
    "4 Videos uebrig" sagt nichts; die Tage sagen, ob man am Wochenende
    drehen muss. Gezaehlt wird nur Gedrehtes und Fertiges -- eine Idee ist
    kein Video, und wer Ideen mitzaehlt, steht am Donnerstag ohne Material.
  * "Ideen lassen sich direkt in Aufgabe/Termin/LIVE-Thema ueberfuehren"
    -- woertlich aus dem Konzept, das letzte unumgesetzte Stueck. Die Idee
    bleibt bestehen und bekommt einen Vermerk, damit niemand dieselbe
    Aufgabe zweimal anlegt.

Farben: Die fuenf Saeulenfarben sind Daten, keine Dekoration. Geprueft
gegen genau diesen Hintergrund (#0a0d13) auf Helligkeitsband,
Farbstaerke, Farbfehlsichtigkeit (schlechtestes Paar dE 8.4),
Normalsicht-Abstand (19.3) und Kontrast -- alle Pruefungen bestanden.
Immer mit Legende UND Beschriftung; Farbe allein traegt nie die
Information.

Beim Ansehen des ersten Bildes fiel der klassische Brett-Fehler auf: Die
Spalte "Veroeffentlicht" waechst ewig und schiebt alles andere aus dem
Bild. Sie zeigt jetzt die juengsten sechs, der Rest ist einen Klick
entfernt. Die vorderen Spalten bleiben ungekuerzt -- was dort liegt, ist
Arbeit.

Nur EIN Schreiber fuer die Tabelle eintraege: workspace-content.js
enthaelt ausschliesslich, was es woanders nicht gibt (Saeulen,
Kennzahlen, Ueberfuehren). Zwei Module auf denselben Zeilen waeren der
sichere Weg zu zwei Wahrheiten.

45 + 40 Pruefungen, Computer und Handy, dazu die Gegenprobe: Ein Creator
sieht die ganze Strecke, die Kennzahlen und die Verteilung -- und keinen
einzigen Knopf, auch keinen versteckten. Ausgeblendet ist nicht dasselbe
wie nicht vorhanden.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 21:45:14 +02:00
DogFatherGitandClaude Opus 5 17c605b93d Sicherung: laeuft von allein, und ein stiller Ausfall faellt auf
Filipe zu Recht: "wieso soll ich diesen Befehl einmal die Woche eingeben,
ich will einmal und dass es dann alleine laeuft". Ein Befehl, den man
selbst eintippen muss, wird irgendwann vergessen -- und zwar genau dann,
wenn er zaehlt.

tools/sicherung-einrichten.ps1 legt eine Windows-Aufgabe an: taeglich
statt woechentlich (der Lauf dauert Sekunden, bei woechentlich waere die
Kopie im schlimmsten Fall sechs Tage alt), 13:30 statt nachts (der
Rechner laeuft nicht durch), und mit StartWhenAvailable -- war der
Rechner aus, holt Windows den Lauf beim naechsten Hochfahren nach. Ohne
diesen Schalter fiele jeder verpasste Termin ersatzlos aus. Braucht keine
Administratorrechte und macht am Ende gleich einen Probelauf: eine
Einrichtung, die man nicht ausprobiert, ist eine Vermutung.

Damit entsteht aber ein neues, schlimmeres Problem: Wenn die Aufgabe
still klemmt oder der Rechner wochenlang aus ist, merkt es NIEMAND. Man
glaubt, man haette eine Kopie ausser Haus, und hat sie nicht. Deshalb
meldet sich das Abholskript nach jedem Lauf beim Server zurueck, und die
Automationen-Seite zeigt, wie alt die Kopie ist -- nach zehn Tagen wird
sie auffaellig.

Die Rueckmeldung laeuft ueber einen eigenen langen Schluessel, nicht ueber
einen Zugangscode: Das Skript laeuft unbeaufsichtigt und muesste einen
Code sonst dauerhaft auf der Platte halten. Der Schluessel kann NUR einen
Zeitstempel setzen -- nichts lesen, nichts aendern. Verglichen wird
zeitunabhaengig.

Dabei eine unauffaellige Falle gefunden: In workspace-aufgaben.js steht
`aufgabenRouter.use("/workspace/api", angemeldet)` -- eine Schranke ueber
JEDEN Pfad unter /workspace/api, nicht nur die eigenen. Alle spaeter
eingehaengten Module leben stillschweigend davon. Die Rueckmeldung wurde
dort mit 401 abgewiesen, bevor ihr Schluessel ueberhaupt geprueft wurde;
der richtige Schluessel sah dadurch aus wie ein Fehler in der Pruefung.
Das Sicherungsmodul haengt jetzt VOR dem Aufgabenmodul und bringt seine
eigene Schranke mit -- damit haengt es an keinem anderen Modul mehr.

Ausserdem: Die Ueberschrift im Kasten nennt jetzt den GRUND, aus dem er
gelb ist. Vorher stand dort "Zuletzt gesichert vor 2 Minuten", waehrend
die Farbe wegen der fehlenden Kopie warnte -- die Anzeige widersprach
sich selbst und man sucht den Fehler an der falschen Stelle.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 18:34:46 +02:00
DogFatherGitandClaude Opus 5 7a393b9335 Workspace: naechtliche Sicherung, die auch wirklich Daten enthaelt
Bisher wurde nur EINMAL gesichert: direkt vor einer Umstellung der
Datenbank. Faellt die Platte aus, ist alles weg -- die komplette
Betreuung, jede Aufgabe, jedes Protokoll. Das war das einzige Risiko im
System, das auf einen Schlag ALLES kostet.

Beim Nachsehen auf dem Server kam ein zweiter, schwerwiegenderer Befund
dazu:

    workspace.db          4.096 B
    workspace.db-wal  2.101.232 B

Im WAL-Betrieb landen Schreibvorgaenge zuerst im -wal und wandern erst
beim Checkpoint in die Hauptdatei. Der lief seit dem ersten Tag nicht.
Wer also workspace.db kopiert haette -- der naheliegendste Sicherungsweg
ueberhaupt -- haette eine LEERE Datenbank gesichert und es nicht gemerkt.
Der Test stellt genau das nach: aus der reinen Dateikopie waren 0 von 200
Aufgaben lesbar.

Deshalb:
- Nie eine Dateikopie. Immer VACUUM INTO -- SQLite schreibt selbst, liest
  das WAL mit, Ergebnis ist in sich stimmig auch waehrend Schreibzugriffen.
- Vor jeder Sicherung ein erzwungener Checkpoint (TRUNCATE). Haelt die
  Hauptdatei aktuell und das WAL klein.
- Jede frische Sicherung wird SOFORT wieder geoeffnet und geprueft: auf
  Unversehrtheit UND darauf, dass Personen darin stehen -- gegen genau den
  Fall einer technisch einwandfreien, aber leeren Datei. Faellt sie durch,
  wird sie geloescht statt behalten.
- Erst unter Zwischennamen schreiben, dann pruefen, dann umbenennen. Sonst
  stuende nach einem Abbruch eine halbe Datei unter dem richtigen Namen.
- Aufbewahrung 7 taeglich / 4 woechentlich / 6 monatlich, je Art getrennt
  aufgeraeumt, damit taegliche nie die monatlichen verdraengen.

Laeuft IM Prozess, nicht als Systemdienst: keine Aenderung an Systemdateien
noetig, die Datenbank ist ohnehin offen, und es kommt mit jedem git pull
mit. Statt setTimeout auf 24 h wird viertelstuendlich geprueft, ob fuer
HEUTE schon eine liegt -- das ueberlebt Neustarts und Ausfaelle.

Dazu eine Zustandsansicht auf der Automationen-Seite: wann zuletzt, wie
gross, wie viele Personen darin, wie viel wartet noch im WAL, wie viel
Platz ist frei. Plus "Jetzt sichern" von Hand. Nur Leitung, 404 statt 403
fuer alle anderen.

Geprueft (server/pruef-sicherung.mjs, 27 Pruefungen) einschliesslich des
Ernstfalls: Sicherung schreiben, Datenbank zerstoeren, zurueckspielen,
Vollstaendigkeit und Schreibbarkeit nachweisen. Eine ungetestete Sicherung
ist eine Vermutung.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 18:20:35 +02:00
DogFatherGitandClaude Opus 5 c0ac041122 Workspace: Versionsstempel gegen Cloudflares 4-Stunden-Cache
Filipe sah die neue Kachel nicht, obwohl sie live war. Ursache gemessen,
nicht vermutet:

  Node liefert   : Cache-Control: no-cache        (richtig)
  Cloudflare macht: Cache-Control: max-age=14400  (ueberschreibt es)
  cf-cache-status: REVALIDATED, Server: cloudflare

Cloudflares voreingestellte Browser-Cache-Zeit von vier Stunden setzt
sich ueber das no-cache des Servers hinweg -- aber NUR bei JS und CSS.
HTML kommt mit DYNAMIC und no-cache immer frisch durch (geprueft an
/creator.html und /workspace/).

Genau deshalb genuegt ein Stempel in der HTML: neue Seite -> neue
Adresse -> Cloudflare kennt sie nicht -> frische Datei. Keine
Cloudflare-Einstellung noetig, nichts, worauf ich warten muss.

tools/workspace-stempel.mjs setzt den Stempel auf alle 71 Verweise in
13 Dateien. Der Lauf ist wiederholbar: ein vorhandener Stempel wird
ersetzt, nicht angehaengt (geprueft).

Gehoert ab jetzt vor jeden Deploy, der JS oder CSS im Workspace anfasst.
Ich verlasse mich damit nicht mehr aufs Erinnern -- das war der
eigentliche Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-28 13:03:33 +02:00