Skip to content

fix(kanban): preserve initially blocked human gates - #64830

Open
salimhamed wants to merge 1 commit into
NousResearch:mainfrom
salimhamed:fix/kanban-initial-block-sticky-gate
Open

fix(kanban): preserve initially blocked human gates#64830
salimhamed wants to merge 1 commit into
NousResearch:mainfrom
salimhamed:fix/kanban-initial-block-sticky-gate

Conversation

@salimhamed

Copy link
Copy Markdown
Contributor

Problem

_has_sticky_block decides whether a blocked task is a deliberate human gate
(which recompute_ready must not auto-promote) by inspecting the task's most
recent blocked/unblocked event. But a task created with
--initial-status blocked — the canonical way to stand up an immediate human
gate — emits only a created event (payload status="blocked"); it has no
blocked event yet.

So such a gate was treated as non-sticky. With no unfinished parents, the empty
parent set is vacuously satisfied and recompute_ready promotes the gate to
ready; the dispatcher then claims it and spawns a worker on a card that was
meant to wait for a human.

Symptom

An initially-blocked human gate is silently promoted → dispatched → and if the
spawned worker re-blocks for input, the same-cause re-block trips
BLOCK_RECURRENCE_LIMITblock_loop_detected → the card is routed out and
archived — instead of simply sitting blocked awaiting a human.

Fix

Treat a created event whose payload records status="blocked" as a sticky
block, so recompute_ready leaves it blocked until an explicit unblock.
Behavior for circuit-breaker/direct-DB blocks (no explicit human-block signal)
is unchanged. Adds a regression test.

@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state P3 Low — cosmetic, nice to have labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused regression fix. The premise is present on current origin/main: create_task() records created with payload.status at hermes_cli/kanban_db.py:2670-2683, but _has_sticky_block() only examines blocked/unblocked at hermes_cli/kanban_db.py:3273-3279. recompute_ready() then considers the blocked task for promotion at hermes_cli/kanban_db.py:3317-3365.

The proposed event ordering preserves explicit unblock_task() semantics, which emits unblocked at hermes_cli/kanban_db.py:5110-5113, while retaining the existing circuit-breaker/direct-write recovery behavior. The new regression test exercises the parentless, initially blocked path directly.

Automated hermes-sweeper review.

@GottZ

GottZ commented Aug 3, 2026

Copy link
Copy Markdown

This was generated by AI during triage.

Summary

Twenty-eight PRs address or reference the two issues: most repair the missing create-time blocked lifecycle event that lets recompute_ready() release and dispatch an approval gate, while others broaden the scope into authorization, stale-state recovery, archival, promotion, or body updates. The focused event-emission diffs match the reported cause while preserving circuit-breaker recovery.

Related pull requests

Duplicates

#39085, #41497, #46274, #46565, #48437, #61890, #71861, #71977, #72030, and the final narrow #76718 substantially duplicate #34735’s create-time blocked event; #39832, #48253, and #64830 instead duplicate the intent through created-payload inference, while #35832, #66993, #69679, #70733, #71147, #69531, and #74839 add separable broader behavior.

Suggested consolidation

Keep #34735 open with its recorded salvage path: transplant the narrow post-created event insertion and lifecycle tests onto current main. Despite keep_open reviews on #39085, #41497, #46565, #64830, #71861, and #71977, close them as duplicates of #34735 because their diffs show either the same event repair or the less complete payload-inference approach; author action on #69531 is to rebase and reconcile its broader recorded best fix with current main, while #69679 must initialize recurrence to 0, #34756/#35832/#66993/#70733/#71147 should split salvageable extras, and #76765 should remain separate pending the requested audit/privacy assertions.

Complex graph

flowchart TD
    classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
    classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
    classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
    classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
    classDef best stroke-width:3px,stroke:#b45309
    classDef target stroke-width:3px,stroke:#4338ca
    I39609(["issue #39609 (open)"])
    I47777(["issue #47777 (open)"])
    subgraph Dup34735 ["PRs duplicating each other"]
        P34735["PR #34735 (open)"]
        P35832["PR #35832 (open)"]
        P39085["PR #39085 (open)"]
        P39832["PR #39832 (closed)"]
        P41497["PR #41497 (open)"]
        P43479["PR #43479 (closed)"]
        P46274["PR #46274 (closed)"]
        P46565["PR #46565 (open)"]
        P48253["PR #48253 (closed)"]
        P48437["PR #48437 (closed)"]
        P60100["PR #60100 (closed)"]
        P61890["PR #61890 (closed)"]
        P64830["PR #64830 (open)"]
        P70733["PR #70733 (open)"]
        P71147["PR #71147 (open)"]
        P71861["PR #71861 (open)"]
        P71977["PR #71977 (open)"]
        P72030["PR #72030 (closed)"]
        P74839["PR #74839 (closed)"]
        P76718["PR #76718 (closed)"]
    end
    P64830 -.->|partial| I39609
    P64830 -.->|partial| I47777
    class I39609 open
    class I47777 open
    class P34735 open
    class P35832 open
    class P39085 open
    class P39832 closed
    class P41497 open
    class P43479 closed
    class P46274 closed
    class P46565 open
    class P48253 closed
    class P48437 closed
    class P60100 closed
    class P61890 closed
    class P64830 open
    class P70733 open
    class P71147 open
    class P71861 open
    class P71977 open
    class P72030 closed
    class P74839 closed
    class P76718 closed
    class P34735 best
    class P34735 best
    class P64830 target
    click I39609 "https://github.com/NousResearch/hermes-agent/issues/39609"
    click I47777 "https://github.com/NousResearch/hermes-agent/issues/47777"
    click P34735 "https://github.com/NousResearch/hermes-agent/pull/34735"
    click P35832 "https://github.com/NousResearch/hermes-agent/pull/35832"
    click P39085 "https://github.com/NousResearch/hermes-agent/pull/39085"
    click P39832 "https://github.com/NousResearch/hermes-agent/pull/39832"
    click P41497 "https://github.com/NousResearch/hermes-agent/pull/41497"
    click P43479 "https://github.com/NousResearch/hermes-agent/pull/43479"
    click P46274 "https://github.com/NousResearch/hermes-agent/pull/46274"
    click P46565 "https://github.com/NousResearch/hermes-agent/pull/46565"
    click P48253 "https://github.com/NousResearch/hermes-agent/pull/48253"
    click P48437 "https://github.com/NousResearch/hermes-agent/pull/48437"
    click P60100 "https://github.com/NousResearch/hermes-agent/pull/60100"
    click P61890 "https://github.com/NousResearch/hermes-agent/pull/61890"
    click P64830 "https://github.com/NousResearch/hermes-agent/pull/64830"
    click P70733 "https://github.com/NousResearch/hermes-agent/pull/70733"
    click P71147 "https://github.com/NousResearch/hermes-agent/pull/71147"
    click P71861 "https://github.com/NousResearch/hermes-agent/pull/71861"
    click P71977 "https://github.com/NousResearch/hermes-agent/pull/71977"
    click P72030 "https://github.com/NousResearch/hermes-agent/pull/72030"
    click P74839 "https://github.com/NousResearch/hermes-agent/pull/74839"
    click P76718 "https://github.com/NousResearch/hermes-agent/pull/76718"
Loading

Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label).

Cross-PR triage: Reviewed 28 pull requests and 2 issues in this complex. Each diff was read against this issue; Assessment working set: 505 kB of PR diffs, 53 kB of issue/PR text, 35 kB of discussion (55 comments), 74 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

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 sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants