diff --git a/docs/architecture/ADP_Archetype_Method_Plugin_Architecture_v0.1.md b/docs/architecture/ADP_Archetype_Method_Plugin_Architecture_v0.1.md new file mode 100644 index 0000000..49ae96d --- /dev/null +++ b/docs/architecture/ADP_Archetype_Method_Plugin_Architecture_v0.1.md @@ -0,0 +1,370 @@ +# ADP — Archetyp- & Methoden-Plugin-Architektur v0.1 + +**Status:** vorgeschlagen (PO-Freigabe vor weiteren Archetypen) +**Stand:** 2026-07-24 +**Autor:** Architektur / PO-Session (Sprint-Planung & Typen-Trennung) +**Bezug:** `ADP_Archetype_and_Method_Catalog_v0.2.md`, `ADP_AP1_10_Initiative_Archetypes_and_Entity_Field_System_v0.1.md`, `Kairo_Target_Architecture_Method_Driven_Adaptive_Steering_Core_v0.1.md`, `Kairo_Method_Design_Principles_v0.1.md`, `Kairo_MVP_Execution_Plan_v0.2.md` +**Auslöser:** Sprint-UI und Vorhabentypen wirken monolithisch; weitere Archetypen und Steuerungstypen sollen **ohne Änderung bestehender Module** erweiterbar sein — nicht nutzerkonfigurierbar, aber **code-modular registrierbar** + +--- + +## 1. Problem + +### 1.1 Produkt-Symptome + +- Sprint- und AP-UI fühlen sich rudimentär an (Inline-Bearbeitung, Carryover, Navigation zwischen Modi). +- Archetypen jenseits von Product/Linear/Maturity/Program sehen dieselbe IA wie Product, obwohl Backend-Methoden anders steuern. +- Mode-Wechsel (Plan → Sprint → Work) löst wiederholt **vollständige Datenladung** aus. + +### 1.2 Architektur-Ist (technisch) + +| Bereich | Soll (ADP v0.2) | Ist (Code Jul 2026) | +|---------|-----------------|---------------------| +| **Schicht 1 — Methode** | Registrierte Module in `backend/steering/methods/` | Registry + einige Registrierungen; viele Stubs teilen Strategien | +| **Schicht 2 — Archetyp** | `entity_archetypes` + `ui_profile_json` | Registry-Seeds; **`ui_profile_json` nicht an Frontend angebunden** | +| **Schicht 3 — Ausprägung** | `method_profiles` | 3 Code-Seeds; Komposition (Product + Sprint) nicht in UI modelliert | +| **Frontend IA** | Methode/Archetyp steuert Nav & Slices | **`methodUiDefaults.js` hardcodiert 4/9 Archetypen** | +| **Datenladung** | Typ- und mode-bewusst | **`InitiativeOperationsContext.load()` ~14 parallele Requests für alle Typen** | +| **Provider-Lifecycle** | Ein Scope-Cache pro Vorhaben | **`ScopedInitiativeProvider` pro Mode-Page → Remount + Full Reload** | + +**Fazit:** Backend ist **strukturell** auf Plugin-Registrierung vorbereitet; Frontend und Client-Datenschicht behandeln alle Vorhaben wie **ein gemeinsames OM-Monolith**. Weitere Archetypen würden die Kopplung verstärken, nicht entkoppeln. + +### 1.3 Risiko bei Fortsetzung ohne Glättung + +- Jeder neue Archetyp erfordert Änderungen an `methodUiDefaults.js`, `InitiativeOperationsContext`, ggf. Routern. +- Steuerungstypen (Method Keys) bleiben schwer testbar isoliert. +- Performance skaliert mit OM-Umfang × Anzahl Typen, nicht mit tatsächlich sichtbarem Mode. +- ADP v0.2 §2.2 („keine Hardcodierung in React“) wird dauerhaft verletzt. + +--- + +## 2. Leitentscheidung + +**Vor Implementierung weiterer Archetypen und voll ausgebauter Steuerungstypen wird die Plugin-Architektur über Backend und Frontend verbindlich gemacht.** + +### 2.1 Prinzipien (verbindlich) + +| Prinzip | Bedeutung | +|---------|-----------| +| **Open for extension, closed for modification** | Neuer Archetyp/Methode = **neues Registrierungsmodul**; Core-Dateien unverändert | +| **Code-Registrierung, nicht Tenant-DSL** | Kein Endnutzer-Workflow-Designer; Erweiterung durch **Deploy neuer Python/JS-Module** | +| **Ein Steering-Kern** | Keine parallele Steuerungslogik außerhalb `backend/steering/` | +| **Ein OM-Kern** | Keine Sonder-Tabellen pro Archetyp (Scope Lock AP1.0) | +| **Archetyp = Baukasten, Methode = Motor, Profile = Ausprägung** | Vier-Schichten-Modell ADP v0.2 bleibt führend | +| **UI folgt Registry** | Sichtbare Modi, Nav, Data-Slices aus **`ui_profile_json`** + Method-Capabilities — nicht aus Page-Ifs | + +### 2.2 Abgrenzung: Was dieses ADP **nicht** ist + +- **Kein** visueller Methoden-Editor für Tenants +- **Kein** Ersatz für Operating Model / RoadmapItem-ADPs +- **Kein** Ausbau von KI/MCP/Gitea (Schicht 4 bleibt eingefroren) +- **Kein** Promise beliebiger Laufzeit-Kombinatorik (keine freie Workflow-Engine) + +--- + +## 3. Zielbild: Plugin-Architektur + +```text +┌──────────────────────────────────────────────────────────────────────────┐ +│ FRONTEND │ +│ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐ │ +│ │ View Registry │ │ UI Profile │ │ Data Slice Registry │ │ +│ │ (Routes/Pages) │◄──│ Resolver │◄──│ (lazy OM loads) │ │ +│ └────────┬────────┘ └────────▲─────────┘ └──────────▲──────────┘ │ +│ │ │ │ │ +│ │ GET /api/initiatives/:id/context │ │ +└───────────┼─────────────────────┼──────────────────────────┼──────────────┘ + │ │ │ +┌───────────┼─────────────────────┼──────────────────────────┼──────────────┐ +│ BACKEND │ │ │ │ +│ ┌────────▼────────┐ ┌────────┴─────────┐ ┌───────────┴──────────┐ │ +│ │ Archetype │ │ Method Registry │ │ Steering Strategies │ │ +│ │ Registry (EFS) │──►│ (registrations/) │──►│ Signals / Next Action│ │ +│ └─────────────────┘ └──────────────────┘ └──────────────────────┘ │ +│ Adaptive Steering Core (Schicht 0) │ +└──────────────────────────────────────────────────────────────────────────┘ +``` + +**Erweiterungsregel:** Neues Paket `registrations/my_method.py` + optional `frontend/plugins/myMethodUi.js` — **kein** Edit an `InitiativeOperationsContext`, `App.jsx`, `default_rules.py` Core. + +--- + +## 4. Backend: Methoden-Plugin-Vertrag + +### 4.1 Bereits vorhanden (beibehalten & härten) + +| Artefakt | Pfad | Rolle | +|----------|------|--------| +| Method Registry | `backend/steering/methods/registry.py` | `register_method()` — einmalig pro Key | +| Registrierungen | `backend/steering/methods/registrations/*.py` | Ein Modul pro Methode; Import in `steering/__init__.py` | +| Archetyp Registry | `backend/entity_archetypes/registry.py` | `default_method_key`, EFS-Sync | +| Method Profiles | `backend/method_profiles/registry.py` | Ausprägungen (Schicht 3) | +| Graph Profiles | `backend/steering/graph/profiles.py` | Gate-Verhalten pro `method_key` | +| Strategies | `backend/steering/strategies/` | Next Action, Lifecycle — pro Methode wählbar | + +### 4.2 Pflicht-Interface pro Methode (Zielvertrag) + +Jede Methode registriert **in einem Modul**: + +```python +# registrations/continuous_product.py (Beispiel — Zielbild) +register_method(MethodDefinition(...)) +register_next_action_strategy("continuous_product", ContinuousProductNextAction()) +register_signal_rules("continuous_product", CONTINUOUS_PRODUCT_RULES) +register_graph_profile("continuous_product", GRAPH_PROFILE) +register_data_slices("continuous_product", frozenset({ + "backlog", "actions", "roadmap", "work_cycles", "steering_snapshot", +})) +``` + +| Hook / Capability | Pflicht | Beschreibung | +|-------------------|---------|--------------| +| `method_key` | ja | Stabil, versioniert in `MethodDefinition` | +| `next_action_strategy_key` | ja | Isolierte Strategie-Klasse | +| `signal_rules` | empfohlen | Attention / Eskalation | +| `graph_profile` | wenn Gates | Block/Fulfill-Verhalten | +| **`data_slices`** | **neu** | Welche OM-Listen der Initiative-Context laden darf | +| `lifecycle_steps` | ja | Standard-Hook-Slugs (ADP Target Architecture) | + +**Regel:** Router und Services fragen **`get_method(initiative.method_key)`** — keine `if archetype == "product"` in Routern. + +### 4.3 Initiative Context API (neu — Schicht 0 Read Model) + +Ein schlanker Endpoint ersetzt Frontend-Raten: + +```text +GET /api/initiatives/{id}/operating-context +``` + +Response (Ziel): + +```json +{ + "initiative_id": "...", + "archetype_key": "initiative.product", + "method_key": "continuous_product", + "method_profile_key": "product.kairo_dev", + "ui_profile": { "processSteps": [...], "planOutlineKeys": [...], "dataSlices": [...] }, + "capabilities": ["backlog", "work_cycle", "roadmap", ...] +} +``` + +- `ui_profile` kommt aus **`entity_archetypes.ui_profile_json`** (Sync aus Code-Seed wie EFS heute). +- `dataSlices` = Vereinigung aus Archetyp-Default + Method-Registration + optional Profile-Override. +- **`steering_snapshot`** nur wenn Slice `steering` oder Mode `control` — nicht immer. + +Bestehendes `backend/routers/operational.py` und `initiative_snapshot.py` dienen als Ausgangspunkt; Snapshot wird **optional** und **slice-gesteuert**. + +### 4.4 Archetyp-Sync erweitern + +In `entity_archetypes/registry.py` pro Spec ergänzen: + +```python +"ui_profile_json": { + "processSteps": [...], + "planDefaultRoute": "/plan/inbox", + "workDefaultRoute": "/work/sprint", + "planOutlineKeys": ["profile", "inbox", "sprint", "gates"], + "workNavKeys": ["sprint", "today", "mine"], + "dataSlices": ["backlog", "actions", "roadmap", "work_cycles", "projects", ...], + "enabledModes": ["plan", "work", "control"], + "enabledRoutes": ["/plan/inbox", "/plan/sprint", ...] +} +``` + +**Migration:** Inhalt aus `frontend/src/config/methodUiDefaults.js` → Seeds → DB-Sync; Frontend-Datei wird **deprecated**. + +--- + +## 5. Frontend: UI- & Data-Plugin-Vertrag + +### 5.1 UI Profile Resolver (Ziel) + +```javascript +// frontend/src/registry/resolveOperatingProfile.js +export function resolveOperatingProfile(context) { + // context von GET /operating-context + // Fallback: GENERIC_UI minimal +} +``` + +- **Keine** Archetyp-Ifs in Pages. +- `MethodProcessBar`, `PlanOutlineNav`, `WorkLayout` lesen nur `context.ui_profile`. +- Unbekannter Archetyp → Generic-Profil (Plan Profile + Work Today + Control Status). + +### 5.2 Data Slice Loader (Ziel) + +Ersetzt monolithisches `load()`: + +```javascript +const SLICE_LOADERS = { + backlog: (id) => listInitiativeBacklog(id), + work_cycles: (id) => listInitiativeWorkCycles(id), + actions: (id) => listInitiativeActions(id), + // … registrierbar pro Modul +} + +export async function loadOperatingSlices(initiativeId, sliceKeys) { + return Promise.all(sliceKeys.map(k => SLICE_LOADERS[k](initiativeId))) +} +``` + +| Slice | Typische Archetypen | Nicht laden für | +|-------|---------------------|-----------------| +| `backlog` | product, program, support_queue | maturity-only | +| `work_cycles` | product (+ agile profile) | linear, dispute | +| `roadmap` | linear, program, maturity | support_queue | +| `projects` | linear, program | support_queue | +| `recurring` | recurring_program | product | +| `steering_snapshot` | control mode only | plan inbox-only views | + +**Regel:** Slice-Liste kommt vom Backend (`operating-context`), nicht vom Frontend geraten. + +### 5.3 Provider-Hoisting (Ziel) + +```text +ProgramScopeLayout + └── InitiativeOperationsProvider ← einmal pro initiativeId + └── Mode Routes (Plan/Work/Control) ← kein Remount, kein Full Reload +``` + +- Cache-Key: `tenantId + initiativeId`. +- Mutationen: **partielle Updates** (bereits begonnen: `applyConvertResults`, `handleMoveActionToSprint`) statt `load()` nach jeder Aktion. +- `ScopedInitiativeProvider` nur noch als **Scope-Gate**, nicht als neuer Data-Provider. + +### 5.4 View Registry & Route Gating + +`frontend/src/registry/viewRegistry.js` erweitern: + +- Jede Route deklariert `requiredSlices` und optional `allowedArchetypes`. +- Unbekannte Route → Redirect auf `planDefaultRoute` aus UI-Profil. +- Beispiel: `/plan/sprint` nur wenn Slice `work_cycles` ∈ context. + +Neue Archetyp-Page = **neuer Registry-Eintrag** + Backend-Seed — keine `App.jsx`-Fork. + +--- + +## 6. Erweiterungs-Workflow (Checkliste) + +**Neue Steuerungsmethode `foo_bar` hinzufügen:** + +1. `backend/steering/methods/registrations/foo_bar.py` — `register_method`, Strategie, Rules, Slices +2. Import in `backend/steering/__init__.py` (eine Zeile) +3. Optional: `backend/tests/test_method_foo_bar.py` +4. Archetyp-Seed mit `default_method_key: "foo_bar"` (falls neuer Typ) oder Profile-Override +5. **Kein** Edit an `default_rules.py` Monolith außer generischem Dispatcher + +**Neuen Archetyp `initiative.my_type` hinzufügen:** + +1. Eintrag in `_INITIATIVE_SPEC_META` + `_METHOD_BY_SUFFIX` in `entity_archetypes/registry.py` +2. `ui_profile_json` + EFS-Feldprofil im Seed +3. Migration nur wenn neue **generische** Spalten (selten — Scope Lock) +4. Frontend: **kein** Pflicht-Edit wenn Generic-UI reicht; sonst optionales `frontend/plugins/archetypes/my_type.js` das sich in View Registry einklinkt +5. Spec unter `docs/product/archetypes/SPEC_*.md` + +**Neue Ausprägung (Method Profile):** + +1. `method_profiles/registry.py` Seed +2. Overrides in `configuration_json` (Cadence, Gate-Set, Sprint-Policy) +3. Keine neuen Tabellen + +--- + +## 7. Performance & Unabhängigkeit + +| Maßnahme | Wirkung | +|----------|---------| +| Slice-bewusstes Laden | −50–80 % Requests auf typischen Plan/Work-Pages | +| Hoisted Provider | Mode-Wechsel ohne 14-fachen Reload | +| Snapshot on demand | Schwere JOIN-Read-Models nur in Control/Steering | +| Method-isolierte Tests | Strategie pro Modul pytest ohne Full OM-Fixture | +| Kein doppeltes Laden | PlanOutlineNav nicht parallel zum Context dieselben Listen | + +**Akzeptanzkriterium (PO-nutzbar):** Navigation Plan → Sprint → Work auf Product-Vorhaben **≤ 1 Initialladung** + partielle Mutations-Updates; Support-Queue-Vorhaben **lädt kein** `work_cycles` / Sprint-UI. + +--- + +## 8. Migrationsplan (vor weiteren Archetypen) + +| Phase | Paket | Lieferung | Abhängigkeit | +|-------|--------|-----------|--------------| +| **A** | AP2.3a Operating Context API | `GET operating-context`, `ui_profile_json` in Archetyp-Sync | AP1.10 Seeds | +| **B** | AP2.3b Frontend Profile Resolver | `methodUiDefaults.js` → Resolver; ProcessBar/Nav aus API | A | +| **C** | AP2.3c Data Slice Loader | `loadOperatingSlices`, Provider-Hoist | A, B | +| **D** | AP2.3d Route Gating | View Registry + Redirects | B | +| **E** | AP2.3e Method `data_slices` | Backend-Registrations refactoren; Stubs deklarieren Slices | A | +| **F** | Archetyp-Specs Welle 2 | `support_queue`, `content_project`, … **nach** A–E | PO Specs | + +**Stop-the-line:** Keine neuen **UI-spezifischen** Archetyp-Features in React-Ifs bis Phase B abgeschlossen. Bugfixes und horizontale OM-Features (Sprint, Backlog) sind erlaubt. + +--- + +## 9. Optionen + +| Option | Beschreibung | Pro | Contra | +|--------|--------------|-----|--------| +| **A — Weiter wie heute** | Archetypen + UI-Patches pro Typ | Schnell kurzfristig | Jeder Typ verstärkt Monolith; ADP-Verstoß | +| **B — Nur Backend Plugins** | Method Registry härten, Frontend bleibt | Weniger Frontend-Aufwand | IA bleibt falsch für 5/9 Typen | +| **C — Vollständige Plugin-Schicht (empfohlen)** | Operating Context + UI/Data Slices + Hoisting | Erweiterbar, performant, ADP-konform | 2–3 Sprints Investition vor Archetyp-Welle | + +**Empfehlung: Option C**, Phasen A→E sequenziell. Parallel: Sprint/Backlog-UX horizontal verbessern (kein Typ-Sonderweg). + +--- + +## 10. Risiken + +| Risiko | Mitigation | +|--------|------------| +| Big-Bang-Refactor Frontend | Phasenweise; `methodUiDefaults` als Fallback bis B live | +| `ui_profile_json` driftet von Specs | Sync-Test: Seed ↔ dokumentierte Spec | +| Over-Engineering Registry | Minimal-Interface: 5 Felder in ui_profile + slice list reichen für MVP | +| Stubs wirken „fertig“ in UI | Route Gating + „Method not fully implemented“ Banner in Control | + +--- + +## 11. Rückbaubarkeit + +- Phase A additive API; alte Endpoints bleiben bis C. +- `methodUiDefaults.js` deprecated, nicht sofort gelöscht. +- Archetyp ohne UI-Profil fällt auf Generic zurück. + +--- + +## 12. Nicht tun (Scope Lock) + +- Keine nutzereditierbare Methoden-Konfiguration (Tenant-DSL) +- Keine parallelen Steering-Pfade außerhalb `backend/steering/` +- Keine OM-Tabellen pro Archetyp +- Keine weiteren hardcodierten Archetyp-Ifs in Pages (`isProductArchetype` → Registry) +- Keine KI/MCP/Gitea in diesem ADP + +--- + +## 13. Bezug zum MVP Execution Plan + +Dieses ADP **ersetzt nicht** den MVP Execution Plan, sondern **priorisiert** die Schicht vor Archetyp-Welle 2: + +```text +Foundation / Sprint-Planung (AP2.2*) → AP2.3 Plugin-Glättung → Archetyp Specs + Seeds → IA pro Typ +``` + +PO-Entscheidung erforderlich: **AP2.3 (A–E) vor** breiter Implementierung von `support_queue`, `content_project`, `dispute_case` UI. + +--- + +## 14. Kurzfassung für PO + +> Vorhabentypen und Steuerungstypen sollen wie **Steckmodule** funktionieren: neues Python/JS-Registrierungsmodul deployen, ohne bestehende Module anzufassen. Nutzer konfigurieren das nicht selbst — Entwickler erweitern den Katalog. Dafür brauchen wir einen **Operating Context** vom Backend und **slice-bewusstes Laden** im Frontend. Erst danach lohnen sich weitere Archetypen — sonst wird jeder neue Typ teurer als der vorherige. + +--- + +## 15. Referenzen (Code-Ist) + +| Thema | Pfad | +|-------|------| +| Archetyp Seeds | `backend/entity_archetypes/registry.py` | +| Method Registry | `backend/steering/methods/registry.py`, `registrations/` | +| UI Hardcoding (deprecated) | `frontend/src/config/methodUiDefaults.js` | +| Monolith Loader | `frontend/src/context/InitiativeOperationsContext.jsx` | +| Provider Remount | `frontend/src/layout/ScopedInitiativeProvider.jsx` | +| Führendes ADP Vier-Schichten | `docs/architecture/ADP_Archetype_and_Method_Catalog_v0.2.md` |