fix(kanban): claim-less complete no longer closes a live worker's run
complete_task authorised a terminal transition by task status alone; the `current_run_id = ?` fence only applied when the caller volunteered expected_run_id (derived from HERMES_KANBAN_* env). A human at the CLI, an orchestrator session or any env-less caller therefore marked a `running` card done and _end_run closed the dispatcher worker's run row while that worker kept executing (#111764). Mirror the fence request_review already carries: a `running` task under a live claim needs expected_run_id (worker ownership) or force=True (explicit operator override), otherwise LiveClaimError. `hermes kanban complete --force` and the dashboard's "mark done" (a human action) carry the override; the kanban_complete tool reports a structured refusal. Completing `ready`, `blocked` or `review` cards without a claim is unchanged, so the manual / orchestrator flows PR #73188 pinned keep working. Fixes #111764
This commit is contained in:
@@ -598,6 +598,12 @@ def _handle_complete(args: dict, **kw) -> str:
|
||||
f"Your task is still in-flight and its scratch workspace was kept. Fix the "
|
||||
f"artifact path or storage error, then retry kanban_complete with the same "
|
||||
f"handoff.")
|
||||
except kb.LiveClaimError as claim_err:
|
||||
# Env-less caller (orchestrator, another session) on a card a dispatcher
|
||||
# worker is executing: refusing here is what keeps that worker's run open.
|
||||
return tool_error(
|
||||
f"kanban_complete refused: {claim_err}. Nothing changed. Wait for the worker "
|
||||
f"to finish, or an operator can run `hermes kanban complete --force {tid}`.")
|
||||
except kb.HallucinatedCardsError as hall_err:
|
||||
# The gate runs before the write txn, so the task was NOT mutated;
|
||||
# say so explicitly or the model treats the error as terminal and
|
||||
|
||||
Reference in New Issue
Block a user