Map every State Hub/core-hub caller to a post-retirement owner. Keep the 15-minute sweep schedule here and point the engine at repo-manager (State Hub dual-run by default, REPO_MANAGER_URL when present). Publish GET /execution/semantics and 410 workplan launch routes so State Hub /execution/* is not re-homed as a task database. T03 still waits on HUB-WP-0004.
88 lines
3 KiB
Python
88 lines
3 KiB
Python
"""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.",
|
|
)
|