"""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.2" 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")