All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 58s
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 12s
Schema 007, regelbasierte Attention/NextAction im Data Layer, CRUD fuer Blocker/Backlog/Meilensteine, Workspace-Widget und Initiative-Detail-Sektionen. 25 Capabilities. Tests fuer Remote-Pytest auf Pi angepasst (conftest Session-Guard). Co-authored-by: Cursor <cursoragent@cursor.com>
452 lines
13 KiB
Markdown
452 lines
13 KiB
Markdown
# AP0.8 – Operating Model Extension I
|
||
## Implementierungsauftrag zur Prüfung v0.1
|
||
|
||
**Status:** ersetzt durch `Sprint0_AP0_8_Assignment_v0.2.md`
|
||
**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.*
|