Doku: Abschlussberichte AP0.4 v0.2 und AP0.6b v0.2 (final)
All checks were successful
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Successful in 29s
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

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Lars 2026-07-05 07:09:40 +02:00
parent 842c39081b
commit 36487d2869
3 changed files with 704 additions and 1 deletions

View File

@ -223,6 +223,8 @@ Feature-, Prompt-, Placeholder- und Config-Registry analog zur Rights Registry:
Startup: `sync_prompt_feature_config.py` nach Rights-Sync (`SKIP_REGISTRY_SYNC=1` zum Überspringen).
Abschlussbericht: `docs/sprints/Sprint0_AP0_4_Completion_Report_v0.2.md`
**Prompt-Modell:** `PromptDefinition``PromptVersion` → optional `PromptStep` (workflow-/pipeline-fähig; AP0.4 führt nur `execution_mode=single` aus).
**Beispiel-Prompts:** `kairo.system.health_summary`, `kairo.context.debug_summary`

View File

@ -0,0 +1,701 @@
# AP0.4 Abschlussbericht Workflow-ready Prompt, Feature & Config Registry
**Status:** abgeschlossen
**Stand:** 2026-07-04 (final)
**Branch:** `develop` · Dev-Deploy und Test Suite grün · Prod nach Merge/deploybar (Schema `005`)
**Version:** `0.4.0-ap0.4`
---
## 1. Scope und Einordnung
AP0.4 schließt die **Registry-Schicht für Features, Prompts, Placeholder und Konfiguration** ab und liefert damit die Grundlage für spätere AI-/Workflow-Funktionen — ohne LLM, ohne Workflow Engine, ohne Billing.
| Anforderung (AP0.4) | Status |
|---------------------|--------|
| Migration `005` (Feature/Prompt/Placeholder/Config/ExecutionLog) | ✓ |
| Feature Registry + DB-Sync | ✓ |
| PromptDefinition / PromptVersion / PromptStep | ✓ |
| PlaceholderDefinition + Validation | ✓ |
| ConfigurationEntry + Config Service | ✓ |
| Single Prompt Rendering (ohne LLM) | ✓ |
| `features`-Block in `/api/me/entitlements` | ✓ |
| 7 neue Capabilities + API-Gates | ✓ |
| Audit (Sync, Config, Render-Fehler) | ✓ |
| Tests + CI grün | ✓ |
**Architekturentscheidung:** Keine produktspezifische Prompt-Sonderlösung, aber auch **keine zentrale Jinkendo Prompt Engine**. Stattdessen ein **lokal in Kairo implementierter, produktneutraler Prompt-Kernel**, der später als `jinkendo_prompt_kernel` extrahiert werden kann.
**Bewusst nicht in AP0.4:** Pipeline-/Workflow-Ausführung, LLM Provider Routing, Tool Calling, MCP, Feature-Limits, produktive Admin-UI, Mitai-/Shinkan-Domänenprompts.
**Wesentlicher Commit:** `53047b6` (Implementierung + Tests + Abschlussbericht v0.1).
---
## 2. Umgesetzte Dateien
### 2.1 Migration & Schema
| Datei | Zweck |
|-------|--------|
| `backend/migrations/005_prompt_feature_config_registry.sql` | 7 Tabellen für AP0.4 |
### 2.2 Feature & Config
| Datei | Zweck |
|-------|--------|
| `backend/feature_registry.py` | In-Memory Feature Registry + Sync |
| `backend/feature_registrations/` | 3 initiale Features |
| `backend/config_service.py` | Config lesen/schreiben, Secret-Schutz |
| `backend/sync_prompt_feature_config.py` | Orchestrierter Startup-Sync |
### 2.3 Prompt Engine (Kern)
| Datei | Rolle im Kernel |
|-------|-----------------|
| `backend/prompt_registry.py` | PromptDefinition, Version, Step — Registry + DB |
| `backend/prompt_registrations/` | Smoke-Prompts (Code-Kanon) |
| `backend/placeholder_registry.py` | PlaceholderDefinition — Registry + DB |
| `backend/placeholder_registrations/` | Tenant-/Actor-/Debug-Placeholder |
| `backend/prompt_validation.py` | **PromptValidationService** |
| `backend/prompt_rendering.py` | **PromptRenderService** + ExecutionLog |
| `backend/prompt_context.py` | Kontext → Placeholder-Werte (TenantContext) |
### 2.4 API, Auth, Integration
| Datei | Zweck |
|-------|--------|
| `backend/routers/features.py` | `GET /api/features` |
| `backend/routers/prompts.py` | Prompt-Liste, Detail, Render |
| `backend/routers/config.py` | Config GET/POST |
| `backend/rights_registrations/registry_ops.py` | 7 AP0.4-Capabilities |
| `backend/capabilities.py` | `require_capability_ctx` (Portal ohne Tenant) |
| `backend/entitlements.py` | `features`-Block aus DB |
| `backend/entrypoint.sh` | Registry-Sync nach Rights-Sync |
| `backend/main.py` | Router-Registrierung |
| `backend/version.py` | `0.4.0-ap0.4`, Schema `005` |
### 2.5 Tests & Doku
| Datei | Zweck |
|-------|--------|
| `backend/tests/test_feature_registry.py` | Feature Registry |
| `backend/tests/test_prompt_registry.py` | Prompt Engine (Validation, Render, API) |
| `backend/tests/test_config_registry.py` | Config + Secrets |
| `backend/tests/test_entitlements.py` | Features im Snapshot (erweitert) |
| `backend/tests/test_migrations.py` | Migration 005 |
| `backend/tests/test_rights_registry.py` | 12 Capabilities |
| `backend/tests/conftest.py` | Registry-Sync in Test-Session |
| `frontend/src/App.jsx` | Header AP0.4 |
| `README.md` | API-Doku AP0.4 |
---
## 3. Neue Migrationen
**`005_prompt_feature_config_registry.sql`**
| Tabelle | Kernel-Konzept |
|---------|----------------|
| `features` | Feature Registry (Metadaten) |
| `prompt_definitions` | PromptDefinition |
| `prompt_versions` | PromptVersion |
| `prompt_steps` | PromptStep |
| `placeholder_definitions` | PlaceholderDefinition |
| `configuration_entries` | ConfigurationEntry |
| `prompt_execution_logs` | PromptExecutionLog |
Migration ist **additiv** und idempotent über den bestehenden `run_migrations.py`-Runner.
---
## 4. Datenmodell (Gesamt)
```
features
feature_key (PK), module, name, description, is_active
prompt_definitions
id (PK), prompt_key (UNIQUE), context_kind, execution_mode, status
active_version_id → prompt_versions
prompt_versions
id (PK), prompt_definition_id (FK), version, body
input_schema, output_schema (JSONB), model_policy_key
prompt_steps
id (PK), prompt_version_id (FK), step_key, step_order, step_type
template_body, input_mapping, output_mapping (JSONB), enabled
placeholder_definitions
(placeholder_key, context_kind) PK, value_type, required, source
configuration_entries
id (PK), config_key, scope (global|tenant), tenant_id, value (JSONB), is_secret
prompt_execution_logs
id (PK), prompt_definition_id, prompt_version_id, execution_mode
status, rendered_preview, input_summary, error_message, created_by
```
**ExecutionMode:** `single` | `pipeline` | `workflow`
**StepType:** `template` | `resolver` | `llm_call` | `postprocess` | `validation`
**ContextKind (Code):** `kairo.tenant_context`, `kairo.actor_context`, `kairo.debug_context`
---
## 5. Registry-Strukturen (Feature / Config)
Analog AP0.3 Rights Registry: **Registry-first**, Validierung beim Registrieren, idempotenter DB-Sync beim Start.
```
backend/
├── feature_registry.py
├── feature_registrations/
│ ├── platform.py # kairo.feature|config|prompt.registry
│ └── prompt_ops.py # reserviert
├── config_service.py
└── sync_prompt_feature_config.py
```
**Startup-Reihenfolge (`entrypoint.sh`):**
```
Migrationen → Seeds → sync_rights_registry.py → sync_prompt_feature_config.py → Uvicorn
```
Env-Overrides: `SKIP_REGISTRY_SYNC=1` überspringt Feature/Prompt/Placeholder/Config-Sync.
**Initiale Features:**
| Feature Key | Modul | Name |
|-------------|-------|------|
| `kairo.feature.registry` | platform | Feature Registry |
| `kairo.config.registry` | config | Configuration Registry |
| `kairo.prompt.registry` | prompt | Prompt Registry |
Keine Usage-Limits — reiner Metadatenkatalog, in Entitlements mit `enabled: true`.
---
## 6. Feature Registry (Detail)
- **Registrierung:** `register_feature(FeatureRegistration)` — Pflichtfelder `key`, `module`, `name`, `description`
- **Sync:** Upsert in `features`, `is_active = TRUE`
- **Entitlements:** `load_active_features()` → Snapshot ohne Billing/Quotas
- **API:** `GET /api/features` mit `kairo.feature.registry.read`
---
## 7. Prompt Engine — Architektur und Implementierung
Dieser Abschnitt dokumentiert die **Kairo Prompt Engine** (lokaler Prompt-Kernel) im Detail.
### 7.1 Einordnung: Was ist die Prompt Engine in AP0.4?
Die Prompt Engine ist **kein LLM-System**. Sie umfasst:
1. **Persistenz** — workflow-ready Datenmodell (Definition → Version → Steps)
2. **Registry** — Prompts und Placeholder als Code-Kanon mit DB-Sync
3. **Validation** — typisierte Placeholder, Required/Optional
4. **Rendering** — Mustache-Style Template-Ersetzung für `execution_mode = single`
5. **Logging**`prompt_execution_logs` für Test-/Preview-Läufe
6. **Kontext-Injektion** — TenantContext → Placeholder-Werte (getrennt vom Template)
Spätere LLM-Aufrufe würden **oberhalb** oder **in Steps vom Typ `llm_call`** andocken — nicht in AP0.4.
### 7.2 Schichtenmodell
```
┌─────────────────────────────────────────────────────────────┐
│ API Layer routers/prompts.py │
│ POST /api/prompts/{key}/render │
└──────────────────────────┬──────────────────────────────────┘
┌──────────────────────────▼──────────────────────────────────┐
│ Context Layer prompt_context.py │
│ TenantContext → Placeholder-Werte (use_context=true) │
└──────────────────────────┬──────────────────────────────────┘
┌──────────────────────────▼──────────────────────────────────┐
│ Render Service prompt_rendering.py │
│ render_prompt_single() — Orchestrierung │
└───────┬──────────────────────────────┬──────────────────────┘
│ │
┌───────▼──────────────┐ ┌──────────▼──────────────────────┐
│ Validation Service │ │ Registry / Persistence │
│ prompt_validation.py │ │ prompt_registry.py + PostgreSQL │
└──────────────────────┘ └─────────────────────────────────┘
┌───────▼──────────────┐
│ Placeholder Registry │
│ placeholder_registry │
└──────────────────────┘
```
### 7.3 Registry-Modell (Code)
Frozen Dataclasses in `prompt_registry.py`:
| Dataclass | Felder (Auszug) |
|-----------|-----------------|
| `PromptRegistration` | `prompt_key`, `name`, `purpose`, `context_kind`, `execution_mode`, `active_version`, `versions` |
| `PromptVersionRegistration` | `version`, `body`, `input_schema`, `output_schema`, `model_policy_key`, `changelog`, `steps` |
| `PromptStepRegistration` | `step_key`, `step_order`, `step_type`, `template_body`, `input_mapping`, `output_mapping`, `enabled` |
**Validierung bei `register_prompt()`:**
- `context_kind ∈ VALID_CONTEXT_KINDS`
- `execution_mode ∈ {single, pipeline, workflow}`
- mindestens eine Version
- `active_version` muss in `versions` existieren
- jeder `step_type ∈ VALID_STEP_TYPES`
- kein doppelter `prompt_key`
Registrierungen liegen in `prompt_registrations/` (Side-Effect-Import wie bei Rights).
### 7.4 DB-Sync (Prompt Registry → PostgreSQL)
`sync_prompts_to_db()` — idempotent, pro registriertem Prompt:
1. Upsert `prompt_definitions` (ON CONFLICT `prompt_key`)
2. Pro Version: Upsert `prompt_versions` (UNIQUE `prompt_definition_id + version`)
3. Pro Step: Upsert `prompt_steps` (UNIQUE `prompt_version_id + step_key`)
4. Setze `prompt_definitions.active_version_id` auf die ID der `active_version`
**Wichtig:** Sync aktualisiert Metadaten und Templates aus Code — kein ad-hoc DDL in Routern. Runtime liest **aus der DB** (nach Sync), nicht direkt aus dem In-Memory-Dict.
### 7.5 Render-Pipeline (`render_prompt_single`)
Ablauf in `prompt_rendering.py`:
```
1. load_prompt_definition(prompt_key)
└─ 404/not_found wenn unbekannt
└─ inactive wenn status ≠ active
2. execution_mode prüfen
└─ pipeline | workflow → PromptRenderError (mode_not_implemented)
└─ single → weiter
3. load_active_prompt_version(definition)
└─ über active_version_id
4. _resolve_template_body(version)
└─ Priorität A: erster aktiver PromptStep mit step_type=template und template_body
└─ Priorität B: prompt_versions.body (falls nicht leer)
└─ sonst: no_template
5. validate_placeholder_input(template, context_kind, values)
└─ Required fehlt / Typ falsch → PlaceholderValidationError
6. _render_template(template, values)
└─ Mustache {{key}} → str(value); dict/list → JSON
7. prompt_execution_logs (optional, log_execution=true)
└─ status success, rendered_preview (max 2000 Zeichen)
8. Return JSON:
prompt_key, version, execution_mode, template_source, rendered_text, validation
```
**Fehlerpfad:**
- Validation → ExecutionLog `error` + Audit `prompt.render.failed` + HTTP 400
- Pipeline/Workflow → HTTP 501
### 7.6 Template-Auflösung: Body vs. PromptStep
Bewusste Designentscheidung: Ein Prompt darf **nicht** nur als monolithischer Body existieren müssen.
| Szenario | Quelle | Beispiel |
|----------|--------|----------|
| Template im Step | `prompt_steps.template_body` | `kairo.system.health_summary` — Body leer, Step `summary` |
| Template im Body | `prompt_versions.body` | `kairo.context.debug_summary` |
| Beides vorhanden | **Step hat Priorität** | Erster aktiver `template`-Step nach `step_order` |
`template_source` im Response: `"body"` oder `"step:{step_key}"` — erleichtert Debugging und Tests.
### 7.7 Placeholder-System
**Registry** (`placeholder_registry.py`):
- Schlüssel `(placeholder_key, context_kind)` — derselbe Key kann pro ContextKind unterschiedlich typisiert sein
- Felder: `value_type`, `required`, `source`, `description`
**Validation** (`prompt_validation.py`):
| Regel | Verhalten |
|-------|-----------|
| Required in Registry, nicht in `values` | `PlaceholderValidationError` (missing) |
| Optional fehlt | kein Fehler; in `optional_missing` |
| Wert vorhanden, Typ falsch | `type_errors` (z. B. `number` erwartet) |
| `{{unknown}}` im Template, nicht in Registry | kein Hard-Fail; in `unknown_placeholders` |
| Template-Syntax | `\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}` |
**Typen:** `string`, `number`, `boolean`, `object`, `array`, `json` (`json` akzeptiert beliebige JSON-Werte)
**Initial-Placeholder:**
| ContextKind | Keys (Auszug) |
|-------------|---------------|
| `kairo.tenant_context` | `tenant_name*`, `tenant_id*`, `portal_role*`, `actor_*`, `tenant_role`, `capabilities` |
| `kairo.actor_context` | `actor_id*`, `actor_type*`, `tenant_id*` |
| `kairo.debug_context` | `debug_message*`, `debug_level` |
`*` = required
### 7.8 Kontext-Injektion (Template ≠ Kontext)
`prompt_context.py` trennt **Template** (in DB/Registry) von **Laufzeit-Kontext** (Session/TenantContext):
```python
# use_context=true (Default im Render-API)
values = merge_context_values(ctx, definition["context_kind"], body.values)
# body.values überschreibt/ergänzt automatische Werte
```
| ContextKind | Automatische Werte aus |
|-------------|------------------------|
| `kairo.tenant_context` | `build_tenant_context_values(ctx)` |
| `kairo.actor_context` | `build_actor_context_values(ctx)` |
| `kairo.debug_context` | keine — nur `body.values` |
Für Tenant-/Actor-Prompts mit `use_context=true` ist **aktiver Tenant** Pflicht (API → HTTP 403).
### 7.9 Execution Modes
| Mode | AP0.4 Registry | AP0.4 Render |
|------|----------------|--------------|
| `single` | ✓ registriert | ✓ ausgeführt |
| `pipeline` | ✓ registriert (`kairo.pipeline.placeholder`) | ✗ HTTP 501 |
| `workflow` | ✓ schema-seitig | ✗ HTTP 501 |
`model_policy_key` auf Version — **nur Vorbereitung** für spätere Model-Routing-Policy, kein LLM in AP0.4.
`input_schema` / `output_schema` (JSONB) — gespeichert, **nicht** voll validiert (Spec: keine komplexe Output-Validation in AP0.4).
### 7.10 PromptExecutionLog
Tabelle `prompt_execution_logs` — Audit-/Debug-Spur für Render-Läufe:
| Feld | Inhalt |
|------|--------|
| `status` | `success` \| `error` \| `skipped` |
| `rendered_preview` | Gerenderter Text (gekürzt) |
| `input_summary` | z. B. `{"keys": ["tenant_id", ...]}` |
| `error_message` | bei Validation/Render-Fehler |
| `created_by` | User-ID aus Session |
Config `prompt.render_logging_enabled` (Default `true`) — Vorbereitung; Render-Endpoint loggt derzeit immer wenn `log_execution=True`.
### 7.11 Registrierte Smoke-Prompts
| prompt_key | context_kind | execution_mode | Template-Quelle |
|------------|--------------|----------------|-----------------|
| `kairo.system.health_summary` | `kairo.debug_context` | single | Step `summary` |
| `kairo.context.debug_summary` | `kairo.tenant_context` | single | Version body |
| `kairo.actor.debug_summary` | `kairo.actor_context` | single | Version body |
| `kairo.pipeline.placeholder` | `kairo.debug_context` | pipeline | (nicht ausführbar) |
Keine Vorhaben-/Projekt-/Gesundheits-/Trainingslogik — nur technische Smoke-Tests.
### 7.12 API-Oberfläche Prompt Engine
| Endpoint | Capability | Beschreibung |
|----------|------------|--------------|
| `GET /api/prompts` | `kairo.prompt.registry.read` | Alle Definitionen (Metadaten) |
| `GET /api/prompts/{key}` | `kairo.prompt.registry.read` | Definition + active_version |
| `POST /api/prompts/{key}/render` | `kairo.prompt.render` | Single-Render |
**Render-Request:**
```json
{
"values": { "debug_message": "OK", "debug_level": "info" },
"use_context": false
}
```
**Render-Response (Erfolg):**
```json
{
"prompt_key": "kairo.system.health_summary",
"version": "1.0.0",
"execution_mode": "single",
"template_source": "step:summary",
"rendered_text": "Kairo Systemstatus: OK (Level: info)",
"validation": {
"used_placeholders": ["debug_level", "debug_message"],
"unknown_placeholders": [],
"optional_missing": []
}
}
```
### 7.13 Erweiterungspunkte (Pipeline / Workflow / LLM)
**Bereits vorbereitet — keine Migration nötig:**
| Erweiterung | Anker in AP0.4 |
|-------------|----------------|
| Multi-Step Pipeline | `prompt_steps`, `step_order`, `step_type` |
| LLM-Aufruf | Step-Typ `llm_call` + `model_policy_key` |
| Resolver / Postprocess | Step-Typen `resolver`, `postprocess`, `validation` |
| Input/Output zwischen Steps | `input_mapping`, `output_mapping` (JSONB) |
| Workflow-Orchestrierung | `execution_mode=workflow` + zukünftiger Executor |
**Empfohlener nächster Schritt (post-AP0.4):**
1. `StepExecutorRegistry` analog `rights_registrations/` — Handler pro `step_type`
2. `render_prompt_pipeline()` — Schleife über Steps, Kontext-Accumulator
3. `llm_call`-Handler — separates Modul, injizierbarer Provider (nicht in Kernel hardcoden)
### 7.14 Extraktion `jinkendo_prompt_kernel`
**Extrahierbare Module (produktneutral):**
- `prompt_registry.py`, `placeholder_registry.py`
- `prompt_validation.py`, `prompt_rendering.py`
- SQL-Tabellen `prompt_*`, `placeholder_definitions`, `prompt_execution_logs`
**Produktspezifisch (bleibt in Kairo):**
- `prompt_registrations/*` (Keys `kairo.*`)
- `placeholder_registrations/*`
- `prompt_context.py` (TenantContext-Kopplung)
- Capabilities, Entitlements-Features
**Realistisch:** Extraktion als Shared Package mit Interfaces `DBConnection`, `AuditHook`, `ContextResolver` — ohne Schema-Bruch möglich.
**Risiken:**
- Step-Executor fehlt noch — Pipeline-Design offen
- Zwei Capability-Dependencies (`require_capability` vs. `require_capability_ctx`)
- Prompt-CRUD nur über Code — Admin-API fehlt (AP0.5)
---
## 8. Workflow-/Pipeline-Fähigkeit (strukturell)
AP0.4 **speichert** Pipeline-/Workflow-Struktur, **führt sie nicht aus**.
```
PromptDefinition (execution_mode=pipeline)
└── PromptVersion 0.1.0
├── Step 1: template
├── Step 2: resolver (disabled/no handler)
└── Step 3: llm_call (disabled/no handler)
```
Render-Service lehnt `pipeline`/`workflow` kontrolliert ab — verhindert falsche Erwartungen, ohne das Schema zu vereinfachen.
---
## 9. Placeholder Validation (Zusammenfassung)
Siehe §7.7. Kernprinzip: **Registry definiert erlaubte Keys pro ContextKind**; Template darf Keys enthalten, die dokumentiert aber nicht blockierend sind, wenn sie nicht in der Registry stehen.
---
## 10. Configuration Registry
| Key (Default) | Wert | Typ |
|---------------|------|-----|
| `prompt.default_execution_mode` | `single` | string |
| `prompt.render_logging_enabled` | `true` | boolean |
| `features.registry_sync_enabled` | `true` | boolean |
- **Scopes:** `global`, `tenant` (tenant erfordert `tenant_id`)
- **Secrets:** `is_secret=true` → nur `{"ref": "env"}`; Klartext wird abgelehnt (`SECRET_VALUE_FORBIDDEN`)
- **API:** `GET/POST /api/config` mit `kairo.config.registry.read/manage`
---
## 11. Entitlements-Erweiterung
`/api/me/entitlements``features` auf Root-, Account- und Tenant-Ebene:
```json
{
"features": {
"kairo.prompt.registry": {
"enabled": true,
"module": "prompt",
"name": "Prompt Registry",
"description": "Workflow-ready Prompt-Definitionen und Versionen"
}
},
"enforcement": {
"capabilities": "probe",
"features": "probe"
}
}
```
Feature-Enforcement bleibt `probe` — Metadaten ohne Limit-Engine.
---
## 12. Capabilities AP0.4
| Capability | Portal admin | Portal user | Tenant owner | Tenant admin | Tenant member |
|------------|:------------:|:-----------:|:------------:|:------------:|:-------------:|
| `kairo.feature.registry.read` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `kairo.feature.registry.manage` | ✓ | | | | |
| `kairo.prompt.registry.read` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `kairo.prompt.registry.manage` | ✓ | | | | |
| `kairo.config.registry.read` | ✓ | | ✓ | ✓ | |
| `kairo.config.registry.manage` | ✓ | | ✓ | ✓ | |
| `kairo.prompt.render` | ✓ | ✓ | ✓ | ✓ | ✓ |
**Begründung Zuordnung:**
- **Lesen/Render** für alle Tenant-Rollen — Prompt-Preview ist technische Grundlage, keine Admin-Gefahr (kein LLM, kein CRUD)
- **Config read/manage** nur Owner/Admin — tenant-scoped Config kann fachliche Einstellungen enthalten
- **Registry manage** nur Portal-Admin — Kanon bleibt Code-Registry + Sync
`require_capability_ctx` — Lese-Endpunkte und Debug-Render ohne aktiven Tenant (Portal-Kontext).
---
## 13. Audit
| Event | Auslöser |
|-------|----------|
| `registry.sync.completed` | Startup `sync_prompt_feature_config.py` |
| `config.entry.changed` | `upsert_config()` |
| `prompt.render.failed` | Placeholder-Validation fehlgeschlagen |
| `capability.denied` | Capability-Gate (bestehend AP0.3) |
**Lücke:** Kein Audit bei Prompt-Sync auf Zeilen-Ebene (nur aggregiertes Sync-Event). Prompt-CRUD über API fehlt — AP0.5 kann granular auditiert werden.
---
## 14. Tests und Verifikation
### pytest (CI / Dev-Container)
```bash
docker compose -f docker-compose.dev-env.yml exec backend python -m pytest tests -ra -vv
```
| Testdatei | Abdeckung | Status |
|-----------|-----------|--------|
| `test_prompt_registry.py` | Sync, Required/Optional, Render, Pipeline 501, API | ✓ |
| `test_feature_registry.py` | Features, Entitlements, Auth | ✓ |
| `test_config_registry.py` | Config, Secret-Schutz, API | ✓ |
| `test_entitlements.py` | Features im Snapshot | ✓ |
| `test_migrations.py` | Migration 005 idempotent | ✓ |
| `test_rights_registry.py` | 12 Capabilities | ✓ |
| Gesamt Test Suite (Gitea) | nach Push `develop` | ✓ (Nutzer bestätigt) |
### Manuell (Dev)
```bash
# Health
curl -s http://localhost:8097/api/health
# → "schema": "005", "version": "0.4.0-ap0.4"
# Nach Login (TOKEN):
curl -s http://localhost:8097/api/prompts -H "X-Auth-Token: TOKEN"
curl -s -X POST http://localhost:8097/api/prompts/kairo.system.health_summary/render \
-H "X-Auth-Token: TOKEN" -H "Content-Type: application/json" \
-d '{"values":{"debug_message":"CI ok","debug_level":"info"},"use_context":false}'
```
Swagger: `http://localhost:8097/api/docs`
---
## 15. Übernommene Muster aus Mitai
| Muster | Kairo-Umsetzung |
|--------|-----------------|
| Prompt Template + Version getrennt | `PromptVersionRegistration` / `prompt_versions` |
| Placeholder-Handling | Registry + Validation vor Render |
| Prompt Preview / Testbarkeit | `POST .../render` + ExecutionLog |
| Feature Registry Metadaten | `features` + Entitlements |
| Entitlements zentrale Schicht | `features`-Block |
| Registry-Sync Startup | wie Rights Registry |
**Nicht übernommen:** Mitai Pipeline-Graphen, Gesundheits-Prompts, Tier/Billing, Usage-Zähler, volle Prompt Engine.
---
## 16. Übernommene Muster aus Shinkan
| Muster | Kairo-Umsetzung |
|--------|-----------------|
| Mustache-/Template-Prinzip | `{{placeholder_key}}` |
| Kontextarten | `context_kind` |
| Registry-first, DB-Sync | Code-Kanon → PostgreSQL |
| Schlanke AI Prompt Runtime | nur Single-Render, kein Overengineering |
| Capability-Gates | `require_capability*` |
**Nicht übernommen:** Trainings-Prompts, Club-Logik, Übungsrechte.
---
## 17. Bewusst nicht übernommen
- Vollständige Mitai Prompt Engine / Workflow-Graphen
- LLM Provider Routing, Tool Calling, MCP, Retry/Fallback
- Shinkan-/Mitai-Domänenprompts und -rechte
- Feature-Limits, Billing, Coupons, Usage-Zähler
- Produktive Admin-UI (Swagger reicht)
- Secrets in `configuration_entries`
- Vorhaben / Projekte / Meilensteine / Seichō-Logik
---
## 18. Abweichungen von Designprinzipien
| Thema | Abweichung | Begründung |
|-------|------------|------------|
| Prompt-CRUD | nur Code-Registry + Sync | Sprint-0-Minimal |
| Output-Validation | JSONB gespeichert, nicht geprüft | Spec AP0.4 |
| ContextKind | Code-Konstanten, keine Tabelle | 3 Kindes ausreichend |
| Feature-Enforcement | immer `probe` | Limits später |
| Pipeline steps | nur erster template-Step in single | Multi-Step = eigener Executor |
**Eingehalten:** keine Hardcodings in Routern; Template/Kontext getrennt; produktneutrale Kernel-Form; Audit-Hooks vorhanden.
---
## 19. Offene Entscheidungen
1. **StepExecutorRegistry** — wann und wie Handler für `resolver`/`llm_call` registrieren?
2. **Prompt-Admin-API** — CRUD in AP0.5 oder weiter Code-only?
3. **`jinkendo_prompt_kernel`** — Package-Grenze, Migrations-Ownership
4. **Feature-Enforcement** — wann über Metadaten hinaus?
5. **Render-Logging in Prod** — Config-Flag wired an `log_execution`?
6. **Prod-pytest-Cleanup** (`*@example.com`) — aus AP0.2 offen
---
## 20. Empfehlung für AP0.5
Laut Foundation **AP0.5 Audit und minimale Admin-Prüfbarkeit**:
- Audit bei Prompt-/Feature-/Config-Änderungen granular
- Minimale Admin-Routen oder Admin-Seite (Prompt-Liste, Render-Test, Entitlements)
- Optional: GUI-Karten für Features/Entitlements
- Prod-Cleanup-Seed für Test-User
Optional parallel: **Pipeline-Executor** Prototyp für 2-Step-`template`-Kette (ohne LLM).
---
## Referenzen
- Auftrag: AP0.4 Assignment (Cursor/Claude)
- `docs/sprints/Jinkendo_Kairo_04_Sprint0_Foundation_v0.3.md` § AP0.4
- `docs/reference/design-principles/mitai/PROMPT_ENGINE_DESIGN_PRINCIPLES.md`
- `docs/reference/design-principles/shinkan/AI_PROMPT_RUNTIME_DESIGN_PRINCIPLES.md`
- Vorgänger: `docs/sprints/Sprint0_AP0_3_Completion_Report_v0.3.md`
---
*Abgeschlossen im Rahmen Sprint 0 AP0.4. Ersetzt `Sprint0_AP0_4_Completion_Report_v0.1.md`.*

View File

@ -6,7 +6,7 @@
**Frontend-Version:** `0.6.1-ap0.6b`
**Backend:** unverändert (Schema `006`)
**Wesentliche Commits:** `48a599e` (Remediation), `26cd9fe` (Fix Vorhaben-Detail)
**Wesentliche Commits:** `48a599e` (Remediation), `26cd9fe` (Fix Vorhaben-Detail), `842c390` (Abschlussbericht v0.2)
---