Skip to content

fix(kanban): keep delegated results in worker turn - #63218

Closed
MustafaK99 wants to merge 1 commit into
NousResearch:mainfrom
MustafaK99:fix/kanban-delegate-delivery
Closed

fix(kanban): keep delegated results in worker turn#63218
MustafaK99 wants to merge 1 commit into
NousResearch:mainfrom
MustafaK99:fix/kanban-delegate-delivery

Conversation

@MustafaK99

Copy link
Copy Markdown
Contributor

What does this PR do?

Dispatcher-spawned Kanban workers now treat detached async delivery as unsupported. When a worker calls delegate_task, Hermes reuses the existing synchronous fallback and returns the consolidated child result in the same turn, before the one-shot worker process can exit.

The same finite-runtime capability also prevents terminal completion watchers from promising delivery after a Kanban worker exits. Long-lived CLI, TUI, Desktop, and messaging-gateway sessions retain their existing async behavior.

The root cause was a lifecycle mismatch: top-level model delegation is backgrounded, while a Kanban worker is a finite subprocess. The background completion queue assumes its parent session remains alive, so a delayed child could outlive its only consumer and leave the card running until the dispatcher classified the dead worker as crashed or protocol_violation.

Related Issue

Fixes #63169

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • Mark dispatcher-spawned Kanban workers as unable to receive detached async completions.
  • Route background delegation through the existing synchronous fallback on that finite surface.
  • Make unsupported-delivery diagnostics runtime-generic rather than HTTP-specific.
  • Add a delayed-child regression proving the parent waits, receives the review verdict in-turn, creates no async delegation record, and queues no orphaned completion.
  • Add capability coverage for the Kanban worker environment.

How to Test

  1. On the parent commit, run the focused regression and observe both new tests fail: the capability reports True and delegate_task allocates a detached async record.

  2. On this branch, run:

    scripts/run_tests.sh \
      tests/gateway/test_async_delivery_capability.py \
      tests/gateway/test_session_context_inheritance.py \
      tests/tools/test_async_delegation.py \
      tests/hermes_cli/test_kanban_goal_mode.py -q
  3. Confirm all 53 directly relevant tests pass. The broader delegation and Kanban tool suites also pass (253 tests), for 306 focused tests total.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Linux under WSL2

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A; runtime contract comments and diagnostics were updated in code
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A; no config changes
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A; existing capability/fallback architecture is reused
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — five-file Windows-footgun scan passes
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A; no model-facing schema change

Screenshots / Logs

53 passed: async-delivery capability, session-context inheritance,
           async delegation, and Kanban goal mode
156 passed: full delegation suite
97 passed: full Kanban tools suite
Ruff: passed
Windows footgun scan: passed (5 files)

Dispatcher-spawned Kanban workers are finite one-shot processes, so detached delegation completions can outlive their only consumer. Mark that runtime as unable to deliver async completions and reuse the synchronous delegation fallback, returning required child results before the worker exits.\n\nAlso make unsupported-session notes runtime-generic and cover the delayed-child lifecycle regression.\n\nRefs NousResearch#63169
@MustafaK99
MustafaK99 marked this pull request as ready for review July 12, 2026 14:29
@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint tool/delegate Subagent delegation P3 Low — cosmetic, nice to have labels Jul 12, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused fix. The current-main path confirms the premise: dispatcher workers are launched as finite chat -q processes (hermes_cli/kanban_db.py:8058-8069, :8107, :8200-8202), while top-level delegation is forcibly detached (run_agent.py:5790-5809). With no session capability bound, async_delivery_supported() defaults to true (gateway/session_context.py:330-346), so delegate_task dispatches to the daemon executor (tools/delegate_tool.py:2795-2827) even though daemon workers intentionally do not survive process exit (tools/daemon_pool.py:12-24).

The change uses the established unsupported-delivery fallback rather than adding a tool, schema, configuration option, or new delivery mechanism. It also keeps asynchronous behavior for normal long-lived sessions. No blocking correctness issue was found from the diff and current-main inspection.

This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #70133 — your commit was cherry-picked onto current main with your authorship preserved in git history (merge SHA 4c88e21). The only reconciliation needed was merging your runtime-generic diagnostics wording with the stateless-channel messages that landed in #66617 after you opened this. Thanks for the clean fix and the delayed-child regression test — the finite-runtime framing was exactly right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state tool/delegate Subagent delegation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: delegate_task results are lost when called from Kanban workers; parent exits even with goal_mode

3 participants