Persistierter Standard Lifecycle pro Initiative, backend/steering/ Skeleton, Attention-Refactor und Hook-Dispatch als Basis für Method Registry. Co-authored-by: Cursor <cursoragent@cursor.com>
6.6 KiB
AP1.0 — Steering Foundation (Skeleton)
Implementierungsauftrag v0.1
Status: umgesetzt
Stand: 2026-07-05
Vorgänger: AP0.10b ✓
ADP: docs/architecture/ADP_AP1_0_Steering_Foundation_Scope_Lock_v0.1.md
Zielversion: 0.11.0-ap1.0 · Schema 009
Ziel
Eine persistierte Steuerungswahrheit pro Initiative — Standard Lifecycle als Foundation, in die Methoden später einhängen.
Leitfrage bleibt: Welcher nächste Schritt bringt ein Vorhaben am wirkungsvollsten voran? — technisch beantwortet über SteeringContext.lifecycle_state + Signal Engine, nicht über verstreute Heuristiken.
Scope Lock (verbindlich)
Siehe ADP § Scope Lock. Kein AP0.10c. Keine neuen Attention-Regeln. Keine neuen OM-Tabellen außer steering_contexts.
Teil A — Schema 009
Tabelle steering_contexts
CREATE TABLE steering_contexts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
initiative_id UUID NOT NULL REFERENCES initiatives(id) ON DELETE CASCADE,
method_key VARCHAR(64) NOT NULL DEFAULT 'generic_operating',
method_version VARCHAR(32) NOT NULL DEFAULT '0.1.0',
lifecycle_state VARCHAR(64) NOT NULL DEFAULT 'intake',
lifecycle_metadata JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (tenant_id, initiative_id)
);
CREATE INDEX idx_steering_contexts_tenant ON steering_contexts(tenant_id);
Backfill (Seed oder Migration-Block)
Bestehende Initiativen erhalten Context:
| Bedingung | lifecycle_state |
|---|---|
status IN (completed, archived) |
closure |
| offene Actions existieren | action_selection |
| nur Backlog (new/triaged/accepted), keine offenen Actions | structure_setup |
| sonst active/paused | planning |
Teil B — backend/steering/
B1 — Lifecycle
Datei: steering/lifecycle/states.py
STANDARD_LIFECYCLE_STEPS = (
"intake", "method_selection", "structure_setup", "planning",
"action_selection", "assignment", "waiting", "result_intake",
"validation", "review", "adaptation", "closure",
)
Datei: steering/lifecycle/orchestrator.py
get_lifecycle_state(ctx, initiative_id) -> strtransition(ctx, initiative_id, to_state, *, reason: str) -> dict— Guard minimal: nur erlaubte Übergänge ausgeneric_operatingoder freier Übergang für AP1.0 stub- Audit-Log bei Transition
B2 — Hook Registry
Datei: steering/hooks/registry.py
HookDefinitiondataclass (slug, lifecycle_step, description, since_version)register_hook(),get_hook(),list_hooks()- Registrierung der Slugs aus Target Architecture §7.3 (Definition only, Implementierung stub)
Datei: steering/hooks/dispatch.py
dispatch_hook(slug, ctx, payload) -> list[dict]— ruft registrierte Handler; AP1.0: leere Handler + Audit-Eintrag
B3 — Method Registry
Datei: steering/methods/registry.py + registrations/generic_operating.py
- Eine Built-in-Methode:
generic_operating - Liefert:
default_lifecycle_steps, erlaubte Hooks (alle globalen), keine Structure Builder
B4 — Signal Engine
Datei: steering/signals/default_rules.py
- Bestehende Regeln aus
data_layer/attention.pyverschieben (nicht duplizieren) evaluate_attention(ctx) -> list[dict]evaluate_next_actions(ctx, *, limit, initiative_id=None) -> list[dict]
Datei: steering/signals/engine.py
evaluate(ctx, kind='attention'|'next_action', **kwargs)— delegiert an default_rules
Datei: data_layer/attention.py
- Wird dünner Wrapper um
steering.signals.engine(API-Kompatibilität)
B5 — Steering Context Service
Datei: steering/context.py + services/steering_context.py (Write)
get_or_create_for_initiative(ctx, initiative_id)get_steering_context(ctx, initiative_id) -> Optional[dict]- Tenant-scoped; Cross-Tenant → None / 404
Teil C — Integration bestehender Flows
C1 — operating_transitions.py
Vor/nach bestehender Logik:
from steering.hooks.dispatch import dispatch_hook
dispatch_hook("on_blocker_resolved", ctx, {...})
# optional: lifecycle transition assignment → action_selection
Verhalten Blocker→entblocken unverändert (Regression-Tests).
C2 — initiative_snapshot.py
Snapshot ergänzt:
{
"lifecycle_state": "action_selection",
"lifecycle_label": "Maßnahmen auswählen",
"operating_phase": "execute",
"operating_phase_deprecated": true
}
_derive_operating_phase bleibt für Rückwärtskompatibilität; markiert deprecated in Docstring.
C3 — Initiative Create
Bei create_initiative → steering_contexts Zeile anlegen (lifecycle_state=intake oder Backfill-Regel).
Teil D — API
| Endpoint | Capability | Beschreibung |
|---|---|---|
GET /api/initiatives/{id}/steering-context |
kairo.initiative.read |
Context DTO |
GET .../steering-snapshot |
(bestehend) | + lifecycle Felder |
Teil E — Frontend (minimal)
Datei: frontend/src/constants/operating.js
LIFECYCLE_LABELSfür 12 Standard-Schritte (DE)- Steuerungszustand-Panel: primär
lifecycle_label;operating_phasenur Fallback
Kein Maßnahmen-Hub. Keine neuen Widgets.
Teil F — Tests
| Test | Erwartung |
|---|---|
test_ap1_steering_context.py |
CRUD Context, tenant isolation |
test_ap1_lifecycle.py |
Transition + Audit |
test_ap1_signals_regression.py |
Attention/NextAction gleich wie vor Refactor |
test_ap10_integration.py |
weiter grün; Snapshot hat lifecycle_state |
Nicht-Scope
- Workflow Runtime, Waiting/Reminder Scheduler
- Zweite Built-in-Methode (
product_milestone_driven) → AP1.1 roadmap_items,projects,milestones-Migration- AP0.10c UI
- Prompt/KI/MCP
- Entfernen von
operating_phase→ AP1.2
Abnahme
- Migration 009 deployed; bestehende Initiativen haben Context
backend/steering/existiert mit Lifecycle, Hooks, Methods, Signals- Attention/NextAction APIs unverändert im Verhalten (Regression)
- Snapshot + neuer steering-context Endpoint liefern
lifecycle_state - Scope Lock aus ADP eingehalten (kein AP0.10c)
- pytest grün remote
Reihenfolge Implementierung
- Migration 009 + Backfill
steering/lifecycle,steering/context- Initiative-Create Hook
steering/signalsRefactor aus attention.py- Hook dispatch in operating_transitions
- API + Snapshot + Frontend Labels
- Tests + Version bump
Nächster Schritt nach Abnahme: AP0.10d Validation Report, dann AP1.1 Method Registry erweitern