Skip to content

fix(kanban): report blocking parents when refusing kanban complete - #110323

Open
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-110315
Open

liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-110315

Conversation

@liuhao1024

Copy link
Copy Markdown

What does this PR do?

hermes kanban complete <task-id> printed cannot complete <task-id> (unknown id or terminal state) when the task exists and the actual refusal was an unfinished parent dependency. The dependency invariant was correct; only the error hid the actionable reason.

This PR makes complete_task capture the blocking parents (id, status) at the same authoritative checks that enforce the invariant (the cheap pre-check and the re-check inside the write transaction, so the reason reflects the state the transaction actually refused — not a later re-derived guess), and surfaces them through an opt-in raise_parents_refusal=True flag that raises ParentsNotSatisfiedError. The boolean API (return False) is unchanged for every existing caller. The CLI opts in and now reports:

cannot complete <task-id>: unsatisfied parent dependencies: t_xxxx (blocked), t_yyyy (todo); complete the parents first (done or archived)

Missing id and terminal-state refusals keep the generic message, and no force-complete path is added — the invariant itself is untouched.

Related Issue

Fixes #110315

Type of Change

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

Changes Made

  • hermes_cli/kanban_db.py: added ParentsNotSatisfiedError (carries blockers + completing_task_id) and _unsatisfied_parents() — the same predicate as _parents_satisfied, enumerated in id order; both refusal points in complete_task now raise it when the caller opts in via the new raise_parents_refusal keyword (default False, boolean contract preserved).
  • hermes_cli/kanban.py: _cmd_complete passes raise_parents_refusal=True and formats the captured blockers into the failure message instead of the generic unknown-id/terminal text.
  • tests/hermes_cli/test_kanban_complete_parents_report.py: regression tests for the CLI message, deterministic multi-parent reporting, missing/terminal staying generic, valid completion unchanged, the default boolean contract, and the pre-check→transactional-check race (blockers captured inside the txn).

How to Test

  1. Create a parent and a child, park the parent as a gate, then complete the child:
    hermes kanban create 'awaiting approval' --assignee planner
    hermes kanban create 'source work' --assignee builder --parents <parent-id>   # parent stays unfinished
    hermes kanban complete <child-id> --result 'delivered'
    
    Observed result: cannot complete <child-id>: unsatisfied parent dependencies: <parent-id> (<status>); complete the parents first (done or archived) — and the child is not completed.
  2. pytest tests/hermes_cli/test_kanban_complete_parents_report.py -q — Observed result: 6 passed.
  3. pytest tests/hermes_cli/test_kanban_parent_reopen_invalidation.py tests/hermes_cli/test_kanban_core_functionality.py tests/hermes_cli/test_kanban_db.py tests/hermes_cli/test_kanban_cli.py -q — Observed result: 66 passed, 2 skipped (pre-existing environment-dependent hook/write-guard flakes in the wider -k kanban sweep reproduce identically on a clean upstream/main checkout, with no failures unique to this change).

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: macOS 15 (arm64)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A (docstrings updated in the touched functions)
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (pure Python/SQLite, no platform surface touched)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

hermes kanban complete <id> printed 'unknown id or terminal state' when
the task exists and the real refusal is an unfinished parent dependency.
complete_task now captures the blockers (parent id + status) at the
authoritative checks (pre-check and inside the write txn) and an opt-in
raise_parents_refusal flag surfaces them as ParentsNotSatisfiedError;
the boolean API is unchanged for every other caller. The CLI names the
blockers instead of guessing. Fixes NousResearch#110315.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cron Cron scheduler and job management comp/cli CLI entry point, hermes_cli/, setup wizard labels Sep 13, 2026
JoaoMarcos44 added a commit to JoaoMarcos44/hermes-agent that referenced this pull request Sep 16, 2026
… delegate handoff contract

kanban_complete tool collapsed every complete_task refusal into
'unknown id, stale run, or already terminal'. When a parent reopens
mid-run, a worker with genuinely done work is refused for a reason the
message hides, and the run burns (then crashes, re-queues, and repeats
deterministic work). Name the unsatisfied parents (id, status) from a
read-only task_links mirror of _parents_satisfied so the worker and the
operator complete the gates instead of re-running; unknown-id and
terminal refusals keep the generic text, and the dependency invariant
itself is untouched (no force path).

Complementary to the CLI-surface PRs NousResearch#110323/NousResearch#110330/NousResearch#110334, which
touch hermes_cli/kanban_db.py + hermes_cli/kanban.py; this change is
tool-surface only (tools/kanban_tools.py).

Also surface the delegate_task handoff contract at spawn time: children
cannot close tracked work and must return findings for the parent to
apply, so a delegated card no longer burns a full run before learning
it can never close (NousResearch#113373 ask 1).

Tests: tests/tools/test_kanban_complete_parents_tool.py (6) — parents
named, deterministic multi-parent order, unknown/terminal generic,
happy path, description contract. Proven red on unfixed sources.
teknium1 pushed a commit that referenced this pull request Sep 18, 2026
… delegate handoff contract

kanban_complete tool collapsed every complete_task refusal into
'unknown id, stale run, or already terminal'. When a parent reopens
mid-run, a worker with genuinely done work is refused for a reason the
message hides, and the run burns (then crashes, re-queues, and repeats
deterministic work). Name the unsatisfied parents (id, status) from a
read-only task_links mirror of _parents_satisfied so the worker and the
operator complete the gates instead of re-running; unknown-id and
terminal refusals keep the generic text, and the dependency invariant
itself is untouched (no force path).

Complementary to the CLI-surface PRs #110323/#110330/#110334, which
touch hermes_cli/kanban_db.py + hermes_cli/kanban.py; this change is
tool-surface only (tools/kanban_tools.py).

Also surface the delegate_task handoff contract at spawn time: children
cannot close tracked work and must return findings for the parent to
apply, so a delegated card no longer burns a full run before learning
it can never close (#113373 ask 1).

Tests: tests/tools/test_kanban_complete_parents_tool.py (6) — parents
named, deterministic multi-parent order, unknown/terminal generic,
happy path, description contract. Proven red on unfixed sources.

This branch has not been deployed

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

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kanban complete: report blocking parent dependencies instead of unknown id or terminal state

2 participants