Kairo-Jinkendo/docs/sprints/Sprint0_AP0_8_Assignment_v0.1.md
Lars c4a66e9773
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Test Suite / pytest-backend (push) Successful in 42s
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 13s
Doku: AP0.8 Implementierungsauftrag v0.1 (Entwurf zur Prüfung)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 08:25:20 +02:00

452 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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) |
| 79 | 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 15, 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 15, 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 8a8d 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.*