hermes - 💡(How to fix) Fix Kanban has no safe task-authoring window: triage bypassed by auto_decompose, "Manual Orchestration" mislabeled, blocking a running task is a no-op

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

The effective user window to fill in a task body before a worker claims it is under one dispatch cycle — often zero, because the specifier runs during the same gateway tick.

Fix Action

Fix / Workaround

Three separate problems compound into a single broken user experience: there is no supported workflow for creating a Kanban task, filling in context, and then releasing it to the dispatcher. Every available mechanism to hold a task either doesn't work as labeled or is immediately undone.

Creating a task into triage should give the user time to fill in context before dispatch. In practice, with auto_decompose: true, the specifier agent promotes triage → todo almost immediately. recompute_ready() then promotes todo → ready, and the dispatcher claims it on the next tick (60s default).

The effective user window to fill in a task body before a worker claims it is under one dispatch cycle — often zero, because the specifier runs during the same gateway tick.

RAW_BUFFERClick to expand / collapse

Three separate problems compound into a single broken user experience: there is no supported workflow for creating a Kanban task, filling in context, and then releasing it to the dispatcher. Every available mechanism to hold a task either doesn't work as labeled or is immediately undone.

This is related to but distinct from #29034 (unbounded swarm defaults). That issue is about the quantity of workers spawned. This issue is about the impossibility of a human-in-the-loop authoring step before any worker is spawned.


The three failure modes

1. Triage is not a safe hold column when auto_decompose: true (the default)

Creating a task into triage should give the user time to fill in context before dispatch. In practice, with auto_decompose: true, the specifier agent promotes triage → todo almost immediately. recompute_ready() then promotes todo → ready, and the dispatcher claims it on the next tick (60s default).

The effective user window to fill in a task body before a worker claims it is under one dispatch cycle — often zero, because the specifier runs during the same gateway tick.

Expected: Triage is a human-controlled holding column. Tasks stay there until the user explicitly promotes them.

Actual: Triage is a 60-second buffer at best, zero at worst.

Root cause: auto_decompose: true is the default. The specifier runs as a background gateway task with no user acknowledgement.


2. The dashboard's "Manual Orchestration" toggle does not stop dispatch

The toggle in the dashboard settings maps to kanban.auto_decompose in config.yaml. It does not affect kanban.dispatch_in_gateway.

A user who finds this setting and enables "Manual Orchestration" reasonably expects it to mean "don't launch workers without my explicit action." It does not. The dispatcher continues to run every 60 seconds and will claim any ready task.

Expected: "Manual Orchestration" = dispatcher does not auto-spawn workers.

Actual: "Manual Orchestration" = specifier AI doesn't auto-promote triage tasks. Dispatcher still runs. Workers still spawn.

Evidence: OrchestrationSettingsBody in plugins/kanban/dashboard/plugin_api.py only writes auto_decompose and auto_promote_children to config. dispatch_in_gateway is never touched by this endpoint.


3. Blocking a running task does not stop the worker

When a task is in running state and the user clicks Block (or runs hermes kanban block <id>), block_task() writes status = 'blocked' to the SQLite DB. The already-spawned worker subprocess does not watch the DB during execution. It runs to completion, calls kanban_complete, and the task transitions to done.

The block is placed against a process that will never read it.

Expected: Blocking a running task interrupts or at minimum prevents the worker from completing.

Actual: Block is a DB write. Worker ignores it. Task ends up done with no user-provided context.

Root cause: block_task() is a DB-only operation. The dispatcher's reclaim path does kill the worker (_terminate_reclaimed_worker → SIGTERM/SIGKILL), but Block does not call reclaim — it only sets the status column.


Steps to reproduce (all three)

  1. Start the gateway with default config (dispatch_in_gateway: true, auto_decompose: true)
  2. Open the dashboard. Enable "Manual Orchestration." Observe: dispatcher is still running.
  3. Create a task. Do not check "Triage." Observe: task is ready immediately and claimed within 60s.
  4. Repeat, this time checking "Triage." Observe: specifier runs and promotes the task before you finish typing the body.
  5. Create a task, wait for it to reach running, then click Block. Observe: task ends up done with no context.

Environment

  • Hermes Agent: main
  • Host: Linux (WSL2, Ubuntu)
  • Gateway: embedded dispatcher, default config
  • dispatch_in_gateway: true, auto_decompose: true, no max_in_progress

Expected behavior

A user should be able to:

  1. Create a task (via UI or CLI)
  2. Fill in the body, assignee, context, skills — at human speed
  3. Explicitly release the task to the dispatcher when ready

This is a standard human-in-the-loop authoring flow. It currently has no supported path.


Suggested fixes

Fix 1 — Make triage actually safe (addresses #1 and partially #4): auto_decompose should be false by default, or triage tasks should require explicit user promotion (not auto-promotion). The specifier should only run when the user requests it.

Fix 2 — Rename or rewire the "Manual Orchestration" toggle (addresses #2): Either: map the toggle to dispatch_in_gateway (what users think it does), or rename it to "Auto-decompose triage" and add a separate "Auto-dispatch ready tasks" toggle that maps to dispatch_in_gateway.

Fix 3 — Block should reclaim the worker (addresses #3): block_task() on a running task should call reclaim_task() internally (SIGTERM + status reset), the same way the dispatcher handles stale claims. A Block that doesn't stop the worker is not a block.

Fix 4 — Explicit "draft" / "hold" state or a safe create flow (addresses all): A draft status (not dispatchable, not auto-promoted) that the user explicitly releases would solve all three problems at once. Alternatively, the create-task UI could default to blocked with an --initial-status blocked pattern, with a prominent "Release to queue" button.


Related

  • #29034 — unbounded default dispatch (same root: dispatcher is always-on with no user gate)
  • #29171 — first-class non-dispatchable waiting states (would directly address Fix 4)
  • #28994 / #28712 — sticky block for review-required (partial fix for #3, but only for worker-initiated blocks)
  • #29014 — blocked tasks repeatedly respawn

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

A user should be able to:

  1. Create a task (via UI or CLI)
  2. Fill in the body, assignee, context, skills — at human speed
  3. Explicitly release the task to the dispatcher when ready

This is a standard human-in-the-loop authoring flow. It currently has no supported path.


Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Kanban has no safe task-authoring window: triage bypassed by auto_decompose, "Manual Orchestration" mislabeled, blocking a running task is a no-op