AP2.0: Archetyp-Katalog, Method-Stubs und sichtbare Steuerung in Kontrolle.
Some checks failed
Deploy Development / deploy (push) Successful in 46s
Test Suite / pytest-backend (push) Failing after 2m2s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
Some checks failed
Deploy Development / deploy (push) Successful in 46s
Test Suite / pytest-backend (push) Failing after 2m2s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
PO-Dokumente (ADP v0.2, MVP v0.3) und Minimal Complete Slice: Registry-Methoden, Initiative/Project-Spiegel, Default-Methode bei Anlage, Lagebild mit Archetyp und Guidance. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
21d948634e
commit
3bd983297b
|
|
@ -11,6 +11,7 @@ from psycopg2.extras import RealDictCursor
|
|||
|
||||
from db import get_connection
|
||||
from data_layer.attention import get_next_action_candidates_for_initiative
|
||||
from entity_archetypes.registry import archetype_label
|
||||
from steering.context import get_steering_context_dto
|
||||
from steering.signals.snapshot_signals import derive_initiative_signals
|
||||
from services.initiatives import get_initiative
|
||||
|
|
@ -20,6 +21,41 @@ OPEN_BLOCKER = ("open", "in_progress")
|
|||
OPEN_ACTION = ("open", "ready", "in_progress", "blocked", "review_required")
|
||||
ACTIVE_INITIATIVE = ("active", "paused")
|
||||
|
||||
_REASON_LABELS = {
|
||||
"open_action_priority": "Offenes Arbeitspaket",
|
||||
"milestone_at_risk_or_active": "Plan-Element aktiv oder gefährdet",
|
||||
"blocked_action": "Blockiertes Arbeitspaket",
|
||||
"backlog_triage": "Eingang triagieren",
|
||||
}
|
||||
|
||||
|
||||
def _steering_guidance(
|
||||
*,
|
||||
next_actions: list[dict[str, Any]],
|
||||
signals: list[str],
|
||||
method_key: str,
|
||||
) -> str:
|
||||
if next_actions:
|
||||
item = next_actions[0]
|
||||
title = item.get("title") or "Nächster Schritt"
|
||||
hint = (
|
||||
item.get("recommended_action")
|
||||
or item.get("summary")
|
||||
or _REASON_LABELS.get(item.get("reason_code", ""), "")
|
||||
)
|
||||
if hint:
|
||||
return f"Als Nächstes: {title} — {hint}"
|
||||
return f"Als Nächstes: {title}"
|
||||
if signals:
|
||||
return "Attention: Struktur oder Ist-Arbeit ergänzen, um Next Actions zu erzeugen."
|
||||
return (
|
||||
f"Methode {method_key}: Plan oder Eingang befüllen, dann committete Arbeit starten."
|
||||
)
|
||||
|
||||
|
||||
def _attention_items(signals: list[str]) -> list[dict[str, str]]:
|
||||
return [{"code": code, "label": code.replace("_", " ")} for code in signals]
|
||||
|
||||
|
||||
def _sid(value: Any) -> Optional[str]:
|
||||
return str(value) if value else None
|
||||
|
|
@ -261,16 +297,32 @@ def get_initiative_steering_snapshot(
|
|||
)
|
||||
|
||||
steering = get_steering_context_dto(ctx, initiative_id=initiative_id)
|
||||
metadata = steering.get("lifecycle_metadata") or {}
|
||||
if isinstance(metadata, str):
|
||||
metadata = {}
|
||||
method_profile_key = metadata.get("method_profile_key")
|
||||
initiative_archetype = initiative.get("archetype_key") or "initiative.generic"
|
||||
|
||||
return {
|
||||
"initiative_id": initiative_id,
|
||||
"initiative_title": initiative["title"],
|
||||
"initiative_status": initiative["status"],
|
||||
"archetype_key": initiative_archetype,
|
||||
"archetype_label": archetype_label(
|
||||
entity_type="initiative", archetype_key=initiative_archetype
|
||||
),
|
||||
"method_profile_key": method_profile_key,
|
||||
"lifecycle_state": steering["lifecycle_state"],
|
||||
"lifecycle_label": steering["lifecycle_label"],
|
||||
"method_key": steering["method_key"],
|
||||
"method_label": steering.get("method_label"),
|
||||
"method_version": steering["method_version"],
|
||||
"steering_guidance": _steering_guidance(
|
||||
next_actions=next_actions,
|
||||
signals=signals,
|
||||
method_key=steering["method_key"],
|
||||
),
|
||||
"attention_items": _attention_items(signals),
|
||||
"signals": signals,
|
||||
"upcoming_milestones": upcoming_milestones,
|
||||
"upcoming_roadmap_items": upcoming_milestones,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
from entity_archetypes.registry import (
|
||||
ENTITY_ARCHETYPES,
|
||||
INITIATIVE_ARCHETYPES,
|
||||
PROJECT_ARCHETYPES,
|
||||
archetype_label,
|
||||
list_archetypes,
|
||||
mirror_project_archetype_key,
|
||||
resolve_default_method_key,
|
||||
validate_archetype_key,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"ENTITY_ARCHETYPES",
|
||||
"INITIATIVE_ARCHETYPES",
|
||||
"PROJECT_ARCHETYPES",
|
||||
"archetype_label",
|
||||
"list_archetypes",
|
||||
"mirror_project_archetype_key",
|
||||
"resolve_default_method_key",
|
||||
"validate_archetype_key",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""System-Archetypen (AP1.10a/10b) — In-Memory-Seed + DB-Registry."""
|
||||
"""System-Archetypen (AP1.10 + AP2.0) — Seeds, Bindings, Spiegel Project."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -8,39 +8,136 @@ from psycopg2.extras import RealDictCursor
|
|||
|
||||
from db import get_connection
|
||||
|
||||
INITIATIVE_ARCHETYPES: tuple[dict[str, Any], ...] = (
|
||||
{
|
||||
"key": "initiative.generic",
|
||||
"entity_type": "initiative",
|
||||
"label": "Allgemeines Vorhaben",
|
||||
"description": "Standard-Vorhaben ohne spezielle Vorlage.",
|
||||
"is_system": True,
|
||||
},
|
||||
{
|
||||
"key": "initiative.program",
|
||||
"entity_type": "initiative",
|
||||
"label": "Programm / Mega-Vorhaben",
|
||||
"description": "Mehrere Stränge, Zielzustand und Vision zentral.",
|
||||
"is_system": True,
|
||||
},
|
||||
{
|
||||
"key": "initiative.product",
|
||||
"entity_type": "initiative",
|
||||
"label": "Produkt / Release",
|
||||
"description": "Produkt- oder Release-orientiertes Vorhaben.",
|
||||
"is_system": True,
|
||||
},
|
||||
# initiative suffix → default method (shared by initiative + project mirror)
|
||||
_METHOD_BY_SUFFIX: dict[str, str] = {
|
||||
"generic": "generic_operating",
|
||||
"maturity_journey": "maturity_progression",
|
||||
"linear_project": "sequential_dependency",
|
||||
"recurring_program": "recurring_control",
|
||||
"support_queue": "queue_pull",
|
||||
"program": "program_delivery",
|
||||
"product": "continuous_product",
|
||||
"dispute_case": "dispute_procedure",
|
||||
"content_project": "chapter_based_progression",
|
||||
}
|
||||
|
||||
_INITIATIVE_SPEC_META: tuple[tuple[str, str, str], ...] = (
|
||||
("generic", "Allgemeines Vorhaben", "Fallback ohne spezielle Steuerungsvorlage."),
|
||||
(
|
||||
"maturity_journey",
|
||||
"Reifegrad-Entwicklung",
|
||||
"Mehrstufige Entwicklung, Routinen, Graph-Voraussetzungen.",
|
||||
),
|
||||
(
|
||||
"linear_project",
|
||||
"Lineares Vorhaben",
|
||||
"Einmalprojekte mit Pfaden, Gates und Graph.",
|
||||
),
|
||||
(
|
||||
"recurring_program",
|
||||
"Dauerprogramm / Rhythmus",
|
||||
"Haushalt, Rhythmen, Abweichungs-Steuerung.",
|
||||
),
|
||||
(
|
||||
"support_queue",
|
||||
"Inbox / Queue",
|
||||
"Ad-hoc-Eingang, triage, thematische Zuordnung.",
|
||||
),
|
||||
(
|
||||
"program",
|
||||
"Programm (begrenzt)",
|
||||
"Phasen, Release-Programm mit Abschluss.",
|
||||
),
|
||||
(
|
||||
"product",
|
||||
"Produkt (kontinuierlich)",
|
||||
"Dauerbetrieb, Wartung, Issues, Weiterentwicklung.",
|
||||
),
|
||||
(
|
||||
"dispute_case",
|
||||
"Verfahren / Konflikt",
|
||||
"Reaktive Steuerung, Fristen, Entscheidungen.",
|
||||
),
|
||||
(
|
||||
"content_project",
|
||||
"Inhalt / Kapitel",
|
||||
"Bücher, Konzepte, Kapitelstruktur.",
|
||||
),
|
||||
)
|
||||
|
||||
_ARCHETYPE_INDEX = {
|
||||
(item["entity_type"], item["key"]): item for item in INITIATIVE_ARCHETYPES
|
||||
|
||||
def _build_specs() -> tuple[dict[str, Any], ...]:
|
||||
specs: list[dict[str, Any]] = []
|
||||
for suffix, label, description in _INITIATIVE_SPEC_META:
|
||||
method = _METHOD_BY_SUFFIX[suffix]
|
||||
specs.append(
|
||||
{
|
||||
"key": f"initiative.{suffix}",
|
||||
"entity_type": "initiative",
|
||||
"label": label,
|
||||
"description": description,
|
||||
"is_system": True,
|
||||
"default_method_key": method,
|
||||
"default_method_profile_key": None,
|
||||
}
|
||||
)
|
||||
specs.append(
|
||||
{
|
||||
"key": f"project.{suffix}",
|
||||
"entity_type": "project",
|
||||
"label": label,
|
||||
"description": f"Project-Spiegel: {description}",
|
||||
"is_system": True,
|
||||
"default_method_key": method,
|
||||
"default_method_profile_key": None,
|
||||
}
|
||||
)
|
||||
return tuple(specs)
|
||||
|
||||
|
||||
ENTITY_ARCHETYPES: tuple[dict[str, Any], ...] = _build_specs()
|
||||
|
||||
INITIATIVE_ARCHETYPES: tuple[dict[str, Any], ...] = tuple(
|
||||
item for item in ENTITY_ARCHETYPES if item["entity_type"] == "initiative"
|
||||
)
|
||||
|
||||
PROJECT_ARCHETYPES: tuple[dict[str, Any], ...] = tuple(
|
||||
item for item in ENTITY_ARCHETYPES if item["entity_type"] == "project"
|
||||
)
|
||||
|
||||
_ARCHETYPE_INDEX: dict[tuple[str, str], dict[str, Any]] = {
|
||||
(item["entity_type"], item["key"]): item for item in ENTITY_ARCHETYPES
|
||||
}
|
||||
|
||||
_KEY_INDEX: dict[str, dict[str, Any]] = {item["key"]: item for item in ENTITY_ARCHETYPES}
|
||||
|
||||
|
||||
def _list_archetypes_from_memory(*, entity_type: Optional[str] = None) -> list[dict[str, Any]]:
|
||||
if entity_type is None:
|
||||
return [dict(item) for item in INITIATIVE_ARCHETYPES]
|
||||
return [dict(item) for item in INITIATIVE_ARCHETYPES if item["entity_type"] == entity_type]
|
||||
items = ENTITY_ARCHETYPES
|
||||
if entity_type is not None:
|
||||
items = tuple(i for i in items if i["entity_type"] == entity_type)
|
||||
return [_public_archetype(item) for item in items]
|
||||
|
||||
|
||||
def _public_archetype(item: dict[str, Any]) -> dict[str, Any]:
|
||||
return {
|
||||
"key": item["key"],
|
||||
"entity_type": item["entity_type"],
|
||||
"label": item["label"],
|
||||
"description": item["description"],
|
||||
"is_system": item["is_system"],
|
||||
"default_method_key": item["default_method_key"],
|
||||
"default_method_profile_key": item.get("default_method_profile_key"),
|
||||
}
|
||||
|
||||
|
||||
def _enrich_row(row: dict[str, Any]) -> dict[str, Any]:
|
||||
base = dict(row)
|
||||
spec = _KEY_INDEX.get(base.get("key", ""))
|
||||
if spec:
|
||||
base.setdefault("default_method_key", spec["default_method_key"])
|
||||
base.setdefault("default_method_profile_key", spec.get("default_method_profile_key"))
|
||||
return base
|
||||
|
||||
|
||||
def list_archetypes(*, entity_type: Optional[str] = None) -> list[dict[str, Any]]:
|
||||
|
|
@ -67,7 +164,7 @@ def list_archetypes(*, entity_type: Optional[str] = None) -> list[dict[str, Any]
|
|||
)
|
||||
rows = cur.fetchall()
|
||||
if rows:
|
||||
return [dict(row) for row in rows]
|
||||
return [_enrich_row(dict(row)) for row in rows]
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
|
|
@ -83,3 +180,19 @@ def validate_archetype_key(*, entity_type: str, archetype_key: str) -> None:
|
|||
def archetype_label(*, entity_type: str, archetype_key: str) -> Optional[str]:
|
||||
item = _ARCHETYPE_INDEX.get((entity_type, archetype_key))
|
||||
return item["label"] if item else None
|
||||
|
||||
|
||||
def resolve_default_method_key(archetype_key: str) -> str:
|
||||
spec = _KEY_INDEX.get(archetype_key)
|
||||
if not spec:
|
||||
return "generic_operating"
|
||||
return spec.get("default_method_key", "generic_operating")
|
||||
|
||||
|
||||
def mirror_project_archetype_key(initiative_archetype_key: str) -> str:
|
||||
if initiative_archetype_key.startswith("initiative."):
|
||||
suffix = initiative_archetype_key[len("initiative.") :]
|
||||
candidate = f"project.{suffix}"
|
||||
if ( "project", candidate) in _ARCHETYPE_INDEX:
|
||||
return candidate
|
||||
return "project.generic"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""System-Felddefinitionen (Seed) — AP1.10b."""
|
||||
"""System-Felddefinitionen (Seed) — AP1.10b / AP2.0b."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -45,4 +45,44 @@ FIELD_DEFINITIONS: tuple[dict[str, Any], ...] = (
|
|||
"sort_order": 20,
|
||||
"validation_json": {},
|
||||
},
|
||||
{
|
||||
"archetype_key": "initiative.maturity_journey",
|
||||
"field_key": "current_focus",
|
||||
"field_type": "text",
|
||||
"label": "Aktueller Fokus",
|
||||
"required": False,
|
||||
"searchable": True,
|
||||
"sort_order": 10,
|
||||
"validation_json": {},
|
||||
},
|
||||
{
|
||||
"archetype_key": "initiative.maturity_journey",
|
||||
"field_key": "training_frequency",
|
||||
"field_type": "enum",
|
||||
"label": "Trainingsfrequenz",
|
||||
"required": False,
|
||||
"searchable": False,
|
||||
"sort_order": 20,
|
||||
"validation_json": {"options": ["daily", "3x_week", "weekly", "flexible"]},
|
||||
},
|
||||
{
|
||||
"archetype_key": "initiative.content_project",
|
||||
"field_key": "manuscript_status",
|
||||
"field_type": "text",
|
||||
"label": "Manuskript-Status",
|
||||
"required": False,
|
||||
"searchable": True,
|
||||
"sort_order": 10,
|
||||
"validation_json": {},
|
||||
},
|
||||
{
|
||||
"archetype_key": "initiative.content_project",
|
||||
"field_key": "word_count_goal",
|
||||
"field_type": "number",
|
||||
"label": "Wortziel",
|
||||
"required": False,
|
||||
"searchable": False,
|
||||
"sort_order": 20,
|
||||
"validation_json": {},
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
"""Sync Entity-Archetypen und Felddefinitionen in PostgreSQL — AP1.10b."""
|
||||
"""Sync Entity-Archetypen und Felddefinitionen in PostgreSQL — AP1.10b / AP2.0b."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from db import get_connection
|
||||
from entity_archetypes.registry import INITIATIVE_ARCHETYPES
|
||||
from entity_archetypes.registry import ENTITY_ARCHETYPES
|
||||
from entity_fields.definitions import FIELD_DEFINITIONS
|
||||
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ def sync_entity_field_registry_to_db() -> int:
|
|||
conn = get_connection()
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
for archetype in INITIATIVE_ARCHETYPES:
|
||||
for archetype in ENTITY_ARCHETYPES:
|
||||
cur.execute(
|
||||
"""
|
||||
INSERT INTO entity_archetypes (
|
||||
|
|
@ -68,7 +68,7 @@ def sync_entity_field_registry_to_db() -> int:
|
|||
conn.commit()
|
||||
print(
|
||||
"[entity_fields] Sync OK — "
|
||||
f"{len(INITIATIVE_ARCHETYPES)} Archetyp(en), "
|
||||
f"{len(ENTITY_ARCHETYPES)} Archetyp(en), "
|
||||
f"{len(FIELD_DEFINITIONS)} Felddefinition(en)"
|
||||
)
|
||||
return 0
|
||||
|
|
|
|||
1
backend/method_profiles/__init__.py
Normal file
1
backend/method_profiles/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
"""Package marker for method profile seeds."""
|
||||
63
backend/method_profiles/registry.py
Normal file
63
backend/method_profiles/registry.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"""Referenz-Ausprägungen (Method Profiles) — Code-Seeds AP2.0b."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
METHOD_PROFILES: tuple[dict[str, Any], ...] = (
|
||||
{
|
||||
"key": "maturity.karate_kumite",
|
||||
"label": "Karate Kumite",
|
||||
"description": "Mehrere Fähigkeiten mit Stufen, Routinen und Voraussetzungs-Graph.",
|
||||
"initiative_archetype_key": "initiative.maturity_journey",
|
||||
"method_key": "maturity_progression",
|
||||
"seed_hints": {
|
||||
"skill_count": 8,
|
||||
"stages_per_skill": "5-7",
|
||||
"graph_prerequisites": True,
|
||||
},
|
||||
},
|
||||
{
|
||||
"key": "content.book_writing",
|
||||
"label": "Buch schreiben",
|
||||
"description": "Kapitelstruktur, Schreib-APs, Review-Gates.",
|
||||
"initiative_archetype_key": "initiative.content_project",
|
||||
"method_key": "chapter_based_progression",
|
||||
"seed_hints": {
|
||||
"roadmap_item_type": "chapter",
|
||||
"review_gates": True,
|
||||
},
|
||||
},
|
||||
{
|
||||
"key": "product.kairo_dev",
|
||||
"label": "Kairo Entwicklung",
|
||||
"description": "Kontinuierliches Produkt mit Gate-Orientierung und optionaler Sprint-Zeitbox.",
|
||||
"initiative_archetype_key": "initiative.product",
|
||||
"method_key": "continuous_product",
|
||||
"seed_hints": {
|
||||
"agile_iteration_profile": True,
|
||||
"default_actor_setup": "po_plus_vibe_coder",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
_PROFILE_INDEX = {item["key"]: item for item in METHOD_PROFILES}
|
||||
|
||||
|
||||
def get_method_profile(key: str) -> Optional[dict[str, Any]]:
|
||||
item = _PROFILE_INDEX.get(key)
|
||||
return dict(item) if item else None
|
||||
|
||||
|
||||
def list_method_profiles(*, initiative_archetype_key: Optional[str] = None) -> list[dict[str, Any]]:
|
||||
items = METHOD_PROFILES
|
||||
if initiative_archetype_key:
|
||||
items = tuple(
|
||||
i for i in items if i["initiative_archetype_key"] == initiative_archetype_key
|
||||
)
|
||||
return [dict(item) for item in items]
|
||||
|
||||
|
||||
def resolve_method_for_profile(profile_key: str) -> Optional[str]:
|
||||
profile = get_method_profile(profile_key)
|
||||
return profile["method_key"] if profile else None
|
||||
27
backend/migrations/019_project_archetype_key.sql
Normal file
27
backend/migrations/019_project_archetype_key.sql
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-- AP2.0b: Project archetype_key (Spiegel der Initiative)
|
||||
|
||||
ALTER TABLE projects
|
||||
ADD COLUMN IF NOT EXISTS archetype_key VARCHAR(64) NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_projects_archetype
|
||||
ON projects (tenant_id, archetype_key)
|
||||
WHERE archetype_key IS NOT NULL;
|
||||
|
||||
-- Bestehende Projects: Mirror aus Initiative (einmalig)
|
||||
UPDATE projects p
|
||||
SET archetype_key = CASE i.archetype_key
|
||||
WHEN 'initiative.generic' THEN 'project.generic'
|
||||
WHEN 'initiative.maturity_journey' THEN 'project.maturity_journey'
|
||||
WHEN 'initiative.linear_project' THEN 'project.linear_project'
|
||||
WHEN 'initiative.recurring_program' THEN 'project.recurring_program'
|
||||
WHEN 'initiative.support_queue' THEN 'project.support_queue'
|
||||
WHEN 'initiative.program' THEN 'project.program'
|
||||
WHEN 'initiative.product' THEN 'project.product'
|
||||
WHEN 'initiative.dispute_case' THEN 'project.dispute_case'
|
||||
WHEN 'initiative.content_project' THEN 'project.content_project'
|
||||
ELSE 'project.generic'
|
||||
END
|
||||
FROM initiatives i
|
||||
WHERE p.initiative_id = i.id
|
||||
AND p.tenant_id = i.tenant_id
|
||||
AND p.archetype_key IS NULL;
|
||||
|
|
@ -124,6 +124,7 @@ def create_initiative(
|
|||
tenant_id=tenant_id,
|
||||
initiative_id=row["id"],
|
||||
user_id=user_id,
|
||||
archetype_key=archetype_key,
|
||||
)
|
||||
return row
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from psycopg2.extras import RealDictCursor
|
|||
|
||||
from db import get_connection
|
||||
from services.audit import log_audit
|
||||
from entity_archetypes import mirror_project_archetype_key, validate_archetype_key
|
||||
from services.initiatives import get_initiative
|
||||
|
||||
ProjectStatus = Literal["active", "paused", "completed", "archived"]
|
||||
|
|
@ -21,7 +22,7 @@ MAX_PROJECT_DEPTH = 5
|
|||
|
||||
_PROJECT_COLUMNS = """
|
||||
id, tenant_id, initiative_id, parent_project_id, container_kind,
|
||||
title, description, status,
|
||||
archetype_key, title, description, status,
|
||||
roadmap_item_id, sort_order, target_date, created_at, updated_at
|
||||
"""
|
||||
|
||||
|
|
@ -227,6 +228,7 @@ def create_project(
|
|||
roadmap_item_id: Optional[str] = None,
|
||||
sort_order: int = 0,
|
||||
target_date: Optional[date] = None,
|
||||
archetype_key: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
) -> dict[str, Any]:
|
||||
title = title.strip()
|
||||
|
|
@ -234,9 +236,15 @@ def create_project(
|
|||
raise ValueError("Titel ist erforderlich")
|
||||
_validate_status(status)
|
||||
_validate_container_kind(container_kind)
|
||||
if not get_initiative(tenant_id=tenant_id, initiative_id=initiative_id):
|
||||
initiative = get_initiative(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||
if not initiative:
|
||||
raise ValueError("Initiative nicht gefunden")
|
||||
|
||||
resolved_archetype = archetype_key or mirror_project_archetype_key(
|
||||
initiative["archetype_key"]
|
||||
)
|
||||
validate_archetype_key(entity_type="project", archetype_key=resolved_archetype)
|
||||
|
||||
conn = get_connection()
|
||||
try:
|
||||
with conn.cursor(cursor_factory=RealDictCursor) as cur:
|
||||
|
|
@ -257,10 +265,10 @@ def create_project(
|
|||
f"""
|
||||
INSERT INTO projects (
|
||||
tenant_id, initiative_id, parent_project_id, container_kind,
|
||||
title, description, status,
|
||||
archetype_key, title, description, status,
|
||||
roadmap_item_id, sort_order, target_date
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
RETURNING {_PROJECT_COLUMNS}
|
||||
""",
|
||||
(
|
||||
|
|
@ -268,6 +276,7 @@ def create_project(
|
|||
initiative_id,
|
||||
parent_project_id,
|
||||
container_kind,
|
||||
resolved_archetype,
|
||||
title,
|
||||
description,
|
||||
status,
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ def ensure_steering_context(
|
|||
initiative_id: str,
|
||||
initial_state: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
method_key: Optional[str] = None,
|
||||
lifecycle_metadata: Optional[dict[str, Any]] = None,
|
||||
) -> dict[str, Any]:
|
||||
existing = get_steering_context(tenant_id=tenant_id, initiative_id=initiative_id)
|
||||
if existing:
|
||||
|
|
@ -113,6 +115,16 @@ def ensure_steering_context(
|
|||
)
|
||||
validate_lifecycle_state(state)
|
||||
|
||||
resolved_method = method_key or DEFAULT_METHOD_KEY
|
||||
from steering.methods.registry import get_method
|
||||
|
||||
method = get_method(resolved_method)
|
||||
if not method:
|
||||
resolved_method = DEFAULT_METHOD_KEY
|
||||
method = get_method(resolved_method)
|
||||
method_version = method.version if method else DEFAULT_METHOD_VERSION
|
||||
metadata = lifecycle_metadata or {}
|
||||
|
||||
conn = get_connection()
|
||||
try:
|
||||
with conn.cursor(cursor_factory=RealDictCursor) as cur:
|
||||
|
|
@ -129,10 +141,10 @@ def ensure_steering_context(
|
|||
(
|
||||
tenant_id,
|
||||
initiative_id,
|
||||
DEFAULT_METHOD_KEY,
|
||||
DEFAULT_METHOD_VERSION,
|
||||
resolved_method,
|
||||
method_version,
|
||||
state,
|
||||
Json({}),
|
||||
Json(metadata),
|
||||
),
|
||||
)
|
||||
row = _serialize_row(dict(cur.fetchone()))
|
||||
|
|
@ -144,7 +156,11 @@ def ensure_steering_context(
|
|||
"steering_context.created",
|
||||
user_id=user_id,
|
||||
tenant_id=tenant_id,
|
||||
details={"initiative_id": initiative_id, "lifecycle_state": state},
|
||||
details={
|
||||
"initiative_id": initiative_id,
|
||||
"lifecycle_state": state,
|
||||
"method_key": resolved_method,
|
||||
},
|
||||
)
|
||||
return row
|
||||
|
||||
|
|
@ -250,10 +266,25 @@ def create_context_for_new_initiative(
|
|||
tenant_id: str,
|
||||
initiative_id: str,
|
||||
user_id: Optional[str] = None,
|
||||
archetype_key: str = "initiative.generic",
|
||||
method_profile_key: Optional[str] = None,
|
||||
) -> dict[str, Any]:
|
||||
from entity_archetypes.registry import resolve_default_method_key
|
||||
from method_profiles.registry import resolve_method_for_profile
|
||||
|
||||
method_key = resolve_default_method_key(archetype_key)
|
||||
lifecycle_metadata: dict[str, Any] = {}
|
||||
if method_profile_key:
|
||||
profile_method = resolve_method_for_profile(method_profile_key)
|
||||
if profile_method:
|
||||
method_key = profile_method
|
||||
lifecycle_metadata["method_profile_key"] = method_profile_key
|
||||
|
||||
return ensure_steering_context(
|
||||
tenant_id=tenant_id,
|
||||
initiative_id=initiative_id,
|
||||
initial_state="intake",
|
||||
user_id=user_id,
|
||||
method_key=method_key,
|
||||
lifecycle_metadata=lifecycle_metadata or None,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
"""Adaptive Steering Core — AP1.0 Foundation."""
|
||||
"""Adaptive Steering Core — AP1.0 Foundation + AP2.0 methods."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.hooks.registry import register_builtin_hooks
|
||||
from steering.methods.registrations import generic_operating, product_milestone_driven
|
||||
from steering.methods.registrations import (
|
||||
ap20_method_stubs,
|
||||
continuous_product,
|
||||
generic_operating,
|
||||
product_milestone_driven,
|
||||
program_delivery,
|
||||
)
|
||||
from steering.strategies.next_action import register_builtin_strategies
|
||||
|
||||
|
||||
|
|
@ -13,6 +19,9 @@ def bootstrap_steering() -> None:
|
|||
register_builtin_strategies()
|
||||
generic_operating.register()
|
||||
product_milestone_driven.register()
|
||||
program_delivery.register()
|
||||
continuous_product.register()
|
||||
ap20_method_stubs.register()
|
||||
|
||||
|
||||
bootstrap_steering()
|
||||
|
|
|
|||
70
backend/steering/methods/registrations/_helpers.py
Normal file
70
backend/steering/methods/registrations/_helpers.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"""Shared registration helper for AP2.0 method stubs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.lifecycle.states import STANDARD_LIFECYCLE_STEPS
|
||||
from steering.methods.registry import MethodDefinition, get_method, register_method
|
||||
|
||||
_PRODUCT_LIKE_STEPS = (
|
||||
"intake",
|
||||
"method_selection",
|
||||
"structure_setup",
|
||||
"planning",
|
||||
"action_selection",
|
||||
"assignment",
|
||||
"waiting",
|
||||
"result_intake",
|
||||
"validation",
|
||||
"review",
|
||||
"adaptation",
|
||||
"closure",
|
||||
)
|
||||
|
||||
_LIGHT_STEPS = (
|
||||
"intake",
|
||||
"structure_setup",
|
||||
"action_selection",
|
||||
"assignment",
|
||||
"waiting",
|
||||
"review",
|
||||
"adaptation",
|
||||
"closure",
|
||||
)
|
||||
|
||||
|
||||
def register_stub_method(
|
||||
*,
|
||||
key: str,
|
||||
label: str,
|
||||
description: str,
|
||||
next_action_strategy_key: str = "default",
|
||||
lifecycle_steps: tuple[str, ...] | None = None,
|
||||
) -> None:
|
||||
if get_method(key):
|
||||
return
|
||||
register_method(
|
||||
MethodDefinition(
|
||||
key=key,
|
||||
version="0.1.0",
|
||||
label=label,
|
||||
description=description,
|
||||
default_lifecycle_steps=lifecycle_steps or STANDARD_LIFECYCLE_STEPS,
|
||||
next_action_strategy_key=next_action_strategy_key,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def register_product_like_method(
|
||||
*,
|
||||
key: str,
|
||||
label: str,
|
||||
description: str,
|
||||
next_action_strategy_key: str,
|
||||
) -> None:
|
||||
register_stub_method(
|
||||
key=key,
|
||||
label=label,
|
||||
description=description,
|
||||
next_action_strategy_key=next_action_strategy_key,
|
||||
lifecycle_steps=_PRODUCT_LIKE_STEPS,
|
||||
)
|
||||
50
backend/steering/methods/registrations/ap20_method_stubs.py
Normal file
50
backend/steering/methods/registrations/ap20_method_stubs.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"""AP2.0a — remaining method stubs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.methods.registrations._helpers import register_stub_method
|
||||
|
||||
|
||||
def register() -> None:
|
||||
register_stub_method(
|
||||
key="maturity_progression",
|
||||
label="Reifegrad-Entwicklung",
|
||||
description="Stufen, Routinen, historische Entwicklung",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
register_stub_method(
|
||||
key="sequential_dependency",
|
||||
label="Sequenzielle Abhängigkeit",
|
||||
description="Graph-Pfade, kritischer Pfad (read model)",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
register_stub_method(
|
||||
key="recurring_control",
|
||||
label="Rhythmus-Steuerung",
|
||||
description="Dauerprogramm, fällig/überfällig, Abweichungen",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
register_stub_method(
|
||||
key="queue_pull",
|
||||
label="Inbox / Queue",
|
||||
description="Pull oder Empfehlung aus Queue",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
register_stub_method(
|
||||
key="agile_iteration",
|
||||
label="Iterations-Zeitbox",
|
||||
description="Sprint/work_cycle Profil auf Product/Programm",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
register_stub_method(
|
||||
key="dispute_procedure",
|
||||
label="Verfahren / Konflikt",
|
||||
description="Reaktive Steuerung, Fristen, Entscheidungen",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
register_stub_method(
|
||||
key="chapter_based_progression",
|
||||
label="Kapitel-Entwicklung",
|
||||
description="Inhaltliche Progression, Reviews",
|
||||
next_action_strategy_key="default",
|
||||
)
|
||||
14
backend/steering/methods/registrations/continuous_product.py
Normal file
14
backend/steering/methods/registrations/continuous_product.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
"""Built-in method: continuous_product — AP2.0a."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.methods.registrations._helpers import register_product_like_method
|
||||
|
||||
|
||||
def register() -> None:
|
||||
register_product_like_method(
|
||||
key="continuous_product",
|
||||
label="Produkt (kontinuierlich)",
|
||||
description="Kontinuierlicher Betrieb — Ist zuerst, Plan als Orientierung",
|
||||
next_action_strategy_key="continuous_product",
|
||||
)
|
||||
14
backend/steering/methods/registrations/program_delivery.py
Normal file
14
backend/steering/methods/registrations/program_delivery.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
"""Built-in method: program_delivery — AP2.0a."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.methods.registrations._helpers import register_product_like_method
|
||||
|
||||
|
||||
def register() -> None:
|
||||
register_product_like_method(
|
||||
key="program_delivery",
|
||||
label="Programm (begrenzt)",
|
||||
description="Meilenstein- und gate-orientierte Steuerung mit Abschluss",
|
||||
next_action_strategy_key="program_delivery",
|
||||
)
|
||||
|
|
@ -2,10 +2,18 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.strategies.next_action.continuous_product import (
|
||||
continuous_product_strategy,
|
||||
register_continuous_product_strategy,
|
||||
)
|
||||
from steering.strategies.next_action.default_strategy import default_strategy
|
||||
from steering.strategies.next_action.product_milestone_driven import (
|
||||
product_milestone_strategy,
|
||||
)
|
||||
from steering.strategies.next_action.program_delivery import (
|
||||
program_delivery_strategy,
|
||||
register_program_delivery_strategy,
|
||||
)
|
||||
from steering.strategies.next_action.registry import (
|
||||
get_next_action_strategy,
|
||||
register_next_action_strategy,
|
||||
|
|
@ -16,3 +24,5 @@ def register_builtin_strategies() -> None:
|
|||
for strategy in (default_strategy, product_milestone_strategy):
|
||||
if not get_next_action_strategy(strategy.key):
|
||||
register_next_action_strategy(strategy)
|
||||
register_program_delivery_strategy()
|
||||
register_continuous_product_strategy()
|
||||
|
|
|
|||
114
backend/steering/strategies/next_action/continuous_product.py
Normal file
114
backend/steering/strategies/next_action/continuous_product.py
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
"""Continuous product NextAction strategy — AP2.0a (Ist zuerst)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from db import get_connection
|
||||
from psycopg2.extras import RealDictCursor
|
||||
from steering.signals import default_rules
|
||||
from steering.strategies.next_action.default_strategy import DefaultNextActionStrategy
|
||||
from steering.strategies.next_action.registry import (
|
||||
get_next_action_strategy,
|
||||
register_next_action_strategy,
|
||||
)
|
||||
from tenant_context import TenantContext
|
||||
|
||||
_default = DefaultNextActionStrategy()
|
||||
|
||||
_OPEN_ACTION = ("open", "ready", "in_progress", "blocked", "review_required")
|
||||
|
||||
|
||||
class ContinuousProductStrategy:
|
||||
key = "continuous_product"
|
||||
|
||||
def evaluate(
|
||||
self,
|
||||
ctx: TenantContext,
|
||||
*,
|
||||
initiative_id: str | None = None,
|
||||
limit: int = 10,
|
||||
) -> list[dict[str, Any]]:
|
||||
if limit < 1:
|
||||
limit = 1
|
||||
if not initiative_id:
|
||||
return _default.evaluate(ctx, limit=limit)
|
||||
|
||||
candidates: list[dict[str, Any]] = []
|
||||
conn = get_connection()
|
||||
try:
|
||||
with conn.cursor(cursor_factory=RealDictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT
|
||||
'action' AS kind,
|
||||
a.title AS title,
|
||||
'Offenes Arbeitspaket priorisieren' AS summary,
|
||||
a.initiative_id,
|
||||
a.id AS action_id,
|
||||
NULL::uuid AS backlog_item_id,
|
||||
'open_action_priority' AS reason_code,
|
||||
'Als Nächstes ausführen' AS recommended_action
|
||||
FROM actions a
|
||||
WHERE a.tenant_id = %s AND a.initiative_id = %s
|
||||
AND a.status = ANY(%s)
|
||||
ORDER BY
|
||||
CASE a.status
|
||||
WHEN 'blocked' THEN 0
|
||||
WHEN 'review_required' THEN 1
|
||||
WHEN 'in_progress' THEN 2
|
||||
WHEN 'ready' THEN 3
|
||||
ELSE 4
|
||||
END,
|
||||
CASE a.priority WHEN 'critical' THEN 0 WHEN 'high' THEN 1 ELSE 2 END,
|
||||
a.due_at ASC NULLS LAST,
|
||||
a.updated_at DESC
|
||||
LIMIT %s
|
||||
""",
|
||||
(ctx.tenant_id, initiative_id, list(_OPEN_ACTION), limit),
|
||||
)
|
||||
for row in cur.fetchall():
|
||||
item = dict(row)
|
||||
item["initiative_id"] = str(item["initiative_id"])
|
||||
item["action_id"] = str(item["action_id"])
|
||||
candidates.append(item)
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
remaining = limit - len(candidates)
|
||||
if remaining > 0:
|
||||
from steering.strategies.next_action.product_milestone_driven import (
|
||||
ProductMilestoneDrivenStrategy,
|
||||
)
|
||||
|
||||
gate_items = ProductMilestoneDrivenStrategy().evaluate(
|
||||
ctx, initiative_id=initiative_id, limit=remaining
|
||||
)
|
||||
for item in gate_items:
|
||||
if item.get("kind") == "review_milestone":
|
||||
candidates.append(item)
|
||||
remaining -= 1
|
||||
if remaining <= 0:
|
||||
break
|
||||
|
||||
if len(candidates) < limit:
|
||||
rest = default_rules.get_next_action_candidates_for_initiative(
|
||||
ctx, initiative_id=initiative_id, limit=limit - len(candidates)
|
||||
)
|
||||
seen = {c.get("action_id") for c in candidates if c.get("action_id")}
|
||||
for item in rest:
|
||||
if item.get("action_id") and item["action_id"] in seen:
|
||||
continue
|
||||
candidates.append(item)
|
||||
if len(candidates) >= limit:
|
||||
break
|
||||
|
||||
return candidates[:limit]
|
||||
|
||||
|
||||
continuous_product_strategy = ContinuousProductStrategy()
|
||||
|
||||
|
||||
def register_continuous_product_strategy() -> None:
|
||||
if not get_next_action_strategy(continuous_product_strategy.key):
|
||||
register_next_action_strategy(continuous_product_strategy)
|
||||
28
backend/steering/strategies/next_action/program_delivery.py
Normal file
28
backend/steering/strategies/next_action/program_delivery.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
"""Program delivery NextAction strategy — AP2.0a (Gate-Horizont)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from steering.strategies.next_action.product_milestone_driven import (
|
||||
ProductMilestoneDrivenStrategy,
|
||||
)
|
||||
from steering.strategies.next_action.registry import (
|
||||
get_next_action_strategy,
|
||||
register_next_action_strategy,
|
||||
)
|
||||
|
||||
_strategy = ProductMilestoneDrivenStrategy()
|
||||
|
||||
|
||||
class ProgramDeliveryStrategy:
|
||||
key = "program_delivery"
|
||||
|
||||
def evaluate(self, ctx, *, initiative_id=None, limit=10):
|
||||
return _strategy.evaluate(ctx, initiative_id=initiative_id, limit=limit)
|
||||
|
||||
|
||||
program_delivery_strategy = ProgramDeliveryStrategy()
|
||||
|
||||
|
||||
def register_program_delivery_strategy() -> None:
|
||||
if not get_next_action_strategy(program_delivery_strategy.key):
|
||||
register_next_action_strategy(program_delivery_strategy)
|
||||
|
|
@ -49,7 +49,11 @@ def test_list_entity_archetypes(client):
|
|||
)
|
||||
assert res.status_code == 200
|
||||
keys = {item["key"] for item in res.json()}
|
||||
assert keys == {"initiative.generic", "initiative.program", "initiative.product"}
|
||||
assert "initiative.generic" in keys
|
||||
assert "initiative.program" in keys
|
||||
assert "initiative.product" in keys
|
||||
assert "initiative.maturity_journey" in keys
|
||||
assert "initiative.content_project" in keys
|
||||
|
||||
|
||||
def test_invalid_archetype_rejected(client):
|
||||
|
|
|
|||
104
backend/tests/test_ap20_steering_archetypes.py
Normal file
104
backend/tests/test_ap20_steering_archetypes.py
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
"""AP2.0 — Method registry, Archetyp defaults, Project mirror."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from auth import AUTH_HEADER
|
||||
from steering.methods.registry import list_methods
|
||||
from tests.factories import provision_user_in_tenant
|
||||
from tests.test_initiatives_actions import _auth, _create_initiative, _login
|
||||
|
||||
|
||||
def test_ap20_all_methods_registered():
|
||||
keys = {m.key for m in list_methods()}
|
||||
assert "generic_operating" in keys
|
||||
assert "product_milestone_driven" in keys
|
||||
assert "program_delivery" in keys
|
||||
assert "continuous_product" in keys
|
||||
assert "maturity_progression" in keys
|
||||
assert "chapter_based_progression" in keys
|
||||
assert "agile_iteration" in keys
|
||||
|
||||
|
||||
def test_product_initiative_gets_continuous_product_method(client):
|
||||
user = provision_user_in_tenant(tenant_role="member")
|
||||
token = _login(client, user)
|
||||
|
||||
created = _create_initiative(
|
||||
client,
|
||||
token,
|
||||
title="Kairo Product",
|
||||
archetype_key="initiative.product",
|
||||
)
|
||||
assert created.status_code == 201
|
||||
initiative_id = created.json()["id"]
|
||||
|
||||
snap = client.get(
|
||||
f"/api/initiatives/{initiative_id}/steering-snapshot",
|
||||
headers=_auth(token),
|
||||
)
|
||||
assert snap.status_code == 200
|
||||
body = snap.json()
|
||||
assert body["method_key"] == "continuous_product"
|
||||
assert body["archetype_key"] == "initiative.product"
|
||||
assert body.get("archetype_label")
|
||||
assert body.get("steering_guidance")
|
||||
|
||||
|
||||
def test_program_initiative_gets_program_delivery_method(client):
|
||||
user = provision_user_in_tenant(tenant_role="member")
|
||||
token = _login(client, user)
|
||||
|
||||
created = _create_initiative(
|
||||
client,
|
||||
token,
|
||||
title="Release Program",
|
||||
archetype_key="initiative.program",
|
||||
)
|
||||
assert created.status_code == 201
|
||||
initiative_id = created.json()["id"]
|
||||
|
||||
ctx = client.get(
|
||||
f"/api/steering/initiatives/{initiative_id}/context",
|
||||
headers=_auth(token),
|
||||
)
|
||||
assert ctx.status_code == 200
|
||||
assert ctx.json()["method_key"] == "program_delivery"
|
||||
|
||||
|
||||
def test_project_inherits_mirror_archetype(client):
|
||||
user = provision_user_in_tenant(tenant_role="member")
|
||||
token = _login(client, user)
|
||||
|
||||
created = _create_initiative(
|
||||
client,
|
||||
token,
|
||||
title="Mirror Test",
|
||||
archetype_key="initiative.product",
|
||||
)
|
||||
initiative_id = created.json()["id"]
|
||||
|
||||
project = client.post(
|
||||
f"/api/initiatives/{initiative_id}/projects",
|
||||
json={"title": "Product Stream"},
|
||||
headers=_auth(token),
|
||||
)
|
||||
assert project.status_code == 201
|
||||
assert project.json()["archetype_key"] == "project.product"
|
||||
|
||||
|
||||
def test_entity_archetypes_include_ap20_portfolio(client):
|
||||
user = provision_user_in_tenant(tenant_role="member")
|
||||
token = _login(client, user)
|
||||
|
||||
res = client.get(
|
||||
"/api/entity-archetypes?entity_type=initiative",
|
||||
headers=_auth(token),
|
||||
)
|
||||
assert res.status_code == 200
|
||||
keys = {item["key"] for item in res.json()}
|
||||
assert "initiative.maturity_journey" in keys
|
||||
assert "initiative.content_project" in keys
|
||||
assert "initiative.product" in keys
|
||||
|
||||
sample = next(i for i in res.json() if i["key"] == "initiative.product")
|
||||
assert sample.get("default_method_key") == "continuous_product"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
APP_VERSION = "0.17.0-ap1.5d"
|
||||
DB_SCHEMA_VERSION = "018"
|
||||
APP_VERSION = "0.18.0-ap2.0"
|
||||
DB_SCHEMA_VERSION = "019"
|
||||
APP_NAME = "jinkendo-kairo"
|
||||
|
|
|
|||
303
docs/architecture/ADP_Archetype_and_Method_Catalog_v0.1.md
Normal file
303
docs/architecture/ADP_Archetype_and_Method_Catalog_v0.1.md
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
# ADP — Archetyp- & Methoden-Katalog v0.1
|
||||
|
||||
> **⚠ Superseded (2026-07-10):** Verwende [`ADP_Archetype_and_Method_Catalog_v0.2.md`](ADP_Archetype_and_Method_Catalog_v0.2.md) — enthält B3 Agile Iteration, Steuerungs-Matrix, Sprint-Semantik.
|
||||
|
||||
**Status:** superseded — siehe v0.2
|
||||
**Stand:** 2026-07-10
|
||||
**Bezug:** `Kairo_MVP_Definition_v0.3.md`, `ADP_AP1_10_Initiative_Archetypes_and_Entity_Field_System_v0.1.md`, `Kairo_Method_Design_Principles_v0.1.md`
|
||||
**Auslöser:** Vorhaben jenseits von Software (Gewohnheit, Haushalt, Queue, Verfahren); Archetypen auf Initiative- **und** Project-Ebene; Steuerung methodengebunden
|
||||
|
||||
---
|
||||
|
||||
## 1. Problem
|
||||
|
||||
Heute:
|
||||
|
||||
- `archetype_key` nur auf **Initiative**, drei Seeds (`generic`, `program`, `product`) — Dev-Sprache
|
||||
- Archetyp ändert **Felder**, nicht **Steuerungsmethode**, Plan-Sicht oder Next-Action-Logik
|
||||
- `project.archetype_key` **deferred** (ADP AP1.10)
|
||||
- Nutzer mit heterogenem Portfolio (privat + beruflich) sieht **eine flache Vorhabenliste** und keine methodengerechte Führung
|
||||
|
||||
**Ziel:** Archetyp = Eintritt in ein **Steuerungspaket** (Methode + Struktur-Empfehlung + UI-Profil + EFS), nicht nur Label.
|
||||
|
||||
---
|
||||
|
||||
## 2. Entscheidung
|
||||
|
||||
### 2.1 Zwei Registry-Ebenen
|
||||
|
||||
| Ebene | Tabelle / Registry | Zweck |
|
||||
|-------|-------------------|--------|
|
||||
| **Initiative-Archetyp** | `entity_archetypes` + EFS | Welches **Programm/Vorhaben** ist das? Default-`method_key`, Profilfelder |
|
||||
| **Project-Archetyp** | `entity_archetypes` (`entity_type=project`) + EFS | Welche **Rolle** hat dieser Strang im Vorhaben? |
|
||||
|
||||
Bestehende Initiativen: Default `initiative.generic` + `generic_operating` — unverändert.
|
||||
|
||||
### 2.2 Archetyp bindet Default-Methode
|
||||
|
||||
Jeder Initiative-Archetyp referenziert genau eine **Default-Steuerungsmethode** (`steering_context.method_key`). Nutzer kann später wechseln (mit Audit), MVP: Default reicht.
|
||||
|
||||
Methoden sind **registrierte Pakete** in `backend/steering/methods/` — keine Hardcodierung in React.
|
||||
|
||||
### 2.3 UI-Profil (kein neues OM-Objekt)
|
||||
|
||||
Pro Archetyp: **dominante Modus-Ansichten** und **versteckte** Patterns (z. B. Queue zeigt Pull-Queue, nicht Gate-Graph).
|
||||
|
||||
Speicherung MVP: Seed-JSON in Registry-Sync (`ui_profile_json`), nicht ad-hoc im Frontend.
|
||||
|
||||
---
|
||||
|
||||
## 3. Katalog — Initiative-Archetypen
|
||||
|
||||
| `archetype_key` | Label (DE) | Beispiel | Default-Methode | MVP-Stufe |
|
||||
|-----------------|------------|----------|-------------------|-----------|
|
||||
| `initiative.generic` | Allgemeines Vorhaben | Fallback | `generic_operating` | ✓ (bestehend) |
|
||||
| `initiative.maturity_journey` | Reifegrad-Entwicklung | Spagat können | `maturity_progression` | **A** |
|
||||
| `initiative.linear_project` | Lineares Vorhaben | Neue Küche | `sequential_dependency` | **A** |
|
||||
| `initiative.recurring_program` | Dauerprogramm / Rhythmus | Haus in Ordnung | `recurring_control` | **B** |
|
||||
| `initiative.support_queue` | Queue / Supportdesk | Tickets, Pool | `queue_pull` | **B** |
|
||||
| `initiative.program` | Programm / Mega-Vorhaben | Kairo Gesamt | `product_milestone_driven` | **A** (bestehend, umbenannt semantisch) |
|
||||
| `initiative.product` | Produkt / Release | Release-Track | `product_milestone_driven` | **B** |
|
||||
| `initiative.dispute_case` | Verfahren / Konflikt | Miterstreit | `dispute_procedure` | **C** (Katalog) |
|
||||
|
||||
**Hinweis:** `initiative.program` / `initiative.product` bleiben technisch; semantisch = agile/technische Entwicklung (B2).
|
||||
|
||||
---
|
||||
|
||||
## 4. Katalog — Project-Archetypen
|
||||
|
||||
| `archetype_key` | Label (DE) | Typische Initiative | Rolle |
|
||||
|-----------------|------------|---------------------|--------|
|
||||
| `project.generic` | Allgemeines Projekt | alle | Standard-Container |
|
||||
| `project.maturity_lane` | Reifegrad-Spur | maturity_journey | Übungs-/Entwicklungsspur pro Körperregion o.ä. |
|
||||
| `project.primary_chain` | Primärstrang | linear_project | Kritischer Pfad (Wasserfall-Hauptlinie) |
|
||||
| `project.companion_track` | Begleitstrang | linear_project | Parallele Nebenaktivitäten |
|
||||
| `project.recurring_domain` | Bereich mit Rhythmus | recurring_program | Küche, Garten, Kind — Recurring-Owner |
|
||||
| `project.queue_stream` | Ticket-Strom | support_queue | Kategorie/Team-Queue |
|
||||
| `project.release_stream` | Release/Phase | program, product | Technischer Strang |
|
||||
| `project.dispute_track` | Verfahrensstrang | dispute_case | z. B. „Gericht“, „Mediation“ |
|
||||
|
||||
Migration: `projects.archetype_key VARCHAR(64) DEFAULT 'project.generic'` (AP2.0b).
|
||||
|
||||
---
|
||||
|
||||
## 5. Steuerungsmethoden (Registry-Ziel)
|
||||
|
||||
| `method_key` | Status heute | Kurzbeschreibung | Next-Action-Fokus |
|
||||
|--------------|--------------|------------------|-------------------|
|
||||
| `generic_operating` | ✓ registriert | Leichte Struktur, Gates optional | offene Actions, Backlog-Triage |
|
||||
| `product_milestone_driven` | ✓ registriert | Gate-horizont, Meilenstein | Gate + offene AP am Gate |
|
||||
| `maturity_progression` | ○ Ziel | Reifegrad-Stufen, Übungswechsel | **heutige Übung** + Stufen-Kriterium |
|
||||
| `sequential_dependency` | ○ Ziel | Linearer Graph, Begleitstränge | **nächster freier Schritt** am kritischen Pfad |
|
||||
| `recurring_control` | ○ Ziel | Dauerprogramm, Assignments | **fällig / überfällig** pro Actor, nicht Gesamtliste |
|
||||
| `queue_pull` | ○ Ziel | Pool, Selbstwahl oder Empfehlung | **1 Empfehlung** oder gewähltes Item |
|
||||
| `dispute_procedure` | ○ Katalog | Phasen, Fristen, Iterationen | **nächste Frist / Entscheidung** |
|
||||
|
||||
Neue Methoden: nur via `steering/methods/registrations/*.py` + Tests — siehe `Kairo_Method_Design_Principles_v0.1.md`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Archetyp-Detail (PO-Spezifikation)
|
||||
|
||||
### A1 — `initiative.maturity_journey` (Spagat)
|
||||
|
||||
**Plan:**
|
||||
|
||||
- `RoadmapItem` mit `item_type=maturity_stage` (Reifegrad-Stufen)
|
||||
- Kriterien pro Stufe (Checkliste AP1.4b)
|
||||
|
||||
**Ist:**
|
||||
|
||||
- `RecurringElement` für Übungsroutine **pro Stufe**
|
||||
- Bei Verify `reached` → Recurring-Set wechseln (Hook/Service, AP2.0d)
|
||||
|
||||
**Steuerung:**
|
||||
|
||||
- Next Action: heutige Recurring-Instanz + Hinweis „Stufe X, Kriterium Y offen“
|
||||
- Attention: Stagnation (keine Recurring-Erfüllung), Stufe ohne Fortschritt
|
||||
|
||||
**EFS (Seed):**
|
||||
|
||||
- `current_body_focus` (text), `training_frequency` (enum), `progress_notes` (longtext)
|
||||
|
||||
**UI-Profil:** Kontrolle dominant; Plan = Stufen; Ausführen = heute; Gates-Graph **aus**
|
||||
|
||||
---
|
||||
|
||||
### A2 — `initiative.linear_project` (Küche)
|
||||
|
||||
**Plan:**
|
||||
|
||||
- `project.primary_chain` + `project.companion_track`
|
||||
- Gates entlang Primärstrang; `roadmap_item_dependencies` (AP1.4d/13)
|
||||
|
||||
**Ist:**
|
||||
|
||||
- Actions an Blatt-Projects / Initiative
|
||||
- Begleit-APs parallel
|
||||
|
||||
**Steuerung:**
|
||||
|
||||
- Next Action: nächster **ready** Schritt am kritischen Pfad (Graph Engine read model)
|
||||
- Attention: Blocker auf Pfad, Gate at risk, überfälliges `target_date`
|
||||
|
||||
**EFS:**
|
||||
|
||||
- `budget_summary`, `primary_contractor`, `target_completion` (date)
|
||||
|
||||
**UI-Profil:** Plan (Graph/Liste) + Kontrolle; Recurring **aus**
|
||||
|
||||
---
|
||||
|
||||
### A3 — `initiative.recurring_program` (Haus)
|
||||
|
||||
**Plan:**
|
||||
|
||||
- optional `project.recurring_domain` pro Bereich/Person
|
||||
- wenig / keine Gates (`generic_operating`-light)
|
||||
|
||||
**Ist:**
|
||||
|
||||
- `RecurringElement` + `ActionAssignment` pro Familien-Actor
|
||||
- Roll-up: überfällige Recurring → Attention
|
||||
|
||||
**Steuerung:**
|
||||
|
||||
- Next Action: **eigene** fällige Recurring (+ optional eine aus Pool „Haus“)
|
||||
- Cockpit: wer ist überfällig — **nicht** alle Tasks aller Personen
|
||||
|
||||
**EFS:**
|
||||
|
||||
- `household_members` (longtext / später actor_ref_list), `cadence_default` (enum)
|
||||
|
||||
**UI-Profil:** Ausführen + Team; Plan minimal
|
||||
|
||||
---
|
||||
|
||||
### B1 — `initiative.support_queue` (Supportdesk)
|
||||
|
||||
**Plan:**
|
||||
|
||||
- flacher Eingang → triage → Queue
|
||||
- optional `project.queue_stream` pro Kategorie
|
||||
|
||||
**Ist:**
|
||||
|
||||
- Actions als Tickets; Status open/ready/in_progress
|
||||
- Actor-Gruppe: Pull-Berechtigung
|
||||
|
||||
**Steuerung:**
|
||||
|
||||
- Next Action: **Empfehlung** aus Queue-Strategie oder selbst gewählt (Pull)
|
||||
- Attention: SLA, unassigned high-priority
|
||||
|
||||
**EFS:**
|
||||
|
||||
- `queue_policy` (enum: pull, assign, hybrid), `sla_hours` (number)
|
||||
|
||||
**UI-Profil:** Ausführen (Queue) dominant; Plan = Eingang
|
||||
|
||||
---
|
||||
|
||||
### B2 — `initiative.program` / `initiative.product` (Agile / Kairo)
|
||||
|
||||
Bestehendes Modell — im Katalog **explizit** als technische Entwicklung verankert, nicht als einziger Typ.
|
||||
|
||||
**UI-Profil:** Plan (Gates) + Kontrolle (Snapshot) + Ausführen
|
||||
|
||||
---
|
||||
|
||||
### C1 — `initiative.dispute_case` (Miterstreit)
|
||||
|
||||
**Plan:**
|
||||
|
||||
- Phasen-Gates: Auslöser → Reaktion → … → Einigung → Abschluss
|
||||
- Iterationen (Reopen / neue Runde) mit Decision-Pflicht
|
||||
|
||||
**Ist:**
|
||||
|
||||
- Decisions (Argumentationsketten), Evidence (Dokumente), Fristen auf Gates/Actions
|
||||
- optional `project.dispute_track` (Anwalt, Gericht, Mediation)
|
||||
|
||||
**Steuerung:**
|
||||
|
||||
- Next Action: **nächste Frist** oder **offene Entscheidung**
|
||||
- Attention: Frist läuft ab, fehlende Evidence
|
||||
|
||||
**EFS:**
|
||||
|
||||
- `counterparty`, `legal_counsel_actor_ref`, `next_deadline` (date), `case_reference` (text)
|
||||
|
||||
**MVP-Stufe C:** Katalog + Profilfelder + generische Gates; spezialisierte UI post-MVP
|
||||
|
||||
---
|
||||
|
||||
## 7. Plan-/Ist-Muster (übergreifend)
|
||||
|
||||
```text
|
||||
Eingang Plan (optional) Ist Steuerung
|
||||
maturity_journey selten maturity_stages Recurring heutige Übung
|
||||
linear_project selten Gate-Graph Actions kritischer Pfad
|
||||
recurring_program selten Domains Recurring fällig/heute
|
||||
support_queue triage Queue-Streams Actions Pull/Empfehlung
|
||||
program/product Backlog Gates Actions+Tasks Gate+Next AP
|
||||
dispute_case Eingang Phasen-Gates Decisions+Ev. Frist/Entscheidung
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Scope Lock
|
||||
|
||||
| Verboten | Erlaubt |
|
||||
|----------|---------|
|
||||
| React-Formulare pro Archetyp hardcoden | FieldRenderer + Registry |
|
||||
| OM-Tabelle `disputes`, `habits`, … | EFS + bestehende OM-Entitäten |
|
||||
| Steering-Heuristiken in Routern | `backend/steering/` |
|
||||
| Alle Methoden voll implementieren vor A-Abnahme | Stubs + A1/A2/B2 zuerst |
|
||||
| Archetyp ohne `method_key`-Bindung | Seed + Sync |
|
||||
|
||||
---
|
||||
|
||||
## 9. Implementierungspakete
|
||||
|
||||
```text
|
||||
AP2.0a Method-Stubs registrieren (4 neue + dispute stub)
|
||||
AP2.0b entity_archetypes Seeds (Initiative + Project); projects.archetype_key; EFS field_definitions
|
||||
AP2.0c Kontrolle-Lagebild: method_key, lifecycle, next action, attention (UI)
|
||||
AP2.0d Next-Action-Strategien: maturity, sequential, recurring, queue (minimal)
|
||||
AP2.0e Recurring-Stufenwechsel bei maturity_stage reached (A1)
|
||||
AP2.1 Validation Report v0.3 — Referenz A1, A2, B2 mit echten Daten
|
||||
```
|
||||
|
||||
Erweitert AP1.10 — **ersetzt nicht** EFS-Architektur, nutzt sie.
|
||||
|
||||
---
|
||||
|
||||
## 10. Risiko
|
||||
|
||||
| Risiko | Mitigation |
|
||||
|--------|------------|
|
||||
| Methoden-Overengineering | Stubs + eine Strategie pro A-Archetyp |
|
||||
| dispute_case zu groß | Stufe C, nur Katalog im MVP |
|
||||
| Recurring-Stufenwechsel komplex | AP2.0e nach A1-Grundlage |
|
||||
| Todo-Wand trotz Archetyp | MVP v0.3 UI-Regeln + Review-Pflicht |
|
||||
|
||||
---
|
||||
|
||||
## 11. PO-Freigabe
|
||||
|
||||
- [ ] Acht Initiative-Archetypen (+ generic) akzeptiert oder korrigiert
|
||||
- [ ] Project-Archetypen akzeptiert
|
||||
- [ ] Methoden-Keys akzeptiert
|
||||
- [ ] MVP-Stufen A/B/C akzeptiert
|
||||
- [ ] AP2.0-Reihenfolge freigegeben
|
||||
|
||||
---
|
||||
|
||||
## Referenzen
|
||||
|
||||
- `docs/product/Kairo_MVP_Definition_v0.3.md`
|
||||
- `docs/architecture/ADP_AP1_10_Initiative_Archetypes_and_Entity_Field_System_v0.1.md`
|
||||
- `docs/architecture/Kairo_Target_Architecture_Method_Driven_Adaptive_Steering_Core_v0.1.md`
|
||||
- `backend/steering/methods/registrations/generic_operating.py`
|
||||
- `backend/steering/methods/registrations/product_milestone_driven.py`
|
||||
601
docs/architecture/ADP_Archetype_and_Method_Catalog_v0.2.md
Normal file
601
docs/architecture/ADP_Archetype_and_Method_Catalog_v0.2.md
Normal file
|
|
@ -0,0 +1,601 @@
|
|||
# ADP — Archetyp- & Methoden-Katalog v0.2
|
||||
|
||||
**Status:** PO-freigegeben
|
||||
**Stand:** 2026-07-10 (Archetypen-, Project- und Methoden-Schichten; Vier-Schichten-Modell)
|
||||
**Bezug:** `Kairo_MVP_Definition_v0.3.md`, `ADP_AP1_10_Initiative_Archetypes_and_Entity_Field_System_v0.1.md`, `Kairo_Method_Design_Principles_v0.1.md`, `Kairo_Canonical_Operating_Model_v0.2.md`
|
||||
**Ersetzt:** `ADP_Archetype_and_Method_Catalog_v0.1.md` (Inhalt konsolidiert + B3 Agile Iteration)
|
||||
**Auslöser:** Vorhaben jenseits von Software; heterogenes Portfolio; **Agile (Backlog, Sprint, Release)** vollständig im Katalog verankern
|
||||
|
||||
---
|
||||
|
||||
## 1. Problem
|
||||
|
||||
Heute:
|
||||
|
||||
- `archetype_key` nur auf **Initiative**, drei Seeds (`generic`, `program`, `product`) — Dev-Sprache
|
||||
- Archetyp ändert **Felder**, nicht **Steuerungsmethode**, Plan-Sicht oder Next-Action-Logik
|
||||
- `project.archetype_key` **deferred** (ADP AP1.10)
|
||||
- **Agile** ist implizit in B2 (`product_milestone_driven`) — **Release-/Gate-Agile**, nicht **Iterations-Agile** (Sprint, Sprint-Backlog)
|
||||
- Nutzer mit heterogenem Portfolio sieht **eine flache Vorhabenliste** und keine methodengerechte Führung
|
||||
|
||||
**Ziel:** Generische **Archetypen** liefern den **Methodenbaukasten** (Default-Methode, Felder, UI); **Ausprägungen** konkretisieren (Buch schreiben, Kumite, …). Die **Magie** (automatische Steuerung, Monitoring, KI, Gitea, Vibe-Coder) sitzt in der **Methoden-Modulregistrierung** auf dem Standard-Framework — nicht im Archetyp hardcodiert.
|
||||
|
||||
---
|
||||
|
||||
## 2. Entscheidung
|
||||
|
||||
### 2.0 Vier Schichten — wo die Magie sitzt — **PO 2026-07-10**
|
||||
|
||||
```text
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Schicht 4 (später) Integrationen & Agenten │
|
||||
│ MCP/Vibe-Coder, Gitea, Webhooks — an Hook Slugs gebunden │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Schicht 3 Ausprägung (Method Profile / Domain Template) │
|
||||
│ „Buch schreiben“, „Karate Kumite“ — Felder, Vorbefüllung, │
|
||||
│ Kategorien, Mitwirkende, Struktur-Seeds │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Schicht 2 Generischer Archetyp (entity_archetypes + EFS) │
|
||||
│ maturity_journey, product, linear_project, … │
|
||||
│ → Default method_key, Feldprofil, UI-Profil (Methodenbaukasten)│
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Schicht 1 Methode (Method Registry — Steuerungsmodul) │
|
||||
│ register_method: Lifecycle, Hooks, Builder, Strategies, Signals│
|
||||
│ → automatische Steuerung, Planung, Monitoring, Next Action │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Schicht 0 Standard-Framework (Adaptive Steering Core) │
|
||||
│ backend/steering/, OM, TenantContext, Audit, Operational API │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Schicht | Was | MVP | Später |
|
||||
|---------|-----|-----|--------|
|
||||
| **0 Framework** | Steering Core, OM, Capabilities | ✓ Foundation | Waiting, Runtime |
|
||||
| **1 Methode** | Modul in `steering/methods/registrations/` | Stubs + 1–2 Strategien | Volle Profiles, Workflow-Fragmente |
|
||||
| **2 Archetyp** | `entity_archetypes` + EFS + `ui_profile_json` | Seeds AP2.0b | Tenant-Templates |
|
||||
| **3 Ausprägung** | `method_profile_key` + `configuration_json` + EFS-Seeds | Katalog + 1–2 Referenz-Seeds | Designer, Tenant-Kopien |
|
||||
| **4 Integration** | Hooks → MCP, Gitea, Vibe-Coder (`/api/operational/`) | **eingefroren** | KI-gestützte Steuerung |
|
||||
|
||||
**PO-Regel:** Archetyp **beschreibt den Baukasten**, Ausprägung **beschreibt die konkrete Variante**. Keine Sonder-OM-Tabellen pro Ausprägung.
|
||||
|
||||
**Beispiele Ausprägungen (Schicht 3) — referenzieren generischen Archetyp:**
|
||||
|
||||
| `profile_key` (Ziel) | Archetyp (Schicht 2) | Methode (Schicht 1) | Liefert u. a. |
|
||||
|----------------------|----------------------|----------------------|---------------|
|
||||
| `maturity.karate_kumite` | `initiative.maturity_journey` | `maturity_progression` | 8 Fähigkeiten-Seed, Stufen-Raster, Coach-Rolle |
|
||||
| `content.book_writing` | `initiative.content_project` | `chapter_based_progression` | Kapitel-Gliederung, Wortziel, Lector |
|
||||
| `product.kairo_dev` | `initiative.product` | `continuous_product` + `agile_iteration` | Gate-Set, Sprint-Cadence, Agent-Actor |
|
||||
| `recurring.household` | `initiative.recurring_program` | `recurring_control` | Domains, Score-Policy (AP2.0g) |
|
||||
|
||||
Speicherung Zielbild: `method_profiles` (tenant-scoped, siehe Target Architecture §15) + EFS `field_definitions` pro Archetyp/Profile; MVP: **Code-Seeds** in Registry-Sync.
|
||||
|
||||
**Integrationen (Schicht 4):** Methoden exponieren **Hook Slugs** (`on_next_action_requested`, `on_result_received`, …). Bindings:
|
||||
|
||||
- **Vibe-Coder / MCP** → Operational API + Hook-Handler (kein Prompt hardcoden)
|
||||
- **Gitea** → Events → `result_intake` / Journey / Gate-Verify
|
||||
- **KI** → Signal Engine / Next-Action-Vorschläge — **ersetzt nicht** Methoden-Strategie ohne Audit
|
||||
|
||||
Siehe `Kairo_Method_Design_Principles_v0.1.md`, `ADP_Operational_Actor_Interface_Vibe_Coder_v0.1.md`.
|
||||
|
||||
### 2.1 Zwei Registry-Ebenen (Archetyp Initiative + Project)
|
||||
|
||||
| Ebene | Tabelle / Registry | Zweck |
|
||||
|-------|-------------------|--------|
|
||||
| **Initiative-Archetyp** | `entity_archetypes` + EFS | Welches **Programm/Vorhaben** ist das? Default-`method_key`, Profilfelder |
|
||||
| **Project-Archetyp** | `entity_archetypes` (`entity_type=project`) + EFS | Welche **Rolle** hat dieser Strang im Vorhaben? |
|
||||
|
||||
Bestehende Initiativen: Default `initiative.generic` + `generic_operating` — unverändert.
|
||||
|
||||
### 2.2 Archetyp → Default-Methode + optional Ausprägung
|
||||
|
||||
Jeder Archetyp referenziert:
|
||||
|
||||
```text
|
||||
default_method_key # Schicht 1 — Steuerungsmodul
|
||||
default_method_profile_key # Schicht 3 — optional, z. B. content.book_writing
|
||||
efs_field_profile # Schicht 2/3 — Felder
|
||||
ui_profile_json # dominante Modus-Ansichten
|
||||
```
|
||||
|
||||
Nutzer/PO wählt bei Anlage: **Archetyp** (generisch) und optional **Ausprägung** (konkret). Project erbt + darf `method_key` / Profile **override** (§4.3).
|
||||
|
||||
Methoden = **registrierte Module** in `backend/steering/methods/` — keine Hardcodierung in React, keine Steuerung in Routern.
|
||||
|
||||
### 2.3 Methoden-Komposition (Product + Sprint)
|
||||
|
||||
**Release/Programm** und **Iterations-Zeitbox** sind **keine Gegensätze**:
|
||||
|
||||
| Methode | Horizont | Steuerungsfrage |
|
||||
|---------|----------|-----------------|
|
||||
| `program_delivery` (B2a) | Begrenztes Programm, Abschluss | „Was blockiert den nächsten Meilenstein?“ |
|
||||
| `continuous_product` (B2b) | Dauerbetrieb, Wartung, Issues | „Was ist jetzt am wirksamsten — ohne fixes Ende?“ |
|
||||
| `agile_iteration` (B3 Profil) | Sprint / `work_cycle` auf B2 | „Was ist der Schritt **in dieser Zeitbox**?“ |
|
||||
|
||||
**Komposition:** Kairo als **`initiative.product`** nutzt `continuous_product` **und** optional `work_cycle` — **kein** eigener Archetyp `agile_team`. Sprint kann in Release/Product-Betrieb übergehen. PO + Vibe Coder; Kairo übernimmt Scrum-Master-Logik (Next Action, Attention).
|
||||
|
||||
Kein zweiter SteeringContext, kein paralleles OM.
|
||||
|
||||
### 2.4 Project-Archetyp: Spiegel der Initiative, Struktur separat — **PO 2026-07-10**
|
||||
|
||||
**Grundsatz:** Project-Archetypen **entsprechen** den Initiative-Archetypen (gleiche Familie, `project.*`-Prefix) — **kein** paralleles Typensystem (`primary_chain`, `maturity_lane`, …).
|
||||
|
||||
| Aspekt | Regel |
|
||||
|--------|--------|
|
||||
| **Default bei Anlage** | `project.archetype_key` = **abgeleitet** von `initiative.archetype_key` (Mapping 1:1) |
|
||||
| **Abweichung erlaubt** | Project darf **andere Methode** (`method_key`) und **andere EFS-Felder** als die Initiative haben |
|
||||
| **Struktur** | Abhängigkeiten, Pfade, Lanes, Domains → **Graph + Roadmap + Konfiguration**, nicht eigener Archetyp pro Pfadtyp |
|
||||
| **`project.generic`** | Nur wenn **nichts** ableitbar — UI-Hinweis: *keine Steuerungsstruktur*; **Prefer inherit** |
|
||||
|
||||
**Beispiel Kumite (A1):** Initiative `maturity_journey` → Projects pro Fähigkeit (ebenfalls `maturity_journey`); Stufen = `maturity_stage`; Routinen = Recurring; **Voraussetzungen** = Graph-Kanten zwischen Stufen/Projects — kein Sondermodell „lane“.
|
||||
|
||||
**Beispiel Küche (A2):** Mehrere Haupt- und Nebenpfade; **kritischer Pfad** = **berechnetes** Read Model aus Graph + Status — nicht fest ein `primary_chain`-Objekt.
|
||||
|
||||
### 2.5 UI-Profil (kein neues OM-Objekt)
|
||||
|
||||
Pro Archetyp: **dominante Modus-Ansichten** und **versteckte** Patterns (z. B. Queue zeigt Pull-Queue, nicht Gate-Graph).
|
||||
|
||||
Speicherung MVP: Seed-JSON in Registry-Sync (`ui_profile_json`), nicht ad-hoc im Frontend.
|
||||
|
||||
---
|
||||
|
||||
## 3. Steuerungs-Landschaft — Vollständigkeits-Matrix
|
||||
|
||||
Diese Matrix ist die **Checkliste**, dass keine wesentliche Steuerungsform übersehen wird.
|
||||
|
||||
### 3.1 Initiative-Archetypen (Referenz-Portfolio)
|
||||
|
||||
| ID | `archetype_key` | Label (DE) | Beispiel | Default-Methode | MVP-Stufe |
|
||||
|----|-----------------|------------|----------|-------------------|-----------|
|
||||
| — | `initiative.generic` | Allgemeines Vorhaben | Fallback | `generic_operating` | ✓ (bestehend) |
|
||||
| **A1** | `initiative.maturity_journey` | Reifegrad-Entwicklung | Spagat können | `maturity_progression` | **A** |
|
||||
| **A2** | `initiative.linear_project` | Lineares Vorhaben | Neue Küche | `sequential_dependency` | **A** |
|
||||
| **A3** | `initiative.recurring_program` | Dauerprogramm / Rhythmus | Haus in Ordnung | `recurring_control` | **B** |
|
||||
| **B1** | `initiative.support_queue` | Queue / Supportdesk | Tickets, Pool | `queue_pull` | **B** |
|
||||
| **B2a** | `initiative.program` | Programm (begrenzt) | Kairo-Release-Programm, Großprojekt mit Abschluss | `program_delivery` | **A** |
|
||||
| **B2b** | `initiative.product` | Produkt (kontinuierlich) | Kairo-Betrieb, Wartung, Issues | `continuous_product` | **A** |
|
||||
| **B3** | *(kein eigener Initiative-Archetyp)* | Sprint / Iteration | PO + Vibe-Coder-Zeitbox | `agile_iteration` als **Profil** auf B2 | **A** (Minimal) |
|
||||
| **C1** | `initiative.dispute_case` | Verfahren / Konflikt | Miterstreit | `dispute_procedure` | **C** (Katalog) |
|
||||
| **D1** | `initiative.content_project` | Inhalt / Kapitel | Buch, Konzept schreiben | `chapter_based_progression` | **B** |
|
||||
|
||||
**PO 2026-07-10 — Archetypen:** A1 ✓ · A2 ✓ · A3 ✓ (Score-Logik, siehe §5) · B1 ✓ · B2a/B2b getrennt · B3 kein eigener Typ · C1 Katalog · D1 in MVP Stufe B
|
||||
|
||||
**Hinweis B2/B3:** `program` vs. `product` = **unterschiedlicher Lifecycle** (begrenzt vs. kontinuierlich). Sprint/`work_cycle` hängt an **Product/Programm**, nicht an `initiative.agile_team`. Kairo-Setup: PO + Vibe Coder; „Scrum Master“ = Kairo-Steuerungslogik.
|
||||
|
||||
### 3.2 Steuerungsmethoden (Registry)
|
||||
|
||||
| `method_key` | Status heute | Archetyp(e) | Kurzbeschreibung | Next-Action-Fokus |
|
||||
|--------------|--------------|-------------|------------------|-------------------|
|
||||
| `generic_operating` | ✓ registriert | generic | Leichte Struktur, Gates optional | offene Actions, Backlog-Triage |
|
||||
| `program_delivery` | ○ Ziel (Stub; heute: `product_milestone_driven`) | program | Begrenztes Programm, Phasen, Abschluss | Gate + AP am Horizont; **Closure** vorgesehen |
|
||||
| `continuous_product` | ○ Ziel (Stub AP2.0a) | product | Kontinuierlicher Betrieb, Wartung, Issues | Nächster wirkungsvoller Schritt; **kein** fixes End-Gate |
|
||||
| `agile_iteration` | ○ Ziel (Profil/Hook) | product, program | Zeitbox / Sprint auf Ist-Ebene | 1–3 Items im aktiven `work_cycle` |
|
||||
| `product_milestone_driven` | ✓ registriert | *(Legacy-Seed → migrieren zu program/product)* | Meilenstein-orientiert | Gate + offene AP am Gate |
|
||||
| `maturity_progression` | ○ Ziel | maturity_journey | Reifegrad-Stufen, Übungswechsel | **heutige Übung** + Stufen-Kriterium |
|
||||
| `sequential_dependency` | ○ Ziel | linear_project | Linearer Graph, Begleitstränge | **nächster ready Schritt** am kritischen Pfad |
|
||||
| `recurring_control` | ○ Ziel | recurring_program | Dauerprogramm, Assignments | **fällig / überfällig** pro Actor |
|
||||
| `queue_pull` | ○ Ziel | support_queue | Pool, Selbstwahl oder Empfehlung | **1 Empfehlung** oder gewähltes Item |
|
||||
| `dispute_procedure` | ○ Katalog | dispute_case | Phasen, Fristen, Iterationen | **nächste Frist / Entscheidung** |
|
||||
| `chapter_based_progression` | ○ Katalog | content_project | Kapitel-Reihenfolge, Review-Gates | **nächstes Kapitel / Review** |
|
||||
|
||||
Neue Methoden: nur via `steering/methods/registrations/*.py` + Tests — siehe `Kairo_Method_Design_Principles_v0.1.md`.
|
||||
|
||||
### 3.3 RoadmapItem-Typen (Plan-Schicht)
|
||||
|
||||
Kanoniche Typen aus OM v0.2 — **keine eigenen Tabellen** pro Typ.
|
||||
|
||||
| `item_type` | Bedeutung | Primär-Archetyp | MVP |
|
||||
|-------------|-----------|-----------------|-----|
|
||||
| `milestone` | Meilenstein / Release-Punkt | program, product, linear_project | ✓ AP1.4 |
|
||||
| `maturity_stage` | Reifegrad-Stufe | maturity_journey | A |
|
||||
| `feature` | Feature-Landschaft (optional) | program, product | post-A |
|
||||
| `review_gate` | Review / Quality Gate | program, product, content_project | ◐ |
|
||||
| `chapter` | Kapitel / Abschnitt | content_project | **B** |
|
||||
| `work_cycle` | **Sprint / Iteration / Zeitbox** | product, program | **A (B3)** |
|
||||
| `phase` | Verfahrensphase | dispute_case | C |
|
||||
|
||||
**Sprint in Kairo** = `RoadmapItem(type=work_cycle)`, nicht eigene `sprints`-Tabelle.
|
||||
|
||||
### 3.4 Ist-Schicht — Was committet wird
|
||||
|
||||
| OM-Entität | Rolle | Nicht verwechseln mit |
|
||||
|------------|-------|------------------------|
|
||||
| `BacklogItem` | Eingang, noch nicht committet | Sprint-Backlog (Ist!) |
|
||||
| `Action` | Committetes Arbeitspaket | Task |
|
||||
| `Task` | Feingranularität unter Action | BacklogItem |
|
||||
| `RecurringElement` | Rhythmus / Routine | Backlog, Sprint |
|
||||
| `Decision` | Steuerungsentscheidung | Action |
|
||||
| `Evidence` | Nachweis für Gate/DoD | Attachment-Dummy |
|
||||
|
||||
**Sprint-Backlog-Semantik (B3):**
|
||||
|
||||
- **Product Backlog** = `BacklogItem` (+ optional Gate-Link) — Plan-Eingang
|
||||
- **Sprint Backlog** = `Action` (Status open/ready/in_progress) mit **`work_cycle_id`** (FK auf `roadmap_items.id` wo `item_type=work_cycle`)
|
||||
- Commit aus Eingang → Action **mit** aktivem Zyklus = Sprint-Commit
|
||||
- Abgeschlossener Sprint: Actions done/cancelled; Zyklus `reached` oder `closed`; Review optional via `Review`-Objekt
|
||||
|
||||
Migration: `actions.work_cycle_id UUID NULL REFERENCES roadmap_items(id)` (AP2.0f).
|
||||
|
||||
### 3.5 Agile-Begriffe — Abbildung in Kairo
|
||||
|
||||
| Scrum/Agile-Begriff | In Kairo | Status |
|
||||
|---------------------|----------|--------|
|
||||
| Product Backlog | `BacklogItem`, Plan → Eingang | ✓ implementiert |
|
||||
| Sprint | `RoadmapItem(type=work_cycle)` | ○ Katalog + AP2.0f |
|
||||
| Sprint Goal | `work_cycle.title` + optional EFS `sprint_goal` | ○ |
|
||||
| Sprint Backlog | `Action.work_cycle_id` | ○ AP2.0f |
|
||||
| Sprint Planning | Commit/Triage Eingang → Sprint-Actions | ○ |
|
||||
| Daily / Standup | **kein Objekt** — Ausführen-Modus zeigt Next Action | bewusst |
|
||||
| Sprint Review | `Review` + Gate optional | ◐ |
|
||||
| Retrospective | `Review` / `Decision` | ◐ |
|
||||
| Velocity / Burndown | — | **explizit post-MVP** |
|
||||
| Kanban-Board | — | **explizit nicht Kern** |
|
||||
| Story Points | EFS optional | post-MVP |
|
||||
|
||||
### 3.6 Explizit nicht im MVP-Kern (Anti-Scope)
|
||||
|
||||
Damit nichts „vergessen“ wirkt, aber klar **ausgeschlossen** ist:
|
||||
|
||||
| Thema | Warum nicht Kern |
|
||||
|-------|------------------|
|
||||
| Kanban-Board als Haupt-UI | Todo-Wand-Risiko; Queue (B1) deckt Pull ab |
|
||||
| Velocity, Burndown, CFD | Reporting-Edge, nicht Steuerungskern |
|
||||
| Scrum-Rituale als Workflow-Engine | Lifecycle + Review reicht |
|
||||
| Jira/Linear-Import | post-MVP |
|
||||
| `sprints`-Tabelle parallel zu RoadmapItem | Scope Lock — nur `work_cycle` |
|
||||
| Mitai/Shinkan-Trainingslogik | Produktfamilien-Trennung |
|
||||
| Billing, SSO, MCP/KI | eingefroren |
|
||||
|
||||
---
|
||||
|
||||
## 4. Katalog — Project-Archetypen — **PO-Neuausrichtung 2026-07-10**
|
||||
|
||||
### 4.1 Spiegel-Tabelle (1:1 zur Initiative)
|
||||
|
||||
Project-Registry **spiegelt** Initiative-Registry (`entity_archetypes`, `entity_type=project`):
|
||||
|
||||
| Initiative-Archetyp | Project-Archetyp (Default bei Anlage) | Anmerkung |
|
||||
|---------------------|----------------------------------------|-----------|
|
||||
| `initiative.generic` | `project.generic` | **Vermeiden** — lieber von Initiative erben |
|
||||
| `initiative.maturity_journey` | `project.maturity_journey` | z. B. eine **Fähigkeit** (Kumite-Angriff) |
|
||||
| `initiative.linear_project` | `project.linear_project` | Strang in einem Gesamtvorhaben |
|
||||
| `initiative.recurring_program` | `project.recurring_program` | Domain **konfigurierbar** (Raum, Person, Thema) |
|
||||
| `initiative.support_queue` | `project.support_queue` | Queue **unter** Product/Programm |
|
||||
| `initiative.program` | `project.program` | Phase/Release-Strang |
|
||||
| `initiative.product` | `project.product` | Stream unter Produkt (Feature, Ops, …) |
|
||||
| `initiative.dispute_case` | `project.dispute_case` | Verfahrensstrang |
|
||||
| `initiative.content_project` | `project.content_project` | Teil, Band, großer Block |
|
||||
|
||||
**Migration AP2.0b:** `projects.archetype_key VARCHAR(64) NULL` — bei INSERT Default = **Mirror** der Initiative, nicht blind `generic`.
|
||||
|
||||
### 4.2 Was **kein** Project-Archetyp ist (Struktur statt Label)
|
||||
|
||||
Diese Konzepte aus v0.2-Entwurf sind **keine** eigenen Archetypen — sie werden **generisch** modelliert:
|
||||
|
||||
| Konzept | Modellierung | Werkzeug |
|
||||
|---------|--------------|----------|
|
||||
| Reifegrad-Spur / Lane | Project oder Roadmap-Lane mit gleichem Archetyp | Roadmap + Graph |
|
||||
| Primär- / Nebenpfad | Knoten + Kanten; Rolle an Kante/Knoten | **Gate-Graph (AP1.13)** |
|
||||
| Kritischer Pfad | **Berechnet** aus Graph + Ist-Status | Steering Read Model |
|
||||
| Voraussetzung Stufe 3 Angriff braucht Stufe 2 Bein | `roadmap_item_dependencies` / Graph | A1 Kumite-Beispiel |
|
||||
| Recurring-Domain (Küche / Person) | `project.recurring_program` + **EFS-Konfiguration** | Felder, nicht Typ |
|
||||
| Sprint-Zeitbox | `RoadmapItem(work_cycle)` + `Action.work_cycle_id` | B3 Profil — **kein** Project-Typ |
|
||||
| Thema ohne Project | **eigene Initiative** (`support_queue`) oder BacklogItem-Triage | B1 PO |
|
||||
|
||||
**PO:** Kein exaktes Datenmodell + exakte Steuerung **pro Bezeichner** — Archetyp liefert **Default-Methode + Feldprofil + UI-Empfehlung**; Feinsteuerung über Graph, EFS, optional `method_key`-Override am Project.
|
||||
|
||||
### 4.3 Abweichende Methode / Struktur am Project
|
||||
|
||||
```text
|
||||
Initiative (method_key, archetype_key)
|
||||
└── Project (archetype_key default=Mirror, method_key optional OVERRIDE)
|
||||
├── structure: parent_project_id, roadmap_item_id, graph edges
|
||||
└── Actions / Recurring / Tasks
|
||||
```
|
||||
|
||||
- **Override `method_key`:** z. B. Initiative `product` (continuous), ein Project `linear_project` (method `sequential_dependency`) für einen begrenzten Release-Strang
|
||||
- **Audit** bei Override; MVP: manuelle Wahl, kein Designer
|
||||
- **`container_kind`** (bestehend: `project|stream|phase|release`) bleibt **Strukturhint** — orthogonal zu `archetype_key` (Variante 1)
|
||||
|
||||
### 4.4 `project.generic` — bewusst schwach
|
||||
|
||||
**PO:** Default `generic` ohne Ableitung ist ** strukturlos** und **steuerungslos** — nur Notfall.
|
||||
|
||||
| Bevorzugt | Statt generic |
|
||||
|-----------|----------------|
|
||||
| Anlage unter Initiative | Archetyp **erben** |
|
||||
| Thema/Inbox ohne Parent-Project | **Neue Initiative** (`support_queue`) |
|
||||
| Explizit unstrukturiert | generic + Attention „Struktur fehlt“ |
|
||||
|
||||
### 4.5 Referenz — Kumite (Komplexität A1)
|
||||
|
||||
```text
|
||||
Initiative: Karate Kumite (maturity_journey)
|
||||
├── Project: Angriff (maturity_journey) — 5–7 Stufen
|
||||
├── Project: Beinarbeit (maturity_journey)
|
||||
├── … (8 Fähigkeiten)
|
||||
│ └── RoadmapItem maturity_stage je Stufe
|
||||
│ └── RecurringElement: Trainingsroutinen (Varianten)
|
||||
└── Graph: Stufe 3 Angriff REQUIRES Stufe 2 Beinarbeit, Stufe 2 Reaktion, …
|
||||
```
|
||||
|
||||
Kein Sonder-Archetyp „lane“ — nur **Spiegel-Archetyp** + **Graph** + **Roadmap** + **Recurring**.
|
||||
|
||||
---
|
||||
|
||||
## 5. Archetyp-Detail (PO-Spezifikation)
|
||||
|
||||
### A1 — `initiative.maturity_journey` (Reifegrad) — **PO ✓**
|
||||
|
||||
**Nutzerbild:** Karate, Fitness, Fähigkeiten mit **mehrstufigen Reifegradmodellen**, Abhängigkeiten zwischen Fähigkeiten, **Variation** der Übungen. Ziel **entwicklungsbasiert**, nicht fest definierter Endzustand — Fortschritt aus **Historie** und erreichtem (weichen) Status. **Ausprägung** z. B. `maturity.karate_kumite` (8 Fähigkeiten, Stufen-Raster, Routinen-Seed, Voraussetzungs-Graph).
|
||||
|
||||
**Plan:** Projects (Spiegel-Archetyp) + `maturity_stage` RoadmapItems; **Graph** für Voraussetzungen zwischen Stufen/Projects
|
||||
|
||||
**Ist:** `RecurringElement` pro Stufe (Übungsvarianten rotierend); bei Verify `reached` → Recurring-Set wechseln (AP2.0e); Journey dokumentiert Entwicklung
|
||||
|
||||
**Steuerung (`maturity_progression`):**
|
||||
|
||||
- Next Action: heutige Recurring-Instanz + Hinweis auf offenes Stufen-Kriterium
|
||||
- Attention: Stagnation (keine Erfüllung), Stufe ohne Fortschritt über Zeit
|
||||
- **Nicht:** starres „Ziel erreicht = Ende“ — Reifegrad bleibt adaptierbar
|
||||
|
||||
**EFS:** `current_body_focus`, `training_frequency`, `progress_notes`, optional `discipline` (enum: karate, fitness, …)
|
||||
|
||||
**UI-Profil:** Kontrolle dominant; Plan = Stufen; Gates-Graph **aus**; Journey **ein**
|
||||
|
||||
---
|
||||
|
||||
### A2 — `initiative.linear_project` (Linear / Einmalprojekt) — **PO ✓**
|
||||
|
||||
**Nutzerbild:** Einmalige Vorhaben (Küche, Umzug, Event). **Ein oder mehrere lineare Pfade** plus **unabhängige/parallele** Aktivitäten — daher **Gate-Graph** als Zielmodell, nicht nur eine Liste.
|
||||
|
||||
**Plan:** Projects + Gates; **mehrere Pfade**, Graph-Designer (AP1.13); kritischer Pfad **dynamisch**
|
||||
|
||||
**Ist:** Actions an Strängen; parallele APs ohne Pfad-Blockade wo erlaubt
|
||||
|
||||
**Steuerung (`sequential_dependency`):**
|
||||
|
||||
- Next Action: nächster **ready** Schritt am gewählten Pfad / kritischen Pfad
|
||||
- Attention: Blocker auf Pfad, Gate at risk, überfälliges `target_date`
|
||||
|
||||
**EFS:** `budget_summary`, `primary_contractor`, `target_completion`
|
||||
|
||||
**UI-Profil:** Plan (Graph/Liste) + Kontrolle; Recurring **aus**
|
||||
|
||||
---
|
||||
|
||||
### A3 — `initiative.recurring_program` (Dauerprogramm / Haushalt) — **PO ✓**
|
||||
|
||||
**Nutzerbild:** Rhythmus-Vorhaben (Haus in Ordnung). Steuerung über **Abweichungen und Gesundheit des Systems** — **nicht** über x-fach auflaufende Einzel-Tasks („10× Staubsaugen mit unterschiedlichem Datum“).
|
||||
|
||||
**Plan:** optional Projects (`recurring_program`); Domains **konfigurierbar** (EFS: Raum, Person, Thema)
|
||||
|
||||
**Ist:** `RecurringElement` + `ActionAssignment` pro Actor; **eine** offene Instanz pro Rhythmus — bei Nicht-Erledigung **Eskalation/Score**, kein neuer Duplikat-Task
|
||||
|
||||
**Steuerung (`recurring_control`) — MVP minimal, Zielbild:**
|
||||
|
||||
| Signal | Logik (Ziel) |
|
||||
|--------|----------------|
|
||||
| Dringlichkeit | Datum **+** Anzahl verpasster Zyklen (nicht nur Fälligkeit) |
|
||||
| Regelmäßigkeit | Bonus / grüner Score bei stabil erfüllter Cadence |
|
||||
| Freiwilligkeit | Bonus bei freiwilliger Übernahme fremder offener Rhythmen |
|
||||
| Haushalts-Pool | Offene Rhythmen einer Person für **alle** sichtbar; andere können **freiwillig übernehmen** (Assignment-Wechsel mit Audit) |
|
||||
| Attention | Abweichung vom Soll-Rhythmus, nicht Gesamtliste aller Haus-Tasks |
|
||||
|
||||
**Anti-Pattern:** Jede verpasste Ausführung erzeugt neuen Task → **verboten**. Stattdessen: Recurring-Instanz + Score/Attention.
|
||||
|
||||
**EFS:** `household_members`, `cadence_default`, optional `domain_label` (Küche, Garten, …)
|
||||
|
||||
**UI-Profil:** Ausführen + Team-Health; Plan minimal; **kein** Task-Wall aller Familienmitglieder
|
||||
|
||||
**MVP-Stufe:** **B** (Minimal: fällig/heute ohne Score); **B+** / AP2.0g: Score + freiwillige Übernahme
|
||||
|
||||
---
|
||||
|
||||
### B1 — `initiative.support_queue` (Inbox / Queue) — **PO ✓**
|
||||
|
||||
**Nutzerbild:** **Inbox** für Ad-hoc-Aufgaben („nicht vergessen“), plus **Queue** für bearbeitbare Items. Items müssen **themenbezogen** zuordenbar sein (Initiative, Project, Tag/Thema) — nicht alles in einer globalen Mülltonne.
|
||||
|
||||
**Plan:** Eingang → triage; Queue **unter** Product/Programm **oder** als **eigene Initiative** (Thema = Vorhaben)
|
||||
|
||||
**Ist:** Actions als Tickets; Zuordnung zu Vorhaben/Thema bei Triage oder Commit
|
||||
|
||||
**Steuerung (`queue_pull`):**
|
||||
|
||||
- Next Action: Empfehlung aus Queue **im gewählten Themen-Scope** oder Pull
|
||||
- Attention: SLA, unassigned high-priority
|
||||
|
||||
**EFS:** `queue_policy`, `sla_hours`, `default_topic_ref` (optional)
|
||||
|
||||
**UI-Profil:** Eingang + Ausführen (Queue) dominant; thematische Filter Pflicht
|
||||
|
||||
**MVP-Stufe:** **B** (Inbox + Queue + Themen-Zuordnung minimal)
|
||||
|
||||
---
|
||||
|
||||
### B2a — `initiative.program` (Programm, begrenzt) — **PO ✓**
|
||||
|
||||
**Abgrenzung zu Product:** Programm hat **Ziel und Abschluss** (Phasen, Release-Programme, Großvorhaben mit Ende). Lifecycle führt zu **Closure**.
|
||||
|
||||
**Plan:** `RoadmapItem`: `milestone`, `feature`, `review_gate`; Product Backlog im Eingang
|
||||
|
||||
**Ist:** Actions + Tasks; optional Gate- und `work_cycle`-Bindung
|
||||
|
||||
**Steuerung (`program_delivery`):**
|
||||
|
||||
- Next Action: nächstes Gate / AP am Programm-Horizont
|
||||
- Attention: Gate at risk, Blocker, offenes Backlog am aktiven Gate
|
||||
- Lifecycle: Standard inkl. **closure**
|
||||
|
||||
**Komposition B3:** `work_cycle` (Sprint) optional; Sprint kann in Release münden → Übergang in Product-Betrieb
|
||||
|
||||
**UI-Profil:** Plan (Gates) + Kontrolle + Ausführen
|
||||
|
||||
---
|
||||
|
||||
### B2b — `initiative.product` (Produkt, kontinuierlich) — **PO ✓**
|
||||
|
||||
**Abgrenzung zu Program:** Produkt = **kontinuierliche Weiterentwicklung** ohne definiertes Ende — **Wartung, Issues, Betrieb** sind Dauer-Themen. Lifecycle **ohne** fixes Closure-Ziel (Adaptation statt Abschluss).
|
||||
|
||||
**Plan:** Gates/Meilensteine als **Orientierung**, nicht als finales End-Gate; Backlog dauerhaft
|
||||
|
||||
**Ist:** Actions (Features, Fixes, Ops); Sprint/`work_cycle` als **Zeitbox** auf Ist-Ebene
|
||||
|
||||
**Steuerung (`continuous_product`):**
|
||||
|
||||
- Next Action: wirkungsvollster Schritt im aktiven Horizont (Gate **oder** aktiver Sprint)
|
||||
- Attention: kritische Issues, technische Schuld, leerer Sprint bei aktivem Zyklus
|
||||
- Lifecycle: **kein** erzwungenes `closure` — `adaptation` / Dauerbetrieb
|
||||
|
||||
**Kairo-Referenz:** Kairo selbst eher **Product** als begrenztes Programm; Vibe-Coding-Sprints hängen hier als `work_cycle`.
|
||||
|
||||
**UI-Profil:** Plan + Kontrolle; Betrieb/Issues sichtbar; Sprint-Banner wenn Zyklus aktiv
|
||||
|
||||
**Technik:** Bestehendes `product_milestone_driven` bleibt Übergangs-Seed bis AP2.0a Split in `program_delivery` + `continuous_product`.
|
||||
|
||||
---
|
||||
|
||||
### B3 — Sprint / Iteration ( **kein** Initiative-Archetyp) — **PO ✓**
|
||||
|
||||
**PO-Entscheidung:** Sprint ist **kein eigener Vorhaben-Typ**, sondern **Plan-/Ist-Konstrukt** auf Product/Programm — fühlt sich nahe an **Arbeitspaket-Zeitbox** an, kann in Release/Product-Betrieb übergehen.
|
||||
|
||||
**Erstes Setup:** **Product Owner + Vibe Coder** — kein klassisches Dev-Team; **Scrum-Master-Rolle** = Kairo-Steuerungslogik (Next Action, Attention, Sprint-Grenzen).
|
||||
|
||||
**Plan:** `RoadmapItem(type=work_cycle)` — optional, nicht jedes Product braucht Sprints
|
||||
|
||||
**Ist:** Actions mit optional `work_cycle_id`; Sprint kann **klein** sein (1–3 APs)
|
||||
|
||||
**Steuerung (`agile_iteration` Profil):** Hook auf `continuous_product` / `program_delivery` wenn aktiver Zyklus
|
||||
|
||||
**Offen (bewusst):** Ob Sprint langfristig eher `Action`-Granularität oder `work_cycle`-Granularität — MVP: `work_cycle` minimal, ohne Team-Archetyp
|
||||
|
||||
**MVP-Stufe A:** ein aktiver Zyklus auf Kairo-Product, Next Action im Zyklus — **ohne** Team-Board
|
||||
|
||||
---
|
||||
|
||||
### C1 — `initiative.dispute_case` (Miterstreit) — **PO ✓ Katalog, nicht MVP**
|
||||
|
||||
**Nutzerbild:** **Reaktiv**, nicht planerisch — aus **Status** entstehen fortlaufend neue Handlungsstränge und Aufgaben (Fristen, Entscheidungen, Reaktionen).
|
||||
|
||||
**Plan:** Phasen-Gates als Orientierung; Iterationen (Reopen) mit Decision-Pflicht
|
||||
|
||||
**Ist:** Decisions, Evidence, Fristen auf Gates/Actions
|
||||
|
||||
**Steuerung (`dispute_procedure`):** Next Action: nächste Frist / offene Entscheidung / neuer Strang aus Statuswechsel
|
||||
|
||||
**MVP-Stufe C:** Katalog + Profilfelder; UI spezialisiert post-MVP
|
||||
|
||||
---
|
||||
|
||||
### D1 — `initiative.content_project` (Inhalt / Kapitel) — **PO ✓ MVP Stufe B**
|
||||
|
||||
**Nutzerbild:** Buch- und Konzeptprojekte — generischer Archetyp; **Ausprägung** z. B. `content.book_writing` mit Kapitel-Seed, Mitwirkenden, Vorbefüllung.
|
||||
|
||||
**Plan:** `RoadmapItem(type=chapter)` + `review_gate`
|
||||
|
||||
**Ist:** Actions (Schreib-APs, Recherche)
|
||||
|
||||
**Steuerung (`chapter_based_progression`):** Next Action: nächstes Kapitel / Review / Schreib-AP
|
||||
|
||||
**Ausprägung `content.book_writing` (Schicht 3):** Gliederungs-Template, `word_count_goal`, Rollen (Autor, Lector), Kategorien
|
||||
|
||||
**MVP-Stufe B:** Archetyp + eine Ausprägung als Seed
|
||||
|
||||
---
|
||||
|
||||
## 6. Plan-/Ist-Muster (übergreifend)
|
||||
|
||||
```text
|
||||
Eingang Plan (optional) Ist Steuerung
|
||||
maturity_journey selten maturity_stages Recurring heutige Übung
|
||||
linear_project selten Gate-Graph Actions kritischer Pfad
|
||||
recurring_program selten Domains Recurring fällig/heute
|
||||
support_queue triage Queue-Streams Actions (Tickets) Pull/Empfehlung
|
||||
program Product Backlog milestones, gates Actions+Tasks Gate-Horizont + Closure
|
||||
product Product Backlog milestones (orientierend) Actions+Tasks+Ops Next Step + Dauerbetrieb
|
||||
(work_cycle) — work_cycles on B2 Actions (Zeitbox) Sprint Next Action (Profil)
|
||||
dispute_case Eingang phase gates Decisions+Evidence reaktiv: Frist/Strang
|
||||
content_project Ideen chapters Actions (Schreib-AP) nächstes Kapitel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Scope Lock
|
||||
|
||||
| Verboten | Erlaubt |
|
||||
|----------|---------|
|
||||
| React-Formulare pro Archetyp hardcoden | FieldRenderer + Registry |
|
||||
| OM-Tabelle `disputes`, `habits`, `sprints` | EFS + RoadmapItem + bestehendes OM |
|
||||
| Steering-Heuristiken in Routern | `backend/steering/` |
|
||||
| Alle Methoden voll implementieren vor A-Abnahme | Stubs + A1/A2/B2/B3-minimal zuerst |
|
||||
| Archetyp ohne `method_key`-Bindung | Seed + Sync |
|
||||
| Sprint-Backlog als BacklogItem-Liste | Actions mit `work_cycle_id` |
|
||||
|
||||
---
|
||||
|
||||
## 8. Implementierungspakete
|
||||
|
||||
```text
|
||||
AP2.0a Method-Stubs: maturity_progression, sequential_dependency, recurring_control,
|
||||
queue_pull, program_delivery, continuous_product, agile_iteration (Profil),
|
||||
dispute_procedure (stub), chapter_based_progression (stub)
|
||||
AP2.0b entity_archetypes Seeds (Initiative + Project Spiegel); projects.archetype_key;
|
||||
EFS profiles; 2–3 Referenz-Ausprägungen (Seeds): kumite, book_writing, kairo_dev
|
||||
AP2.0c Kontrolle-Lagebild: method_key, lifecycle, next action, attention (UI)
|
||||
AP2.0d Next-Action-Strategien: maturity, sequential, recurring, queue (minimal)
|
||||
AP2.0e Recurring-Stufenwechsel bei maturity_stage reached (A1)
|
||||
AP2.0f work_cycle + actions.work_cycle_id; Sprint auf Product/Programm; agile_iteration Profil
|
||||
AP2.0g A3 Score + freiwillige Übernahme (recurring_control erweitert) — Stufe B+
|
||||
AP2.1 Validation Report v0.3 — A1, A2, B2b (Kairo Product), D1 mit echten Daten
|
||||
```
|
||||
|
||||
Erweitert AP1.10 — **ersetzt nicht** EFS-Architektur, nutzt sie.
|
||||
|
||||
---
|
||||
|
||||
## 9. Risiko
|
||||
|
||||
| Risiko | Mitigation |
|
||||
|--------|------------|
|
||||
| Methoden-Overengineering | Stubs + eine Strategie pro A-Archetyp |
|
||||
| B2/B3 Verwechslung | Kompositions-Regel §2.3; UI zeigt aktiven Horizont |
|
||||
| Sprint = Todo-Wand | Default-Ansicht Sprint-Next-Action, nicht alle Actions |
|
||||
| dispute_case zu groß | Stufe C |
|
||||
| work_cycle ohne Migration | AP2.0f explizit, FK auf roadmap_items |
|
||||
|
||||
---
|
||||
|
||||
## 10. PO-Freigabe
|
||||
|
||||
- [x] Initiative-Archetypen A1–D1 — **2026-07-10** (Details §5)
|
||||
- [x] Project-Archetypen — **Spiegel-Modell §4** (2026-07-10)
|
||||
- [x] Vier-Schichten-Modell §2.0 (Framework → Methode → Archetyp → Ausprägung)
|
||||
- [x] Methoden-Keys §3.2 inkl. `program_delivery`, `continuous_product`, `agile_iteration`-Profil
|
||||
- [x] B3 ohne eigenen Archetyp; Sprint/`work_cycle` auf Product/Programm
|
||||
- [x] A3 Score-Logik Zielbild §5; MVP minimal, AP2.0g für Score/Übernahme
|
||||
- [x] MVP-Stufen A/B/C (§3.1)
|
||||
- [x] AP2.0-Reihenfolge §8 inkl. AP2.0f/2.0g
|
||||
|
||||
---
|
||||
|
||||
## 11. PO-Beschluss — Kurzfassung
|
||||
|
||||
**Gültig ab 2026-07-10.** Verbindlich für MVP v0.3 und AP2.0-Reihenfolge.
|
||||
|
||||
1. **Vier Schichten:** Framework → **Methode (Modul/Registry)** → **generischer Archetyp** → **Ausprägung (Profile)** → Integrationen später (MCP, Gitea, KI).
|
||||
2. **Initiative-Archetypen:** A1–A3, B1, B2a/B2b, B3 als Profil, C1 Katalog, D1 Stufe B — Portfolio vollständig im Katalog.
|
||||
3. **Project-Archetypen:** 1:1-Spiegel der Initiative; Struktur via Graph/Roadmap/EFS; Override `method_key` erlaubt; `generic` nur Notfall.
|
||||
4. **Agile:** Product Backlog = Eingang; Sprint = `work_cycle`; Sprint-Backlog = Actions mit `work_cycle_id`; kein Kanban/Burndown-Kern.
|
||||
5. **Program vs Product:** unterschiedlicher Lifecycle (Abschluss vs. Dauerbetrieb); gleiche Steuerungsbausteine.
|
||||
6. **Nächster Code-Auftrag nach Push-Freigabe:** AP2.0a → 2.0b → 2.0c (kein Plan-Politur ohne Steuerung).
|
||||
|
||||
---
|
||||
|
||||
## Referenzen
|
||||
|
||||
- `docs/product/Kairo_MVP_Definition_v0.3.md`
|
||||
- `docs/architecture/ADP_AP1_10_Initiative_Archetypes_and_Entity_Field_System_v0.1.md`
|
||||
- `docs/architecture/Kairo_Target_Architecture_Method_Driven_Adaptive_Steering_Core_v0.1.md`
|
||||
- `docs/architecture/Kairo_Method_Design_Principles_v0.1.md`
|
||||
- `docs/product/Kairo_Canonical_Operating_Model_v0.2.md`
|
||||
- `backend/steering/methods/registrations/generic_operating.py`
|
||||
- `backend/steering/methods/registrations/product_milestone_driven.py`
|
||||
|
|
@ -65,7 +65,8 @@ Verhindert, dass Zielbild-Dokumente als Ist-Stand gelesen werden.
|
|||
| steering_contexts (009) | ✓ | Lifecycle, method_key |
|
||||
| backend/steering/ lifecycle | ✓ | |
|
||||
| Signal Engine | ◐ | Regeln begrenzt |
|
||||
| Method Registry | ◐ | generic_operating, product_milestone_driven |
|
||||
| Method Registry | ◐ | generic_operating, product_milestone_driven; **Ziel AP2.0a:** program_delivery, continuous_product, … — siehe `ADP_Archetype_and_Method_Catalog_v0.2.md` |
|
||||
| Archetyp-/Methoden-Katalog PO | ✓ | ADP v0.2 + MVP v0.3 freigegeben 2026-07-10 |
|
||||
| NextActionCandidate | ◐ | API + Widget; nicht konfigurierbar auf beiden Ebenen |
|
||||
| Portfolio-Priorität (Initiativen) | ✗ | |
|
||||
| Situativer Steuerungskontext (Next Action) | ✗ | 📄 Vision §7.6 |
|
||||
|
|
|
|||
223
docs/product/Kairo_MVP_Definition_v0.3.md
Normal file
223
docs/product/Kairo_MVP_Definition_v0.3.md
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
# Jinkendo Kairo
|
||||
## MVP Definition v0.3
|
||||
|
||||
**Status:** PO-freigegeben (bezogen auf `ADP_Archetype_and_Method_Catalog_v0.2.md`)
|
||||
**Stand:** 2026-07-10
|
||||
**Auslöser:** Programm-Director-Ziel vs. flache Vorhabenliste; private und professionelle Vorhaben gleichwertig; Steuerung vor Status-Monitoring; **Agile vollständig** (Backlog ✓, Sprint/Iteration ○)
|
||||
**Bezug:** `Kairo_Vision_and_Product_Direction_v0.2.md`, `Kairo_Canonical_Operating_Model_v0.2.md`, `ADP_Archetype_and_Method_Catalog_v0.2.md`
|
||||
**Ersetzt als MVP-Nordstern:** implizite Annahme „MVP = Software-Programm mit Gates + Tasks“ in Sprint-Delivery; **nicht** die technische Roadmap v0.2 (bleibt Referenz für AP-Reihenfolge)
|
||||
|
||||
---
|
||||
|
||||
## 1. Nordstern
|
||||
|
||||
Kairo ist der **operative Program Director** — nicht ein To-do-Tool.
|
||||
|
||||
**Leitfrage (unverändert):**
|
||||
|
||||
> Welcher nächste Schritt bringt dieses Vorhaben **jetzt** am wirksamsten voran — und **warum**?
|
||||
|
||||
Der MVP ist erreicht, wenn ein Nutzer **mehrere typische Vorhabenarten** (privat und professionell) in Kairo **erfassen, steuern und nachvollziehen** kann — **ohne** dass die Oberfläche in unendliche To-do-Listen kollabiert.
|
||||
|
||||
---
|
||||
|
||||
## 2. Was der MVP **ist** und **nicht ist**
|
||||
|
||||
### MVP ist
|
||||
|
||||
- **Steuerung sichtbar:** Methode, Lifecycle, Attention, Next Action (begründet) — nicht nur Status-Ampeln
|
||||
- **Schichtenmodell:** Framework → Methode (Registry) → Archetyp (Baukasten) → Ausprägung (z. B. Buch, Kumite) — siehe ADP §2.0
|
||||
- **Archetyp-gesteuert:** Vorhaben- und Projekt-Typ bestimmt Default-Methode, Felder, dominante Modus-Ansichten
|
||||
- **Plan vs. Ist getrennt:** Eingang ≠ committete Arbeit; Recurring ≠ Backlog; **Product Backlog ≠ Sprint-Backlog**
|
||||
- **Agile zweigleisig:** Release-Horizont (Gates, B2) **und** Iterations-Horizont (Sprint/`work_cycle`, B3) — komponierbar
|
||||
- **Referenz-Portfolio:** mehrere Vorhaben **unterschiedlicher Typen** parallel im Tenant, davon **2–3 voll** durchspielbar
|
||||
- **Historie:** Journey als steuerungsrelevante Narrative (inkl. rückwirkender Erfassung wichtiger Ereignisse)
|
||||
|
||||
### MVP ist nicht
|
||||
|
||||
- Vollständiger Import aus externen Tools
|
||||
- Tenant-Admin-UI für Archetyp-Designer
|
||||
- KI/Prompt/Workflow/MCP (bleibt eingefroren)
|
||||
- Alle Archetypen **gleichzeitig voll implementiert** — Katalog ja, Vollimplementierung gestaffelt
|
||||
- **Kanban-Board, Velocity, Burndown** als Kern
|
||||
- Gantt-/Capacity-Planung
|
||||
- Ersatz für Mitai/Shinkan oder Rechts-/Gesundheits-Spezialsoftware
|
||||
|
||||
---
|
||||
|
||||
## 3. Anti-Patterns (explizit verboten im MVP-Slice)
|
||||
|
||||
| Verboten | Warum |
|
||||
|----------|--------|
|
||||
| Hauptbild = flache Liste aller offenen Actions/Tasks | Todo-Explosion; widerspricht Program Director |
|
||||
| Archetyp nur als Formular-Label ohne Methode/Steuerung | Täuscht Vielfalt vor |
|
||||
| Annahme „Vorhaben = Software-Release“ | schließt private Vorhaben aus |
|
||||
| **Sprint-Backlog als BacklogItem-Liste** | Sprint = committete Actions am `work_cycle` |
|
||||
| Plan-Modus ausbauen ohne Kontrolle/Steuerung | Monitoring ohne Begleitung |
|
||||
| Neue OM-Tabellen pro Archetyp (`sprints`, `habits`, …) | Scope Lock — Method Registry + EFS + OM |
|
||||
| Steering-Logik in Routern oder Frontend hardcoden | nur `backend/steering/` + Registry |
|
||||
|
||||
---
|
||||
|
||||
## 4. Referenz-Portfolio (Archetyp-Katalog)
|
||||
|
||||
Vollständige Matrix: **`ADP_Archetype_and_Method_Catalog_v0.2.md`** §3.
|
||||
|
||||
| ID | Typ | Beispiel | Default-Methode | Agile-Bezug |
|
||||
|----|-----|----------|-------------------|-------------|
|
||||
| **A1** | Reifegrad | Spagat können | `maturity_progression` | — |
|
||||
| **A2** | Linear / Wasserfall | Neue Küche | `sequential_dependency` | — |
|
||||
| **A3** | Dauerprogramm / Rhythmus | Haus in Ordnung | `recurring_control` | — |
|
||||
| **B1** | Queue / Supportdesk | Tickets | `queue_pull` | Pull statt Board |
|
||||
| **B2a** | Programm (begrenzt) | Release-Programm | `program_delivery` | Release + Abschluss |
|
||||
| **B2b** | Produkt (kontinuierlich) | Kairo, Betrieb | `continuous_product` | Dauerbetrieb + Issues |
|
||||
| **B3** | Sprint-Zeitbox *(Profil, kein Archetyp)* | PO + Vibe-Coder | `agile_iteration` | Zeitbox auf B2b |
|
||||
| **C1** | Verfahren / Konflikt | Miterstreit | `dispute_procedure` | reaktiv, Katalog |
|
||||
| **D1** | Inhalt / Kapitel | Buch, Konzept | `chapter_based_progression` | **Stufe B** |
|
||||
|
||||
### B2a vs B2b vs B3 (PO 2026-07-10)
|
||||
|
||||
- **Programm:** Ziel, Phasen, **Abschluss** — z. B. Release-Programm
|
||||
- **Product:** **Kein** fixes Ende — Wartung, Issues, Weiterentwicklung; Kairo selbst = Product
|
||||
- **Sprint:** Kein eigener Vorhaben-Typ — `work_cycle` auf Product/Programm; nahe an Arbeitspaket-Zeitbox
|
||||
|
||||
### MVP-Abnahfe-Priorität
|
||||
|
||||
| Stufe | Archetypen | Bedeutung |
|
||||
|-------|------------|-----------|
|
||||
| **Abnahfe A** | A1, A2, B2b (+ B3 minimal auf Kairo-Product) | Reifegrad, Linear, Kairo Product + optional Sprint |
|
||||
| **Abnahfe B** | A3, B1, **D1**, B3 ausgebaut | Haushalt-Score (AP2.0g), Inbox/Queue, Buch |
|
||||
| **Katalog C** | C1 | Miterstreit — Spezifikation, nicht MVP |
|
||||
|
||||
---
|
||||
|
||||
## 5. MVP-Nutzbarkeits-Bar (v0.3)
|
||||
|
||||
Kairo ist **MVP-nah**, wenn ein Nutzer **pro Archetyp der Stufe A**:
|
||||
|
||||
1. Ein Vorhaben **anlegt** (Initiative-Archetyp, Default-Methode, Profil/EFS)
|
||||
2. Die **passende Struktur** modelliert (Reifegrad-Stufen / Gate-Kette / Sprint-Zyklen — methodenabhängig)
|
||||
3. **Ist** committet (Actions, Tasks, Recurring — nicht alles gleichzeitig sichtbar)
|
||||
4. In **Kontrolle** den **Lagebild-Steuerungskern** sieht: Lifecycle, Methode, 1–3 Next Actions, Attention — **mit Begründung**
|
||||
5. In **Journey** Entwicklung und Abweichungen **nachvollzieht** (min. 5 steuerungsrelevante Events, auch rückwirkend)
|
||||
6. **Ohne CRUD-Wand** in ≤2 Minuten die Leitfrage für dieses Vorhaben beantworten kann
|
||||
|
||||
**Portfolio-Ebene (zusätzlich):**
|
||||
|
||||
7. Auf **Cockpit** sieht, **welches** Vorhaben welche Art von Attention braucht — nicht Details aller offenen Tasks
|
||||
|
||||
---
|
||||
|
||||
## 6. Steuerung vs. Monitoring
|
||||
|
||||
| Monitoring (reicht nicht) | Steuerung (MVP-Pflicht) |
|
||||
|---------------------------|-------------------------|
|
||||
| „12 offen“ | „Nächster Schritt: X, weil Gate Y blockiert / Stufe Z / **Sprint endet Freitag**“ |
|
||||
| Status-Dropdown | Lifecycle-Übergang + Methode |
|
||||
| Alle Tasks listen | Recurring: **heute fällig**; Queue: **nächster Pull**; Reifegrad: **aktuelle Übung**; Sprint: **1–3 Items im aktiven Zyklus** |
|
||||
| Journey als Archiv | Journey + Decision als **Plan-Abweichung** |
|
||||
| Product Backlog als Hauptliste | Sprint-Modus: **nur Sprint-Backlog** als Default |
|
||||
|
||||
Technische Anker: `steering_context.method_key`, `backend/steering/`, NextActionCandidate, AttentionItem, Method Registry, `actions.work_cycle_id` (AP2.0f).
|
||||
|
||||
---
|
||||
|
||||
## 7. Todo-Explosion verhindern (verbindliche UI-Regeln)
|
||||
|
||||
1. **Default-Ansicht** pro Methode zeigt **Next Action** (1–3), nicht Gesamtbestand
|
||||
2. **Recurring** erscheint in Rhythmus-Ansicht, nicht im Action-Backlog
|
||||
3. **Backlog/Eingang** (Product Backlog) getrennt von committeter Arbeit und von **Sprint-Backlog**
|
||||
4. **Plan** (Gates, Graph, Stufen, **Sprints**) = Orientierung; **Ist** = Ausführung
|
||||
5. **Drill-down** zu vollen Listen nur auf explizite Nutzeraktion („Alle anzeigen“)
|
||||
6. **Scope:** Portfolio → Vorhaben → Projekt filtert sichtbare Operative
|
||||
7. **Aktiver Sprint:** Ausführen-Modus default = Sprint-Backlog, nicht Product Backlog
|
||||
|
||||
---
|
||||
|
||||
## 8. Abnahme-Szenarien (konkret)
|
||||
|
||||
### A1 — Spagat (Reifegrad)
|
||||
|
||||
- Stufen als `maturity_stage` RoadmapItems
|
||||
- Recurring-Übungen; bei Stufenübergang **andere** Routine
|
||||
- Kontrolle: aktuelle Stufe + heutige Übung + Kriterium bis nächste Stufe
|
||||
- **Nicht:** 200 Übungs-Tasks in der Hauptliste
|
||||
|
||||
### A2 — Küche (Wasserfall)
|
||||
|
||||
- Primärstrang mit Abhängigkeiten (Graph oder sequenzielle Liste)
|
||||
- Begleitprojekte parallel
|
||||
- Kontrolle: kritischer Pfad / nächster blockierender Schritt
|
||||
- **Nicht:** alle Handwerker-Schritte als flache Todo-Liste
|
||||
|
||||
### B2b — Kairo (Product, kontinuierlich)
|
||||
|
||||
- Gates/Meilensteine als Orientierung; Backlog im Eingang; Issues/Betrieb als Dauer-Thema
|
||||
- Optional: `work_cycle` (Sprint-Zeitbox) für PO + Vibe Coder
|
||||
- Kontrolle: Next Action im aktiven Horizont (Gate **oder** Sprint) — begründet
|
||||
- **Nicht:** alle APs aller Gates gleichzeitig in der Hauptliste
|
||||
|
||||
### B3 — Sprint-Zeitbox (Profil auf Product, kein eigener Archetyp)
|
||||
|
||||
- Optional ein aktiver `work_cycle`; 1–3 Actions in der Zeitbox
|
||||
- Kairo-Steuerung statt Scrum-Master-Rolle
|
||||
- **Nicht:** Team-Board, Velocity
|
||||
|
||||
### D1 — Buch / Konzept (Stufe B)
|
||||
|
||||
- Kapitel als `chapter` RoadmapItems; mindestens ein Schreib-AP committet
|
||||
- Kontrolle: nächstes Kapitel / aktuelles Schreib-AP
|
||||
|
||||
---
|
||||
|
||||
## 9. Implementierungsfolge (nach PO-Freigabe dieses Dokuments)
|
||||
|
||||
**Kein weiterer „Plan-Modus-Politur“-Slice ohne Steuerungs-Bezug.**
|
||||
|
||||
```text
|
||||
1. ADP Archetype & Method Catalog v0.2 — ✓ PO-freigegeben 2026-07-10
|
||||
2. AP2.0a Method Registry: Stubs inkl. program_delivery, continuous_product, agile_iteration
|
||||
3. AP2.0b Archetyp-Seeds (Initiative + Project Spiegel); EFS; Referenz-Ausprägungen (Kumite, Buch, Kairo)
|
||||
4. AP2.0c Kontrolle/Lagebild: Methode + Next Action + Attention (Hauptfläche)
|
||||
5. AP2.0d Next-Action-Strategien: maturity, sequential, recurring, queue (minimal)
|
||||
6. AP2.0f work_cycle + actions.work_cycle_id; Sprint auf Product; agile_iteration Profil
|
||||
7. AP2.0g A3 Score + freiwillige Übernahme (Stufe B+)
|
||||
8. AP2.1 Referenz-Abnahme A1, A2, B2b (+ B3 minimal), D1 (Validation v0.3)
|
||||
9. Parallel wenn tragfähig: AP1.13 Gate-Graph für A2/B2 — nicht Default für alle
|
||||
```
|
||||
|
||||
Bestehende APs (1.12, 1.10, 1.5d) bleiben **Infrastruktur** — werden im MVP v0.3 erst **wertvoll**, wenn 2.0c/2.0d/2.0f sie archetyp- und methodengebunden nutzen.
|
||||
|
||||
---
|
||||
|
||||
## 10. Dokumentenpriorität bei Konflikten
|
||||
|
||||
Bei MVP-Fragen gilt:
|
||||
|
||||
1. Dieses Dokument (v0.3) + `ADP_Archetype_and_Method_Catalog_v0.2.md`
|
||||
2. `Kairo_Vision_and_Product_Direction_v0.2.md`
|
||||
3. `Kairo_Canonical_Operating_Model_v0.2.md`
|
||||
4. `Kairo_Corrected_MVP_Roadmap_v0.2.md` (AP-Reihenfolge, technisch)
|
||||
5. Sprint Completion Reports (historisch)
|
||||
|
||||
---
|
||||
|
||||
## 11. PO-Freigabe
|
||||
|
||||
- [x] Nordstern und Anti-Patterns akzeptiert
|
||||
- [x] Referenz-Portfolio A1–D1 als Katalog akzeptiert
|
||||
- [x] Vier-Schichten-Modell (ADP §2.0) akzeptiert
|
||||
- [x] B2a/B2b + B3-Profil; Project-Spiegel-Modell akzeptiert
|
||||
- [x] Abnahfe Stufe A = A1 + A2 + B2b + B3-minimal; Stufe B = A3, B1, D1
|
||||
- [x] Sprint-Semantik (Product Backlog vs. Sprint-Backlog) akzeptiert
|
||||
- [x] Implementierungsfolge §9 akzeptiert
|
||||
- [x] Kein MVP-Fortschritt mehr ohne sichtbare Steuerung pro Archetyp
|
||||
|
||||
---
|
||||
|
||||
## Referenzen
|
||||
|
||||
- `docs/architecture/ADP_Archetype_and_Method_Catalog_v0.2.md`
|
||||
- `docs/architecture/Kairo_Method_Design_Principles_v0.1.md`
|
||||
- `docs/architecture/Kairo_Target_Architecture_Method_Driven_Adaptive_Steering_Core_v0.1.md`
|
||||
- `docs/product/Kairo_Implementation_Truth_Table_v0.1.md`
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
# AP2.0 — Steering, Archetypen & Ausprägungen (Minimal Complete Slice)
|
||||
## Implementierungsauftrag v0.1
|
||||
|
||||
**Status:** umgesetzt (2026-07-10)
|
||||
**Stand:** 2026-07-10
|
||||
**PO-Basis:** `ADP_Archetype_and_Method_Catalog_v0.2.md` §11, `Kairo_MVP_Definition_v0.3.md`
|
||||
**Vorgänger:** AP1.10 (EFS), AP1.1 (Method Registry), AP1.9 (Kontrolle-Shell)
|
||||
**Zielversion:** `0.18.0-ap2.0` · Schema `019`
|
||||
|
||||
---
|
||||
|
||||
## 1. Ziel
|
||||
|
||||
Erster **Minimal Complete Steering Slice**: Archetyp-Katalog und Methoden-Module sind registriert; neues Vorhaben startet mit **passender Default-Methode**; **Kontrolle** zeigt Methode, Archetyp, Lifecycle, Next Actions **mit Begründung** — nicht nur Zähler.
|
||||
|
||||
**Leitfrage-Test (MVP §5):** Nutzer kann für ein Kairo-Product-Vorhaben in ≤2 Minuten beantworten: *Was ist als Nächstes dran — und warum?*
|
||||
|
||||
---
|
||||
|
||||
## 2. Vier Schichten — was dieser Slice liefert
|
||||
|
||||
| Schicht | AP2.0 | Nicht in AP2.0 |
|
||||
|---------|-------|----------------|
|
||||
| **0 Framework** | unverändert nutzen | Waiting Runtime, Workflow |
|
||||
| **1 Methode** | **2.0a** — alle Keys registriert; 2 Strategien (program/continuous) | Volle Builder, KI |
|
||||
| **2 Archetyp** | **2.0b** — Initiative + Project Spiegel, Default-Methode | Tenant-Designer |
|
||||
| **3 Ausprägung** | **2.0b** — 3 Code-Seeds (Kumite, Buch, Kairo) | `method_profiles`-DB, UI |
|
||||
| **4 Integration** | — | MCP, Gitea, KI |
|
||||
|
||||
---
|
||||
|
||||
## 3. Arbeitspakete
|
||||
|
||||
### AP2.0a — Method Registry erweitern
|
||||
|
||||
**DoD:**
|
||||
|
||||
- [ ] Registriert: `program_delivery`, `continuous_product`, `maturity_progression`, `sequential_dependency`, `recurring_control`, `queue_pull`, `agile_iteration`, `dispute_procedure`, `chapter_based_progression`
|
||||
- [ ] Legacy `product_milestone_driven` bleibt (Alias-Kompatibilität)
|
||||
- [ ] Next-Action-Strategien: `program_delivery` (Gate-Horizont), `continuous_product` (Ist zuerst, dann Plan)
|
||||
- [ ] Stubs nutzen `default`-Strategy bis AP2.0d
|
||||
- [ ] `GET /api/steering/methods` listet alle Methoden
|
||||
- [ ] pytest: Methoden registriert, unbekannte Keys abgewiesen
|
||||
|
||||
**Nicht-Scope:** Structure Builder, Hook-Handler mit MCP, Method Profiles DB.
|
||||
|
||||
---
|
||||
|
||||
### AP2.0b — Archetyp- & Project-Spiegel
|
||||
|
||||
**DoD:**
|
||||
|
||||
- [ ] `entity_archetypes` Seeds: alle Initiative-Archetypen aus ADP §3.1 + Project-Spiegel §4.1
|
||||
- [ ] Jeder Initiative-Archetyp: `default_method_key` (Code-Registry, API-Response)
|
||||
- [ ] Migration **019**: `projects.archetype_key` NULL → Default = Mirror der Initiative bei INSERT
|
||||
- [ ] `create_initiative` → SteeringContext mit **Archetyp-Default-Methode** (nicht blind `generic_operating`)
|
||||
- [ ] `create_project` → `archetype_key` = Mirror der Initiative
|
||||
- [ ] 3 Referenz-**Ausprägungen** (Code-Seeds): `maturity.karate_kumite`, `content.book_writing`, `product.kairo_dev`
|
||||
- [ ] EFS: mindestens Felder für `initiative.product`, `initiative.content_project`, `initiative.maturity_journey`
|
||||
- [ ] pytest: Product → `continuous_product`; Project erbt Archetyp
|
||||
|
||||
**Nicht-Scope:** Graph-Designer, Score-Logik (→ AP2.0g), `method_profiles`-Tabelle.
|
||||
|
||||
---
|
||||
|
||||
### AP2.0c — Kontrolle / Lagebild
|
||||
|
||||
**DoD:**
|
||||
|
||||
- [ ] `steering-snapshot` enthält: `archetype_key`, `archetype_label`, optional `method_profile_key`, `steering_guidance` (1 Satz)
|
||||
- [ ] Next Actions enthalten `reason_code` / `recommended_action` sichtbar in UI
|
||||
- [ ] `SteeringSnapshotPanel`: Archetyp-Zeile, Guidance, Attention aus Signals
|
||||
- [ ] Kein neues Omnibus-CRUD; nutzt bestehende Kontrolle-Route (`ControlStatusPage`)
|
||||
- [ ] pytest: Snapshot-Felder für Product-Initiative
|
||||
|
||||
**Nicht-Scope:** Burndown, Kanban, Sprint-UI (→ AP2.0f), Gate-Graph (→ AP1.13).
|
||||
|
||||
---
|
||||
|
||||
## 4. Referenz-Abnahme (manuell nach Deploy)
|
||||
|
||||
1. Vorhaben **Kairo** anlegen: Archetyp `initiative.product` → Methode `continuous_product`
|
||||
2. Kontrolle: Lifecycle, Methode, Archetyp, ≥1 Next Action mit Begründung
|
||||
3. Project anlegen → `archetype_key` = `project.product`
|
||||
4. Optional: Archetyp `initiative.content_project` + Feldprofil sichtbar
|
||||
|
||||
---
|
||||
|
||||
## 5. Explizit nicht in AP2.0
|
||||
|
||||
- Kanban-Board, Velocity, Burndown
|
||||
- `work_cycle` / Sprint (`actions.work_cycle_id`) — AP2.0f
|
||||
- A3 Score / freiwillige Übernahme — AP2.0g
|
||||
- Gate-Graph-Designer — AP1.13
|
||||
- MCP / Gitea / KI-Anbindung — eingefroren
|
||||
- `method_profiles` PostgreSQL-Tabelle
|
||||
- Archetyp-Designer Admin-UI
|
||||
|
||||
---
|
||||
|
||||
## 6. Reihenfolge & Abhängigkeiten
|
||||
|
||||
```text
|
||||
AP2.0a → AP2.0b → AP2.0c (ein Release-Strang 0.18.0-ap2.0)
|
||||
Danach: AP2.0d (Strategien pro Archetyp), AP2.0f (Sprint), AP2.0g (Score)
|
||||
```
|
||||
|
||||
**Guardrail:** Kein AP1.12/Plan-Politur-Commit ohne Bezug zu §3 AP2.0c DoD.
|
||||
|
||||
---
|
||||
|
||||
## 7. Referenzen
|
||||
|
||||
- `docs/architecture/ADP_Archetype_and_Method_Catalog_v0.2.md`
|
||||
- `docs/product/Kairo_MVP_Definition_v0.3.md`
|
||||
- `docs/architecture/Kairo_Method_Design_Principles_v0.1.md`
|
||||
- `docs/sprints/Sprint1_AP1_1_Method_Registry_Assignment_v0.1.md`
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "kairo-jinkendo-frontend",
|
||||
"version": "0.17.0-ap1.5d",
|
||||
"version": "0.18.0-ap2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,11 @@ export function SteeringSnapshotPanel({
|
|||
lifecycle_label,
|
||||
method_key,
|
||||
method_label,
|
||||
archetype_key,
|
||||
archetype_label,
|
||||
method_profile_key,
|
||||
steering_guidance,
|
||||
attention_items = [],
|
||||
signals = [],
|
||||
counts,
|
||||
upcoming_milestones = [],
|
||||
|
|
@ -74,6 +79,9 @@ export function SteeringSnapshotPanel({
|
|||
<h2 className="steering-hero-title">
|
||||
Wo stehe ich — und was ist als Nächstes dran?
|
||||
</h2>
|
||||
{steering_guidance && (
|
||||
<p className="steering-guidance">{steering_guidance}</p>
|
||||
)}
|
||||
</div>
|
||||
<span className="badge status-badge status-active steering-lifecycle-badge">
|
||||
{displayLabel}
|
||||
|
|
@ -81,6 +89,12 @@ export function SteeringSnapshotPanel({
|
|||
</header>
|
||||
|
||||
<div className="steering-hero-toolbar">
|
||||
{(archetype_label || archetype_key) && (
|
||||
<p className="steering-archetype-row muted">
|
||||
Archetyp: <strong>{archetype_label || archetype_key}</strong>
|
||||
{method_profile_key ? ` · Ausprägung: ${method_profile_key}` : ''}
|
||||
</p>
|
||||
)}
|
||||
{(method_label || canManageMethod) && (
|
||||
<p className="steering-method-row">
|
||||
<span className="muted">Methode: </span>
|
||||
|
|
@ -117,9 +131,13 @@ export function SteeringSnapshotPanel({
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
{signals?.length > 0 && (
|
||||
<p className="muted snapshot-signals">
|
||||
{signals.map((s) => SIGNAL_LABELS[s] || s).join(' · ')}
|
||||
{(attention_items?.length > 0 || signals?.length > 0) && (
|
||||
<p className="muted snapshot-signals snapshot-attention">
|
||||
Attention:{' '}
|
||||
{(attention_items.length > 0
|
||||
? attention_items.map((a) => a.label)
|
||||
: signals.map((s) => SIGNAL_LABELS[s] || s)
|
||||
).join(' · ')}
|
||||
</p>
|
||||
)}
|
||||
|
||||
|
|
@ -135,6 +153,7 @@ export function SteeringSnapshotPanel({
|
|||
<strong>{item.title}</strong>
|
||||
<span className="muted list-item-sub">
|
||||
{NEXT_ACTION_KIND_LABELS[item.kind] || item.kind}
|
||||
{item.reason_code ? ` · ${item.reason_code}` : ''}
|
||||
{item.recommended_action ? ` — ${item.recommended_action}` : ''}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -716,6 +716,21 @@
|
|||
margin: 0.75rem 0 0;
|
||||
}
|
||||
|
||||
.steering-guidance {
|
||||
margin: 0.35rem 0 0;
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-secondary, #555);
|
||||
}
|
||||
|
||||
.steering-archetype-row {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.snapshot-attention {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.steering-method-row {
|
||||
margin: 0.5rem 0 0;
|
||||
font-size: 0.9rem;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user