/game — Fortschritt

Hinweis: Rahmen: 00-rahmen.md. Code: plugins/src/progress/ — Schirm, Menü, Fähigkeitsbaum, Hauptfähigkeiten, Gewohnheitsliste, Anfragen, Skilldarstellung, die Proben der leeren Zustände (Leerzustaende.test.tsx) und der Zeilenaktionen (Zeilenaktionen.test.tsx) und der Einstellungsabschnitt „Skills: Symbole und Farben"; Server unter progress/server/, Werkzeugliste unter progress/mcp/, die Rechnung für die drei Booststände unter packages/shared/src/handlers/game/boostStand.ts, die Ereignismarke in der Kopfleiste (progress/client/Ereignismarke.tsx, mit Ereignismarke.test.tsx) · Nachweise verify:game und verify:xp (seit 17.09.2026 unter progress/nachweis/) sowie verify:verlauf (backend/src/database/scripts/verifyVerlauf.ts, seit dem 21.09.2026 wieder in der Kette — siehe den Kasten darunter). Abgelegtes zum Bereich: archiv/2026-09-21-quests-ohne-schirm/ (die Quest-Endpunkte, A08) und packages/frontend/archiv/QuestList.tsx (ihr Schirm, N66).
verify:verlauf fehlte hier fünf Tage lang und ist seit dem 21.09.2026 wieder da — der dritte Nachweis des Bereichs. Die Datei packages/backend/src/database/scripts/verifyVerlauf.ts liegt seit Q03 da und war grün, wenn man sie von Hand startete (zwanzig Proben, alle ok) — aber packages/backend/package.json kannte sie weder als eigenes Skript noch in verify:kette, und betrieb/nachweise.mjs liest den Bestand genau aus dieser Kette. Der Nachweis lief also von seiner Entstehung bis zum 21.09.2026 kein einziges Mal.
Gemessen in der Gegenprobe, spät am 21.09.2026: beides steht jetzt — "verify:verlauf": "tsx src/database/scripts/verifyVerlauf.ts" (Zeile 28) und der Platz in verify:kette. Ein Nachweis, den niemand startet, ist eine Datei; dieser wird wieder gestartet.

Wofür

Die Kuppel: das große Teleskop — hier sieht man weit. Skills, Gewohnheiten, Boosts und XP.

Der Bereich ist umschaltbar — und in einer frischen Anlage ausgeschaltet. plugin.ts trägt aktivVorgabe: false (FEATURES_DEFAULT_OFF): das Spiel ist gewährt, aber niemand bekommt es ungefragt. Wer XP will, schaltet sie ein; wer nicht, sieht sie nirgends. Das ist der Normalfall dieses Schirms und nicht die Ausnahme — wer zum ersten Mal auf /game geht, liest zuerst den Ausgeschaltet-Satz.

Ist er ausgeschaltet, sagt der Schirm genau das — und nicht „Fehler". Fehlt der Grant ganz, antwortet der Server mit 404 und der Bereich existiert für diesen Nutzer nicht; dann ist auch hier nichts zu erklären.

XP werden nie gespeichert, sondern gerechnet (Grundsatz 45) — und erst bei Freigabe gutgeschrieben.

Weg und Rahmen

Route/game
MerkmalGAMIFICATION — abschaltbar, in einer frischen Anlage aus
Rechtepfadgold.progress
ZimmerKuppel · Lautstärke 5 (die lauteste Seite) · #ef5da8

Was man sieht

AbschnittInhalt
SkillsBaum aus Oberskills und Skills, mit XP und Stufe. Immer ganz aufgeklappt — die Tiefe steht in der Einrückung, die Farbe des Zweigs im Fortschrittsbalken (bis zum 10.10.2026 auch im Rand links; ES-261009-farbige-seitenstreifen, E11)
Hauptskillsdie obersten, hervorgehoben: Kürzel, Kristall mit Stufe, Balken zur nächsten, Gesamt-XP
GewohnheitenSträhne · Name · Takt · Stand im laufenden Takt · längste Strähne (nur wenn sie über der laufenden liegt) · Gesamtzahl der Vollzüge · „pausiert"
BoostsFaktor · Skill · „global" · Bis (oder „unbefristet") · Grund · „ab <Datum>" (fängt erst an) oder „abgelaufen"

Seit dem 23.09.2026 tragen die drei Abschnitte ein Zeichen vor dem Namen (N134, Guide §7.3 — alle drei oder keiner): Skills den Kristall, denselben wie der Bereich selbst, weil ein Skill für sich schon eine wachsende „Stufe" ist; Gewohnheiten die Flamme — dasselbe Zeichen, das in der Zeile vor der „längsten Strähne" steht; Boosts das Zeichen „Hoch", weil ein Boost Punkte über das Normale hebt. Die Zuordnung steht als ABSCHNITTSZEICHEN in Fortschrittsmenue.tsx, geprüft in client/zeichen.test.ts. Aus demselben Grund trägt die „längste Strähne" in der Gewohnheitenzeile (Gewohnheitsliste.tsx, nur wenn sie über der laufenden liegt) jetzt dieselbe Flamme davor, mit currentColor — die Zeile bleibt neutral.

Richtiggestellt am 23.09.2026: Hier stand, die Flamme am Reiter sei „dieselbe wie die Strähne in der Zeile darunter" und wiederhole, was die laufende Strähne links schon zeigt. Das stimmt nicht: Die laufende Strähne (Streak in Gewohnheitsliste.tsx, Zeile 366) ist und bleibt eine reine Zahl, ohne Zeichen — nur die längste Strähne trägt die Flamme davor. Keine Zeile bekommt dadurch ein zweites Zeichen.

