mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-21 03:39:54 +00:00
fix(kanban): reject direct running transitions in dashboard bulk updates
Salvages #24050 by @kronexoi. The single-task PATCH already rejects direct status='running' since it bypasses the dispatcher/claim invariant, but the bulk-update endpoint still accepted it. Aligns bulk with single by emitting an error result row for any 'running' entry.
This commit is contained in:
@@ -913,7 +913,17 @@ def bulk_update(payload: BulkTaskBody, board: Optional[str] = Query(None)):
|
||||
ok = kanban_db.unblock_task(conn, tid)
|
||||
else:
|
||||
ok = _set_status_direct(conn, tid, "ready")
|
||||
elif s in {"todo", "running", "triage"}:
|
||||
elif s == "running":
|
||||
entry.update(
|
||||
ok=False,
|
||||
error=(
|
||||
"Cannot set status to 'running' directly; "
|
||||
"use the dispatcher/claim path"
|
||||
),
|
||||
)
|
||||
results.append(entry)
|
||||
continue
|
||||
elif s in {"todo", "triage"}:
|
||||
ok = _set_status_direct(conn, tid, s)
|
||||
else:
|
||||
entry.update(ok=False, error=f"unknown status {s!r}")
|
||||
|
||||
@@ -880,6 +880,31 @@ def test_bulk_status_done_forwards_completion_summary(client):
|
||||
conn.close()
|
||||
|
||||
|
||||
def test_bulk_status_running_rejected(client):
|
||||
"""Bulk updates must match single-task PATCH: direct 'running' is invalid."""
|
||||
t = client.post("/api/plugins/kanban/tasks", json={"title": "x"}).json()["task"]
|
||||
|
||||
r = client.post(
|
||||
"/api/plugins/kanban/tasks/bulk",
|
||||
json={"ids": [t["id"]], "status": "running"},
|
||||
)
|
||||
|
||||
assert r.status_code == 200
|
||||
results = r.json()["results"]
|
||||
assert len(results) == 1
|
||||
assert results[0]["id"] == t["id"]
|
||||
assert results[0]["ok"] is False
|
||||
assert "running" in results[0]["error"]
|
||||
|
||||
board = client.get("/api/plugins/kanban/board").json()
|
||||
statuses = {
|
||||
tt["id"]: col["name"]
|
||||
for col in board["columns"]
|
||||
for tt in col["tasks"]
|
||||
}
|
||||
assert statuses.get(t["id"]) != "running"
|
||||
|
||||
|
||||
def test_dashboard_done_actions_prompt_for_completion_summary():
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
bundle = (
|
||||
|
||||
Reference in New Issue
Block a user