Add workplan execution queue

This commit is contained in:
2026-05-23 19:11:30 +02:00
parent 0ea46f081c
commit d4dea7864d
13 changed files with 1022 additions and 10 deletions

View File

@@ -806,3 +806,139 @@ class TestReconciliationEndpoints:
r = await client.get(f"/tasks/{task['id']}")
assert r.json()["status"] == "todo"
class TestExecutionQueueEndpoints:
async def test_execution_semantics_separates_state_hub_and_activity_core(self, client):
r = await client.get("/execution/semantics")
assert r.status_code == 200
body = r.json()
assert "queued" in body["execution_states"]
assert "immediate" in body["launch_modes"]
assert "parallel" in body["concurrency_modes"]
assert any("launch requests" in item for item in body["state_hub_responsibility"])
assert any("dispatch" in item for item in body["activity_core_responsibility"])
async def test_execution_intent_update_does_not_change_lifecycle_status(self, client):
await _create_domain(client)
topic = await _create_topic(client)
ws = await _create_workstream(client, topic["id"], status="ready")
r = await client.patch(f"/execution/workstreams/{ws['id']}/intent", json={
"execution_state": "queued",
"launch_mode": "queued",
"concurrency_mode": "parallel",
"queue_rank": 7,
"execution_group": "ui-state",
})
assert r.status_code == 200, r.text
body = r.json()
assert body["execution_state"] == "queued"
assert body["launch_mode"] == "queued"
assert body["concurrency_mode"] == "parallel"
assert body["queue_rank"] == 7
r = await client.get(f"/workstreams/{ws['id']}")
assert r.json()["status"] == "ready"
assert r.json()["execution_state"] == "queued"
async def test_workplan_stack_orders_eligible_queued_work_before_blocked(self, client):
await _create_domain(client)
topic = await _create_topic(client)
queued = await _create_workstream(
client,
topic["id"],
slug="queued-wp",
status="ready",
planning_priority="high",
planning_order=2,
)
blocked = await _create_workstream(
client,
topic["id"],
slug="blocked-wp",
status="ready",
planning_priority="high",
planning_order=1,
)
lifecycle_blocked = await _create_workstream(
client,
topic["id"],
slug="lifecycle-blocked-wp",
status="blocked",
planning_priority="high",
planning_order=0,
)
dependency = await _create_workstream(
client,
topic["id"],
slug="dependency-wp",
status="active",
planning_priority="low",
planning_order=3,
)
await client.patch(f"/execution/workstreams/{queued['id']}/intent", json={
"execution_state": "queued",
"launch_mode": "queued",
"queue_rank": 2,
})
await client.patch(f"/execution/workstreams/{blocked['id']}/intent", json={
"execution_state": "queued",
"launch_mode": "queued",
"queue_rank": 1,
})
await client.patch(f"/execution/workstreams/{lifecycle_blocked['id']}/intent", json={
"execution_state": "queued",
"launch_mode": "queued",
"queue_rank": 0,
})
await client.post(
f"/workstreams/{blocked['id']}/dependencies/",
json={"to_workstream_id": dependency["id"], "description": "wait"},
)
r = await client.get("/execution/workplan-stack?include_manual=false")
assert r.status_code == 200, r.text
rows = r.json()
assert [row["slug"] for row in rows] == ["queued-wp", "lifecycle-blocked-wp", "blocked-wp"]
assert rows[0]["eligible"] is True
assert rows[1]["eligible"] is False
assert rows[1]["status"] == "blocked"
assert rows[2]["eligible"] is False
assert rows[2]["blocked_by_workstream_ids"] == [dependency["id"]]
async def test_launch_request_records_handoff_and_updates_execution_intent(self, client):
await _create_domain(client)
topic = await _create_topic(client)
ws = await _create_workstream(client, topic["id"], status="ready")
r = await client.post("/execution/launch-requests", json={
"workstream_id": ws["id"],
"requested_by": "dashboard",
"requested_actor": "activity-core",
"launch_mode": "immediate",
"concurrency_mode": "sequential",
"priority": "high",
"branch_preference": "codex/state-wp-0049",
"immediate_pickup": True,
"notes": "start now",
})
assert r.status_code == 201, r.text
body = r.json()
assert body["workstream_id"] == ws["id"]
assert body["launch_mode"] == "immediate"
assert body["immediate_pickup"] is True
assert body["status"] == "requested"
r = await client.get(f"/workstreams/{ws['id']}")
updated = r.json()
assert updated["status"] == "ready"
assert updated["execution_state"] == "launching"
assert updated["launch_mode"] == "immediate"
r = await client.get(f"/execution/launch-requests?workstream_id={ws['id']}")
assert len(r.json()) == 1