Die Zeile eines Boosts nennt seit dem 21.09.2026 wirklich das Bis. Hier stand „Skill · Faktor · Bis · Grund", seit die Datei am 16.09.2026 angelegt wurde — der Code zeigte das Ablaufdatum nie. Man konnte im Anlegefach ein „Bis" eintragen, sah es danach nirgends wieder und erfuhr erst am angehängten Wort „abgelaufen", dass der Boost vorbei war. Ein Formularfeld, dessen Wert nirgends wieder auftaucht, sieht aus wie eines, das nicht angekommen ist. Das Datum steht in Zone und Format des Lesers (useZeit), nicht in denen des Servers.

Ein Boost hat drei Zustände und nicht zwei (seit 22.09.2026). Der Server schickt ein active, das „angefangen und noch nicht abgelaufen" heißt; die Zeile machte daraus laufend oder abgelaufen und schrieb damit jedem Boost, der erst morgen anfängt, das Gegenteil an. Jetzt entscheidet booststand(active, starts_at, jetzt) in @shared/handlers/game/boostStand.ts zwischen kommt („ab" plus Datum), läuft (nichts dahinter, der Normalfall) und abgelaufen. Die Jetztzeit ist ein Übergabewert und keine Uhr in der Funktion (Grundsatz 59) — sonst ließe sich der Fall „morgen" nicht prüfen, ohne zu warten.

Wofür ein Boost gilt, seit dem 24.09.2026 (D22, Etappe boosts, Wanderung 116, N193). Ein globaler Boost (scope = 'global') gehört keinem Konto (user_id leer), hat nie einen Skill und gilt für jeden Skill jedes Kontos; ein CHECK in der Datenbank hält das fest. Ein eigener Boost ohne Skill gilt für jeden eigenen Skill — vorher galt er für keinen; der Schirm legt solche Boosts heute nicht an, die Rechnung in Gutschrift, Aufgaben-XP und Skill-Liste kennt sie aber. Der Faktor liegt zwischen 0,1 und 10 (CHECK; stehen auf einem Server ältere Zeilen außerhalb, entsteht er NOT VALID, gelöscht wird nichts). Globale Boosts liest jedes Konto über eine eigene Leserichtlinie; anlegen, ändern oder beenden kann sie hier niemand — „Beenden" steht deshalb nur an eigenen. Die Einfuhr übernimmt keine globalen Zeilen und setzt die Besitzspalte auf das einführende Konto.

Laufen mehrere Boosts gleichzeitig, addieren sich ihre Zuschläge (seit 07.10.2026, W24; Christian in N358 auf C28, Frage V10 — vorher wurden sie multipliziert): 1,5 und 1,2 ergeben 1,7, ein Faktor unter 1 zieht ab, und mehr als alles abziehen kann die Summe nicht — der Faktor fällt nie unter 0. Die Regel steht einmal, als boostfaktor in @shared/handlers/game/xpRules.ts. Gutschrift, Aufgaben-XP, Skill-Liste, Ereignismarke und die Nachweise rechnen mit ihr; die Abfragen wählen nur aus, welche Boosts gerade laufen. Der Hinweis über dem Formular sagt es in einem Satz.

