Skip to content

fix(delegate): block kanban lifecycle tools for delegated children - #541

Open
hashbender wants to merge 1 commit into
mainfrom
mirror/pr-56651
Open

fix(delegate): block kanban lifecycle tools for delegated children#541
hashbender wants to merge 1 commit into
mainfrom
mirror/pr-56651

Conversation

@hashbender

Copy link
Copy Markdown
Owner

What does this PR do?

Prevents children spawned via delegate_task from holding kanban lifecycle tools pinned to their parent's card.

Children run in-process (ThreadPoolExecutor) and inherit the parent's environment, including the HERMES_KANBAN_TASK pin. A delegated leaf that calls kanban_complete / kanban_block therefore acts on the parent worker's card — we observed a delegated child closing its parent's card mid-task in our production fleet.

Two complementary mechanisms, because a name-strip alone is insufficient:

  1. Blocklist: the nine kanban tools join DELEGATE_BLOCKED_TOOLS. _strip_blocked_tools derives its strip set from the blocklist, so the whole kanban toolset is dropped from inherited child toolsets — the same blocklist/strip-set lockstep the existing cronjob block relies on. The list matches TOOLSETS["kanban"]["tools"] exactly (a test enforces the lockstep).
  2. Hard disable: child construction passes disabled_toolsets=["kanban"]. This is load-bearing: model_tools.get_tool_definitions re-adds the kanban toolset to any process whose env carries HERMES_KANBAN_TASK (so dispatcher-spawned workers keep their lifecycle surface even with a restricted chat toolset), and an in-process child inherits that env — the name-strip is silently undone one layer down. The disabled_toolsets subtraction is applied after that re-add, so only it survives.

This also aligns with NousResearch#56386: toolset scoping is a capability decision the delegation layer makes, and the env-based re-add was a bypass of that boundary for children.

Workers still complete their own cards after consolidating child output; children return text only.

Related Issue

Fixes NousResearch#56647

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • tools/delegate_tool.py — add the nine kanban_* tools to DELEGATE_BLOCKED_TOOLS; add _CHILD_DISABLED_TOOLSETS = ["kanban"] and pass it as disabled_toolsets in _build_child_agent's AIAgent construction.
  • tests/tools/test_delegate.py — four regression tests: toolset strip, blocklist/TOOLSETS["kanban"] lockstep, child construction under HERMES_KANBAN_TASK (asserts kanban both stripped from enabled_toolsets and present in disabled_toolsets), and a characterization test that the model_tools env re-add is defeated by disabled_toolsets (if the re-add is ever removed upstream, that test flags the guard for re-evaluation).

How to Test

  1. pytest tests/tools/test_delegate.py -q — 155 tests pass (4 new).
    Full suite via scripts/run_tests.sh: 37,695 passed, 39 failed — all 39 failures reproduce identically on unmodified main in my environment (host-credential and timing-sensitive tests, e.g. test_anthropic_adapter.py, test_gateway_service.py); this change introduces zero new failures.
  2. Unit-level repro of the leak on main without this patch:
    import os, model_tools
    os.environ["HERMES_KANBAN_TASK"] = "some-card"
    defs = model_tools.get_tool_definitions(enabled_toolsets=["terminal"], quiet_mode=True)
    print([t["function"]["name"] for t in defs if t["function"]["name"].startswith("kanban_")])
    # kanban tools present even though only 'terminal' was enabled
  3. End-to-end: run a kanban dispatcher worker that calls delegate_task and instruct the child to "mark the task complete" — with this patch the child has no kanban tools; the parent's card stays open until the parent completes it.

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 (via scripts/run_tests.sh; the only failures are pre-existing in my environment and fail identically on unmodified main — see How to Test)
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26 (Apple Silicon), Python 3.11

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A (behavior documented in code comments and tests)
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A (no config keys touched)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — no OS-specific code; tests use patch.dict(os.environ, ...)
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A (no schema changes; toolset availability only)

Mirror-of: NousResearch#56651
NousResearch#56651

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

delegate_task children inherit HERMES_KANBAN_TASK and can complete/block the parent's kanban card

1 participant