# Review 05: Projekt-Seiten - Umfang: `src/content/docs/projekt/*.md`, 15 Dateien, 2999 Zeilen (Stand 2026-10-16). - Geprüft gegen: `AGENTS.md` §1, `tibi-svelte-starter` (`api/collections/*.yml`, `api/config.yml`, `api/hooks/*`, `frontend/src/App.svelte`), `tibi-server` (`internal/controller/collection_get.go`, `collection_count.go`, `setup.go:514-536`, `internal/mcp/*`, `internal/models/scope_enforce.go`, `internal/config/admin_token.go:115`), `tibi-types/schemas/config/*.schema.json`. - Methode: jede Datei vollständig gelesen; Code-Behauptungen per grep am Quellcode verifiziert. Zählung: MD-FEHLER 6, FEHLER-INHALT 5 (+ 7 PRUEFEN), STIL 9, STARLIGHT 15 (1–2 pro Seite), STRUKTUR 7, LUECKE 8, KOPFZEILE 15 (eine je Seite). ## Befund-Tabelle | # | Datei:Zeile | Kategorie | Befund (kurz) | Vorschlag | |---|---|---|---|---| | 1 | mcp-nutzen.md:61-90 | FEHLER-INHALT | Scope-Tabelle nennt `.get` (`namespace...get`), Detail-Abschnitte (Z102ff.) nennen `.read`. Code: `MethodToAction("GET")` → `"read"` (`admin_token.go:115`). | Tabelle auf `.read`/`.create`/`.update`/`.delete` umstellen (fünf Zeilen 63-67, 71). | | 2 | abfragen-lesen.md:99 | FEHLER-INHALT | „`…/comment/count` landet auf der Einzel-Route (`:id = "count"`)“. Code: `_count` (setup.go:514) ist statisch vor `:id` (:536) registriert, statisches Segment gewinnt in Gin. | Satz streichen oder umkehren: `/comment/count` zählt; nur `?facet=` an der Liste wird ignoriert (in `collection_get.go` keine Facet-Behandlung, verifiziert). | | 3 | hooks-schreiben.md:85 | FEHLER-INHALT | „Ohne `return` läuft der Hook ins Leere — eingeloggte Nutzer sehen dann alles.“ Hook filtert nur Anonyme (`filter_public.js`); ohne `return` sehen **anonyme** alles. | „eingeloggte“ → „anonyme“; Folge (Entwürfe öffentlich) nennen. | | 4 | sammlungen-anlegen.md:87 | FEHLER-INHALT | Gruppen-Zeile: „`content`, `content`, `community`“. Starter: `content` (content, navigation, medialib, tag), `community` (comment), `system` (ssr). Doppelung + `system` fehlt. | „`content`, `community`, `system` (`ssr.yml`)“; Beispiel-Spalte bereinigen. | | 5 | abfragen-lesen.md:34-35 | STIL | Aside mit „Achtung, Tippfehler im Code“ ist inhaltlich korrekt (`collection_get.go:32` schreibt wörtlich `Content-Range:`), Ton („Tippfehler“) grenzt an Binsen. | Sachlich lassen, „Tippfehler im Code“ → „Abweichung im Code (mit Doppelpunkt)“; kein Handlungsbedarf sonst. | | 6 | dateien-bilder.md:10, hooks-schreiben.md:10, navigation-i18n.md:9, suche.md:9 | MD-FEHLER | „Suche-Begriffe“ (4× mit Bindestrich) vs. „Suchbegriffe“ (audit-backup:10, deploy:10, jobs-actions:10); 8 Seiten (abfragen, felder, rechte, sammlungen, ssr, pagebuilder, llm, mcp) haben gar keine Suchbegriff-Zeile. | Einheitlich „Suchbegriffe:“ in allen 15 Seiten oder Zeile überall streichen (Entscheid dokumentieren). | | 7 | navigation-i18n.md:75-76 vs. felder-widgets.md:19 | STIL | Pfad-Muster doppelt, notationell verschieden: `^/[a-z0-9-/]*$` vs. `^\/[a-z0-9\-\/]*$` (äquivalent; Starter nutzt in `content.yml` die escaped Form, in `meta.agent.instructions` die kurze). | Eine Schreibweise wählen (kurze), an beiden Stellen + ssr-website:32 angleichen. | | 8 | audit-backup.md:50-58 | STRUKTUR | 4 Admin-UI-Absätze (Verlaufspanel, Diff-Ansicht, Wiederherstellen-Dialog, Seitenleiste) sind Prosa-Wände über **Admin**-Verhalten in einer Projekt-Seite; gehört nach `admin/` (Konzept/Editor). | Auf 1 Absatz + Verweis kürzen; Details nach `admin/eintrags-editor.md` oder `admin/konzept.md` verschieben. | | 9 | mcp-nutzen.md:1-754 | STRUKTUR | 754 Zeilen (> 600er-Richtwert), 36 Werkzeug-Referenzen à Beispiel + Fehler. Seite ist de facto Referenz, kein Projekt-Leitfaden. | Werkzeug-Referenz (Z100-683) nach `reference/mcp-werkzeuge.md` auslagern; hier Übersicht + `agent_guide_get`-Pflege + REST-only-Tabelle behalten. | | 10 | abfragen-lesen.md:124-129 vs. suche.md:44-49 | STRUKTUR | `qName`-Tabelle steht wortgleich in zwei Seiten (combined/fuzzy/semantic/default). | Tabelle nur in `suche.md` pflegen, in `abfragen-lesen.md` auf 2 Zeilen + Verweis kürzen. | | 11 | rechte-tokens.md:90-123, dateien-bilder.md:46-50, navigation-i18n.md:43-47+82-88, ssr-website.md:64-68, abfragen-lesen.md:89-93 | STRUKTUR | `active:true`-Falle an 5 Stellen erklärt (teils wortgleich: „Vorfall 2026-10-05“ in dateien + navigation). Querverweise existieren, aber Wortlaut driftet (einmal „count 0“, einmal „Header/Footer leer“). | Kanonischen 3-Zeilen-Kasten in `rechte-tokens.md` definieren; andere Seiten nur Aside + Verweis. | | 12 | pagebuilder-dev.md:183-247 | STRUKTUR | Editor-Overlay, Viewport-Steuerung, Übersichts-Overlay, BlueprintCard (65 Zeilen reines **Admin**-UI-Verhalten mit `de.json`-Schlüsseln) in einer Dev-Seite. | UI-Beschreibung nach `admin/eintrags-editor.md` verschieben oder verweisen; hier nur Registry-Vertrag + CSS-Transform + Lookup + Screenshot-Pipeline behalten. | | 13 | jobs-actions.md:34, jobs-actions.md:20 | PRUEFEN | „Ohne `cron` läuft der Job nie“ + „Schema-Pflicht: nur `type` + `file`“ — gegen `job.schema.json` nicht verifiziert (Schema-Datei in diesem Lauf nicht gelesen). | Am Schema + Runner (`internal/models/api.go:270`) belegen oder als ungesichert kennzeichnen. | | 14 | deploy.md:91 | PRUEFEN | „`POST /api/ssr?clear=1`, keiner nötig (`public.post: true`)“ — `ssr.yml` erlaubt `public.post: true` (Z17-22 verifiziert), aber ob `clear_cache`/`post_bind`-Pfad ohne Auth den Komplett-Wipe auslöst, ist nur aus Doku-Zitat übernommen. | Gegen `hooks/ssr/post_bind.js` + Server-Log belegen. | | 15 | suche.md:21 | PRUEFEN | „`navigation.yml` und `medialib.yml` nutzen nur einen `default`-Index im Modus `regex`“ — `search`-Blöcke verifiziert (beide `default`/`regex`), aber „kein Textindex nötig“ ist eine Wertung ohne Beleg. | „kein Textindex nötig“ streichen oder begründen (regex braucht keinen `$text`-Index). | | 16 | hooks-schreiben.md:111 | PRUEFEN | „Das ist die einzige Log-Hilfe im Starter.“ Absolut-Aussage, nur aus `lib/utils.js` abgeleitet. | Abschwächen („die Standard-Log-Hilfe“) oder Volltextsuche nach `console.log` im Starter belegen. | | 17 | abfragen-lesen.md:105 | STIL | „Schnelle Schätzung statt exakter Zahl (nur **ohne** `filter`)“ — korrekt (`collection_count.go:145`), aber Klammer-Format inkonsistent zu anderen Tabellen. | Einheitlich: Bedingung in eigene Spalte oder Fußnote. | | 18 | rechte-tokens.md:42 | STIL | „aber keinen Lese-Hook“ — `tag.yml` verifiziert (nur post/put/delete-`return`), Formulierung ok, aber Vorwärtsverweis auf `clear_cache.js` ohne Link. | Link auf `projekt/hooks-schreiben/` ergänzen. | | 19 | llm-nutzen.md:89 | STIL | „Preise stehen nirgends im Code — erfinde keine.“ Imperativ an den Leser, Ton grenzwertig belehrend. | „Modellnamen aus `GET /llm/providers` übernehmen, keine erfinden.“ | | 20 | sammlungen-anlegen.md:74 | STIL | „`uploadPath` setzen, auch wenn die Sammlung keine Dateien enthält“ — unbegründete Pflicht ohne Code-Beleg. | Begründung ergänzen (Server-Default/Fehlerbild Z159) oder zu Empfehlung abschwächen. | | 21 | deploy.md:15, deploy.md:79 | STIL | Platzhalter `LIVE_URL=https://www` + `__PROJECT_NAME__` werden erklärt, aber das Beispiel ist keine gültige URL (Leser kopiert ggf.). | Kommentar `# TODO: echte Domain eintragen` direkt in den Block schreiben. | | 22 | ssr-website.md:45-47 | STIL | `sort: "sort"` im Beispiel ohne Erklärung (Feld `sort` aus Starter vorausgesetzt, in `App.svelte:171` verifiziert). | Ein Satz: „`sort` ist ein Starter-Feld für die Reihenfolge.“ | | 23 | hooks-schreiben.md:127 | STIL | „Weitere im Starter genutzte Zugriffe“ — Aufzählung mit 8 Gliedern in einer Zeile, schwer scannbar. | Als Tabelle oder Bullet-Liste mit je einem Halbsatz umbrechen. | | 24 | felder-widgets.md:56-58 | STIL | 25 Enum-Werte als Fließtext-Code-Span; `pagebuilder`/`pageBuilder`-Doppelung nur in Klammern erklärt. | Als Tabelle (Widget → Wofür) oder `FileTree`-ähnliche Liste; Doppelung als `Aside note` mit Schema-Beleg. | | 25 | audit-backup.md:96 | STIL | „Übernimm die Liste nicht blind“ — belehrender Ton (Binsen-Nähe), dazu Klammer-Schachtelung. | „Gleiche jeden Namen gegen `api/collections/*.yml` ab, sonst …“ | | 26 | dateien-bilder.md:105 | STIL | „Passiert nicht von selbst“ als Lösungs-Spalte — flapsig, keine Handlungsanweisung. | „Kein Handlungsbedarf; Waisen per Dateisuche im Upload-Pfad prüfen.“ | | 27 | navigation-i18n.md:66 | STIL | „Kollidiert auf `null` — kein ‚geht schon gut‘“ — umgangssprachlich, Anführungs-Floskel. | „Zweiter Datensatz ohne Schlüssel verletzt den Unique-Index (`null`/`lang`).“ | | 28 | abfragen-lesen.md:143 | KOPFZEILE | „Verifiziert am e3f92eb 2026-10-14 (tibi-svelte-starter), am 68b42785 2026-10-15 (tibi-server, …).“ Format ok, Hash 7-stellig. | — | | 29 | audit-backup.md:145 | KOPFZEILE | Vier Belege, Hashes 7-stellig, Daten 2026-10-13 bis 15. Doppel-Beleg gleiche Commit `2b091d89` zweimal. | Doppel-Beleg zusammenfassen. | | 30 | dateien-bilder.md:109 | KOPFZEILE | Hash 8-stellig (`e3f92ebf`) — uneinheitlich zu 7-stelligen anderswo; nur Starter-Beleg trotz Server-Aussagen (filecleanup, Lookup-Regel). | Hash-Länge vereinheitlichen (7 oder 8 überall); Server-Beleg ergänzen. | | 31 | deploy.md:131 | KOPFZEILE | Nur Starter-Beleg (`e3f92eb`), obwohl Reload-Endpunkte + Token-Tabelle Server-Verhalten beschreiben. | Server-Beleg (setup.go/reload-Docs) ergänzen. | | 32 | felder-widgets.md:199 | KOPFZEILE | Drei Belege (Starter, tibi-types, Server), Hashes 7-stellig. Vorbildlich. | — | | 33 | hooks-schreiben.md:234 | KOPFZEILE | Hashes 8-stellig (`e3f92ebf`, `4c55f824`) — uneinheitlich zu Z28/32. | Hash-Länge vereinheitlichen. | | 34 | jobs-actions.md:144 | KOPFZEILE | Drei Belege, 7-stellig, mit Dateinamen (job-/action-schema, Test-Plan 40). Vorbildlich. | — | | 35 | llm-nutzen.md:172 | KOPFZEILE | Ein Beleg, sehr lange Klammer (11 Dateien), Datum 2026-10-16 (jüngste Prüfung). Lesbarkeit leidet. | Dateiliste kürzen (nur Handler + Registry + Scope). | | 36 | mcp-nutzen.md:754 | KOPFZEILE | Zwei Belege, Files namentlich — ok, aber längste Seite mit knappstem Beleg (keine Test-Pläne, keine Guards-Zeilen). | Guards-/Methoden-Beleg ergänzen. | | 37 | navigation-i18n.md:119 | KOPFZEILE | Starter + Admin-Test-Pläne, 8-/7-stellig gemischt (`e3f92ebf`, `2b091d89`). | Hash-Länge vereinheitlichen. | | 38 | pagebuilder-dev.md:248 | KOPFZEILE | Admin-Commit + Starter-Commit mit Komponentenliste. Vorbildlich, längste Klammer. | Evtl. kürzen, sonst ok. | | 39 | rechte-tokens.md:154 | KOPFZEILE | Starter + Server (Matrix-Test). Vorbildlich. | — | | 40 | sammlungen-anlegen.md:166 | KOPFZEILE | Starter + tibi-types, aber kein Server-Beleg trotz Aussagen zu `409` vs. `500` (Legacy-Default, Z133). | Server-Beleg (Fehler-Mapping) ergänzen. | | 41 | ssr-website.md:178 | KOPFZEILE | Nur Starter-Beleg, obwohl Seite Server-Verhalten beschreibt (Cache-Regeln, `X-SSR-Cache`, `duplicate key`, 500-Dummy). | Server-Beleg (`get_read.js` läuft im Server, SSR-Docs) ergänzen. | | 42 | suche.md:103 | KOPFZEILE | Drei Belege inkl. rankfusion + Test-Plan 41. Vorbildlich; Hash-Länge gemischt. | Hash-Länge vereinheitlichen. | | 43 | abfragen-lesen.md:143, suche.md:74-75, sammlungen-anlegen.md:133 | LUECKE | Bulk-Operationen (`bulkCreate`/`bulkUpdate`/`bulkDelete`, `items[]` bei MCP-`document_create`) werden nirgends aus REST-Sicht gezeigt. | Abschnitt „Mehrere Einträge auf einmal“ in `abfragen-lesen.md` (Bulk-Query, Bulk-Freigabe, Fehlerbild). | | 44 | ssr-website.md:45-51 | LUECKE | `aggregate` (commentCount) nur hier gezeigt, in `abfragen-lesen.md` fehlt jede Erwähnung (Parameter-Tabelle Z39-45 kennt nur filter/sort/limit/offset/count). | `aggregate`-Zeile + Verweis in `abfragen-lesen.md` ergänzen. | | 45 | felder-widgets.md:76 | LUECKE | `accept` (MIME-Typen) ohne Beispiel („—“); Starter-`medialib.yml` setzt nur `maxFileSize`, kein `accept` — unklar, ob MIME-Filter überhaupt möglich. | Am Schema (`collection.schema.json`) klären und Beispiel oder „nicht zutreffend“ schreiben. | | 46 | felder-widgets.md:194-197 | LUECKE | `meta.protected` in 2 Zeilen abgehandelt; Feld-Level-Read-Rechte/Projektionen (`invalid projection`, `lookup permission denied`) nur als Fehlerbilder. | Abschnitt „Wer darf welches Feld sehen/ändern“ oder Verweis auf Server-Permissions-Docs. | | 47 | jobs-actions.md:121-123, mcp-nutzen.md:702-740 | LUECKE | `GET /_meta` / `system_meta_get` und `meta.query`/`extra`-Parameter nur als Nebensatz; keine Seite erklärt `_meta` aus Projektsicht. | Kurzabschnitt in `sammlungen-anlegen.md` oder `mcp-nutzen.md` (was `_meta` liefert, wofür `extra`). | | 48 | alle Seiten | LUECKE | System-CRUD (Projekte/Collections per API anlegen, `X-Admin-Token`, Namensraum-Registrierung) fehlt komplett; `deploy.md` und `rechte-tokens.md` erwähnen nur Köpfe. | Verweis auf Server-Docs oder Kurzabschnitt (gehört ggf. nach `server/`, dann Link setzen). | | 49 | suche.md:58, abfragen-lesen.md:131 | LUECKE | `qExplain=1`/`?qExplain=1` als Debug-Hinweis, aber Ausgabe-Format nirgends erklärt. | 1 Beispiel-Output oder Satz zur Interpretation. | | 50 | audit-backup.md:62-86 | LUECKE | Snapshot-Restore per API (Fehlerfälle, Teilmengen, `collections: []`-Semantik beim Restore) fehlt; nur Admin-UI-Klickpfad. | Restore-Fehlerbilder (Platz, laufende Jobs, Cache danach) ergänzen. | ## Starlight-Potenzial (pro Seite) - `abfragen-lesen.md`: `Steps` für „Erste Liste → filtern → zählen“-Rezept statt Fließtext (Z8-10); `Badge` für `_count`/`_facet`-Routen-Warnung (Z97-100); Fehlertabelle (Z135-141) ist bereits gut, zusätzlich `Aside tip` mit Copy-paste-fähiger Basis-URL. - `audit-backup.md`: `CardGrid` bereits genutzt — zusätzlich `Tabs` (UI-Pfad vs. API-Pfad) in „Audit einschalten“ (Z18-46); `FileTree` für `snapshotPath`-Layout; `Badge` („Betreiber-Sache“) an Server-Schaltern (Z29). - `dateien-bilder.md`: `Steps` bereits genutzt — zusätzlich `Tabs` um Upload-Antwort vs. Fehlerantwort (Z22-31); Filter-Tabelle (Z84-91) um `Badge`-Spalte (Standard vs. Spezial) erweitern; Code-Titel enthalten bereits Pfade, gut. - `deploy.md`: `Tabs` bereits genutzt — zusätzlich `Aside tip` mit 1-Befehl-Verify (`curl` Reload + `clear=1`) nach Z93; Checkliste (Z113-121) als `Steps` ist gut, zusätzlich `Badge` („Staging“/„Live“) an Bühnen-Tabelle. - `felder-widgets.md`: `Tabs` bereits genutzt — zusätzlich `Badge` für Pflicht-/Optional-Schlüssel in Validator-Tabelle (Z65-79); 25 Widgets (Z58) als einspaltige Liste mit `Badge` pro Kategorie (Auswahl, Datei, Datum) statt Fließtext. - `hooks-schreiben.md`: `Steps` + `Tabs` bereits genutzt — zusätzlich `FileTree` für `api/hooks/`-Layout (Z50-59 statt Tabelle); `Aside` statt Klammer-Zusatz bei `context_response.header` (Z138). - `jobs-actions.md`: `CardGrid` + `Tabs` bereits genutzt — zusätzlich `Badge` („Cron“/„HTTP“) an Baustein-Tabelle (Z95-101); `Steps` um Verify-Schritt mit erwartetem Log-Auszug erweitern. - `llm-nutzen.md`: `Tabs` bereits genutzt — zusätzlich `Aside caution` für 429-Budget-Stopp statt Tabellen-Zeile (Z166); `Badge` für Normal-/Streaming-Modi an Z17/37; lange Budget-Regeln (Z105-113) als nummerierte `Steps` lesbarer. - `mcp-nutzen.md`: `Badge` bereits genutzt — nach Auslagerung (Nr. 9) `LinkCard`s zu `reference/mcp-werkzeuge.md` + `projekt/hooks-schreiben/`; pro Werkzeug einklappbar wäre ideal (Starlight ohne Details-Plugin: stattdessen Anker-Links + Inhaltsverzeichnis oben). - `navigation-i18n.md`: `Steps` + `Tabs` bereits genutzt — zusätzlich `FileTree` für 4 Singleton-Bäume (statt Z13-Satz); Checkliste (Z82-88) als `Badge`-Tabelle („Schema hat Feld: ja/nein“) schärfer als Fließtext. - `pagebuilder-dev.md`: `Steps` + `Tabs` bereits genutzt — zusätzlich `Badge` („Admin-UI“ vs. „Projekt-Code“) an Abschnitten ab Z183 zur Trennung nach Nr. 12; Registry-Vertrag (Z47-54) als `Code`-Titel mit Dateipfad ist gut. - `rechte-tokens.md`: `Tabs` bereits genutzt — zusätzlich `Badge` („anonym“/„Token“/„JWT“/„Admin“) an Kopf-Tabelle (Z48-53); `active:true`-Tabelle (Z114-120) als kanonischer Kasten mit `Aside caution` + Anker für andere Seiten. - `sammlungen-anlegen.md`: `FileTree` + `Steps` bereits genutzt — zusätzlich `Tabs` (Minimal vs. Voll mit Suche/Hooks) statt einem Block; `Badge` an Modi-Tabelle (Z141-146, „Starter-Standard“). - `ssr-website.md`: `FileTree` + `Tabs` bereits genutzt — zusätzlich `Badge` (`X-SSR-Cache`/`X-SSR-Cleared`) an Cache-Abschnitt (Z122-144); `Steps` für „Eigener Block“ ist gut, Code-Titel bereits mit Dateipfad. - `suche.md`: `Steps` + `Tabs` bereits genutzt — zusätzlich `LinkCard`s zu den drei Index-Quellen (Starter-YAML, rankfusion, Test-Plan 41) unter „Neuaufbau“; RRF-Formel (Z69-71) als `Aside note` mit Formel-Hervorhebung. ## Unsichere Punkte (PRUEFEN, 7) 1. Nr. 13 — Job-`cron`-Pflicht und Schema-Felder (`job.schema.json` + Runner-Verhalten ungelesen). 2. Nr. 14 — `POST /api/ssr?clear=1` ohne Auth: `post_bind.js`-Wipe-Pfad nicht am Code verifiziert. 3. Nr. 15 — „kein Textindex nötig“ für `default`/`regex` (Wertung ohne Beleg). 4. Nr. 16 — „einzige Log-Hilfe im Starter“ (Volltextsuche im Starter fehlt). 5. `navigation-i18n.md:13` — „genau vier Singleton-Bäume“ + `maxLevel`-Regel (Header 2, Footer 1, Z28): `declaredTrees` nur teilweise gelesen (Header DE/EN gesehen, Footer nicht). Am vollständigen `navigation.yml`-Block belegen. 6. `rechte-tokens.md:130-142` — Org-/Team-Modell (`matrixorga`, `teama1`, Zugriffsregeln) aus `access_control_matrix_test.go` übernommen; Test-Namen als Doku-Beleg sind fragil — gegen Server-Docs oder Admin-Verhalten gegenlesen. 7. `pagebuilder-dev.md:62-86` und `mcp-nutzen.md:702-740` — Aussagen über Admin-Verhalten (`PagebuilderOverlay`, `de.json`-Schlüssel, `meta.agent`-Pflege) bzw. Server-Interna (`query.go`-Validierung) konnten in diesem Lauf nicht am jeweiligen Repo verifiziert werden; Stichprobe pro Datei empfohlen.