146 lines
13 KiB
Markdown
146 lines
13 KiB
Markdown
# Phase 06 — Plugin-System
|
||
|
||
> **Docs-sidecar status:** Historical phase plan with shipped/deferred notes.
|
||
> The production-facing entrypoints are `../../features/plugins.md`,
|
||
> `../../plugins.md`, `../../operations/plugin-lifecycle.md`, and
|
||
> `../../plugins/*.md`. This file preserves original phase intent and should
|
||
> not be read as a claim that Marketplace, full hook fanout, or production
|
||
> third-party plugin execution is complete.
|
||
|
||
**Dauer:** 10-13 Wochen
|
||
**Tasks:** 3
|
||
**Ziel:** Vollwertiges Runtime-Plugin-System auf WASM-Basis. Drittanbieter (oder interne Teams) können die Boilerplate ohne Forking um neue Funktionen erweitern — sicher isoliert, kapazitäts- und ressourcenbegrenzt, signiert, und mit klarer Consent-Flow für Tenants. Phase 06 liefert die drei zwingenden Bausteine: (1) eine **WASM-Sandbox + Plugin-SDK**, (2) die **Host-seitigen Hook-Points + Plugin-Lifecycle + Admin-UI** und (3) **Audit-Logging, Developer-Docs, externe Security-Review** vor Production-Freigabe.
|
||
|
||
Ein Plugin-Marketplace mit Discovery, Ratings, Billing und Auto-Updates ist explizit **nicht** Teil dieser Phase — er liegt im Backlog (Phase 11, Task `plugin-marketplace.md`) und setzt voraus, dass diese Phase stabil ausgeliefert wurde.
|
||
|
||
## Current shipped vs blocked
|
||
|
||
Phase 06 has shipped substantial runtime foundation, but it is **not** a completed public Marketplace. Current code includes `@toolctrl/plugin-runtime` / `@toolctrl/plugin-sdk` foundations, manifest validation and signature checks, a WebAssembly sandbox wrapper, capability gating, the `outbox.plugin-hook` fanout path into the isolated `toolctrl.plugin-invoke` queue, tenant plugin lifecycle services, hook publishing for selected host events, tenant settings/API surfaces for installed plugins, plugin migrations, audit retention/capability-use trails, crash tracking and operator CLI commands.
|
||
|
||
Still blocked or deferred: public Marketplace discovery, ratings, billing and auto-updates; external security review and production sign-off; Wasmtime/per-instruction fuel migration; hook coverage beyond the shipped foundation set; richer settings UX and encrypted secret host bindings beyond the shipped iframe/CSP/postMessage shell; hot reload; and production rollout evidence. Treat Phase 06 as internally audit-ready foundation plus admin/operator controls, not as a finished third-party Marketplace.
|
||
|
||
## Warum diese Phase nach Phase 03 und Phase 05
|
||
|
||
- **Outbox-Pattern** (Task #42 aus Phase 03) ist Pflicht-Voraussetzung. Plugin-Hook-Events (`onTenantSignup`, `onEntityCreate`, `onWorkflowExecute`, etc.) werden **niemals** synchron im Request-Path aufgerufen. The shipped foundation emits hook outbox events, fans them out on `worker-general` via `outbox.plugin-hook`, and enqueues isolated invocation jobs on `toolctrl.plugin-invoke`. Sonst würde ein einzelnes hängendes Plugin den Host-Request blockieren oder mit Tenant-Operationen in einer DB-Transaktion ringen.
|
||
- **Worker-Queues + Worker-Trennung** (Task #45 aus Phase 03) liefern den Pattern für einen dedizierten `worker-plugin`-Service. WASM-Instanzen sind CPU- und memory-bound; execution stays on the plugin worker group through `toolctrl.plugin-invoke`, while subscriber fanout remains cheap on the general worker.
|
||
- **Feature-Flags** (Phase 05, Task #53) sind eine optionale Rollout-Schicht für Plugin-Funktionen. Das aktuelle Capability-Gating läuft über Manifest-Schema, tenant-gebundene Capability-Grants und den Consent-Dialog; Feature-Flags können ganze Plugin-Oberflächen oder Capability-Klassen zusätzlich abschalten.
|
||
- **SharedStore** (Task #37 package / #38 migration aus Phase 03) wird für Plugin-Resource-Counters genutzt (Rate-Limits, CPU-Budget pro Plugin pro Tenant pro Minute).
|
||
- **Sentry + OTel** (Phase 02) müssen Plugin-Spans/Errors mit Tags `plugin.id`, `plugin.version`, `plugin.capability` versehen — die Wiring-Punkte müssen vor Phase 06 stehen, sonst sind Plugin-Crashes blind.
|
||
|
||
Ohne diese Foundation würden wir Plugin-Code synchron in Web-/Worker-Prozessen laufen lassen müssen — das produziert messbare Latenz, gefährdet Mandanten-Isolation und macht Resource-Limits unmöglich durchzusetzen.
|
||
|
||
## Was diese Phase blockt
|
||
|
||
- **Phase 11 / `plugin-marketplace.md` (Backlog):** Der Marketplace ist der Discovery-Layer über diesem System. Ohne Sandbox + Lifecycle + Audit kein veröffentlichbares Plugin und damit kein Marketplace.
|
||
- **Phase 08 / `cli-scaffolding.md`:** Die CLI bekommt einen `tc plugin scaffold`-Subcommand der die Plugin-Templates aus dieser Phase nutzt (`audit-docs.md` enthält Template-Definition). Phase 08 ist nicht hart geblockt — sie kann unabhängig starten und das Plugin-Template nachreichen sobald Phase 06 fertig ist.
|
||
- **Phase 07 / Chatbot-Tool-Plugins:** Plugins können Chatbot-Tools registrieren (über `tool.register`-Capability). Phase 07 ist nicht geblockt — Chatbot kann ohne Plugin-Tools laufen, gewinnt aber durch das System.
|
||
|
||
Phase 06 blockt **nichts kritisches** für die Produktionsreife der Boilerplate. Sie ist ein Differenzierungs-Feature, kein Foundation-Stack.
|
||
|
||
## Task-Reihenfolge
|
||
|
||
| Reihenfolge | Task-ID | Datei | Parallelisierbar mit |
|
||
| ----------- | ------- | -------------------- | ---------------------------------------------------- |
|
||
| 1 | #21 | `wasm-sandbox.md` | — (Foundation, alle anderen hängen dran) |
|
||
| 2 | #22 | `hooks-lifecycle.md` | — (braucht #21 für Plugin-Runtime) |
|
||
| 3 | #23 | `audit-docs.md` | — (braucht #21 + #22 für vollständige Audit-Surface) |
|
||
|
||
Die drei Tasks sind **strikt sequenziell**. Anders als bei Phase 03/04 lohnt sich hier keine Parallelisierung, weil:
|
||
|
||
- `hooks-lifecycle` braucht ein funktionierendes SDK aus `wasm-sandbox`, um Hook-Handler überhaupt definieren zu können.
|
||
- `audit-docs` schreibt Developer-Docs und Beispiel-Plugins, die ohne stabile Hook-API + Lifecycle-Flows nicht realistisch sind.
|
||
- Die externe Security-Review (Acceptance-Criterion in `audit-docs`) prüft den **gesamten** Phase-06-Code-Surface — wir wollen keine Review zur Halbzeit, weil sonst Folge-Findings die Sandbox-Architektur retroaktiv aufreißen.
|
||
|
||
## Dependency-Graph (intern)
|
||
|
||
```
|
||
Phase 03 (Outbox #42, Worker-Trennung #45, SharedStore #37/#38)
|
||
│
|
||
│
|
||
Phase 05 (Feature-Flags #53)
|
||
│
|
||
▼
|
||
┌─────────────────────────────┐
|
||
│ #21 wasm-sandbox │
|
||
│ (Node 22 WebAssembly │
|
||
│ runtime, Wasmtime/jco │
|
||
│ upgrade path, │
|
||
│ SDK-Package, Manifest- │
|
||
│ Schema, Ed25519-Sign, │
|
||
│ Capability-Validator, │
|
||
│ Resource-Limits, │
|
||
│ Worker-Isolation) │
|
||
└──────────────┬──────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────┐
|
||
│ #22 hooks-lifecycle │
|
||
│ (15-20 Host-Hook-Points, │
|
||
│ Install/Enable/Disable/ │
|
||
│ Update/Uninstall, │
|
||
│ Plugin-DB-Migrations, │
|
||
│ Tenant-Admin-UI, │
|
||
│ Per-User-Enablement, │
|
||
│ Crash-Auto-Disable) │
|
||
└──────────────┬──────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────┐
|
||
│ #23 audit-docs │
|
||
│ (Audit-Log pro Call, │
|
||
│ SDK-API-Referenz, │
|
||
│ Capability-Matrix, │
|
||
│ 3 Beispiel-Plugins, │
|
||
│ Plugin-CLI, │
|
||
│ externe Security-Review, │
|
||
│ Compatibility-Matrix) │
|
||
└──────────────┬──────────────┘
|
||
│
|
||
▼
|
||
Production-Rollout-Freigabe
|
||
(gated by external review sign-off)
|
||
```
|
||
|
||
## Phase Done-Definition (historical completion gate)
|
||
|
||
Current shipped/deferred state is summarized above; this checklist remains the original production-readiness gate.
|
||
|
||
Diese Phase ist `completed` wenn:
|
||
|
||
- [ ] Alle 3 Tasks `completed` in `PROGRESS.md`
|
||
- [ ] `pnpm lint`, `pnpm typecheck`, `pnpm test` global grün
|
||
- [ ] `packages/plugin-runtime/`, `packages/plugin-sdk/`, `packages/plugin-cli/` exportieren stabile öffentliche APIs (in jeweils einer `index.ts` + Type-Exporten + SemVer-Tagging)
|
||
- [ ] `worker-plugin`-Service ist im Docker-Compose und in Coolify-Staging deployed; current shipped handler consumes `toolctrl.plugin-invoke`; historical install/uninstall/migrate handler names below are plan context, not live queue names.
|
||
- [ ] Manifest-Schema (`plugin.json`) versioniert (`schemaVersion: 1`), Ed25519-Public-Key-Registry seedable per CLI
|
||
- [ ] Tenant-Admin-UI unter `/app/$tenant/settings/plugins` lauffähig: Liste, Install-Dialog mit Capability-Consent, Settings-Page-Slot, Per-User-Enable
|
||
- [x] `.env.example` enthält die aktuell produktiv verdrahteten Runtime-Keys: `PLUGIN_TRUSTED_PUBLIC_KEYS`, `PLUGIN_MAX_FUEL`, `PLUGIN_MAX_MEMORY_MB`, `PLUGIN_MAX_WALL_CLOCK_MS`, `PLUGIN_RATE_LIMIT_PER_MINUTE`, `PLUGIN_RATE_LIMIT_WINDOW_SECONDS`, `PLUGIN_AUDIT_RETENTION_DAYS`
|
||
- [ ] Doku-Files vorhanden: `docs/features/plugins.md`, `docs/plugins/sdk-reference.md`, `docs/plugins/capability-matrix.md`, `docs/plugins/cli-reference.md`, `docs/plugins/manifest-reference.md`, `docs/plugins/versioning.md`, `docs/operations/plugin-lifecycle.md`
|
||
- [ ] 3 Referenz-Plugins (`examples/plugins/slack-notification/`, `examples/plugins/datev-export/`, `examples/plugins/custom-auth-provider/`) bauen mit der Plugin-CLI, signieren mit Test-Key, installieren auf Staging und laufen je 1× erfolgreich
|
||
- [ ] Externe Security-Review-Report von einer unabhängigen Security-Firma vorliegend, alle Critical/High-Findings adressiert, Report unter `docs/security-reviews/plugin-runtime-<date>.md` archiviert
|
||
- [ ] Staging-Deployment auf `agent/phase-06-final` deployed: 1× Sandbox-Escape-Test (siehe Test Requirements der Tasks), 1× Resource-Limit-Test, 1× Capability-Enforcement-Test alle grün
|
||
- [ ] Integration-Test-Flow: Plugin-Install (CLI sign → Tenant-Admin install → Capability-Consent → Enable) → Hook-Trigger (`onTenantSignup` durch Sign-up-Flow) → Plugin-Call → Audit-Log-Eintrag mit `capability=http.outbound` sichtbar im Tenant-Admin
|
||
- [ ] Tenant-Isolation-Test: Plugin in Tenant A kann auf keinerlei Daten von Tenant B zugreifen (DB-Capability, Storage-Capability, Audit-Logs separat)
|
||
- [ ] Crash-Test: Plugin das in 5 aufeinanderfolgenden Calls panic'ed wird automatisch disabled, Tenant-Admin-Notification gefeuert
|
||
- [ ] `gsd-code-reviewer`-Subagent hat alle Phase-06-Commits reviewed; Findings adressiert
|
||
- [ ] Phase-Summary in dieser README.md ergänzt (siehe unten)
|
||
|
||
## Phase Summary
|
||
|
||
_(Wird nach Abschluss der Phase vom ausführenden Agent ergänzt.)_
|
||
|
||
### Lessons Learned
|
||
|
||
_(Wird nach Abschluss ergänzt — insbesondere: Wasmtime- vs Wasmer-Findings, SDK-Ergonomie-Erfahrungen aus dem Bauen der 3 Referenz-Plugins, Performance-Overhead pro Hook-Call, externe Security-Review-Findings + Architektur-Anpassungen, Capability-Granularität-Erfahrungen, Plugin-DB-Migration-Pitfalls.)_
|
||
|
||
## Verweise
|
||
|
||
- Detail-MD-Template: `../DETAIL-MD-TEMPLATE.md`
|
||
- Agent-Workflow: `../AGENT-INSTRUCTIONS.md`
|
||
- Execution-Order: `../00-execution-order.md`
|
||
- Live-Status: `../PROGRESS.md`
|
||
- Vorgänger-Phase: `../05-business-features/README.md`
|
||
- Foundation-Phase: `../03-scaling-infrastructure/README.md`
|
||
- Nachfolger-Phase (nicht hart geblockt): `../08-mobile-cli-storybook-sdk/README.md`
|
||
- Backlog-Folge-Item: `../11-backlog/plugin-marketplace.md`
|
||
- Current plugin docs: `../../plugins.md`, `../../features/plugins.md`, `../../operations/plugin-lifecycle.md`
|