Doku: AP0.8 Implementierungsauftrag v0.1 (Entwurf zur Prüfung)
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

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Lars 2026-07-05 08:25:20 +02:00
parent 01b3c594a1
commit c4a66e9773
2 changed files with 453 additions and 0 deletions

View File

@ -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.

View File

@ -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) |
| 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.*