Laufende globale Boosts stehen auch außerhalb dieses Schirms — als Ereignismarke in der Kopfleiste (Rahmen §1, Christian in N185: „wie ein Game-Event, aber natürlich nicht schreibbar"). Sie zeigt den Faktor aus den laufenden globalen Boosts, nach derselben Regel addiert, und das früheste Ende, führt nach /game?a=boosts und fragt nur, solange die Gamification für das Konto eingeschaltet ist. Ohne laufenden globalen Boost ist sie nicht da. Offen, bei Christian: ob der Ort (vor der Suche) und die Form (Chip in der Bereichsfarbe; in der kompakten Leiste ohne das Ende) so bleiben, oder ob die Marke in die Übersicht gehört; und ob ein globaler Boost mehr als ×10 geben darf.

Über den Reitern steht die Tafel „Wie es läuft" (seit 21.09.2026, Q03): zwei Kurven über Zeit — Erfahrungspunkte und Gewohnheiten abgehakt. Sie gehört zu keinem der drei Abschnitte, sondern zu allen, und steht deshalb über ihnen und nicht in einem vierten Reiter: ein Ort, an den man erst gehen müsste, um zu sehen, was den Rest erklärt, wäre der falsche.

Ist im ersten Zeitraum nichts passiert, steht die Tafel gar nicht da (ES-261009-kennzahlen-nur, 10.10.2026) — weder Kopf noch Zeitraumwahl noch Satz. Seit RL02 (28.09.2026) stand dort statt flacher Kurven auf null der Satz „In diesem Zeitraum ist nichts passiert.“; auch er war ein Block, der nur meldete, dass er nichts zu melden hat, und schob am Telefon den Leerzustand des Reiters samt Knopf nach unten. Wer den Zeitraum selbst wechselt, behält die Tafel, auch wenn der neue leer ist: Die Reihen zeichnen dann auf null, und der Weg zurück bleibt stehen.

Bis dahin stand über diesem Schirm eine einzige Zahl — „x XP über y Skills". Eine Gesamtsumme steigt immer; ob gerade etwas passiert, steht nicht darin. Sie blieb trotzdem im Kopf stehen, bei einem neuen Konto als „0 XP über 0 Skills“, bis sie am 10.10.2026 ging (ES-261009-kennzahlen-nur, E13): Sie führte zu nichts, und die XP je Skill stehen in der Liste darunter.

Die Kurve zeichnet aus game.xp_events und game.habit_log, also aus dem, was der Bereich ohnehin für sich selbst führt. Nichts wird für die Statistik zusätzlich mitgeschrieben. Die Grundlinie ist immer die Null, und die Zahl rechts (Summe über den Zeitraum) kommt aus dem Server — nicht aus dem Schirm.

Der Takt steht in zwei Teilen (seit 21.09.2026, L10). Die Einheit sagt, was ein Takt ist — ein Tag, eine Woche ab Montag, ein Kalendermonat —, das Ziel, wie oft er darin vollzogen sein muss. „Dreimal pro Woche" ist deshalb kein dritter Eintrag in der Auswahl, sondern die Woche mit dem Ziel 3; sonst müsste dort auch „viermal pro Woche" und „zweimal im Monat" stehen, und die Liste wäre nach drei Wünschen unbrauchbar.

In der Zeile steht der Takt so, wie man ihn sagt: „täglich", „3× pro Woche", „monatlich". Bei einem Ziel über eins steht der Stand daneben — „2 von 3 diese Woche". Bei Ziel eins steht er nicht da: „1 von 1 heute" sagte dasselbe wie der gesetzte Haken.

Knopf und Zeile zeigen Verschiedenes, und das ist der Punkt. Der Haken am Knopf beantwortet „habe ich heute geklickt?", der Rahmen der Zeile und die Strähne links „ist der Takt gehalten?". Bei „3× pro Woche" stehen die beiden nach dem ersten Klick auseinander — ein einziger Zustand wäre dort in jedem Fall eine Lüge: entweder sähe der Klick aus, als wäre er nicht angekommen, oder die Woche gälte nach einem Drittel als erfüllt.

Die Strähne zählt Takte, nicht Vollzüge. Zwei von drei Tagen in einer Woche halten den Takt nicht; die Strähne fällt dort auf null, so wie ein ausgelassener Tag sie bei einer täglichen Gewohnheit beendet. Der laufende Takt zählt nie gegen sie, solange er läuft.

Ein Ziel, das der Takt nicht hergibt, wird gelegt und nicht abgewiesen. „Dreimal täglich" kann das Protokoll nicht halten — es trägt höchstens einen Vollzug je Kalendertag — und wird deshalb still zu „täglich, einmal". Eine Absicht, die der Takt nicht fassen kann, ist kein Fehler des Nutzers.

Kein Suchfeld — dieser Schirm zeigt Bäume und Listen, keine Tabelle.

Die leeren Zustände erklären den Schirm (seit 21.09.2026). Vorher standen dort drei wahre und stumme Sätze — „Noch keine Skills angelegt.", „Noch keine Gewohnheiten angelegt.", „Kein Boost angelegt." Sie sagten, dass nichts da ist, und nicht, wofür der Abschnitt da wäre. Jetzt:

AbschnittWas im Leeren stehtKnopf
Skillswas ein Skill ist, dass erledigte To-Dos ihm Punkte gutschreiben und dass Unter-Skills nach oben vererben„Ersten Skill anlegen"
Gewohnheitendass man in einem Takt abhakt — täglich, dreimal pro Woche, monatlich — und Denotato die Strähne zählt„Erste Gewohnheit anlegen"
Boostsdass ein Boost Punkte vervielfacht — und, wenn es noch keinen Skill gibt, dass er einen braucht„Ersten Boost anlegen", sonst „Zuerst einen Skill anlegen"

Der Boost-Fall ist der, an dem jemand ohne Erfahrung hängen bleibt: skillId ist Pflicht, und die Auswahl wird aus den Skills gebaut. Ohne einen einzigen Skill öffnete sich ein Formular mit totem Auswahlfeld, das nicht sagte, warum es sich nicht absenden lässt.

Die Knöpfe führen ins Anlegefach des Abschnitts und setzen den Zeiger ins erste Feld (AnlegenKnopf); dafür tragen die drei Formulare seit dem 21.09.2026 die Kennungen fortschritt-skill, fortschritt-gewohnheit und fortschritt-boost.

Was man tun kann

Reiter ordnen (OE10, N500): Wer Vorgaben für alle setzen darf, ordnet und blendet die Reiter über „Bearbeiten“ im Kopf; die Folge steht in oberflaeche.reiter unter progress (Rahmen §3).

ElementWas passiert
Skill anlegenName · Oberskill (die Auswahl ist die Liste aller eigenen Skills)
Ändern an einer Skillzeileöffnet in der Zeile ein Fach mit Name und Oberskill, beides vorbelegt. Die Auswahl lässt den Skill selbst und alles unter ihm weg, und „kein Oberskill" hängt ihn nach oben
Symbol eines Skills anklickenöffnet den Darstellungswähler — Farbe, Zeichen, „zurücksetzen" und, wer darf, „für alle". Dasselbe am Baum und an der Hauptskill-Karte
Gewohnheit abhakenhakt heute ab; ein zweiter Klick nimmt es zurück (Label „{Name}: für heute abhaken" bzw. „{Name}: Haken für heute wegnehmen", seit I07 übersetzt). Die Strähne steigt erst, wenn der Takt voll ist
Gewohnheit anlegenName · Takt (täglich · pro Woche · pro Monat) · Wie oft
Ändern an einer Gewohnheitszeileöffnet in der Zeile ein Fach mit Name, Takt und Ziel, alles vorbelegt. Der Pausenstand bleibt, wie er war
Pausieren · Fortsetzenhält eine Gewohnheit an oder lässt sie weiterlaufen. Eine pausierte lässt sich nicht abhaken — der Hakenknopf ist tot und nicht bloß wirkungslos
Beendenbeendet einen laufenden Boost. Steht nur an eigenen, nicht an globalen
Boost anlegenSkill, Faktor, Bis, Grund
7 Tage · 30 Tage · 3 Monate · 1 Jahran der Tafel: schaltet den Zeitraum um und holt ihn neu
über die Kurve fahrenstatt der Summe steht rechts der Tag und sein Wert

Was misslingt, steht an der Zeile (seit 22.09.2026). Abhaken, Pausieren, Ändern und „Beenden" sagen es dort, wo geklickt wurde, und nicht in der Meldungszeile des Schirms: die gehört dem Laden und trägt „Konnte nicht laden". Der Text kommt aus meldungstext(message, details) und damit aus derselben Quelle wie überall sonst; steht kein Satz im Katalog, steht die Kennung da — sichtbar falsch ist besser als still falsch.

Hinweis: Skill aufklappen — zeigt die Unterskills. Falsch, korrigiert am 21.09.2026. Der Baum ist nie zugeklappt: Faehigkeitsbaum.tsx zeichnet buildTree(skills, 'parent_id') in einem Zug und kennt kein Auf und Zu. Was sich öffnet, wenn man klickt, ist der Darstellungswähler — und er hängt am Symbol, nicht an der Zeile. Hier stand also ein Knopf beschrieben, den es nicht gibt, direkt neben einem, den es gibt und der in keiner Zeile stand. Genau davor soll diese Ablage schützen, also bleibt die Korrektur stehen.

Woher die Daten kommen

Farbe und Zeichen eines Skills kommen seit dem 21.09.2026 (A04) aus darstellung.skills.<skill-id> und nicht mehr aus skill.colors und skill.icons; useSkilldarstellung liest und schreibt seit A28 (24.09.2026) nur noch den einen Schlüssel. Am Baum ändert das nichts.

Neun Wege, alle unter /api/game, alle verschlüsselt und POST — progress/server/routen.ts, gemessen am 21.09.2026, der neunte seit dem 24.09.2026:

WasAPIPaths
Skills mit XP, Stufe und FaktorGAME_SKILLS
Skill anlegen oder ändernGAME_SKILL_SAVE
Gewohnheiten mit Takt und SträhneGAME_HABITS
Gewohnheit anlegen oder ändernGAME_HABIT_SAVE
Gewohnheit abhaken (oder zurücknehmen)GAME_HABIT_TOGGLE
Boosts, eigene und globaleGAME_MULTIPLIERS
eigenen Boost anlegenGAME_MULTIPLIER_ADD
eigenen Boost jetzt ablaufen lassenGAME_MULTIPLIER_END
nur die laufenden globalen Boosts, für die Ereignismarke (lesend; MCP boosts_global)GAME_MULTIPLIERS_GLOBAL

Was „ändern" heißt, stand nirgends — seit dem 22.09.2026 steht es hier. Beide Speicherwege nehmen eine id und machen daraus ein Update, und beide lassen stehen, was nicht mitkommt:

Ein Ring wird abgewiesen, nicht geknüpft. Ein Skill unter sich selbst oder unter einen eigenen Nachfahren zu hängen, beantwortet der Server mit SKILL_MOVE_CYCLE_ERROR und 409; geprüft wird mit derselben rekursiven Abfrage (subtreeCte), aus der auch die XP-Summe kommt. Der Schirm bietet es gar nicht erst an — die Auswahl lässt den Skill und seinen Unterbaum weg —, aber die API steht auch dem offen, der den Schirm nicht benutzt. (Der deutsche Satz dazu steht im Katalog und bricht dort ab — Punkt 33.)

Dazu VERLAUF (verschlüsselt, POST; die Reihen xp und habits). Ist GAMIFICATION aus, fallen die beiden Reihen still aus der Antwort — nicht als Fehler, sonst ließe sich an der Meldung ablesen, welche Bereiche es gibt (Grundsatz 22).

Hinweis: Hier standen /api/game/boosts und /api/game/xp — beide gibt es nicht (korrigiert am 21.09.2026). Der Boost-Weg heißt seit jeher multipliers; ein XP-Endpunkt existiert überhaupt nicht, die Punkte stehen in der Skill-Antwort und in der Verlaufsreihe. Fünf der acht echten Wege fehlten dafür ganz.
Dass es so lange durchging, hat einen Grund, der über diese Seite hinausgeht: verify:seiten prüft nur APIPaths-Namen in Backticks gegen den Quelltext, und ein hingeschriebener URL-Pfad wie /api/game/boosts fällt durch dieses Netz. Deshalb stehen die Wege hier jetzt unter ihren Namen — so prüft der Nachweis sie mit.

Aufgehoben wird unter progress.faehigkeiten, progress.gewohnheiten und progress.verstaerker (G03, 21.09.2026, Rahmen 7). Eine Marke für alle drei, und sie nennt den ältesten Stand — eine Gewohnheitskette, die bei einem Ausfall auf null zurückspringt, wäre eine Falschaussage über etwas, das wehtut.

Was A08 anfasst, liest dieser Schirm nicht (gemessen am 21.09.2026). Der Schirm zieht aus game.skills, game.habits, game.habit_log, game.skill_multipliers und game.xp_events. A08 lässt personal.habits fallen und schiebt game.quests nach archiv. — keine der fünf. Die Gewohnheiten hier sind nicht die aus personal.habits; jene steht seit dem Alpha-Aufsatz in setup.sql, wurde von game.habits (Migration 3) abgelöst und hat im ganzen Bau keinen einzigen Leser. Nach A08 zeigt dieser Schirm dasselbe wie vorher. Was sich ändern kann, ist die Datenauskunft: exportTabellen.ts nennt personal.habits, game.quests und game.quest_progress mit Schemanamen, und exportController.ts fragt jeden Eintrag einzeln ab, ohne try/catch. Fällt eine der drei weg, ohne dass die Liste mitkommt, scheitert die ganze Auskunft — laut, nicht leise, aber vollständig.

Die Eule sagt den Stand in Worten (KI18, 27.09.2026). In der schwebenden Eule steht „Deinen Stand in Worten“ als Knopf. Er schickt nur die Kennung des Angebots an BEGLEITER_ANGEBOT; was das Modell liest, holt der Bereich selbst (progress/server/angebote.ts): die eigenen Fähigkeiten aus ladeSkills — dieselben Zahlen wie der Fähigkeitsbaum —, höchstens 40, die mit den meisten XP zuerst, je mit Stufe, XP, dem Rest bis zur nächsten Stufe, einem Boost, wenn einer wirkt, und bei einer Unterfähigkeit dem Namen der darüber. Dazu die Summe der XP über die obersten Fähigkeiten. Gewohnheiten, einzelne Boosts und der Verlauf gehen nicht mit. Ein Klick zählt als freie Frage; was dahinter steht, sagt docs/seiten/begleiter.md, Abschnitt „Die Angebote der Eule“.

Was fehlt

Hinweis: Korrigiert am 17.09.2026. Drei Punkte standen hier, die es längst gibt — sie waren aus der Bauteilliste erschlossen und nicht am Code geprüft. Genau davor soll diese Ablage schützen, also stehen die Korrekturen hier und werden nicht stillschweigend entfernt.

Was ich falsch hatte:

Was wirklich fehlt:

  1. Quests haben Endpunkte, aber keinen Schirm. — abgeräumt am 21.09.2026 (A08). /api/game/quests, /api/game/quests/save und /api/game/quests/complete gibt es nicht mehr; die drei Wege antworten mit 404, und verify:game hält genau das fest — auf 404 und nicht auf „irgendetwas außer 200", weil ein 400 hieße, die Route steht wieder und beanstandet nur den Rumpf. Der Code liegt in archiv/2026-09-21-quests-ohne-schirm/ samt WARUM.md.

    Der Schirm war am 16.09. gefallen (N66), weil Migration 31 die Quests am selben Tag in Aufgaben überführt hatte — Christian am 11.09.2026: „Quests sollen mit To-Dos gemerged werden." Die Endpunkte blieben fünf Tage länger stehen und antworteten zuletzt mit festen Nullen für task_count und task_done: eine Antwort, die ihre Form erfüllt und nichts mehr aussagt.

    Die Tabelle bleibt stehen. Grundsatz 55: gelöscht wird nichts. game.quests und game.quest_progress warten auf die Umbenennung nach archiv.quests — Bauplan Block 3, und das ist Christians Entscheidung, weil ein Umbenennen sich aus der Anwendung heraus nicht zurücknehmen lässt. Der zweite Teil des Nachweises hält fest, dass die Tabelle noch da ist.

    Wer sie umbenennt, muss die Schnellsuche mitnehmen (gemessen in der Gegenprobe am 21.09.2026). searchController.ts führt game.quests als Quelle „Quest" und baut alle erlaubten Quellen zu einer UNION ALL-Abfrage ohne try/catch zusammen. Fehlt die Tabelle, fällt nicht der Quest-Treffer weg, sondern die ganze Schnellsuche — auf jedem Schirm, bei jedem Tastendruck, für jeden Nutzer mit GAMIFICATION an. Dieselbe Falle wie bei der Datenauskunft. Der Eintrag zeigt ohnehin auf /game?a=quests, einen Abschnitt, den es seit dem 16.09.2026 nicht mehr gibt: Ein Treffer führt heute schon ins Leere. Auch verifyForeign.ts, verifyImport.ts und der Notion-Import importGame.ts fassen die Tabelle weiter an.

    „167 Zeilen" ist gelesen, nicht gemessen (21.09.2026). Hier stand „im Bestand 167 Zeilen" wie eine Tatsache. Weitergereicht wird sie von docs/kontext/plan-dienst.md, Block 3 — hierher, in den Kommentar von progress/nachweis/verifyGame.ts und nach archiv/2026-09-21-quests-ohne-schirm/WARUM.md.

    An keiner der vier Stellen steht, wann und woran gezählt wurde; vermutlich auf dem Pi. Vier Fundstellen sehen aus wie vier Belege und sind einer. Falsch, richtiggestellt in der Gegenprobe am 21.09.2026. Gemessen (grep über das ganze Repository): Es sind mindestens elf Fundstellen, nicht vier — und die Herkunft steht da. docs/migration/GOLD_Notion_Abloeseplan.md §3.1a trägt die Überschrift „Datenmengen (gemessen 06.09.2026)" und führt Quests | 167. Die Zahl wurde am 06.09.2026 in Notion gezählt, nicht auf dem Pi.

    Was trotzdem gilt: Sie ist seither nicht nachgezählt worden, und dazwischen lag Migration 31 (16.09.2026), die 73 dieser Quests in Gewohnheiten und 94 in Aufgaben überführt hat. Als Aussage über den heutigen Inhalt von game.quests taugt sie nicht.

    Gemessen wurde am 21.09.2026 in denotato_wolke auf Port 5432: game.quests 0, game.quest_progress 0. Diese Datenbank ist am selben Tag frisch aufgesetzt worden — auth.users trägt nur Zeilen von heute —, also sagt die Null nichts über den Bestand. Vor der Umbenennung wird auf dem Server gezählt.

    Was blieb, ist der Wunsch dahinter: Quests und To-Dos wirklich zu verschmelzen. Das steht nicht hier, sondern bei den Aufgaben — dieser Schirm hat damit nichts mehr offen.

  2. Kein XP-Verlauf. — gebaut am 21.09.2026 (Q03). Die Tafel „Wie es läuft" zeigt Erfahrungspunkte und abgehakte Gewohnheiten über 7 Tage bis 1 Jahr, gerechnet im Server aus game.xp_events und game.habit_log. Was offen bleibt, steht als Punkt 18 bis 20 weiter unten.
  3. Kein Vergleich zwischen Skills. Welcher wächst, welcher liegt — die Daten reichen dafür, die Ansicht fehlt.
  4. Keine Gewohnheits-Historie. Strähne und längste Strähne stehen da, der Kalender dazu nicht. Man sieht, dass man bei 12 ist, nicht wo die Lücken lagen.
  5. Kein Gnadentag. Eine Strähne bricht beim ersten Fehltag. Ein Gnadentag je Woche ist der übliche Weg und steht in Christians Vorschlag 21.
  6. Keine Erklärung, woher XP kamen. Eine Gutschrift hat keinen Beleg; xp_events weiß es und niemand fragt.
  7. Keine Stufenbelohnung. Eine neue Stufe passiert lautlos — auf der Seite mit Lautstärke 5.
  8. Kein Ziel. „Stufe 10 bis Weihnachten" gibt es nicht.
  9. Eigene Boosts sind außerhalb unsichtbar. Ein laufender eigener Boost steht in keinem Briefing und auf keiner Kachel. Die globalen stehen seit dem 24.09.2026 als Ereignismarke in der Kopfleiste (D22).
  10. XP liest nicht aus dem Ereignisstrom. („Kein Ereignisstrom" stimmt seit dem 17.09.2026 nicht mehr: personal.event_stream steht, und vier Domänen schreiben hinein — Karte bewertet, Aufgabe erledigt, Thema abgeschlossen, Übung bewertet. Es fehlt die Leseseite, und zwar mit Absicht: „ab jetzt, nicht rückwirkend", also frühestens ab dem 24.09.2026, wenn eine Woche Daten dasteht.)
  11. Gewohnheiten haben keinen eigenen Ort. Sie sind ein Reiter in /game und hängen damit an GAMIFICATION: wer kein Spiel will, verliert seinen Gewohnheitszähler mit.
  12. Kein Takt außer täglich und wöchentlich. — gebaut am 21.09.2026 (L10). Die Einheit kennt jetzt Tag, Woche und Monat, und dazu kommt ein Ziel je Takt: „3× pro Woche" ist die Woche mit dem Ziel 3. „Jeden zweiten Tag" bleibt offen und steht als Punkt 16 weiter unten — es ist kein Ziel je Takt, sondern ein Abstand zwischen zwei Vollzügen, und dafür reicht das Zählwerk nicht.
  13. Briefing und Tageskachel fragen nach dem Tag, nicht nach dem Takt. Beide zählen die Gewohnheiten, bei denen heute kein Eintrag steht — dashboard/server/uebersicht.ts und briefingController.ts. Für eine monatliche Gewohnheit heißt das: an dreißig von einunddreißig Tagen steht sie als offen da. Der Fehler ist älter als L10 (er traf schon jede wöchentliche Gewohnheit), fällt jetzt aber deutlicher auf. Die Rechnung dafür steht fertig in habitStreak.ts; es fehlt die Abfrage, die nach date_trunc über dem Takt gruppiert.
  14. Der Takt lässt sich nicht mehr ändern. — gebaut am 22.09.2026. Jede Gewohnheitszeile trägt „Ändern" und „Pausieren"/„Fortsetzen". Das Fach öffnet sich in der Zeile und ist mit Name, Takt und Ziel vorbelegt; der Pausenstand bleibt dabei, wie er war, weil der Server stehen lässt, was nicht mitkommt (siehe „Woher die Daten kommen"). Der Weg dahin war nicht der Knopf, sondern der Server: saveHabit füllte für jedes fehlende Feld die Vorgabe ein, und ein Pausenklick hätte damit den Takt zurückgesetzt. Was offen bleibt: eine Gewohnheit lässt sich anhalten und nicht wegstellen (Punkt 25), und „jeden zweiten Tag" gibt es weiterhin nicht (Punkt 16).
  15. Kein MCP-Werkzeug für Gewohnheiten — die Liste liegt bereit, sie hängt nur noch nicht. GAME_HABITS, GAME_HABIT_SAVE und GAME_HABIT_TOGGLE gibt es seit Migration 8; packages/mcp kannte aus dem ganzen Bereich nur skills_liste, und ein Modell konnte eine Gewohnheit weder sehen noch abhaken.

    Seit dem 21.09.2026 steht die Beschreibung der drei Werkzeuge — gewohnheiten_liste, gewohnheit_speichern, gewohnheit_abhaken — als Daten in progress/mcp/werkzeuge.ts, dort, wo Grundsatz 43 sie haben will. Was fehlt, sind zwei Zeilen im Server (packages/mcp/src/werkzeuge.ts: der Import und die Schleife, die die Liste anhängt) und die Zeilen in packages/mcp/README.md. Solange die fehlen, ist die Datei eine Zusage und kein Werkzeug.

    Im selben Zug gehört skills_liste hierher: es wohnt bis heute mitten im Server, und ein Bereich, dessen Werkzeuge an zwei Orten stehen, hat beim nächsten Umbau eines davon vergessen.

  16. Kein Takt über Abstände. „Jeden zweiten Tag", „alle drei Wochen": das ist keine Einheit mit Ziel, sondern ein Abstand seit dem letzten Vollzug. Es braucht eine zweite Art zu rechnen, nicht eine dritte Einheit.

    Das Modell dafür steht schon einmal in der Datenbank — in der Tabelle, die A08 fallen lässt. Gemessen am 21.09.2026 in denotato_wolke: personal.habits trägt frequency_amount, frequency_time_span_multiplier und frequency_time_span_unit (hour, day, week, month, year). Der Multiplikator ist genau das fehlende Stück: „alle drei Wochen" ist multiplier = 3, unit = week. game.habits kennt daneben nur cadence (taeglich, woechentlich, monatlich) und target (1…31) und kann einen Abstand deshalb nicht sagen. Der Notion-Rest hatte hier mehr Ausdruck als sein Nachfolger; die Spaltenform steht seit heute hier, damit sie das Fallenlassen überlebt.

  17. Keine Gewohnheits-Historie je Takt. Punkt 4 wird durch das Ziel dringlicher: „2 von 3 diese Woche" sagt, wo man steht, und nicht, welche Tage es waren — und bei einem Ziel über eins ist genau das die Frage, die man stellt.
  18. Der Verlauf trennt die Skills nicht. Die XP-Kurve ist die Summe über alle. Punkt 3 („kein Vergleich zwischen Skills") wird dadurch sichtbarer und nicht kleiner: die Reihe xp in packages/backend/src/database/access/verlauf.ts trägt keine Bedingung auf skill_id, und es gibt keinen Weg, eine mitzugeben.
  19. Die Gewohnheitskurve zählt Vollzüge, nicht gehaltene Takte. Sie liest game.habit_log und damit Haken je Kalendertag. „Wie viele Wochen habe ich den Takt gehalten" ist eine andere Frage — die Rechnung dafür steht in habitStreak.ts und läuft nicht in SQL.
  20. Ein Boost taucht im Verlauf nicht auf. Die XP-Kurve zeigt die gutgeschriebenen Punkte, also die vervielfachten; woher ein Ausschlag kommt — mehr getan oder ein Faktor 3 —, steht nirgends. Punkt 6 („keine Erklärung, woher XP kamen") ist damit die Hälfte einer Kurve, die man falsch liest.
  21. XP-Zahlen kennen keine Abkürzung. 1.234.567 XP steht in voller Länge in einer Zeile, die dreißigmal untereinander vorkommt. Seit dem 21.09.2026 in der Sprache des Lesers (I05), aber „1,2 Mio." gibt es nicht — und im Baum ist die Zeile dafür zu schmal.
  22. Der Multiplikator zeigt keine Herkunft. „×1,5" steht an der Zeile; von welchem Boost er kommt und wie lange er noch gilt, sagt erst die Boost-Liste auf einem anderen Reiter.
  23. Der Baum verrät nicht, woher eine Farbe kommt. Seit A04 kann sie aus zwei Quellen stammen (bis A28 waren es drei, mit dem Altbestand skill.colors): aus darstellung.skills oder aus der eingebauten Ableitung vom Namen. „Zurücksetzen" steht nur bei der ersten — aber welche gerade gilt, sieht man dem Feld nicht an. Die API liefert die Herkunft (origin) längst mit; der Schirm zeigt sie nicht.
  24. Die Fähigkeiten fallen zurück, der Baum nicht. Die drei Listen überleben einen Ausfall; was Faehigkeitsbaum.tsx daraus zeichnet, holt sich seine Zwischenstände selbst und ist dann leer (G03, Rahmen 7).
  25. Ein Skill lässt sich nicht wegstellen. („Nichts in diesem Bereich lässt sich entfernen" — für Gewohnheiten stimmt das seit dem 22.09.2026 nicht mehr: „Pausieren" schickt active: false, und eine pausierte Gewohnheit steht mit totem Hakenknopf da.) routen.ts kennt weiterhin acht Wege und keinen zum Löschen. Für Boosts ist das gewollt (Grundsatz 55: was einmal gutgeschrieben wurde, bleibt erklärbar). Für Skills fehlt schon die Spalte: game.skills trägt id, name, parent_id, position, owner_id, visibility und zwei Zeitstempel — kein active. Ein versehentlich angelegter Skill steht für immer im Baum und rechnet seine Null nach oben weiter, und was hier fehlt, ist deshalb keine Taste, sondern eine Wanderung. Auch sie wäre nicht das Löschen, sondern das Wegstellen.
  26. Ein Skill lässt sich nicht umbenennen und nicht umhängen. — gebaut am 22.09.2026. Jede Zeile des Baums trägt „Ändern"; das Fach nennt Name und Oberskill, und die Auswahl lässt den Skill selbst und alles unter ihm weg, damit niemand einen Ring anbietet, den der Server danach abweist. Zwei Dinge blieben dabei liegen: Die Reihenfolge unter einem Oberskill (position) lässt sich am Schirm nicht setzen (Punkt 34), und der deutsche Satz zur Absage bricht mitten im Nebensatz ab (Punkt 33).
  27. verify:verlauf ist eine Datei und kein Nachweis. — behoben am 21.09.2026, gemessen in der Gegenprobe. Sie lag seit Q03 in packages/backend/src/database/scripts/verifyVerlauf.ts, war grün, wenn man sie von Hand startete — und stand in keinem Skript und in keiner Kette; die Tafel „Wie es läuft" war damit der einzige Teil dieses Schirms, dessen Nachweis nie lief. Genau die zwei Zeilen, die hier gefordert waren, stehen jetzt in packages/backend/package.json: das Skript (Zeile 28) und sein Platz in verify:kette.
  28. Der Bereich heißt an zwei Stellen noch nach den Quests. Auf der Übersicht steht unter dem Bereichslink „Skills, XP und Quests" (progress/plugin.ts), im Schalterbestand der Einstellungen „Fortschritt (Skills, XP, Quests)" (plugins/src/settings/shared/bereichstexte.ts) — dazu quests: 'Quest' in shared/handlers/meldungen/meldungsstufen.ts. Der Code ist seit A08 weg, die Worte stehen noch, und beide haben einen englischen Eintrag in shared/src/languages/oberflaeche.en_us.json: wer den deutschen Satz ändert, muss den englischen mitnehmen, sonst verliert er seine Übersetzung.
  29. Ein Boost, der erst morgen anfängt, steht als „abgelaufen" da. — behoben am 22.09.2026. Die Zeile kennt jetzt drei Zustände (booststand in @shared/handlers/game/boostStand.ts): kommt, läuft, abgelaufen. Ein Boost mit starts_at in der Zukunft trägt „ab" und sein Anfangsdatum, in Zone und Format des Lesers. Die Rechnung liegt im gemeinsamen Teil und nimmt die Jetztzeit als Übergabewert — geprüft wird sie deshalb ohne Datenbank und ohne Warten (drei Proben in verify:game, dazu drei in Zeilenaktionen.test.tsx).
  30. Ein Klick auf „Beenden" sagt nichts, wenn er misslingt. — behoben am 22.09.2026. „Beenden", das Abhaken, das Pausieren und das Ändern prüfen ihren Rückgabewert und schreiben den Grund an die Zeile, aus meldungstext(message, details). Die Meldungszeile des Schirms bleibt dem Laden; eine Zeilenmeldung nimmt dem Schirm nichts weg, während sie dasteht. Was offen bleibt: Der Text ist nur so gut wie der Satz im Katalog, und einer von ihnen bricht ab (Punkt 33).
  31. Ein Klick holt seine Liste — und eine Gewohnheit holt sie zweimal. („Jeder Klick holt alles" stimmt seit dem 22.09.2026 nicht mehr: Abhaken, Pausieren und Ändern holen nur noch die Gewohnheiten, das Anlegen eines Skills nur die Skills. Das Anlegen und Beenden eines Boosts holt zwei Listen, und das mit Absicht — ein Faktor steht als multiplier in der Skill-Antwort, und ein Skillbaum mit einem Faktor, den es nicht mehr gibt, wäre die schlechtere Ersparnis.) Was bleibt: GAME_HABIT_TOGGLE liefert done, done_in_period, target und streak der angeklickten Zeile mit, und der Schirm holt danach trotzdem die ganze Liste. Eine Zeile aus der Antwort zu setzen, statt neu zu fragen, spart die zweite Runde — dafür braucht es aber einen Weg, useListenstand eine einzelne Zeile unterzuschieben, und den gibt es im Rahmen noch nicht.
  32. Der aufgehobene Stand wird aufgehoben und nicht gezeigt. Alle drei Listen liegen in useListenstand (progress.faehigkeiten, progress.gewohnheiten, progress.verstaerker), und die Standmarke steht auch dann da, wenn der Server schweigt. Nur: bereit ist !schirm.laedt && !switchedOff && message === null, und message setzt schon die erste misslungene der drei Anfragen. Fällt eine, ist bereit falsch, und damit verschwinden Tafel und Reiterinhalt — auch die beiden Listen, die geantwortet haben, und auch der aufgehobene Stand, den die Marke darüber gerade ankündigt. Der Rahmen (00-rahmen.md §7, G03) verlangt das Gegenteil: „Die Antwort kommt nicht, es gibt einen aufgehobenen Stand → Den aufgehobenen … darunter, wie bei jedem Fehler, die Fehlerzeile des Schirms." Was ein Schirm mit drei Listen zeigen soll, wenn eine von dreien fällt, sagt der Rahmen nicht — er kennt nur eine Liste. Erst diese Festlegung, dann die Zeile.
  33. Der deutsche Satz für den abgewiesenen Ring bricht ab. SKILL_MOVE_CYCLE_ERROR steht seit dem 22.09.2026 in messages.ts und in messageCodes.ts (409), und der Katalog kennt ihn auch — gemessen am 22.09.2026, beide Dateien Zeile 95. Englisch steht dort ein ganzer Satz („a skill cannot move under one of its own descendants"), deutsch ein halber: „Ein Skill kann nicht unter einen seiner eigenen Nachfahren" — ohne Verb, der Satz hört mitten im Nebensatz auf. Wer die API unmittelbar anspricht, liest das; über den Schirm sieht es niemand, weil die Auswahl den Ring gar nicht anbietet. Es fehlt ein Wort in einer gesperrten Datei (packages/shared/src/languages/de.json); der fertige Text liegt im Bericht. Rot wird davon kein Nachweis: verify:uebersetzung vergleicht, ob beide Kataloge dieselben Schlüssel tragen, und liest keinen Satz. Auch das ist ein offener Punkt — eine Lücke, die kein Nachweis sieht, ist die, die bleibt.
  34. Die Reihenfolge im Baum lässt sich nicht setzen. position sortiert die Geschwister unter einem Oberskill, GAME_SKILL_SAVE nimmt den Wert entgegen, und kein Schirm schickt je einen — jeder neue Skill bekommt die Null, und sortiert wird danach nach Namen. Seit dem 22.09.2026 ist wenigstens sicher, dass ein Umbenennen die Position nicht auf null zurückstellt — vorher hätte es das getan, und gemerkt hätte es niemand, weil kein Schirm je eine Position schickt. verify:game liest sie jetzt nach dem Umbenennen direkt aus der Tabelle. Was fehlt, ist das Ziehen einer Zeile — und dafür braucht der Baum eine Greiffläche, die es dort nicht gibt.
  35. Ein Boost lässt sich anlegen und beenden, aber nicht ändern. GAME_MULTIPLIER_ADD und GAME_MULTIPLIER_END sind die beiden einzigen Wege; ein Vertipper im Faktor oder ein falsches „Bis" lässt sich nur beenden und neu anlegen. Das ist für die Gutschrift richtig (Grundsatz 55: was gewirkt hat, bleibt erklärbar), für einen Boost, der noch nicht angefangen hat, aber nicht — der hat auf nichts gewirkt, und seit Punkt 29 sieht man ihn auch als solchen. Genau für diesen Zustand fehlt der Weg.
  36. Das Ersatzzeichen „◆" in skilldarstellung.ts ist absichtlich keine Registry-Ikone geworden. — gebaut am 12.10.2026 (I06): Der Wert bleibt „◆", gezeichnet wird er als raute über SymbolValue — in Darstellungseinstellung.tsx, Faehigkeitsbaum.tsx (je 18 px) und Hauptfaehigkeiten.tsx (24 px), dazu in der Symbolauswahl. Der Einwand vom 23.09.2026 trug nicht: Vorgabe und Wahl waren schon vorher dieselbe Glyphe, jetzt sind sie dasselbe gezeichnete Zeichen. Die Maße stehen in der Skala des Guides (12/14/16/18/20/24/32).
  37. Punkte ohne Skill tauchen in der Skillansicht nicht auf (seit dem 24.09.2026, F99, N278). Ein XP-Eintrag, der beim Zurückspielen eines Exports auf den Skill eines anderen Kontos zeigte, kommt mit leerem skill_id herein (Wanderung 145) — die Punkte bleiben dem Konto, aber der Baum gruppiert nach Skill und findet für sie keinen. Übersicht, Rückblick und Verlauf zählen sie mit; hier fehlen sie, und nichts sagt, dass es welche gibt. Ein Sammelposten „ohne Skill" wäre die ehrliche Anzeige, gebaut ist er nicht.

Lesbare Skillfarben (F21, 25.09.2026). Schrift auf einer Skillfarbe wird mit schriftAufFlaeche aus genau dieser Laufzeitfarbe berechnet; der alte gemeinsame Statuston existiert nicht mehr.

Skillfarben am Tag (E11, N345, 29.09.2026). Rand, Füllbalken, Punkt und Kürzelfläche malen die Skillfarbe in der Tagszene abgedunkelt (auskunftsfarbe, Guide §3.6), und die Schrift auf der Fläche wird gegen die abgedunkelte Farbe gewählt. Gespeichert bleibt der gewählte Wert; die zarte Tönung der Hauptskill-Karte bleibt ungerechnet.