Skip to content

fix: prevent kanban dispatcher from retrying handoff blocks (#29027) - #29064

Closed
AllynSheep wants to merge 8 commits into
NousResearch:mainfrom
AllynSheep:fix/kanban-handoff-retry-loop
Closed

fix: prevent kanban dispatcher from retrying handoff blocks (#29027)#29064
AllynSheep wants to merge 8 commits into
NousResearch:mainfrom
AllynSheep:fix/kanban-handoff-retry-loop

Conversation

@AllynSheep

Copy link
Copy Markdown
Contributor

Problem

When workers call kanban_block with handoff reasons like review-required:, the dispatcher treats it as a failure and retries the task up to failure_limit times. This causes:

  • Wasted coordinator tokens
  • Polluted run logs
  • Confused orchestrator agents

Root Cause

The dispatcher's failure counting logic doesn't distinguish between:

  • True failures: crashes, timeouts, genuine errors
  • Deliberate handoffs: completed work awaiting review (e.g., review-required:)

Both trigger consecutive_failures incrementing and retry behavior.

Solution

Add a handoff parameter to kanban_block to mark deliberate handoffs. The dispatcher now:

  1. Stores handoff flag in the database (0 = failure, 1 = handoff)
  2. Auto-detects handoff patterns from reason text:
    • review-required:
    • handoff:
    • needs-review:
    • awaiting review:
  3. Skips failure counting and retry logic for handoff blocks

Changes

  • Database: Added handoff INTEGER NOT NULL DEFAULT 0 column to tasks table with migration
  • Core: Updated block_task() to accept handoff parameter
  • Dispatcher: Modified _record_task_failure() to skip handoff blocks
  • Tools: Updated _handle_block() to parse and auto-detect handoff parameter
  • Schema: Added handoff parameter to kanban_block tool registration
  • Documentation: Updated kanban-worker skill with handoff usage guidance
  • Tests: Added comprehensive tests for handoff functionality

Testing

All tests pass:

  • test_handoff_block_prevents_retry(): Verifies handoff blocks don't increment failure counter
  • test_regular_block_counts_as_failure(): Ensures regular blocks still count as failures
  • test_auto_detect_handoff_from_reason(): Tests pattern-based auto-detection

Impact

  • Backward compatible: Existing code continues to work (handoff defaults to 0)
  • User-friendly: Auto-detection means workers don't need to explicitly set handoff=True
  • Efficient: Prevents wasteful retry loops for legitimate handoffs

Fixes #29027

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/tools Tool registry, model_tools, toolsets labels May 20, 2026
…arch#29027)

Add handoff parameter to kanban_block to distinguish deliberate handoffs
(e.g., awaiting review) from genuine failures. The dispatcher now skips
failure counting and retry logic for tasks blocked with handoff=True.

Changes:
- Add handoff INTEGER column to tasks table with migration support
- Add handoff parameter to block_task() function
- Update _handle_block() to auto-detect handoff from reason patterns
- Modify _record_task_failure() to skip handoff blocks
- Update kanban-worker skill with handoff usage guidance
- Add comprehensive tests for handoff functionality

Fixes NousResearch#29027

# Conflicts:
#	hermes_cli/kanban_db.py
#	tools/kanban_tools.py
@AllynSheep
AllynSheep force-pushed the fix/kanban-handoff-retry-loop branch from c22e5f9 to f4f2424 Compare May 20, 2026 07:34
@MKI13

MKI13 commented May 20, 2026

Copy link
Copy Markdown

Autofix update: I diagnosed the latest failing test run after the attribution failure was already resolved. The remaining failures were:

  • tests/plugins/web/test_web_search_provider_plugins.py expected seven web providers while the branch now registers bundled xAI web search too.
  • tests/hermes_cli/test_update_hangup_protection.py used a stale imported _UpdateOutputStream class after hermes_cli.main reloads.

I prepared and verified a fix in commit 4a8bb20 on MKI13:autofix/pr-29064-test-fix. I could not push directly to AllynSheep/fix/kanban-handoff-retry-loop because GitHub returned 403 to MKI13, so I opened a PR against the contributor branch here:

AllynSheep#1

Verification:

  • /home/marios/.hermes/hermes-agent/venv/bin/python -m pytest tests/plugins/web/test_web_search_provider_plugins.py tests/hermes_cli/test_update_hangup_protection.py -q: 64 passed
  • /home/marios/.hermes/hermes-agent/venv/bin/python -m ruff check tests/plugins/web/test_web_search_provider_plugins.py tests/hermes_cli/test_update_hangup_protection.py: passed

@teknium1

Copy link
Copy Markdown
Contributor

This is already fixed on current main, so this PR is superseded.

Automated hermes-sweeper review evidence:

  • hermes_cli/kanban_db.py:2843 defines _has_sticky_block(), which distinguishes worker/operator kanban_block events from circuit-breaker gave_up blocks.
  • hermes_cli/kanban_db.py:2923 has recompute_ready() skip sticky blocked tasks, so review-required: handoffs are not promoted back to ready and respawned.
  • hermes_cli/kanban_db.py:4163 shows block_task() emits the blocked event that drives that guard.
  • tests/hermes_cli/test_kanban_blocked_sticky.py:56 covers the exact regression: a review-required: worker block stays blocked across dispatcher ticks.
  • The fix landed in 34120a0ae20ae3fc23eeb304efd750e2d2c83c87 (fix(kanban): worker-initiated block must not be auto-promoted (#28712)), included in v2026.5.28.

Thanks for the concrete fix attempt and the detailed trace; the same failure mode is now handled on main without adding a separate handoff column/tool parameter.

@teknium1 teknium1 closed this Jun 15, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kanban dispatcher retries kanban_block with 'review-required:' reasons up to failure_limit, causing duplicate worker runs of finished tasks

5 participants