"""Execution-queue contract surface (ACTIVITY-WP-0029-T04). Workplan launch rows stay out of this API. Callers that send State Hub ``/execution/*`` workplan shapes get 410 with a replacement pointer. """ from __future__ import annotations from fastapi import APIRouter from fastapi.responses import JSONResponse router = APIRouter(prefix="/execution", tags=["execution"]) SEMANTICS = { "port": "port.schedule", "document": "docs/execution-queue-boundary.md", "activity_core_owns": [ "schedules, wakeups, and recurring ActivityDefinition fires", "POST /activity-definitions/{id}/trigger", "ops_run claim, heartbeat, complete, and fail", ], "activity_core_does_not_own": [ "workplan and task files (ADR-001 / repo-manager index)", "task lifecycle assign/track/close (issue-core / work records)", "ITC Task Model types", "policy publication (policy-nexus)", "C-rule consistency engine (repo-manager)", ], "replacements": { "GET /execution/semantics": "GET /execution/semantics", "GET /execution/launch-requests": "GET /ops-runs", "POST /execution/launch-requests": ( "POST /activity-definitions/{id}/trigger for a schedule fire; " "do not POST workplan ids here" ), "GET /execution/workplan-stack": "repo-manager port.work / hub-core projection", "PATCH /execution/workplans/{id}/intent": "edit the workplan file in its repo", }, } @router.get("/semantics") async def execution_semantics() -> dict: return SEMANTICS def _gone(replacement: str, detail: str) -> JSONResponse: return JSONResponse( status_code=410, content={ "detail": detail, "replacement_ref": replacement, "document": "docs/execution-queue-boundary.md", }, ) @router.api_route("/launch-requests", methods=["GET", "POST"]) async def launch_requests_retired() -> JSONResponse: return _gone( SEMANTICS["replacements"]["GET /execution/launch-requests"], "Workplan launch-requests are not stored in activity-core. " "Use GET /ops-runs or POST /activity-definitions/{id}/trigger.", ) @router.get("/workplan-stack") async def workplan_stack_retired() -> JSONResponse: return _gone( SEMANTICS["replacements"]["GET /execution/workplan-stack"], "Workplan stacks are a work-record index, not an ops-run queue.", ) @router.patch("/workplans/{workplan_id}/intent") async def workplan_intent_retired(workplan_id: str) -> JSONResponse: return _gone( SEMANTICS["replacements"]["PATCH /execution/workplans/{id}/intent"], "Execution intent for a workplan belongs in the repo file, not here.", ) @router.patch("/workstreams/{workstream_id}/intent") async def workstream_intent_retired(workstream_id: str) -> JSONResponse: return _gone( SEMANTICS["replacements"]["PATCH /execution/workplans/{id}/intent"], "Legacy workstream execution intent is retired with State Hub.", )