Skip to content

fix(agent): gate the kanban worker protocol on dispatch context, not tool presence - #68608

Open
Sora-bluesky wants to merge 2 commits into
NousResearch:mainfrom
Sora-bluesky:fix/issue-68592
Open

fix(agent): gate the kanban worker protocol on dispatch context, not tool presence#68608
Sora-bluesky wants to merge 2 commits into
NousResearch:mainfrom
Sora-bluesky:fix/issue-68592

Conversation

@Sora-bluesky

Copy link
Copy Markdown
Contributor

Fixes #68592.

Problem

The kanban worker task-execution protocol (KANBAN_GUIDANCE — "You have been assigned ONE task… Call kanban_show() first") was injected into the system prompt on mere kanban_show tool presence. But _check_kanban_mode (tools/kanban_tools.py) exposes the kanban tool surface in two situations: dispatcher-spawned workers (HERMES_KANBAN_TASK set) and profiles with kanban in their toolsets config (orchestrator mode, no task id). On an orchestrator profile, every agent run — notably every cron run — was instructed to call kanban_show() first, which fails with task_id is required and logs a warning per run. The gating comment in agent_init.py ("kanban_show tool is present iff HERMES_KANBAN_TASK is set") described a constraint that no longer held.

Fix

Three-way split at both injection sites (the session-static resolution in agent_init.py and the bypass-agent_init fallback in agent/system_prompt.py):

  • HERMES_KANBAN_TASK set + tool present → full worker protocol, unchanged.
  • Tool present, no task id → new lean KANBAN_ORCHESTRATOR_GUIDANCE: board-routing rules only, explicitly stating there is no assigned task and kanban_show() needs an explicit task_id.
  • No tool → nothing, unchanged.

The orchestrator block deliberately preserves the routing rules that were folded into the always-injected guidance when the standalone kanban-orchestrator skill was removed (#50473): discover profiles before assigning (the dispatcher silently drops cards with unknown assignees), express dependencies via parents=[...], never invent created-card ids, attach artifacts instead of pasting links, and don't shell out to hermes kanban. Removing the guidance wholesale would have regressed those.

The env-var gate matches how workers are actually spawned: _default_spawn starts the worker host-locally with HERMES_KANBAN_TASK in Popen(env=...); Docker/SSH/Modal are terminal backends inside that process, not separate spawn paths. (Custom plugin spawn_fn implementations own their environment contract.)

Operational note

Durable sessions restore their persisted system prompt verbatim, so an interactive orchestrator session resumed from before this fix keeps the old mandatory-kanban_show() text until its prompt is rebuilt. Cron runs are unaffected (each run gets a fresh session). No cache invalidation is attempted here — that's a separate design decision; #68598 (input-fingerprint restore gating) provides the general mechanism.

Tests

  • RED-first: new test_kanban_guidance_not_in_orchestrator_profile_prompt (kanban toolset via config.yaml, no env var → tool surface present, worker protocol absent, board guidance present) failed before the fix.
  • New test_kanban_guidance_fallback_three_way_split covers the system_prompt.py fallback directly (deletes _kanban_worker_guidance to simulate bypassing agent_init).
  • tests/tools/test_kanban_tools.py: 116 passed. tests/agent/test_system_prompt.py + tests/agent/test_platform_hint_desktop.py: 32 passed. The 8 failures in tests/hermes_cli/test_kanban_core_functionality.py on this Windows machine reproduce identically on clean upstream/main (pre-existing, unrelated).

🤖 Generated with Claude Code

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for carrying the full worker/orchestrator split.

Current main still has the reported defect: tools/kanban_tools.py:92-108 exposes kanban_show for a profile configured with the kanban toolset even without HERMES_KANBAN_TASK, while agent/agent_init.py:1420-1423 injects the worker protocol on tool presence alone. That protocol requires kanban_show() first (agent/prompt_builder.py:215-219), and the handler rejects an unscoped call at tools/kanban_tools.py:404-408.

The PR also covers the separate bypass-init injection at agent/system_prompt.py:238-243, rather than fixing only the primary initialization path. Its separate orchestrator guidance fits the intent of 84e1d31e5442eeff0bfcf1c2ffab6acf7fe95f45, which folded routing rules into the injected Kanban guidance when the standalone skills were removed.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 30, 2026
@Sora-bluesky

Copy link
Copy Markdown
Contributor Author

Thanks for tracing both injection sites. The bypass-init one at agent/system_prompt.py:238-243 is the reason this is not a one-line gate: fixing only the toolset path in agent/agent_init.py would leave a profile that skips init still receiving the worker protocol, and the handler at tools/kanban_tools.py:404-408 would keep rejecting the call the protocol asks for first.

@roboticsalign

Copy link
Copy Markdown

Independently verified against current main: the reported failure is reproducible in an interactive Desktop/orchestrator session when the profile has the kanban toolset but no HERMES_KANBAN_TASK. The current code injects the worker protocol, which prompts an unscoped kanban_show() call and produces task_id is required.

PR #68608 fixes that failure through the three-way worker/orchestrator/no-Kanban split while preserving board-routing guidance. It merges cleanly with current main, and the relevant suites pass after the merge (66 passed). I found no blocking issues.

@alt-glitch alt-glitch added needs-decision Awaiting maintainer decision before any implementation and removed sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) labels Aug 12, 2026
… presence

Orchestrator profiles (kanban in the toolsets config) carry kanban_show
without HERMES_KANBAN_TASK, but the worker task-execution protocol was
injected on mere tool presence — so every cron run on such a profile was
told to call kanban_show() first and recorded a 'task_id is required'
error (issue NousResearch#68592). Gate both injection sites (the session-static
resolution in agent_init and the bypass fallback in system_prompt) on
HERMES_KANBAN_TASK being set, and fix the stale 'present iff
HERMES_KANBAN_TASK' comment that hid the gap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…task

Addresses review: removing KANBAN_GUIDANCE entirely from orchestrator
profiles (kanban toolset, no HERMES_KANBAN_TASK) would also drop the
routing rules that were folded into the always-injected guidance when
the standalone kanban-orchestrator skill was removed — profile
discovery before assigning (unknown assignees are silently dropped),
parents=[...] dependencies, no phantom created-card ids, attachments,
and the no-shell-out rule. Split the guidance: dispatcher-spawned
workers keep the full task-execution protocol, tool-only profiles get a
lean board-routing block with no mandatory kanban_show() first step.
The system_prompt fallback mirrors the same three-way split and is now
covered directly by a bypass-agent_init test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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 needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cron agents without HERMES_KANBAN_TASK get mandatory kanban_show protocol

4 participants