fix(kanban): guard needs_input unblock from non-interactive sessions - #59906
Open
jeslyntsw wants to merge 2 commits into
Open
fix(kanban): guard needs_input unblock from non-interactive sessions#59906jeslyntsw wants to merge 2 commits into
jeslyntsw wants to merge 2 commits into
Conversation
Contributor
|
Thanks for tracing the CLI path; current Problems
Suggested changes
This is an automated hermes-sweeper review. |
Detect dispatched workers from dispatcher-recorded worker PIDs and process ancestry, rather than trusting mutable environment variables alone. Allow non-task-scoped orchestrator profiles to unblock needs_input gates.
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.
Problem
A worker profile with the
terminaltool can bypass thekanban_unblockmodel-tool guard (_check_kanban_orchestrator_modechecksHERMES_KANBAN_TASK) by callinghermes kanban unblock <task_id>as a shell command. The terminal tool has no such guard, so the CLI path is unrestricted.Observed in production: a dispatched planner worker blocked a card with
kind: needs_input(awaiting human review), then usedterminalto callhermes kanban unblockvia CLI, unblocking itself. The next run claimed the card and proceeded as if the human had approved, creating 6 downstream cards.The model-tool path (
tools/kanban_tools.py) is already guarded. This PR closes the CLI gap.Fix
Add a DB-level guard in
unblock_task()(hermes_cli/kanban_db.py) soneeds_inputblocks cannot be unblocked from non-interactive sessions. Detection:HERMES_KANBAN_TASKis set ORHERMES_PROFILEis set to a non-default profile. The guard fires before any status mutation, inside awrite_txnso a raise rolls back cleanly (task stays blocked, block_kind preserved).needs_inputis gated. Other block kinds (capability,transient,review-required,dependency, untyped) are unaffected — workers can still unblock those.hermes_cli/kanban.py) — catchesValueError, prints clear error, returns non-zerotools/kanban_tools.py) — catches at existing exception boundary, returnstool_errorplugin_api.py) — does not catch, but dashboard runs asHERMES_PROFILE=defaultso the guard never fires there; uncaught → 500 is a safe fail-closedRefused: cannot unblock needs_input block from non-interactive session. This block requires human (Main/default) approval.Files changed
hermes_cli/kanban_db.py_is_noninteractive_unblock_session()+ guard insideunblock_task()before stale-run recovery / status mutationhermes_cli/kanban.py_cmd_unblockcatchesValueError, prints kanban error, marks task failed for handler-level nonzero returntests/hermes_cli/test_kanban_block_kinds.pyVerification
uv run pytest tests/hermes_cli/test_kanban_block_kinds.py -q→ 19 passedHERMES_HOME: worker env attemptedhermes kanban unblock <needs_input>→ refusal printed, task remainedblocked needs_input; Main/default unblocked same task →ready needs_inputNon-blocking note
hermes_cli.maindoes not currently propagate subcommand return codes to the shell process exit status (pre-existing broader behavior). The_cmd_unblockhandler returns non-zero correctly on refusal; the shell exit code may still read 0. The security guard itself works — mutation is prevented regardless. Separate CLI return-code cleanup if desired.