hermes - 💡(How to fix) Fix [Bug]: Tasks created with --initial-status blocked auto-promote to ready ~1s later with no actor — human approval gate bypassed

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…

Error Message

Additional Logs / Traceback (optional)

Root Cause

In our deployment, blocked is used as a human approval gate: an automated maintenance pipeline files recommended mutations as blocked tasks, and a human is supposed to be the only thing that moves them to ready (authorization = execution). Because blocked tasks self-promote, that gate is bypassed entirely. On 2026-06-04 this caused un-reviewed mutations to execute on a production host with no human in the loop. The concrete damage: a task body ran uv pip install pytest==2.7.0, which downgraded pytest to 2.7.0 in the live service venv at 23:32:52 and left it unable to import (py 1.11.0 too old). A second un-reviewed task ran a Hermes "promotion" against the live install. Neither was ever authorized.

Fix Action

Fix / Workaround

  1. Ensure the dashboard service is running (hermes dashboard), gateway dispatch may be off (kanban.dispatch_in_gateway: false).
  2. Create a task already in the blocked state:
    hermes kanban create "ASSENT: example gated action" --initial-status blocked
  3. Immediately watch the task's events:
    hermes kanban show <task_id>          # or: hermes kanban tail <task_id>
  4. Observe a promoted event ~1 second after created, with no operator unblock and no actor in the event payload, followed by the worker claiming and running the task.
  • Distinct event kinds for both tasks: created, promoted, completedno claimed/started/running event was recorded. hermes kanban show reports each run as @default 0s (#101, #102); hermes kanban log <id> returns no command log.
  • The dispatcher's own counter reported promoted=0. The gateway dispatch loop that emits these counters logged, at 23:32:38 on the incident night: gateway.run: kanban dispatcher: disabled via config kanban.dispatch_in_gateway=false, and every nearby counter line shows ... promoted=0 auto_blocked=0. So the documented dispatch loop was disabled and recorded zero promotions, yet the tasks were promoted anyway — meaning the promote originates from a separate loop that does not attribute the transition.

The locus appears to be the dispatch loop in the dashboard service. Supporting observation: the gateway dispatcher was disabled via kanban.dispatch_in_gateway=false and reported promoted=0, ruling it out; the only other long-running process holding the kanban DB open and writing to it on this box is hermes dashboard --tui. The promote fires ~1s after creation regardless of the gateway dispatcher being off. (Stated as the apparent locus, not a confirmed code path.)

Code Example

hermes kanban create "ASSENT: example gated action" --initial-status blocked

---

hermes kanban show <task_id>          # or: hermes kanban tail <task_id>

---

⚠️  This will upload the following to a public paste service:
System info (OS, Python version, Hermes version, provider, which API keys
    are configured — NOT the actual keys)
Recent log lines (agent.log, errors.log, gateway.log, desktop.log — may
    contain conversation fragments and file paths)
Full agent.log, gateway.log, and desktop.log (up to 512 KB each — likely
    contains conversation content, tool outputs, and file paths)

Pastes auto-delete after 6 hours.

Collecting debug report...
Uploading...

Debug report uploaded:
  Report       https://paste.rs/UcvMs
  agent.log    https://dpaste.com/8UGEV9PSZ
  gateway.log  https://dpaste.com/8FJB3EURT

Pastes will auto-delete in 6 hours.
To delete now:  hermes debug delete <url>

Share these links with the Hermes team for support.

---

### Evidence — verbatim `task_events` rows (SQLite kanban.db)


task_id     ts (local)           kind       payload
----------  -------------------  ---------  -------------------------------------------------
t_e89520e8  2026-06-04 23:30:08  created    {"assignee":"default","status":"blocked", ...}
t_e89520e8  2026-06-04 23:30:09  promoted   (empty payload — no actor)
t_e89520e8  2026-06-04 23:32:44  completed  {"result_len":0,"summary":"Promotion to 96cd37e21 completed. ..."}

t_fcac06bc  2026-06-04 23:30:09  created    {"assignee":"default","status":"blocked", ...}
t_fcac06bc  2026-06-04 23:30:09  promoted   (empty payload — no actor)
t_fcac06bc  2026-06-04 23:33:04  completed  {"result_len":0,"summary":"pytest==2.7.0 install succeeded but import fails. ..."}


- Distinct event kinds for both tasks: `created`, `promoted`, `completed`**no
  `claimed`/`started`/`running` event** was recorded. `hermes kanban show` reports each
  run as `@default 0s` (`#101`, `#102`); `hermes kanban log <id>` returns no command log.
- **The dispatcher's own counter reported `promoted=0`.** The gateway dispatch loop that
  emits these counters logged, at 23:32:38 on the incident night:
  `gateway.run: kanban dispatcher: disabled via config kanban.dispatch_in_gateway=false`,
  and every nearby counter line shows `... promoted=0 auto_blocked=0`. So the documented
  dispatch loop was **disabled and recorded zero promotions**, yet the tasks were promoted
  anyway — meaning the promote originates from a **separate loop** that does not attribute
  the transition.

### Locus

The locus **appears to be the dispatch loop in the dashboard service**. Supporting
observation: the gateway dispatcher was disabled via `kanban.dispatch_in_gateway=false`
and reported `promoted=0`, ruling it out; the only other long-running process holding
the kanban DB open and writing to it on this box is `hermes dashboard --tui`. The
promote fires ~1s after creation regardless of the gateway dispatcher being off. (Stated
as the apparent locus, not a confirmed code path.)

## Affected Component

Kanban — task lifecycle / auto-promote of `blocked` tasks (apparent locus: dashboard
service dispatch loop). Related: #24699 / PR #28712.

## OS

Ubuntu 26.04 LTS (Resolute Raccoon); kernel 7.0.0-22-generic x86_64

## Python Version

3.12.13 (service venv: `~/.hermes/hermes-agent/.venv`)

## Hermes Version

git commit `0401176c7` (`0401176c7ace2f1a76474fa8d0f3899d24c10102`), branch `main`
RAW_BUFFERClick to expand / collapse

Bug Description

A kanban task created with --initial-status blocked is automatically promoted to ready roughly 1 second after creation, with no actor recorded on the transition and no operator action. The task is then claimed and executed by the default worker.

In our deployment, blocked is used as a human approval gate: an automated maintenance pipeline files recommended mutations as blocked tasks, and a human is supposed to be the only thing that moves them to ready (authorization = execution). Because blocked tasks self-promote, that gate is bypassed entirely. On 2026-06-04 this caused un-reviewed mutations to execute on a production host with no human in the loop. The concrete damage: a task body ran uv pip install pytest==2.7.0, which downgraded pytest to 2.7.0 in the live service venv at 23:32:52 and left it unable to import (py 1.11.0 too old). A second un-reviewed task ran a Hermes "promotion" against the live install. Neither was ever authorized.

This appears related to the guarantee in #24699 (closing comment / PR #28712), which states that worker-initiated blocks are NOT auto-promoted and remain blocked until an operator moves them. That guarantee appears to hold for worker-initiated blocks, but is bypassed for tasks created directly in the blocked state via --initial-status blocked: those are auto-promoted within ~1s.

Steps to Reproduce

  1. Ensure the dashboard service is running (hermes dashboard), gateway dispatch may be off (kanban.dispatch_in_gateway: false).
  2. Create a task already in the blocked state:
    hermes kanban create "ASSENT: example gated action" --initial-status blocked
  3. Immediately watch the task's events:
    hermes kanban show <task_id>          # or: hermes kanban tail <task_id>
  4. Observe a promoted event ~1 second after created, with no operator unblock and no actor in the event payload, followed by the worker claiming and running the task.

Expected Behavior

A task created with --initial-status blocked stays blocked until an explicit, attributed operator action (dashboard unblock / kanban unblock) moves it to ready — matching the #24699 / PR #28712 guarantee for worker-initiated blocks. Every status transition should record the actor that performed it.

Actual Behavior

The task is auto-promoted blocked → ready ~1s after creation, with an empty event payload (no actor), then claimed and run by the default worker. The run completes in 0s with no claim/started lifecycle event and no command log, marking the task done (including one whose own summary reports the action failed).

Affected Component

Other

Messaging Platform (if gateway-related)

No response

Debug Report

⚠️  This will upload the following to a public paste service:
  • System info (OS, Python version, Hermes version, provider, which API keys
    are configured — NOT the actual keys)
  • Recent log lines (agent.log, errors.log, gateway.log, desktop.log — may
    contain conversation fragments and file paths)
  • Full agent.log, gateway.log, and desktop.log (up to 512 KB each — likely
    contains conversation content, tool outputs, and file paths)

Pastes auto-delete after 6 hours.

Collecting debug report...
Uploading...

Debug report uploaded:
  Report       https://paste.rs/UcvMs
  agent.log    https://dpaste.com/8UGEV9PSZ
  gateway.log  https://dpaste.com/8FJB3EURT

⏱  Pastes will auto-delete in 6 hours.
To delete now:  hermes debug delete <url>

Share these links with the Hermes team for support.

Operating System

Ubuntu 26.04

Python Version

3.12.13 (service venv: ~/.hermes/hermes-agent/.venv)

Hermes Version

git commit 0401176c7 (0401176c7ace2f1a76474fa8d0f3899d24c10102), branch main

Additional Logs / Traceback (optional)

### Evidence — verbatim `task_events` rows (SQLite kanban.db)


task_id     ts (local)           kind       payload
----------  -------------------  ---------  -------------------------------------------------
t_e89520e8  2026-06-04 23:30:08  created    {"assignee":"default","status":"blocked", ...}
t_e89520e8  2026-06-04 23:30:09  promoted   (empty payload — no actor)
t_e89520e8  2026-06-04 23:32:44  completed  {"result_len":0,"summary":"Promotion to 96cd37e21 completed. ..."}

t_fcac06bc  2026-06-04 23:30:09  created    {"assignee":"default","status":"blocked", ...}
t_fcac06bc  2026-06-04 23:30:09  promoted   (empty payload — no actor)
t_fcac06bc  2026-06-04 23:33:04  completed  {"result_len":0,"summary":"pytest==2.7.0 install succeeded but import fails. ..."}


- Distinct event kinds for both tasks: `created`, `promoted`, `completed` — **no
  `claimed`/`started`/`running` event** was recorded. `hermes kanban show` reports each
  run as `@default 0s` (`#101`, `#102`); `hermes kanban log <id>` returns no command log.
- **The dispatcher's own counter reported `promoted=0`.** The gateway dispatch loop that
  emits these counters logged, at 23:32:38 on the incident night:
  `gateway.run: kanban dispatcher: disabled via config kanban.dispatch_in_gateway=false`,
  and every nearby counter line shows `... promoted=0 auto_blocked=0`. So the documented
  dispatch loop was **disabled and recorded zero promotions**, yet the tasks were promoted
  anyway — meaning the promote originates from a **separate loop** that does not attribute
  the transition.

### Locus

The locus **appears to be the dispatch loop in the dashboard service**. Supporting
observation: the gateway dispatcher was disabled via `kanban.dispatch_in_gateway=false`
and reported `promoted=0`, ruling it out; the only other long-running process holding
the kanban DB open and writing to it on this box is `hermes dashboard --tui`. The
promote fires ~1s after creation regardless of the gateway dispatcher being off. (Stated
as the apparent locus, not a confirmed code path.)

## Affected Component

Kanban — task lifecycle / auto-promote of `blocked` tasks (apparent locus: dashboard
service dispatch loop). Related: #24699 / PR #28712.

## OS

Ubuntu 26.04 LTS (Resolute Raccoon); kernel 7.0.0-22-generic x86_64

## Python Version

3.12.13 (service venv: `~/.hermes/hermes-agent/.venv`)

## Hermes Version

git commit `0401176c7` (`0401176c7ace2f1a76474fa8d0f3899d24c10102`), branch `main`

Root Cause Analysis (optional)

Notes for maintainers

  • Severity is elevated because blocked is being relied on as a security/authorization gate; auto-promotion turns "file for human review" into "execute immediately."
  • Two distinct defects observed: (1) the unattributed blocked → ready auto-promote (this issue), and (2) the worker marking a task done with a 0s run, no claim/started/command-log evidence, and even when its own summary reports failure — worth a separate issue if not already covered.

Proposed Fix (optional)

No response

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING