refactor(worker): drop ForceSetStatusAsync, route every status write through a guarded transition

Mark-done now fires OnChildTerminalAsync, so ticking a chain child or the last open child
off by hand unblocks the successor and advances the parent. The hub's Mark-as menu and
update_task_status map onto MarkDone/Cancel(retire)/Enqueue/Reset; revert_merge uses the
new ReopenForReviewAsync (Done|WaitingForReview -> WaitingForReview).
This commit is contained in:
mika kuns
2026-10-02 16:03:59 +02:00
parent 59d990c267
commit ff7197c410
9 changed files with 113 additions and 61 deletions
+7 -7
View File
@@ -109,13 +109,13 @@ Description/Result) in `tasksFull` instead (`tasks` null). Filtering by `created
happens before the lean/full projection either way.
**`UpdateTaskStatus`** accepts `Idle` / `Queued` / `Cancelled` / `Done` only.
- `Cancelled` goes through `TaskStateService.CancelAsync(..., allowFromIdle: true)` — the
**only** caller that opts into cancelling from `Idle`. `PlanningChainCoordinator` relies on
`Idle` staying a no-op there by default, because a child parked back to `Idle` mid-chain is
a manual opt-out signal.
- `Done` goes through `TaskStateService.ForceSetStatusAsync` (the same unconditional write the
UI's "set status freely" affordance uses) but is **refused** for a task with an active
worktree, since that would skip `review_task`'s merge.
- `Cancelled` goes through `TaskStateService.CancelAsync(..., retire: true)` — like the UI's
"Mark as cancelled", it opts into cancelling from `Idle`/`Failed`. `PlanningChainCoordinator`
relies on `Idle` staying a no-op there by default, because a child parked back to `Idle`
mid-chain is a manual opt-out signal.
- `Done` goes through `TaskStateService.MarkDoneAsync` (the done toggle, so a chain successor
unblocks and the parent advances) but is **refused** for a task with an active worktree,
since that would skip `review_task`'s merge.
**`AddTask`** — always creates the task; also returns `possibleDuplicates` (up to 3, id/title/status
only, no descriptions) — open (non-terminal) tasks in the *same list* whose normalized title