Skip to content

fix(kanban): surface the link-time demotion of a ready child to todo - #111005

Open
kokhlo wants to merge 1 commit into
NousResearch:mainfrom
kokhlo:kokhlo/kanban-link-gate-110996
Open

kokhlo wants to merge 1 commit into
NousResearch:mainfrom
kokhlo:kokhlo/kanban-link-gate-110996

Conversation

@kokhlo

@kokhlo kokhlo commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

A card linked under an unfinished parent is demoted ready -> todo by link_tasks with no trace: no event, no operator signal. The card then sits in todo (or, on releases before #106550, after a promote --force that claimed success, gets claim_rejected parents_not_done at claim time) and the only evidence is buried in task_events. Reported in #110996 as the delegation shape "spawn a support card for the task I am blocked on" producing a silent deadlock.

Root cause: link_tasks (hermes_cli/kanban_db.py) runs the demotion as a bare UPDATE — the linked event says an edge was added, nothing says the child's status was gated. The claim-time re-check in claim_task is deliberate ("never ready -> running with an undone parent, whichever writer set 'ready'") and is not changed here.

Fix — make the gate observable at every surface, without changing any routing decision:

  • link_tasks now returns whether it demoted a ready child, and records a dependency_wait event ({"reason": "parent_not_done", "demoted": true, "parent": <id>}) on the child when the demotion fires, so the board's event stream explains the flip to todo.
  • hermes kanban link prints a note naming the blocking parent and pointing at hermes kanban unlink when the link gated the child.
  • The kanban_link orchestrator tool reports gated: true (+ gated_by) in its success payload instead of a bare ok.
  • Docs: the kanban_link row in the orchestrator tools table now documents the gate.

bool return of link_tasks keeps the existing call sites (CLI, kanban_link tool, dashboard plugin API, tests) working unchanged — the dashboard plugin ignores the return value, which is safe: its UI has its own link diagnostics.

Testing

On a fresh main clone (v0.21.3, 345cd2b):

$ python -m pytest tests/hermes_cli/test_kanban_db.py tests/hermes_cli/test_kanban_cli.py tests/tools/test_kanban_tools.py -q
80 passed, 1 skipped

$ python -m pytest tests/hermes_cli/test_kanban_notify.py tests/hermes_cli/test_kanban_block_kinds.py tests/hermes_cli/test_kanban_transfer.py tests/hermes_cli/test_kanban_worktree_teardown.py tests/hermes_cli/test_kanban_review_lifecycle_complete.py -q
82 passed

RED verified: with the three source files reverted to main (tests kept), the two new db-layer tests and the CLI test fail (gated missing / no dependency_wait event / no warning), then pass with the fix. ruff check clean on all touched files; new lines verified untouched by ruff format --diff.

Fixes #110996

A ready child linked under an unfinished parent drops to todo with no
event and no operator signal; the only trace used to be claim_rejected
after a forced promote. Record a dependency_wait event when the demotion
fires, return the gate from link_tasks, warn in the CLI link command,
report gated in the kanban_link tool, and document the gate.

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/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.

Cards created as children of a blocked parent are unclaimable by construction: claim_task re-rejects parents_not_done even after promote --force

2 participants