Close lifecycle transition helper workplan

This commit is contained in:
2026-05-23 18:42:32 +02:00
parent ab23ef4f1f
commit 0ea46f081c
8 changed files with 221 additions and 19 deletions

View File

@@ -11,7 +11,12 @@ from api.models.task import Task
from api.models.task import TaskStatus
from api.models.workstream import Workstream
from api.schemas.reconciliation import StateChangeRequest, StateChangeResponse
from api.services.lifecycle import status_value
from api.services.lifecycle import (
should_activate_parent_for_task_start,
status_value,
transition_task_status,
transition_workstream_status,
)
from api.services.reconciliation import (
ReconciliationClass,
StateChangeClassification,
@@ -172,7 +177,7 @@ async def classify_state_change(
)
conflict = True
else:
ws.status = target_status
transition_workstream_status(ws, target_status)
await session.commit()
write_result = "applied"
@@ -281,24 +286,54 @@ async def classify_state_change(
)
conflict = True
else:
original_text = None
parent_will_activate = should_activate_parent_for_task_start(
previous_task_status=current_status,
new_task_status=target_status,
parent_workstream_status=ws.status if ws else None,
)
try:
original_text = workplan_ref.path.read_text(encoding="utf-8")
patch_task_status(workplan_ref.path, task.id, target_status)
patched_status = status_value(task_block_status(workplan_ref.path, task.id))
if parent_will_activate:
patch_workplan_status(workplan_ref.path, "active")
parent_status = normalize_workstream_status(workplan_status(workplan_ref.path))
if parent_status != "active":
if original_text is not None:
workplan_ref.path.write_text(original_text, encoding="utf-8")
classification = _conflict(
"parent workplan status could not be patched to 'active'",
"inspect the workplan frontmatter format before retrying",
)
conflict = True
except OSError as exc:
if original_text is not None:
workplan_ref.path.write_text(original_text, encoding="utf-8")
classification = _conflict(
f"workplan task write failed: {exc}",
"fix repo file access and retry the reconciliation",
)
conflict = True
else:
if patched_status != target_status:
if conflict:
pass
elif patched_status != target_status:
if original_text is not None:
workplan_ref.path.write_text(original_text, encoding="utf-8")
classification = _conflict(
f"workplan task block could not be patched to {target_status!r}",
"inspect the task block format before retrying",
)
conflict = True
else:
task.status = TaskStatus(target_status)
transition = transition_task_status(
task,
target_status,
parent_workstream=ws,
previous_task_status=current_status,
status_coercer=TaskStatus,
)
if body.blocking_reason is not None:
task.blocking_reason = body.blocking_reason
await session.commit()