NousResearch/hermes-agent

unlink_tasks missing recompute_ready call fix

Cluster 22459. Data as of

Nothing open on GitHub. Fix merged in #22669 on 9 May 2026. Check it covers your case.

The short answer

0open issues
0open PRs
4items grouped
Known?
Yes. 4 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #22669. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #22669. That is separate from the fix event.
Still open
Nothing open on GitHub.

These issues and PRs concern a bug where unlink_tasks does not trigger recompute_ready, potentially leaving tasks stuck. Multiple fix attempts and a salvage PR address the same missing call.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #22669 fix(kanban): call recompute_ready after unlink_tasks (salvage #22646)

    merged to main

    files: hermes_cli/kanban_db.py, scripts/release.py, tests/hermes_cli/test_kanban_db.py

    Show the diff
    • hermes_cli/kanban_db.py
      @@ -1504,7 +1504,14 @@ def unlink_tasks(conn: sqlite3.Connection, parent_id: str, child_id: str) -> boo
                       conn, child_id, "unlinked",
                       {"parent": parent_id, "child": child_id},
                   )
      -        return cur.rowcount > 0
      +        removed = cur.rowcount > 0
      +    if removed:
      +        # Dependency edge removed — re-evaluate promotion eligibility for the
      +        # child immediately.  Matches the contract of complete_task and
      +        # unblock_task; without this the child stays stuck in todo until the
      +        # next dispatcher tick or a manual `hermes kanban recompute` (issue #22459).
      +        recompute_ready(conn)
      +    return removed
       
       
       def parent_ids(conn: sqlite3.Connection, task_id: str) -> list[str]:
    • scripts/release.py
      @@ -64,6 +64,7 @@
           "[redacted:email]": "liquidchen",
           "[redacted:email]": "subtract0",
           "[redacted:email]": "qWaitCrypto",
      +    "[redacted:email]": "wesleysimplicio",
           "[redacted:email]": "uzunkuyruk",
           "[redacted:email]": "Zhekinmaksim",
           "[redacted:email]": "KvnGz",
    • tests/hermes_cli/test_kanban_db.py
      @@ -966,3 +966,37 @@ def wal_blocking_connect(*args, **kwargs):
           tasks = kb.list_tasks(conn)
           assert any(row.id == t for row in tasks)
           conn.close()
      +
      +
      +def test_unlink_tasks_triggers_recompute_ready(kanban_home):
      +    """Regression test for issue #22459.
      +
      +    Removing a dependency via unlink_tasks must immediately promote the child
      +    to ready when all remaining parents are done — same contract as
      +    complete_task and unblock_task.
      +
      +    Before the fix, child stayed 'todo' indefinitely after unlink; only the
      +    next dispatcher tick or a manual 'hermes kanban recompute' would promote it.
      +    """
      +    with kb.connect() as conn:
      +        # A is done.
      +        a = kb.create_task(conn, title="parent-done")
      +        kb.complete_task(conn, a)
      +
      +        # C is running (not done) — blocks child B.
      +        c = kb.create_task(conn, title="parent-running")
      +        kb.claim_task(conn, c, claimer="worker:1")
      +
      +        # B depends on both A (done) and C (running) → stays todo.
      +        b = kb.create_task(conn, title="child", parents=[a, c])
      +        assert kb.get_task(conn, b).status == "todo"
      +
      +        # Remove the blocking dependency C → B.
      +        removed = kb.unlink_tasks(conn, c, b)
      +        assert removed is True
      +
      +        # B's only remaining parent is A (done) → must be ready immediately.
      +        assert kb.get_task(conn, b).status == "ready", (
      +            "child should promote to ready immediately after unlink_tasks "
      +            "removes its last blocking dependency"
      +        )

2 PRs closed without merging

From the close comments: done elsewhere 1 · merged via another change 1

  • #22454 fix(kanban): trigger recompute_ready after unlink_tasks · done elsewhere → 0c22434, #22459
  • #22646 fix(kanban): call recompute_ready after unlink_tasks removes a dependency · merged via another change → #22669
Closed issues · 1
  • Closed#22459[Bug]: unlink_tasks does not trigger recompute_ready — tasks stuck in todo without dispatcher
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.50: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Merged PRs
#22669
Closed issues
1
Attempts
2 PRs closed without merging
Fix link checked
9 May 2026

For your agent

The same facts, typed.