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
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:
parent
842c39081b
commit
36487d2869
|
|
@ -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).
|
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).
|
**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`
|
**Beispiel-Prompts:** `kairo.system.health_summary`, `kairo.context.debug_summary`
|
||||||
|
|
|
||||||
701
docs/sprints/Sprint0_AP0_4_Completion_Report_v0.2.md
Normal file
701
docs/sprints/Sprint0_AP0_4_Completion_Report_v0.2.md
Normal 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`.*
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
**Frontend-Version:** `0.6.1-ap0.6b`
|
**Frontend-Version:** `0.6.1-ap0.6b`
|
||||||
**Backend:** unverändert (Schema `006`)
|
**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)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user