All checks were successful
Deploy Development / deploy (push) Successful in 47s
Test Suite / pytest-backend (push) Successful in 4m15s
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 19s
Test Suite / playwright-smoke (push) Successful in 20s
Behebt 6 CI-Failures nach Agent-Slots/Tech-Debt-Release. Co-authored-by: Cursor <cursoragent@cursor.com>
166 lines
4.9 KiB
Python
166 lines
4.9 KiB
Python
"""Steering Kernel Spine v0.2 — events + continuous_product."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from tests.factories import provision_user_in_tenant
|
|
from tests.test_initiatives_actions import _auth, _create_initiative, _login
|
|
|
|
|
|
def test_action_done_emits_lifecycle_via_kernel(client):
|
|
user = provision_user_in_tenant(tenant_role="admin")
|
|
token = _login(client, user)
|
|
|
|
created = _create_initiative(
|
|
client,
|
|
token,
|
|
title="Event Action Done",
|
|
archetype_key="initiative.linear_project",
|
|
apply_starter_kit=False,
|
|
)
|
|
initiative_id = created.json()["id"]
|
|
|
|
action = client.post(
|
|
f"/api/initiatives/{initiative_id}/actions",
|
|
json={"title": "Erledigen", "status": "open"},
|
|
headers=_auth(token),
|
|
)
|
|
assert action.status_code == 201
|
|
|
|
done = client.patch(
|
|
f"/api/actions/{action.json()['id']}",
|
|
json={"status": "done"},
|
|
headers=_auth(token),
|
|
)
|
|
assert done.status_code == 200
|
|
|
|
ctx = client.get(
|
|
f"/api/initiatives/{initiative_id}/steering-context",
|
|
headers=_auth(token),
|
|
)
|
|
assert ctx.status_code == 200
|
|
assert ctx.json()["lifecycle_state"] == "action_selection"
|
|
|
|
|
|
def test_gate_verify_emits_lifecycle_via_kernel(client):
|
|
user = provision_user_in_tenant(tenant_role="admin")
|
|
token = _login(client, user)
|
|
|
|
created = _create_initiative(
|
|
client,
|
|
token,
|
|
title="Event Gate",
|
|
archetype_key="initiative.linear_project",
|
|
)
|
|
initiative_id = created.json()["id"]
|
|
|
|
roadmap = client.get(
|
|
f"/api/initiatives/{initiative_id}/roadmap/items",
|
|
headers=_auth(token),
|
|
)
|
|
active_gate = next(i for i in roadmap.json() if i.get("status") == "active")
|
|
|
|
evidence = client.post(
|
|
f"/api/initiatives/{initiative_id}/evidence",
|
|
json={
|
|
"title": "Gate-Nachweis",
|
|
"roadmap_item_id": active_gate["id"],
|
|
"status": "accepted",
|
|
},
|
|
headers=_auth(token),
|
|
)
|
|
assert evidence.status_code == 201
|
|
|
|
verified = client.post(
|
|
f"/api/roadmap-items/{active_gate['id']}/verify-reached",
|
|
headers=_auth(token),
|
|
)
|
|
assert verified.status_code == 200
|
|
body = verified.json()
|
|
assert body.get("steering_event", {}).get("handled") is True
|
|
assert "validation" in (body.get("steering_event", {}).get("lifecycle_chain") or [])
|
|
|
|
ctx = client.get(
|
|
f"/api/initiatives/{initiative_id}/steering-context",
|
|
headers=_auth(token),
|
|
)
|
|
assert ctx.json()["lifecycle_state"] == "action_selection"
|
|
|
|
|
|
def test_continuous_product_routes_through_spine(client):
|
|
user = provision_user_in_tenant(tenant_role="admin")
|
|
token = _login(client, user)
|
|
|
|
created = _create_initiative(
|
|
client,
|
|
token,
|
|
title="Product Spine",
|
|
archetype_key="initiative.product",
|
|
)
|
|
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()
|
|
kernel = body["steering_kernel"]
|
|
assert kernel["primary_method_key"] == "continuous_product"
|
|
assert kernel["data_source"] == "steering_kernel_v0.4"
|
|
assert kernel["lifecycle"]["slot_map"]["closure"] == "n/a"
|
|
assert kernel["lifecycle"]["slot_map"]["planning"] == "active"
|
|
assert body.get("next_actions") is not None
|
|
|
|
|
|
def test_product_action_done_lifecycle_chain(client):
|
|
user = provision_user_in_tenant(tenant_role="member")
|
|
token = _login(client, user)
|
|
|
|
created = _create_initiative(
|
|
client,
|
|
token,
|
|
title="Product Event",
|
|
archetype_key="initiative.product",
|
|
)
|
|
initiative_id = created.json()["id"]
|
|
|
|
action = client.post(
|
|
f"/api/initiatives/{initiative_id}/actions",
|
|
json={"title": "Fix Bug", "status": "open"},
|
|
headers=_auth(token),
|
|
)
|
|
assert action.status_code == 201
|
|
|
|
client.patch(
|
|
f"/api/actions/{action.json()['id']}",
|
|
json={"status": "done"},
|
|
headers=_auth(token),
|
|
)
|
|
|
|
ctx = client.get(
|
|
f"/api/initiatives/{initiative_id}/steering-context",
|
|
headers=_auth(token),
|
|
)
|
|
assert ctx.json()["lifecycle_state"] == "action_selection"
|
|
|
|
|
|
def test_slot_providers_registered():
|
|
from steering.lifecycle.slot_providers import list_slot_provider_registrations
|
|
|
|
keys = {r.slot_key for r in list_slot_provider_registrations()}
|
|
assert "result_intake" in keys
|
|
assert "validation" in keys
|
|
assert "adaptation" in keys
|
|
|
|
|
|
def test_resolve_lifecycle_chain_respects_slot_map():
|
|
from steering.lifecycle.event_transitions import resolve_lifecycle_chain
|
|
|
|
chain = resolve_lifecycle_chain(
|
|
primary_method_key="generic_operating",
|
|
event_kind="gate_verified",
|
|
payload={},
|
|
)
|
|
assert "validation" not in chain
|
|
assert chain == ("adaptation", "action_selection")
|