diff --git a/README.md b/README.md index 3eaa5b3..bbed8e1 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ Siehe auch `CLAUDE.md` für die verbindliche Dokumentenreihenfolge. Abschlussbericht: `docs/sprints/Sprint0_AP0_R1_Completion_Report_v0.1.md` +**Nächster geplanter Auftrag (Entwurf):** `docs/sprints/Sprint0_AP0_8_Assignment_v0.1.md` + ## Startzustand Dieses Repository startet mit einem reinen Spezifikations- und Sprint-0-Handover-Paket. diff --git a/docs/sprints/Sprint0_AP0_8_Assignment_v0.1.md b/docs/sprints/Sprint0_AP0_8_Assignment_v0.1.md new file mode 100644 index 0000000..ca6a713 --- /dev/null +++ b/docs/sprints/Sprint0_AP0_8_Assignment_v0.1.md @@ -0,0 +1,451 @@ +# AP0.8 – Operating Model Extension I +## Implementierungsauftrag zur Prüfung v0.1 + +**Status:** Entwurf zur Freigabe +**Stand:** 2026-07-05 +**Vorgänger:** AP0.7 ✓ · AP0.R1 ✓ +**Zielversion:** `0.8.0-ap0.8` · Schema `007` + +--- + +## Einordnung + +AP0.8 ist der **erste fachliche Ausbau nach dem Product Reset**. + +Ziel: Kairo sichtbar über `Initiative → Action` hinausheben und die Leitfrage operationalisieren: + +> Welcher nächste Schritt bringt ein Vorhaben aktuell am wirkungsvollsten voran? + +AP0.8 baut auf AP0.7 auf (Tenant-Invarianten, Actor Directory, Data Layer) und bleibt **regelbasiert ohne KI**. + +--- + +## Verbindliche Referenzen + +Vor Umsetzung lesen (Reihenfolge siehe `CLAUDE.md`): + +1. `docs/product/Kairo_Product_Definition_and_MVP_Reset_v0.1.md` +2. `docs/product/Kairo_Canonical_Operating_Model_v0.1.md` — §7 Attention Logic, §5 Objektmodell +3. `docs/product/Kairo_Corrected_MVP_Roadmap_v0.1.md` — AP0.8 +4. `docs/architecture/Kairo_Tenant_Invariants_v0.1.md` +5. `docs/architecture/Kairo_Current_State_Gap_Analysis_AP0.1_AP0.6b_v0.1.md` +6. `docs/sprints/Sprint0_AP0_7_Completion_Report_v0.2.md` + +--- + +## Leitentscheidungen (Vorschlag) + +| Entscheidung | Vorschlag | Begründung | +|--------------|-----------|------------| +| Umsetzungsreihenfolge | 4 interne Slices (8a→8d) in **einem** AP0.8 | Jeder Slice liefert Prüfbares; Attention zuerst für Produktwirkung | +| Blocker | **Eigenes Objekt** (`blockers`-Tabelle) | Canonical Model; `action.status=blocked` bleibt kompatibel, optional Verknüpfung | +| Backlog vs. Action | **Getrennte Tabellen** | Kernunterscheidung Program Director vs. To-do | +| Project | **Nicht in AP0.8** | Milestone direkt an Initiative | +| Action-Status `ready`/`review_required` | **Nicht in AP0.8** | Erweiterung in AP0.9; AP0.8 nutzt bestehendes Statusmodell | +| Due Dates | **Optional vorbereiten** | Spalten `due_at` nur wenn trivial; Attention-Regel 7 sonst stub | +| Capabilities | 4 neue Paare read/manage | Registry-first wie AP0.5 | +| UI | AP0.6b-Optik beibehalten | Kein Redesign | + +--- + +## Empfohlene Umsetzungsreihenfolge + +```text +AP0.8a Attention / NextActionCandidate (Read Model + Widget) +AP0.8b Blocker (Domäne + API + UI-Ausschnitt) +AP0.8c BacklogItem (Domäne + API + UI-Ausschnitt) +AP0.8d Milestone minimal (Domäne + API + UI-Ausschnitt) +``` + +Alle Slices gehören zum AP0.8-DoD. Reihenfolge ist verbindlich für die Implementierung. + +--- + +# Teil A — AP0.8a: Attention / NextActionCandidate + +## Ziel + +Regelbasierte **Attention-Schicht** im Data Layer — beantwortet „Was braucht jetzt Aufmerksamkeit?“ ohne KI. + +## Scope + +### Data Layer + +Neue Datei: `backend/data_layer/attention.py` + +Funktionen (Vorschlag): + +```text +get_attention_items(ctx) -> list[AttentionItemDTO] +get_next_action_candidates(ctx, *, limit=10) -> list[NextActionCandidateDTO] +``` + +**AttentionItemDTO** (minimal): + +```json +{ + "kind": "blocked_action | high_priority_action | unassigned_action | initiative_without_next_action | stale_initiative | milestone_at_risk", + "severity": "info | warning | critical", + "title": "...", + "summary": "...", + "initiative_id": "...", + "action_id": "...", + "milestone_id": "...", + "reason_code": "..." +} +``` + +### Regeln in AP0.8a (aus Canonical Model §7) + +| # | Regel | Datenquelle AP0.8a | +|---|-------|---------------------| +| 1 | Blockierte Maßnahmen | `actions.status = blocked` | +| 2 | High-Priority offen | `priority = high`, Status open/in_progress | +| 3 | Maßnahmen ohne Assignment | keine `action_assignments` | +| 4 | Vorhaben ohne offene nächste Maßnahme | active/paused Initiative, keine offene Action | +| 5 | Lange unveränderte Vorhaben | `initiatives.updated_at` > 14 Tage, status active | +| 6 | Meilenstein at_risk | **ab AP0.8d** (Stub/leer bis Milestones existieren) | +| 7–9 | Due Dates, Reviews, Recurring | **AP0.9+** — nicht in 8a | + +Regeln deterministisch, tenant-scoped, actor-bewusst wo sinnvoll (z. B. „meine“ high-priority vs. tenant-weit — **Vorschlag:** personal für zugewiesene Actions, tenant-weit für Initiativen ohne Maßnahme). + +### API + +```text +GET /api/workspace/attention +GET /api/workspace/next-actions?limit=10 +``` + +- Auth + TenantContext +- Capability: **`kairo.attention.read`** oder Erweiterung **`kairo.workspace.read`** — **Vorschlag:** `kairo.attention.read` (explizit, Grants = wie workspace.read) + +### Frontend + +- Neues Widget: **`AttentionWidget`** (Registry-Key `kairo.attention`) +- Platzierung: Workspace, direkt unter „Überblick“ (order 8) +- Zeigt Top-N Attention Items + Link zu betroffenen Vorhaben/Maßnahmen +- Loading / Error / Empty States +- **Keine** Client-seitige Priorisierungslogik + +### Tests + +- Attention enthält blockierte Action +- Attention enthält unassigned Action +- Attention enthält Initiative ohne offene Maßnahme +- Cross-Tenant: leer / 404 +- Router delegiert an Data Layer + +--- + +# Teil B — AP0.8b: Blocker + +## Ziel + +Blocker als **eigenes Steuerungsobjekt**, nicht nur Action-Status. + +## Migration `007_operating_model_extension_i.sql` + +Tabelle **`blockers`** (Vorschlag): + +```sql +blockers ( + id UUID PK, + tenant_id UUID NOT NULL REFERENCES tenants(id), + initiative_id UUID NOT NULL REFERENCES initiatives(id), + action_id UUID NULL REFERENCES actions(id), -- optional + title VARCHAR(255) NOT NULL, + description TEXT DEFAULT '', + status VARCHAR(32) NOT NULL, -- open, in_progress, resolved, accepted_risk, dismissed + reported_by_actor_id UUID NULL REFERENCES actors(id), + created_at, updated_at +) +``` + +- `tenant_id` immer gesetzt +- FK RESTRICT wie bei AP0.5 +- Index: `(tenant_id, initiative_id)`, `(tenant_id, status)` + +## Service + +`backend/services/blockers.py` — CRUD minimal: + +- `create_blocker`, `list_blockers_for_initiative`, `get_blocker`, `update_blocker`, `delete_blocker` +- Validierung: Initiative + optional Action im selben Tenant +- Audit: `blocker.created`, `blocker.updated`, `blocker.status_changed`, `blocker.deleted` + +## API + +```text +GET /api/initiatives/{id}/blockers +POST /api/initiatives/{id}/blockers +GET /api/blockers/{id} +PATCH /api/blockers/{id} +DELETE /api/blockers/{id} +``` + +Capabilities: **`kairo.blocker.read`**, **`kairo.blocker.manage`** + +Default Grants: wie `kairo.action.read/manage` (Member+ read, Member+ manage — ** zur Prüfung **) + +## Frontend + +- Vorhaben-Detail: Sektion **Blocker** (Liste + anlegen + Status) +- Optional: Attention verknüpft open Blockers (zusätzlich zu blocked Actions) +- Status-Badges konsistent mit AP0.6b + +## Abgrenzung + +- Kein Blocker-Workflow-Engine +- Keine Eskalationsstufen +- `action.status=blocked` bleibt; UI kann bei Blocker-Anlage optional Action-Status setzen (nicht zwingend) + +--- + +# Teil C — AP0.8c: BacklogItem + +## Ziel + +**Backlog getrennt von Maßnahmen** — Ideen/Risiken/Vorschläge vor Commit. + +## Migration (gleiche `007`) + +Tabelle **`backlog_items`**: + +```sql +backlog_items ( + id UUID PK, + tenant_id UUID NOT NULL, + initiative_id UUID NOT NULL REFERENCES initiatives(id), + title VARCHAR(255) NOT NULL, + description TEXT DEFAULT '', + status VARCHAR(32) NOT NULL, -- new, triaged, accepted, rejected, converted + priority VARCHAR(16) DEFAULT 'normal', + converted_action_id UUID NULL REFERENCES actions(id), + created_at, updated_at +) +``` + +## Service + API + +Analog Blocker: + +```text +GET/POST /api/initiatives/{id}/backlog +GET/PATCH/DELETE /api/backlog/{id} +POST /api/backlog/{id}/convert-to-action -- optional, minimal: erzeugt Action, setzt status=converted +``` + +Capabilities: **`kairo.backlog.read`**, **`kairo.backlog.manage`** + +**Convert-to-action:** Erzeugt Action im selben Initiative, setzt `converted_action_id`, Audit. Kein Drag & Drop. + +## Frontend + +- Vorhaben-Detail: Sektion **Backlog** +- Einfache Liste, anlegen, Status triaged/accepted/rejected +- Button „In Maßnahme umwandeln“ (wenn manage) + +--- + +# Teil D — AP0.8d: Milestone minimal + +## Ziel + +Überprüfbare Zielpunkte im Vorhaben — **keine Tasks**. + +## Migration (gleiche `007`) + +Tabelle **`milestones`**: + +```sql +milestones ( + id UUID PK, + tenant_id UUID NOT NULL, + initiative_id UUID NOT NULL REFERENCES initiatives(id), + title VARCHAR(255) NOT NULL, + goal_description TEXT DEFAULT '', + status VARCHAR(32) NOT NULL, -- planned, active, at_risk, reached, moved, discarded + target_date DATE NULL, + created_at, updated_at +) +``` + +## Service + API + +```text +GET/POST /api/initiatives/{id}/milestones +GET/PATCH/DELETE /api/milestones/{id} +``` + +Capabilities: **`kairo.milestone.read`**, **`kairo.milestone.manage`** + +## Attention-Regel 6 + +Nach AP0.8d: `milestone_at_risk` in `data_layer/attention.py` aktivieren. + +## Frontend + +- Vorhaben-Detail: Sektion **Meilensteine** (kompakte Liste) +- Status-Badge, optional target_date Anzeige +- Kein Gantt, kein Timeline-UI + +--- + +# Capabilities AP0.8 (Vorschlag) + +| Capability | Modul | Grants (Vorschlag) | +|------------|-------|-------------------| +| `kairo.attention.read` | attention | Member+ (wie workspace.read) | +| `kairo.blocker.read` | blocker | Member+ | +| `kairo.blocker.manage` | blocker | Member+ | +| `kairo.backlog.read` | backlog | Member+ | +| `kairo.backlog.manage` | backlog | Member+ | +| `kairo.milestone.read` | milestone | Member+ | +| `kairo.milestone.manage` | milestone | Member+ | + +Registrierung: `backend/rights_registrations/operating_model_ops.py` + +Gesamt nach AP0.8: **25 Capabilities** (18 + 7) + +--- + +# Architekturregeln (verbindlich) + +1. **Tenant-first** — alle neuen Tabellen mit `tenant_id`; Context-only +2. **Actor-first** — Assignments unverändert an Actors; `reported_by_actor_id` optional +3. **Data Layer read / Services write** — Attention nur im Data Layer +4. **Router dünn** — keine Aggregations-SQL in Routern +5. **Widgets ohne fachliche KPI-Logik** — Attention-Daten vom API-Endpunkt +6. **Cross-Tenant → 404** +7. **Nummerierte Migration `007`** — kein ad-hoc DDL +8. **Kein Prompt/KI/MCP/Workflow** +9. **Product Reset** — kein Rückfall zu reiner To-do-Liste + +--- + +# Nicht-Scope AP0.8 + +Nicht implementieren: + +- Project / Program +- Evidence, Decision, Review, RecurringElement (→ AP0.9) +- Action-Status-Erweiterung `ready`, `review_required` +- Due Dates Pflicht / Überfälligkeits-Engine (nur optional `target_date` Milestone) +- KI-Priorisierung, MCP, Workflow Engine +- Admin-Konsole, Audit-UI +- Neue Top-Level-Navigation „Backlog“ (erst Initiative-Detail; optional später) +- Backend-Widget-Registry +- Initiative-Status `draft` (optional AP0.8.1) +- Vollständige Portfolio-/Report-Sichten +- AP0.10 Validation Testvorhaben + +--- + +# Tests (Mindestumfang) + +## Backend + +Neue Datei: `backend/tests/test_ap08_operating_model.py` + +| Bereich | Tests | +|---------|-------| +| Attention | Regeln 1–5, Limit, Cross-Tenant | +| Blocker | CRUD, Tenant-Isolation, optional action_id | +| Backlog | CRUD, convert-to-action, converted status | +| Milestone | CRUD, at_risk in Attention | +| Capabilities | Member grants, Gate 403 | +| Registry | 25 Capabilities sync | +| Migration | `007` in test_migrations | + +Bestehende Tests dürfen nicht brechen. + +## Frontend + +- Vitest: Registry enthält `kairo.attention` +- Build grün +- Manueller Smoke (Checkliste im Abschlussbericht) + +--- + +# Frontend-Übersicht (AP0.8) + +| UI-Element | Neu/Geändert | +|------------|--------------| +| `AttentionWidget` | neu — Workspace | +| Vorhaben-Detail Blocker | neu — Sektion | +| Vorhaben-Detail Backlog | neu — Sektion | +| Vorhaben-Detail Meilensteine | neu — Sektion | +| App Shell / Navigation | unverändert | +| Design Tokens / PWA | unverändert | + +Widget Registry erweitern; **keine** God Page. + +--- + +# Abnahmekriterien AP0.8 + +AP0.8 ist abgeschlossen, wenn: + +1. Migration `007` läuft; Schema-Version `007` +2. Attention/NextAction liefert regelbasierte Items (Regeln 1–5, 6 nach 8d) +3. Blocker, Backlog, Milestone CRUD tenant-sicher +4. Data Layer `attention.py` existiert; Router delegieren +5. Workspace zeigt Attention-Widget +6. Vorhaben-Detail zeigt Blocker, Backlog, Meilensteine +7. Convert Backlog → Action funktioniert (minimal) +8. Cross-Tenant-Tests grün +9. Capabilities registriert und in Entitlements sichtbar +10. AP0.6b UX nicht verschlechtert +11. Kein Prompt/KI/MCP-Scope +12. Abschlussbericht + README aktualisiert + +--- + +# Abschlussbericht (nach Umsetzung) + +```markdown +# AP0.8 – Abschlussbericht Operating Model Extension I + +## 1. Scope und Einordnung +## 2. Definition of Done — Prüfmatrix +## 3. Migration 007 +## 4. Attention / NextActionCandidate +## 5. Blocker +## 6. BacklogItem +## 7. Milestone minimal +## 8. Data Layer Erweiterung +## 9. API-Endpunkte +## 10. Capabilities +## 11. Frontend-Integration +## 12. Tests und Verifikation +## 13. Abweichungen von diesem Auftrag +## 14. Offene Punkte für AP0.9 +## 15. Empfehlung für AP0.10 / Validation +``` + +--- + +# Offene Punkte zur Freigabe (bitte prüfen) + +| # | Frage | Vorschlag | +|---|-------|-----------| +| 1 | AP0.8 als ein Auftrag oder 8a–8d separat deployen? | Ein Auftrag, 4 Slices intern | +| 2 | `kairo.attention.read` vs. Erweiterung `workspace.read`? | Eigene Capability | +| 3 | Blocker + `action.status=blocked` synchron halten? | Optional bei Create, nicht zwingend | +| 4 | Convert Backlog→Action in AP0.8 Pflicht? | Ja, minimaler Flow | +| 5 | Member dürfen Blocker/Backlog/Milestone managen? | Ja (wie Actions) | +| 6 | Initiative-Status `draft` mit aufnehmen? | Nein, AP0.8.1 optional | +| 7 | Neue Nav „Backlog“ workspace-weit? | Nein, nur Initiative-Detail | + +--- + +# Nach Freigabe + +1. Du gibst AP0.8 (ggf. mit Anpassungen) frei. +2. Umsetzung auf `develop` gemäß Slice-Reihenfolge 8a→8d. +3. Ein Commit-Bundle oder mehrere Commits pro Slice — nach Absprache. +4. Abschlussbericht v0.1 → nach QA v0.2 (final). + +--- + +*Entwurf zur Prüfung — noch nicht umgesetzt.*