# Divi-Freigabe je Fähigkeit – Entscheidungen Stand 2026-10-18, Branch `etappe-4`. Plan: `docs/superpowers/plans/2026-10-18-divi-faehigkeiten.md`. Ersetzt die pauschale Sperre der Divi-Absicherung (2026-09-29) durch eine Freigabe je Fähigkeit und löst den Kern von Divi. ## Entscheidungen des Nutzers - **E1 Automatische Freigabe je Fähigkeit.** Eine Divi-Version ohne Freigabe wird je Fähigkeit freigegeben, wenn alle Anforderungen dieser Fähigkeit unverändert sind: jeder Aufruf existiert und nimmt die Argumentzahl an, sein Signatur-Fingerabdruck stimmt mit `fingerprints.json` überein, jeder Mirror-Fingerabdruck stimmt, jede Konstante ist definiert. Der Filter `lit_mcp_divi_auto_release` (bool, Standard `true`) schaltet das ab; dann gilt für nicht freigegebene Versionen wieder „alles ungetestet“. Eine Admin-Freigabe gibt alle Fähigkeiten ohne Probleme frei. - **E2 Lese-Werkzeuge lehnen ebenfalls ab**, wenn eine ihrer Fähigkeiten nicht nutzbar ist (`divi_untested` bzw. `divi_incompatible`), statt in `internal_error` zu laufen. Der frühere Hinweis in `warnings` entfällt. - **E3 Gesperrte Werkzeuge bleiben registriert** und lehnen beim Aufruf ab. `lit-site-status` meldet je Fähigkeit Zustand, Quelle, Probleme und betroffene Werkzeuge; der Reiter „Divi“ zeigt dieselbe Tabelle; ein Admin-Hinweis erscheint, sobald eine Fähigkeit nicht nutzbar ist; `wp lit-mcp divi-check` gibt die Matrix aus. - **E4 Umfang:** Kern-Entkopplung und Sperre je Fähigkeit samt Anzeige; weitere Wartbarkeit kommt später. ## Umsetzung - **Elf Fähigkeiten** (`DiviFeature`): `page-read`, `page-write`, `catalog`, `dynamic-sources`, `design-read`, `preset-write`, `library-read`, `library-write`, `roles`, `tb-read`, `tb-write`. Jeder Manifest-Eintrag (Aufruf, Mirror, Konstante) trägt seine Fähigkeiten; geteilte Aufrufe (z. B. `remove_static_resources` für Seiten und Theme Builder) tragen alle betroffenen, ein Bruch sperrt bewusst beide. Ein Test verlangt mindestens eine Fähigkeit je Anforderung. - **Werkzeuge erklären ihre Fähigkeiten** (`RequiresDiviFeatures`, `DeclaresRequirements` für `lit-content-create`, das nur mit `divi` und nur bei aktivem Divi 5 etwas braucht: `page-read`, `page-write`, `catalog`, `design-read`, `dynamic-sources` – `DiviContentComposer::FEATURES`; ohne aktives Divi antwortet das Werkzeug selbst mit `unsupported`). `DiviFeatureGate` prüft sie vor dem Aufruf, auch im `permission_callback`. Im vendorten mcp-adapter ruft nur der Werkzeugaufruf diesen Callback auf (`tools/call`: `Handlers/Tools/ToolsHandler.php`, `call_tool()`; `mcp-adapter-execute-ability`: `Abilities/ExecuteAbilityAbility.php`), das Auflisten nicht. Die Adapter prüfen vor jedem Schreiben zusätzlich selbst (`assertFeature`); `DiviSaver` ergänzt je Speicherbereich `library-write` bzw. `tb-write`. - **Ablehnung:** `divi_untested` (mindestens eine Fähigkeit ungetestet, keine inkompatibel) oder `divi_incompatible`, HTTP 423, Details `features` (`id`, `label`, `state`, `problems`) und ein Hinweis, der die Fähigkeiten nennt und sagt, dass andere Divi-Werkzeuge weiter funktionieren. - **Zustand:** Code-, Signatur- und Konstanten-Prüfungen laufen je Request live. Gecacht wird nur die Mirror-Prüfung (Transient `lit_mcp_divi_state`, Format 2: Mirror-Probleme mit Art und Fähigkeiten, ein Tag); ein Eintrag im alten Format zählt als Miss. Ein Divi-Hotfix ohne Versionssprung wird so sofort erkannt. - **Kern ohne Divi:** `CoreIndependenceTest` erzwingt, dass `Abilities`, `Admin`, `ChangeLog`, `Cli`, `Guides`, `Integrations/{Core,Media,Pods,WordPress}`, `Server` sowie die Dateien direkt unter `src/` und `src/Integrations/` nichts aus `Integrations\Divi` importieren (auch kein Alias-Import). Einzige Ausnahme ist `Plugin.php` als Composition Root. Die Divi-Oberfläche liegt in der Divi-Integration: `Integrations/Divi/Admin/DiviTab.php` und `Integrations/Divi/Cli/DiviCheckCommand.php`. ## Ergänzungen bei der Umsetzung - **Signatur-Fingerabdruck vergleicht die Aufrufform, nie das Verhalten.** Er enthält Parameterzahl, Typen und Rückgabetyp, aber keine Parameternamen und keine Default-Werte (die Adapter rufen Divi positional). 14 der 29 Divi-Symbole sind untypisiert; dort sichert der Hash nur Aufrufform und Parameterzahl. Ein neuer optionaler Parameter am Ende sperrt die Fähigkeit (fail closed, gewollt); ein geänderter Default-Wert fällt nicht auf. Die automatische Freigabe sagt daher „Aufrufe unverändert“, nicht „funktioniert“. - **Referenz und PHP-Version:** `fingerprints.json` wurde unter PHP 8.4 berechnet. Reflection gibt Typen je PHP-Version unterschiedlich aus (z. B. `iterable` ab 8.2 als `Traversable|array`); eine andere PHP-Version in Produktion kann deshalb scheinbare `signature`-Probleme melden. Das zählt nur für die automatische Freigabe einer nicht freigegebenen Divi-Version und schlägt geschlossen fehl: Es entsteht schlimmstenfalls ein falsches „inkompatibel“/„ungetestet“, nie eine falsche Freigabe. `wp lit-mcp divi-check --update-reference` erzeugt die Referenz neu. - **Mirror ohne Referenz ist ein harter Befund** (Art `mirror`), auch bei freigegebener Version: sonst würde ein Nachbau ungeprüft schreiben. „Referenz fehlt → ungetestet“ gilt nur für Aufruf-Signaturen und nur bei nicht freigegebener Version. - **Freigabe und Signaturen:** Eine freigegebene Version – per Admin-Freigabe (`ReleaseStore`) oder im Code getestet (`DiviReleases::TESTED`) – berücksichtigt Signatur-Probleme nicht; Signaturen dienen der Automatik für Versionen ohne Freigabe. Ein Divi-Hotfix ohne Versionssprung, der nur eine Signatur ändert, sperrt bei einer freigegebenen Version nicht; Aufrufe, Mirrors und Konstanten sperren weiter. - **Registrierungs-Prüfungen** (Post-Typen, Taxonomien, Block-Typen) bleiben informativ und sperren nicht. Die Schreibprobe bleibt der Seitenpfad und ist nur für die Admin-Freigabe nötig. - **Protokoll:** Ablehnungen (`ChangeLog`, Ergebnis `refused`) werden nur für schreibende Werkzeuge protokolliert; eine abgelehnte Lese-Anfrage ändert nichts. Da das Gate vor `permission()` läuft, bekommen Aufrufer ohne Recht die Divi-Sperre statt `forbidden` und einen Protokolleintrag; es entsteht kein Leck, weil die Antwort nur Fähigkeiten nennt. Die Eigenschaft `warnings` bleibt im Ausgabeschema der Divi-Werkzeuge. - **Eingabeabhängige Fähigkeiten:** `lit-site-status` und der Reiter zeigen je Werkzeug die Grundmenge; je nach Eingabe (Bibliotheks- oder Theme-Builder-Ziel, `dry_run: false`, `nodes`) kommen weitere hinzu. `dynamic-sources` ist eine Obermenge: ein Bruch sperrt alle Werkzeuge mit Composer. - **Exit-Code von `wp lit-mcp divi-check`:** 0 = Prüfung grün und alle Fähigkeiten nutzbar, 1 = Prüfung rot, 2 = Prüfung grün, aber mindestens eine Fähigkeit nicht nutzbar. Skripte, die nur 0/1 kennen, lesen 2 als Fehler – gewollt. - **Admin-Hinweis:** erscheint für Administratoren bei aktivem Divi auf allen Admin-Seiten außer dem Reiter „Divi“; er ist nicht wegklickbar und verschwindet mit der Ursache. Die Freigabe-Formulare im Reiter richten sich weiter nach dem Gesamtzustand; die Freigabe selbst verlangt einen vollständig grünen Prüfbericht. ## Smoke `tests/Integration/divi-release-smoke.sh` simuliert eine Abweichung ohne Divi-Dateien oder `fingerprints.json` anzufassen: Es trägt ein Mirror-Problem für `page-write` in den Cache `lit_mcp_divi_state` ein. Das kann nur verschärfen, gilt nur für diesen Schlüssel (`stateKey()`), höchstens zehn Minuten, und der EXIT-Trap löscht den Transient. Ein Filter im Produktionscode für die Referenz wurde verworfen: er wäre ein zusätzlicher Weg, die Sperre zu beeinflussen, ohne dass ein Test ihn bräuchte. ## Offen - Der Admin-Hinweis berechnet den Zustand auf jeder Admin-Seite (Reflection und Dateihashes je Aufruf); bei Bedarf kurzlebig cachen. - `DesignArea::feature()`: Farben (`color-write`) und Variablen (`variable-write`) haben seit Etappe 4c eigene Fähigkeiten; Theme-Optionen bekommen ihre mit 4d.