fix(delegate): block kanban lifecycle tools for delegated children - #541
Open
hashbender wants to merge 1 commit into
Open
fix(delegate): block kanban lifecycle tools for delegated children#541hashbender wants to merge 1 commit into
hashbender wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Prevents children spawned via
delegate_taskfrom 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_TASKpin. A delegated leaf that callskanban_complete/kanban_blocktherefore 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:
DELEGATE_BLOCKED_TOOLS._strip_blocked_toolsderives its strip set from the blocklist, so the wholekanbantoolset is dropped from inherited child toolsets — the same blocklist/strip-set lockstep the existingcronjobblock relies on. The list matchesTOOLSETS["kanban"]["tools"]exactly (a test enforces the lockstep).disabled_toolsets=["kanban"]. This is load-bearing:model_tools.get_tool_definitionsre-adds thekanbantoolset to any process whose env carriesHERMES_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. Thedisabled_toolsetssubtraction 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
Changes Made
tools/delegate_tool.py— add the ninekanban_*tools toDELEGATE_BLOCKED_TOOLS; add_CHILD_DISABLED_TOOLSETS = ["kanban"]and pass it asdisabled_toolsetsin_build_child_agent'sAIAgentconstruction.tests/tools/test_delegate.py— four regression tests: toolset strip, blocklist/TOOLSETS["kanban"]lockstep, child construction underHERMES_KANBAN_TASK(asserts kanban both stripped fromenabled_toolsetsand present indisabled_toolsets), and a characterization test that themodel_toolsenv re-add is defeated bydisabled_toolsets(if the re-add is ever removed upstream, that test flags the guard for re-evaluation).How to Test
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 unmodifiedmainin my environment (host-credential and timing-sensitive tests, e.g.test_anthropic_adapter.py,test_gateway_service.py); this change introduces zero new failures.mainwithout this patch:delegate_taskand 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
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass (viascripts/run_tests.sh; the only failures are pre-existing in my environment and fail identically on unmodifiedmain— see How to Test)Documentation & Housekeeping
docs/, docstrings) — N/A (behavior documented in code comments and tests)cli-config.yaml.exampleif I added/changed config keys — N/A (no config keys touched)CONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/Apatch.dict(os.environ, ...)Mirror-of: NousResearch#56651
NousResearch#56651